WebView plugin SDK basics¶
To support user data retrieval, trade execution, event handling and more, a WebView plugin (client) must establish reliable communication with the cTrader application (host). The WebView plugin SDK facilitates these interactions with cTrader, and this guide explains the communication pipeline between the client and the host.
Installation¶
Install the WebView plugin SDK, external API and other critical packages via NPM. Navigate to your project directory in a terminal window, then run this command:
npm install @spotware-web-team/sdk @spotware-web-team/sdk-external-api rxjs @veksa/logger
Note
In addition to the SDK, developers must also install and use the external API, as it facilitates messaging between the plugin and the host application using postMessage or CustomEvent.
Client-host synchronisation¶
Note
The relevant protocols are available as reference messages.
Before any message can be exchanged, a communication channel must be established. Use the adapter synchronisation logic below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | |
Requests¶
Once synchronisation is complete, the plugin can interact with cTrader services by calling SDK methods. The plugin sends requests using the same adapter pattern as the handshake but with the required payload.
1 2 3 4 5 6 7 8 9 10 | |
Note
SDK methods for sending requests and receiving responses are available as reference server messages, while details on the repeated fields within requests and responses are provided as models.
Responses¶
The SDK routes these responses through the previously created adapter to the plugin that sent a request.
Events and subscriptions¶
WebView plugins can subscribe to real-time data such as quotes, deal updates, execution events and more.
-
Subscribe to quote data by sending a request:
1 2 3 4 5 6 7 8 9
import { subscribeQuotes } from '@spotware-web-team/sdk'; // Use previously created adapter subscribeQuotes(adapter, {symbolId: [quotesSymbolId]}).pipe( take(1), tap(result => { console.log(JSON.stringify(result, null, 2)); }) ).subscribe(); -
The subscription triggers the host to send periodic responses:
1 2 3 4 5 6 7 8
import { quoteEvent } from '@spotware-web-team/sdk'; // Use previously created adapter quoteEvent(adapter).pipe( tap(result => { console.log(JSON.stringify(result, null, 2)); }), ).subscribe();
Deeplinks¶
Note
WebView plugin operations involving deeplinks work only on cTrader Mobile.
A plugin can ask cTrader to open a deeplink (internal URL) using an SDK method as demonstrated below.
1 2 3 4 5 6 7 8 9 10 | |
Domain restrictions¶
For security reasons and compliance with cTrader rules, WebView plugins should load content only from the domain specified in the URL field during the build process. Any redirect or navigation attempt to a different domain is blocked inside the WebView in cTrader Web.
If your plugin must open or send users to a different domain, you must code your website to explicitly open the link in a new browser tab. Consider the examples below.
1 2 | |
1 2 | |
Summary of messages¶
The table below summarises key operations.
| Method | Accepted arguments | Returned type | Description |
|---|---|---|---|
openInternalUrl | { url } | ProtoOpenInternalUrlRes | Opens a cTrader internal URL or screen inside the platform environment. |
registerEvent | { uuid } | ProtoPublicRegisterEvent (event) | Registers the plugin instance so it can receive events; part of the handshake sequence. |
confirmEvent | { } | ProtoPublicConfirmEvent | Confirms an event during the connect → confirm → register flow required by the protocol. |
getAccountInformation | { } | ProtoGetAccountInformationRes | Retrieves the authenticated trader’s complete account details, including balance, equity, margin and permissions. |
getAccountGroupInformation | { } | ProtoGetAccountGroupInformationRes | Retrieves the group configuration governing the account (fees, commissions, margin rules, restrictions and legal entity mappings). |
getLightSymbolList | { includeArchivedSymbols? } | ProtoGetLightSymbolListRes | Returns a lightweight list of symbols with essential tradability attributes. |
getSymbol | { symbolId: number[] } | ProtoGetSymbolRes | Retrieves detailed symbol information such as precision, swap data, leverage profiles and trading rules. |
subscribeQuotes | { symbolId: number[], enableStaleQuotesFiltering?, subscribeToSpotTimestamp? } | ProtoSubscribeQuotesRes | Subscribes the plugin to live quotes for one or more symbols. |
unsubscribeQuotes | { symbolId: number[] } | ProtoUnsubscribeQuotesRes | Unsubscribes from live quote streaming for the supplied symbol IDs. |
getDynamicLeverage | { leverageId } | ProtoGetDynamicLeverageRes | Retrieves dynamic leverage tiers based on the symbol’s leverage profile. |
getDealList | { fromTimestamp, toTimestamp } | ProtoGetDealListRes | Returns closing deals occurring within the specified timestamp range. |
getTrendbarList | { symbolId, period, fromTimestamp, toTimestamp, count, type } | ProtoGetTrendbarListRes | |
quoteEvent | — | Stream of ProtoQuoteEvent | Emits live quote data including bid, ask, highs, lows, trendbars, tickbars and depth if enabled. |
executionEvent | — | Stream of ProtoExecutionEvent | Emits trading events: order acceptance, fills, amendments, cancellations, rejections, stop-outs, deposits and withdrawals. |
createNewOrder | { symbolId, orderType, tradeSide, volume, …optional fields… } | ProtoExecutionEvent (event response) | Submits a new trade order (market, limit, stop, stop-limit, market-range). The result arrives through an execution event. |
modifyOrder | { orderId, limitPrice?, stopPrice?, volume?, expirationTimestamp?, stopLoss?, takeProfit?, … } | ProtoExecutionEvent | Modifies an existing pending order. |
modifyOrderProtection | { positionId, stopLoss?, takeProfit?, guaranteedStopLoss?, trailingStopLoss?, stopLossTriggerMethod? } | ProtoExecutionEvent | Modifies stop-loss and take-profit protections on an open position. Removing both protections may generate an ORDER_CANCELLED event. |
cancelOrder | { orderId, originalClientOrderId?, clientOrderId? } | ProtoExecutionEvent (ORDER_CANCELLED) | Cancels an existing pending order. |
closePosition | { positionId, volume, stake?, desiredVWAP?, closeWithPID? } | ProtoExecutionEvent (ORDER_ACCEPTED) | Closes all or part of an existing open position. |