Lightweight JS wrapper of the Tradable API that will make the integration really easy.
JavaScript HTML
Latest commit 7ee8313 Nov 29, 2016 @oizulain oizulain committed with oizulain TP and SL validation correction

README.md

Tradable Core

Tradable lets users trade from any app by connecting multiple brokerages through one modern API. This project is a lightweight JavaScript wrapper of the Tradable API that will make the integration with it really easy.

Build Status npm version Dependency Status Code Climate codecov

NPM

Documentation: https://tradable.github.io/js/docs/

Getting Started

These instructions will help you understand how to get started with Tradable Core. But first things first, in order to be able to connect with our API we need to setup a developer account for you and provide you with an App ID and an App Key. The App ID and App Key identify your app for every request made from it. If you don't have them yet, you can sign up here.

Prerequisities

Tradable core requires jQuery 2.1.4 and it uses it in noConflict mode. Meaning that after Tradable core is executed, the jQuery variable is scoped in the global object 'trEmbJQ'.

Tip! If you want to reuse the same jQuery version, you can either assign the jQuery variable back to its original value ($ = trEmbJQ; or jQuery = trEmbJQ;) or just use it calling the mentioned global object.

Integration

There are two ways of integrating Tradable core into your project:

Option 1 - Link our script directly

If you don't need to bundle Tradable core in your code base, then you can simply link jQuery and our script:

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" type="text/javascript" ></script>
<script src="//js-api.tradable.com/core/1.23/tradable.min.js" type="text/javascript" 
        id="tradable" data-app-id="{your_app_id}" data-app-key="{your_app_key}"></script>
Option 2 - Include our npm module
npm install jquery --save
npm install tradable-core --save

If you decide to go with this approach, you will need to specify the configuration before requiring core:

jQuery = require("jquery");
tradableConfig = {"appId": your-app-id, "appKey": your-app-key};
tradable = require("tradable-core");
//$ = trEmbJQ; // Uncomment if you want to use our jQuery version

How to use

We have used our knowledge building trading applications to create a framework that will make it really easy to implement any trading application. We will start explaining how to use this framework. However, if our framework does not fit you, you can still use the light integration.

Authentication

The first thing you need to solve to trade enable your application is the authentication. The most common way to authenticate with the Tradable API is OAuth2 and there are 2 ways to initiate authentication:

You can open the authentication window in a small window the way Facebook does:

tradable.authenticateWithWindow();

Or you can simply redirect to the authentication page:

tradable.authenticate();
Tradable ready event

If the user authenticates successfully Tradable Core will notify you about it as follows:

tradable.on("myEmbedReadyListener", "embedReady", function() {
        console.log("Trading is enabled: " + tradable.tradingEnabled);
});

The embedReady listener is notified every time that the status of tradable.tradingEnabled changes. As you might guess, if tradable.tradingEnabled is true, it means that the OAuth token was received and the user is successfully authenticated, i.e. you can now execute trades and orders. On the other hand, if you receive an embedReady event and tradable.tradingEnabled is false, you need to show the disconnected state.

Turning the listener off is as easy as:

tradable.off("myEmbedReadyListener", "embedReady");
Selected account

If the authentication is successful, Tradable Core will initialize the users' broker account before calling embedReady. You can access the account just calling: tradable.selectedAccount.

Not only that, Tradable Core will also cache the list of Tradable instruments in tradable.availableInstruments. If you want to access a particular instrument you can use:

var instrument = tradable.getInstrumentFromId("EURUSD"); //synchronous

Note! Some brokers do not provide the full instrument list. In that case, instruments are gradually cached by Tradable Core for the requested prices (before prices are retrieved). All instruments related to to the open positions and pending orders are cached since the beginning.

Trading

Placing trades is really simple, let's say that you want to place a MARKET order to BUY 10.000 EURUSD. This is how it's done:

tradable.placeMarketOrder(10000, "BUY", "EURUSD").then(function(order) {
     // Success
}, function(jqXHR) {
     // Error
});

Tradable Core provides a bunch of additional helper methods to place orders, here are some examples:

Note that not all accounts support all order types, the account object (tradable.selectedAccount) provides information about what is supported: [account.takeProfitSupported, account.stopLossSupported, account.marketOrdersSupport, account.limitOrdersSupport, account.stopOrdersSupport]

Portfolio: Account updates and Prices

In order to keep the UI updated with the changes that happen on the account, we provide a a listener that will request the account snapshot every certain time (700 milliseconds by default) and notify with it. The account snapshot is an object that contains everything you need to know about the user's portfolio: Metrics (snapshot.metrics), Positions (snapshot.positions), Orders (snapshot.orders) and Prices (snapshot.prices).

Here's how you subscribe to it:

tradable.on("myAccountUpdateListener", "accountUpdated", function(snapshot) {
     console.log("New snapshot received: " + JSON.stringify(snapshot));
});

If you want to subscribe to prices for an instrument you can simply add the instrument id to the updates:

