tradable-core
v1.24.2
Published
Lightweight JS wrapper of the Tradable API that will make the integration really easy.
Downloads
4,198
Readme
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.
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.24.2/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:
- Limit order: placeLimitOrder(amount, price, side, instrumentId)
- Stop order: placeStopOrder(amount, price, side, instrumentId)
- Order with protections: placeProtectedOrder(amount, price, side, instrumentId, type, takeProfitPrice, stopLossPrice, currentBidOrAskPrice)
- Cancel order: cancelOrder(orderId)
- Many more...
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. We have 2 types of 2 factor authentication, one requires for the user to send a code and the other requires do user to click a link on their phone.
The listener sends an object, let's call it twoFactorObj
:
- If the
twoFactorObj.requiresUserInput
istrue
, you will need to let the user enter a code and send it throughtradable.submitTwoFactorAuthenticationCode(userCode)
. - If
twoFactorObj.requiresUserInput
is false, the sdk will automatically know when the user has completed the two factor authentication challenge and no method call is required.
The detection of the challenge, the completion and the failure are handled by the SDK. 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:
- calculatePipDistance: Calculates the distance in Pips/Points between prices.
- calculatePositionSizeForRiskAmount: Calculates a position size for an instrument out of a given amount willing to risk.
- calculatePositionSizeForRiskPercentage: Calculates a position size for an instrument out of a given equity percentage willing to risk.
- calculateExpectedProfitOrLoss: Calculates the resulting equity profit or loss for a position size if a take profit or stop loss at a Pips/Points distance is hit.
- calculatePipSize: Calculates the pip size for an instrument.
- roundPrice: Rounds a price for a certain instrument. Note that it is required to round the order prices so that they are not rejected by the brokerages.
Configuration
The following are the configuration (tradableConfig
) options that can be customized:
tradableConfig.appId
(or attrdata-app-id
): App identifier id (required)tradableConfig.appKey
(or attrdata-app-key
): App identifier key (required)tradableConfig.configId
(or attrdata-config-id
): If your app requires to load different account configurations, you can specify different configuration ids.tradableConfig.redirectURI
(or attrdata-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