tradable.addInstrumentIdToUpdates("myPricesWidget", "EURUSD");
// Now the snapshot retrieved by the "accountUpdated" event will include prices for the specified instrument
// To unsubscribe the prices:
tradable.removeInstrumentIdFromUpdates("myPricesWidget", "EURUSD");

You can customize the account update frequency:

tradable.setAccountUpdateFrequencyMillis(1000); // 1 second updates

And as always you can turn off the updates:

tradable.off("myAccountUpdateListener", "accountUpdated");
Additional events

In addition to the mentioned events, these are the rest of the events that should be handled by the UI to deliver a nice experience:

Starting

The embedStarting event is fired when tradable core receives a token either from the OAuth flow or direct authentication and before the account is initialized. This is useful if you want to have a loading indication that trading is being enabled, this loading indication should start when this listener is called and stopped with the embedReady event.

tradable.on("myStartListener", "embedStarting", function() {});
Executions

The execution listener provides an easy way to listen for new positions, changes in positions (amount or side), new orders, closed positions and cancelled orders. Every time that any of those happens, the listener will be called with an object that provides the new executions.

tradable.on("myNotificationService", "execution", function(execution) {});

The execution object looks like this:

{
    orders: [...],
    cancelledOrders: [...],
    positions: [...],
    closedPositions: [...]
}
Token expiration

This listener gets called when the token expires. Before it's called tradable.tradingEnabled will be set to false and going through the authentication process will be required.

tradable.on("myTokenExpiredListener", "tokenExpired", function() {});
Re-login

Sometimes, when the user connects an account from multiple clients at a time, a re-login might be required to continue trading. When this event is fired, tradable.tradingEnabled will be set to false and the UI should ask the user whether a re-login is desired or not. If a re-login is desired, either tradable.reLogin() or tradable.reLoginForAccount(accountId) should be called to resume trading.

tradable.on("myReloginListener", "reLoginRequired", function() {});
Two factor authentication

Some brokers require the user to use multiple authentication factors. For those, the twoFactorAuthentication listener needs to be used. So far, the only type of two factor authentication we have requires the users to use their phones to pass the two-factor authentication challenge. Therefore, it is not required to send any pin code like other systems usually require.

The detection of the challenge, the completion and the failure are automatically handled by the SDK. In other words, all you need to do is show a notification with the received instruction and hide it according to the events. For every challenge, the listener will be notified with different statuses that can be seen in the JS example below:

tradable.on("my2fAuthListener", "twoFactorAuthentication", function(twoFactorObj) {
    if(twoFactorObj.status === "received") {
        // A notification needs to be shown with the received twoFactorObj.instruction
    } else if(twoFactorObj.status === "passed") {
        // The two factor authentication has been passed and the notification can be hidden
    } else if(twoFactorObj.status === "failed") {
        // Something went wrong and the notification can be hidden, but the received twoFactorObj.error should be displayed
    }
});
Errors

Gets called when a general error occurs, for example an account initialization error due to a password change.

tradable.on("myErrorListener", "error", function(error) {});
Account switch

Gets notified every time the selectedAccount is changed (through the setSelectedAccount method). This is only applicable for apps that support multi-accounts.

tradable.on("myAccountSwitchListener", "accountSwitch", function() {});
Token about to expire

Gets called back every 5 minutes when the remaining token time is less than 30 minutes.

tradable.on("myTokenWillExpireListener", "tokenWillExpire", function(remainingMillis) {});
Rounding

The prices and amounts need to be rounded in order to ensure that they will be accepted by the trading system.

  • roundPrice: Rounds a price for a certain instrument according to the required decimals. To be used for displaying received prices.
  • roundPriceWithIncrement: When the user is entering a price for an order, this method needs to be used to ensure a valid price. The user must always see the final price before sending an order.
  • roundAmount: Rounds an amount (order size) according to the required decimals.
  • roundAmountWithIncrement: Rounds an amount (order size) according to the order size decimals and increments. It is not required to round the amounts according to the increments for them to be accepted by a brokerage, but this method will provide the closest recommended order size.
Calculation utilities

Tradable Core provides a few helper methods to perform different calculations:

Configuration

The following are the configuration (tradableConfig) options that can be customized:

  • tradableConfig.appId (or attr data-app-id): App identifier id (required)
  • tradableConfig.appKey (or attr data-app-key): App identifier key (required)
  • tradableConfig.configId (or attr data-config-id): If your app requires to load different account configurations, you can specify different configuration ids.
  • tradableConfig.redirectURI (or attr data-redirect-uri): Specify to redirect to a different URL than the current one.

Light integration

In order to initialize Tradable Core in light mode you just need to feed it with the Tradable token values:

tradable.initializeWithToken(accessToken, endPoint, expiresIn).then(function() {
        console.log("You can now use the Tradable API calls");
});

Beware! The light integration has limitations:

  • It is only possible to make API calls that require an accountId.
  • on/off listeners can not be used
  • There won't be any instrument caching

License

This project is licensed under the MIT License - see the LICENSE.md file for details