Skip to Content
API ReferenceTrading API

Trading API

The Trading API enables comprehensive trading integration through the trading configuration and setBrokerAccounts() method. It provides order placement, position management, and real-time trading data display on the chart.

Literal unions used by trading payloads (OrderType, OrderSide, OrderStatus, TimeInForce, ExecutionDirection, AppCallbackEventType) are cataloged under Enums & literal unions and defined on TypeScript Types.

Quick Start

Basic Trading Integration

import { createChart } from "@gocharting/chart-sdk"; const chart = createChart("#chart", { symbol: "AAPL", interval: "1D", datafeed: myDatafeed, licenseKey: "YOUR_LICENSE_KEY", // Enable trading features trading: { enableTrading: true, showOpenOrders: true, showPositions: true, showExecutions: true, }, // Handle trading events — receives a single event object appCallback: ({ eventType, message, onClose }) => { if (eventType === "PLACE_ORDER") { // Handle order placement placeOrder(message.order); if (onClose) onClose(); } }, // Set broker data when ready onReady: (chartInstance) => { chartInstance.setBrokerAccounts({ accountList: accounts, orderBook: orders, tradeBook: trades, positions: positions, }); }, });

Trading Configuration

TradingConfig Type

type TradingConfig = { // Core Settings enableTrading?: boolean; // Enable trading panel features (default: false) // UI Display Options showReverseButton?: boolean; // Show reverse button (default: true) showOpenOrders?: boolean; // Show open orders panel (default: true) showPositions?: boolean; // Show positions panel (default: true) showExecutions?: boolean; // Show executions/trades panel (default: true) showNotifications?: boolean; // Show trading notifications (default: true) // Trading Behavior beep?: boolean; // Play sound on order execution (default: true) quickTradeMode?: boolean; // Enable quick trade mode (default: false) // Take Profit Settings enableTakeProfitDefaults?: boolean; // Enable TP defaults (default: false) defaultTakeProfitSpread?: number; // Default TP spread (default: 1) defaultTakeProfitSpreadType?: "tick" | "price" | "percent"; // Default: "tick" // Stop Loss Settings enableStopLossDefaults?: boolean; // Enable SL defaults (default: false) defaultStopLossSpread?: number; // Default SL spread (default: 1) defaultStopLossSpreadType?: "tick" | "price" | "percent"; // Default: "tick" // Display Settings boxAlignment?: "left" | "right"; // Trading box alignment (default: "right") lineCategory?: "extended" | "compact"; // Order/position line category (default: "extended") // Order Type Support supportStopOrders?: boolean; // Enable Stop orders (default: false) supportStopLimitOrders?: boolean; // Enable Stop-Limit orders (default: false) };

See Configuration API for complete trading configuration details.

Trading Events

Trading events are handled through the appCallback configuration. For complete event documentation, see the Events API page.

Key Trading Events

  • PLACE_ORDER - User places a new order
  • MODIFY_ORDER - User modifies an existing order
  • CANCEL_ORDER - User cancels an order
  • MODIFY_POSITION - User modifies a position (TP/SL)
  • CLOSE_POSITION - User clicks the position X button to close it (message { position, chartIdx })
  • EXIT_ALL_POSITIONS - User requests to exit all positions
  • CANCEL_ALL_ORDERS - User requests to cancel all orders

See Events API for complete event type documentation and message structures.

setBrokerAccounts Method

The setBrokerAccounts() method updates the chart with broker account data including accounts, orders, trades, and positions.

Signature:

setBrokerAccounts(data: BrokerAccountData): void

BrokerAccountData Type:

type BrokerAccountData = { accountList: Account[]; // List of accounts orderBook: Order[]; // Open orders tradeBook: Trade[]; // Executed trades positions: Position[]; // Open positions }

Usage Example:

// Get chart instance via onReady callback onReady: (chartInstance) => { // Set broker data chartInstance.setBrokerAccounts({ accountList: [ { id: "ACC_001", name: "Trading Account", balance: 50000, currency: "USD", }, ], orderBook: [ { orderId: "ORD_001", symbol: "AAPL", productId: "NASDAQ:EQUITY:AAPL", side: "buy", size: 100, price: 150.50, status: "open", orderType: "limit", }, ], tradeBook: [], positions: [ { id: "POS_001", symbol: "AAPL", productId: "NASDAQ:EQUITY:AAPL", side: "buy", size: 50, price: 148.25, }, ], }); }

Updating Broker Data:

// Update broker data when orders/positions change function updateBrokerData(newData) { const chartInstance = chart.getChartInstance(); if (chartInstance) { chartInstance.setBrokerAccounts(newData); } }

Runtime Modification Types

The SDK includes TypeScript types for tracking order and position modifications at runtime. These types help distinguish between different modification operations.

Order Modification Types

/** * Order task type - distinguishes between order placement and modification */ type OrderTask = "placement" | "modify"; /** * Order update type - specifies the type of modification operation */ type OrderUpdateType = | "DELETE_SL" // Delete stop loss from order | "DELETE_TP" // Delete take profit from order | "SHAPE_MODIFY" // Modify order shape (price, TP, SL) | "STANDARD"; // Standard price/quantity modifications /** * Order shape update type - specifies what aspect is being modified */ type OrderShapeUpdateType = | "TAKE_PROFIT" // Modify existing take profit price | "NEW_TAKE_PROFIT" // Add new take profit (first time) | "DELETE_TAKE_PROFIT" // Delete take profit from order | "STOP_LOSS" // Modify existing stop loss price | "NEW_STOP_LOSS" // Add new stop loss (first time) | "DELETE_STOP_LOSS" // Delete stop loss from order | "STOP_PRICE" // Modify stop trigger price | "LIMIT_PRICE"; // Modify order limit price

Position Modification Types

/** * Position update type - specifies the type of position modification */ type PositionUpdateType = "SHAPE_MODIFY"; /** * Position shape update type - specifies what aspect is being modified */ type PositionShapeUpdateType = | "DELETE_STOP_LOSS" // Delete stop loss from position | "DELETE_TAKE_PROFIT" // Delete take profit from position | "STOP_LOSS" // Modify existing stop loss price | "NEW_STOP_LOSS" // Add new stop loss (first time) | "TAKE_PROFIT" // Modify existing take profit price | "NEW_TAKE_PROFIT"; // Add new take profit (first time)

Usage in Order and Position Objects

These types are used as optional fields in Order and Position objects:

type Order = { // ... other fields ... task?: OrderTask; // "placement" or "modify" update?: OrderUpdateType; // Type of modification updateType?: OrderShapeUpdateType; // Specific modification detail defaultTradeSettings?: TradingConfig; // Default trade settings (TP/SL) exitPosition?: boolean; // True if this order closes a position }; type Position = { // ... other fields ... update?: PositionUpdateType; // Always "SHAPE_MODIFY" updateType?: PositionShapeUpdateType; // Specific modification detail };

[!NOTE] The task field is only present in Order objects, not Position objects. Positions are always modified, never “placed”.

Order Modification Events

The MODIFY_ORDER event provides detailed information about what type of modification is being performed. The event structure includes:

{ "order": { "orderId": "ORDER_123", "task": "modify", "update": "SHAPE_MODIFY", // or "DELETE_SL", "DELETE_TP" "updateType": "TAKE_PROFIT", // or "STOP_LOSS", "LIMIT_PRICE" "takeProfit": 125000, // New take profit value "stopLoss": 110000, // New stop loss value "price": 115500 // New limit price } }

Modification Types

Delete Operations

  • update: "DELETE_SL" - Delete stop loss from order
  • update: "DELETE_TP" - Delete take profit from order

Shape Modifications

  • update: "SHAPE_MODIFY", updateType: "TAKE_PROFIT" - Update take profit price
  • update: "SHAPE_MODIFY", updateType: "STOP_LOSS" - Update stop loss price
  • update: "SHAPE_MODIFY", updateType: "LIMIT_PRICE" - Update order limit price

Standard Modifications

  • update: "STANDARD" - Standard price/quantity modifications

Handling Order Modifications

function handleTradingEvents({ eventType, message }) { const eventData = message; switch (eventType) { case "MODIFY_ORDER": const order = eventData.order || eventData; switch (order.update) { case "DELETE_SL": // Remove stop loss from order updateOrder(order.orderId, { stopLoss: null }); break; case "DELETE_TP": // Remove take profit from order updateOrder(order.orderId, { takeProfit: null }); break; case "SHAPE_MODIFY": if (order.updateType === "TAKE_PROFIT") { // Update take profit price updateOrder(order.orderId, { takeProfit: order.takeProfit, }); } else if (order.updateType === "STOP_LOSS") { // Update stop loss price updateOrder(order.orderId, { stopLoss: order.stopLoss, }); } else if (order.updateType === "LIMIT_PRICE") { // Update limit price updateOrder(order.orderId, { price: order.price }); } break; default: // Handle standard modifications updateOrder(order.orderId, { price: order.price, quantity: order.quantity || order.size, }); break; } break; } }

Position Modification Events

The MODIFY_POSITION event is triggered when users interact with position Stop Loss and Take Profit buttons on the chart. This event provides detailed information about what type of modification is being performed.

Event Structure:

{ "position": { // All original position fields "id": "POS_001", "productId": "BYBIT:FUTURE:BTCUSDT", "size": 0.05, "price": 49500, // ... other position fields ... // Modification metadata "update": "SHAPE_MODIFY", "updateType": "NEW_TAKE_PROFIT", // or other updateType values // Updated TP/SL values "takeProfit": 51000, "stopLoss": 48000 } }

Position Modification Types

Delete Operations

  • update: "SHAPE_MODIFY", updateType: "DELETE_STOP_LOSS" - Delete stop loss from position
  • update: "SHAPE_MODIFY", updateType: "DELETE_TAKE_PROFIT" - Delete take profit from position

Shape Modifications

  • update: "SHAPE_MODIFY", updateType: "NEW_TAKE_PROFIT" - Add new take profit (first time)
  • update: "SHAPE_MODIFY", updateType: "TAKE_PROFIT" - Modify existing take profit price
  • update: "SHAPE_MODIFY", updateType: "NEW_STOP_LOSS" - Add new stop loss (first time)
  • update: "SHAPE_MODIFY", updateType: "STOP_LOSS" - Modify existing stop loss price

Handling Position Modifications

function handleTradingEvents({ eventType, message }) { const eventData = message; switch (eventType) { case "MODIFY_POSITION": const position = eventData.position; if (position.update === "SHAPE_MODIFY") { switch (position.updateType) { case "NEW_STOP_LOSS": // User added a stop loss for the first time console.log("New Stop Loss:", position.stopLoss); await brokerAPI.addStopLoss(position.id, position.stopLoss); break; case "STOP_LOSS": // User modified existing stop loss console.log("Updated Stop Loss:", position.stopLoss); await brokerAPI.updateStopLoss(position.id, position.stopLoss); break; case "NEW_TAKE_PROFIT": // User added a take profit for the first time console.log("New Take Profit:", position.takeProfit); await brokerAPI.addTakeProfit( position.id, position.takeProfit ); break; case "TAKE_PROFIT": // User modified existing take profit console.log("Updated Take Profit:", position.takeProfit); await brokerAPI.updateTakeProfit( position.id, position.takeProfit ); break; case "DELETE_TAKE_PROFIT": // User removed take profit console.log("Deleted Take Profit"); await brokerAPI.removeTakeProfit(position.id); break; case "DELETE_STOP_LOSS": // User removed stop loss console.log("Deleted Stop Loss"); await brokerAPI.removeStopLoss(position.id); break; } // Update the chart with the modified position updateChartPositions(); } break; case "MODIFY_ORDER": // ... handle order modifications ... break; } }

Integration Examples

Basic Trading Integration

// Create chart with trading enabled const chart = GoChartingSDK.createChart("#trading-chart", { symbol: "NASDAQ:AAPL", interval: "1D", datafeed: myDatafeed, licenseKey: "YOUR_LICENSE_KEY", trading: { enableTrading: true, }, appCallback: ({ eventType, message }) => { // Handle all trading events console.log("Trading event:", eventType, message); }, });

Advanced Trading with Broker Integration

// Advanced trading setup with broker accounts const chart = GoChartingSDK.createChart("#advanced-trading", { symbol: "BYBIT:FUTURE:BTCUSDT", interval: "1m", datafeed: myDatafeed, licenseKey: "YOUR_LICENSE_KEY", trading: { enableTrading: true, }, appCallback: handleTradingEvents, }); // Set broker accounts for realistic trading experience chart.setBrokerAccounts({ accountList: [{ id: "demo-account", name: "Demo Account", balance: 10000 }], orderBook: [], tradeBook: [], positions: [], }); function handleTradingEvents({ eventType, message }) { switch (eventType) { case "PLACE_ORDER": // Send order to your broker API placeBrokerOrder(message.order); break; case "CANCEL_ORDER": // Cancel order through broker API cancelBrokerOrder(message.order); break; } }

UI Features

Context Menu Options

When trading.enableTrading: true, users can:

  1. Right-click on chart → See “Buy” and “Sell” options
  2. Hover over price levels → See trading options in CrossHair menu
  3. Access Settings > Trading → Configure trading preferences

Trading Tab in Settings

The Trading tab provides configuration options for:

  • Order line display settings
  • Position visualization
  • Trading notifications
  • Default order parameters

Trading Panel Components

Order Entry Form

The trading panel includes a comprehensive order entry form with the following fields:

<!-- Trading Panel Structure --> <div class="trading-panel"> <div class="form-group"> <label>Quantity</label> <input type="number" id="quantity" min="1" value="100" /> </div> <div class="form-group"> <label>Stop Loss</label> <input type="number" id="stop-loss" step="0.01" /> </div> <div class="form-group"> <label>Take Profit</label> <input type="number" id="take-profit" step="0.01" /> </div> <div class="form-group"> <label>Order Type</label> <select id="order-type"> <option value="market">Market</option> <option value="limit">Limit</option> </select> </div> <div class="form-group"> <label>Limit Price</label> <input type="number" id="limit-price" step="0.01" /> </div> <div class="trading-buttons"> <button id="buy-btn" class="btn buy"> BUY</button> <button id="sell-btn" class="btn sell"> SELL</button> <button id="reset-broker-btn" class="btn secondary"> Reset Broker </button> </div> </div>

Trading Actions

Buy/Sell Orders

  • Market Orders: Execute immediately at current LTP (Last Traded Price)
  • Limit Orders: Added to orderbook as “open” status
  • Stop Loss/Take Profit: Optional risk management levels

Reset Broker Functionality

The Reset Broker button provides a clean way to reset the demo environment:

// Reset Broker Implementation function resetBroker() { // Clear all broker data arrays this.currentOrderBook = []; this.currentTradeBook = []; this.currentPositions = []; // Update chart with empty broker data this.updateChartBrokerData(); console.log( " Broker data reset - All orders, trades, and positions cleared", ); }

What gets reset:

  • OrderBook: All pending and filled orders cleared
  • TradeBook: All trade history cleared
  • Positions: All open positions cleared
  • Chart Display: All order lines, position markers removed

Order Type Behavior

Market Orders

// Market order execution { orderType: "market", price: 0, // Uses current LTP status: "filled", // Immediately filled // Creates position and trade immediately }

Limit Orders

// Limit order placement { orderType: "limit", price: 115500, // User-specified price status: "open", // Pending execution // Waits for market price to reach limit price }

Broker Data Structures

setBrokerAccounts Method

The setBrokerAccounts() method is the primary way to provide trading data to the chart. This method accepts an object with four main arrays that represent your broker’s current state:

chartInstance.setBrokerAccounts({ accountList: [...], // Account information orderBook: [...], // Active orders tradeBook: [...], // Trade history positions: [...] // Current positions });

Method Signature:

setBrokerAccounts(data: BrokerAccountData): void interface BrokerAccountData { accountList: Account[]; orderBook: Order[]; tradeBook: Trade[]; positions: Position[]; }

Account List Structure

The accountList array contains information about trading accounts:

accountList: [ { account_id: "DEMO_001", // Unique account identifier AccountID: "DEMO_001", // Alternative account ID field AccountType: "Demo Trading", // Account type description label: "Demo Account (Trading)", // Display label for UI currency: "USD", // Account base currency balance: 100000, // Account balance equity: 100000, // Account equity margin: 0, // Used margin freeMargin: 100000, // Available margin }, ];

Account Fields:

FieldTypeRequiredDescription
account_idstringUnique account identifier
AccountIDstringAlternative account ID (for compatibility)
AccountTypestringAccount type (Demo, Live, Paper)
labelstringDisplay name for the account
currencystringBase currency (USD, EUR, etc.)
balancenumberCurrent account balance
equitynumberAccount equity value
marginnumberUsed margin amount
freeMarginnumberAvailable margin for trading

Order Book Structure

The orderBook array contains all active (pending) orders:

orderBook: [ { orderId: "ORDER_001", // Unique order identifier datetime: new Date(), // Order creation date timeStamp: new Date().getTime(), // Order timestamp (ms) lastTradeTimestamp: null, // Last trade timestamp status: "open", // Order status price: 50000, // Order price size: 0.1, // Order quantity productId: "BYBIT:FUTURE:BTCUSDT", // Full symbol identifier remainingSize: 0.1, // Remaining quantity orderType: "limit", // Order type side: "buy", // Order side cost: null, // Order cost trades: [], // Associated trades fee: { // Fee information currency: "USDT", cost: 0.0, rate: 0.0, }, info: {}, // Additional broker info fillPrice: null, // Fill price (if any) avgFillPrice: null, // Average fill price filledSize: 0, // Filled quantity modifiedAt: null, // Last modification time exchange: "BYBIT", // Exchange name symbol: "BTCUSDT", // Base symbol takeProfit: null, // Take profit price stopLoss: null, // Stop loss price isGC: true, // GoCharting flag paperTraderKey: null, // Paper trading key key: "demo-BYBIT:FUTURE:BTCUSDT-ORDER_001", // Unique key validity: "DAY", // Order validity commissions: 0, // Commission amount broker: "demo", // Broker identifier stopPrice: null, // Stop price (for stop orders) productType: "FUTURE", // Product type rejReason: null, // Rejection reason security: { // Security information symbol: "BTCUSDT", exchange: "BYBIT", segment: "FUTURE", tick_size: 0.01, lot_size: 0.001, }, userTag: null, // User-defined tag }, ];

Order Fields:

FieldTypeRequiredDescription
orderIdstringUnique order identifier
datetimeDateOrder creation date
timeStampnumberOrder timestamp in milliseconds
statusstringOrder status: “open”, “filled”, “cancelled”
pricenumberOrder price (0 for market orders)
sizenumberOrder quantity
productIdstringFull symbol identifier
remainingSizenumberRemaining unfilled quantity
orderTypestringOrder type: “limit”, “market”, “stop”, “stopLimit”
sidestringOrder side: “buy”, “sell”
exchangestringExchange name
symbolstringBase symbol name
brokerstringBroker identifier
productTypestringProduct type: “FUTURE”, “SPOT”, “OPTION”
securityobjectSecurity information object
feeobjectFee structure
takeProfitnumberTake profit price
stopLossnumberStop loss price
stopPricenumberStop trigger price

Trade Book Structure

The tradeBook array contains the history of executed trades:

tradeBook: [ { tradeId: "TRADE_001", // Unique trade identifier orderId: "ORDER_FILLED", // Associated order ID datetime: new Date(Date.now() - 3600000), // Trade execution date timeStamp: new Date(Date.now() - 3600000).getTime(), // Trade timestamp lastTradeTimestamp: null, // Last trade timestamp status: "filled", // Trade status price: 49500, // Execution price tradeSize: 0.05, // Trade quantity tradeValue: 2475, // Trade value (price * size) productId: "BYBIT:FUTURE:BTCUSDT", // Full symbol identifier orderType: "Market", // Original order type side: "buy", // Trade side cost: null, // Trade cost takerOrMaker: null, // Taker/Maker flag isGC: true, // GoCharting flag fee: { // Fee information currency: "USDT", cost: 2.475, // Fee amount rate: 0.001, // Fee rate }, info: {}, // Additional broker info broker: "demo", // Broker identifier paperTraderKey: null, // Paper trading key key: "demo-BYBIT:FUTURE:BTCUSDT-TRADE_001", // Unique key type: "tradeExecuted", // Trade type remainingSize: "0", // Remaining order size orderDetails: { // Original order details orderId: "ORDER_FILLED", orderType: "market", }, triggerLogicPending: false, // Trigger logic flag spread: 0, // Bid-ask spread productType: "FUTURE", // Product type security: { // Security information symbol: "BTCUSDT", exchange: "BYBIT", segment: "FUTURE", tick_size: 0.01, lot_size: 0.001, }, }, ];

Trade Fields:

FieldTypeRequiredDescription
tradeIdstringUnique trade identifier
orderIdstringAssociated order ID
datetimeDateTrade execution date
timeStampnumberTrade timestamp in milliseconds
statusstringTrade status: “filled”, “partial”
pricenumberExecution price
tradeSizenumberTrade quantity
tradeValuenumberTrade value (price × quantity)
productIdstringFull symbol identifier
orderTypestringOriginal order type
sidestringTrade side: “buy”, “sell”
brokerstringBroker identifier
productTypestringProduct type: “FUTURE”, “SPOT”, “OPTION”
securityobjectSecurity information object
feeobjectFee structure
takerOrMakerstring”taker” or “maker”
spreadnumberBid-ask spread at execution

Positions Structure

The positions array contains current open positions:

positions: [ { size: 0.05, // Net position size size_currency: 0.05, // Position quantity price: 49500, // Average entry price amount: 2475, // Position value openPosVal: 0, // Open position value closedPosVal: 0, // Closed position value productId: "BYBIT:FUTURE:BTCUSDT", // Full symbol identifier broker: "demo", // Broker identifier isGC: true, // GoCharting flag paperTraderKey: null, // Paper trading key key: "demo-BYBIT:FUTURE:BTCUSDT-POS_001", // Unique key productType: "FUTURE", // Product type currency: "USDT", // Position currency id: "POS_001", // Position ID positions: { // Detailed position data "demo-BYBIT:FUTURE:BTCUSDT-FUTURE": { positionId: "demo-BYBIT:FUTURE:BTCUSDT-FUTURE", positionFlag: true, // Position active flag security: { // Security information symbol: "BTCUSDT", exchange: "BYBIT", segment: "FUTURE", tick_size: 0.01, lot_size: 0.001, }, positionStatus: "open", // Position status entry: 49500, // Entry price exit: null, // Exit price (if closed) size: 0.05, // Position size positionSize: 0.05, // Position size (duplicate) transaction_type: "real", // Transaction type trades: [], // Associated trades broker: "demo", // Broker identifier currency: "USDT", // Position currency productId: "BYBIT:FUTURE:BTCUSDT", // Full symbol identifier ticker: "BYBIT:FUTURE:BTCUSDT", // Ticker symbol created: null, // Creation timestamp symbol: "BTCUSDT", // Base symbol exchange: "BYBIT", // Exchange name segment: "FUTURE", // Market segment underlying: "BYBIT:FUTURE:BTCUSDT", // Underlying asset series: null, // Series (for options) strike: null, // Strike price (for options) optionType: null, // Option type (for options) expiration_timestamp: null, // Expiration (for options) strategyId: "1000", // Strategy ID strategyType: "1000", // Strategy type strategyLabel: "Real", // Strategy label strategyColor: "#000000", // Strategy color strategyFlag: true, // Strategy active flag strategyStatus: "open", // Strategy status stratgeyFormulae: null, // Strategy formula fee: { // Fee information currency: "USDT", cost: 0.0, rate: 0.0, }, side: "buy", // Position side modified: new Date().getTime(), // Last modified timestamp productType: "FUTURE", // Product type rpnl: 0, // Realized PnL totalBuyQty: 0.05, // Total buy quantity avgBuyPrice: 49500, // Average buy price totalSellQty: 0, // Total sell quantity avgSellPrice: 0, // Average sell price }, }, underlying: "BYBIT:FUTURE:BTCUSDT", // Underlying asset unPnl: 25, // Unrealized PnL rPnl: 0, // Realized PnL pnl: 25, // Total PnL pnlMultiplier: 1, // PnL multiplier security: { // Security information symbol: "BTCUSDT", exchange: "BYBIT", segment: "FUTURE", tick_size: 0.01, lot_size: 0.001, }, symbol: "BTCUSDT", // Base symbol segment: "FUTURE", // Market segment exchange: "BYBIT", // Exchange name }, ];

Position Fields:

FieldTypeRequiredDescription
sizenumberNet position size (positive = long, negative = short)
size_currencynumberPosition quantity in base currency
pricenumberAverage entry price
amountnumberPosition value (price × quantity)
productIdstringFull symbol identifier
brokerstringBroker identifier
productTypestringProduct type: “FUTURE”, “SPOT”, “OPTION”
currencystringPosition currency
idstringPosition identifier
underlyingstringUnderlying asset identifier
unPnlnumberUnrealized profit/loss
rPnlnumberRealized profit/loss
pnlnumberTotal profit/loss
securityobjectSecurity information object
symbolstringBase symbol name
segmentstringMarket segment
exchangestringExchange name
positionsobjectDetailed position breakdown
pnlMultipliernumberPnL calculation multiplier
showStopLossButtonbooleanEnable Stop Loss button on position line (default: false)
showTakeProfitButtonbooleanEnable Take Profit button on position line (default: false)
stopLossnumberCurrent Stop Loss price for the position
takeProfitnumberCurrent Take Profit price for the position

Position Modification with Stop Loss and Take Profit Buttons

When you set showStopLossButton: true and/or showTakeProfitButton: true on a position object, interactive buttons will appear on the position line in the chart, allowing users to add or modify Stop Loss and Take Profit levels directly from the chart.

Example Position with TP/SL Buttons:

positions: [ { size: 0.05, price: 49500, productId: "BYBIT:FUTURE:BTCUSDT", broker: "demo", // ... other required fields ... // Enable interactive TP/SL buttons showStopLossButton: true, // Shows red S/L button showTakeProfitButton: true, // Shows blue T/P button // Current TP/SL values (can be null if not set) stopLoss: null, // No stop loss set yet takeProfit: null, // No take profit set yet }, ];

When users interact with these buttons, you’ll receive a MODIFY_POSITION event:

appCallback: ({ eventType, message }) => { if (eventType === "MODIFY_POSITION") { const position = message.position; // Check the modification type if (position.update === "SHAPE_MODIFY") { // The position shape (TP/SL) was modified switch (position.updateType) { case "NEW_STOP_LOSS": // User clicked the red S/L button and placed a NEW Stop Loss console.log("New Stop Loss added:", position.stopLoss); // This is the FIRST time a stop loss is being added break; case "STOP_LOSS": // User modified an EXISTING Stop Loss price console.log("Stop Loss updated:", position.stopLoss); // There was already a stop loss, user changed the price break; case "NEW_TAKE_PROFIT": // User clicked the blue T/P button and placed a NEW Take Profit console.log("New Take Profit added:", position.takeProfit); // This is the FIRST time a take profit is being added break; case "TAKE_PROFIT": // User modified an EXISTING Take Profit price console.log("Take Profit updated:", position.takeProfit); // There was already a take profit, user changed the price break; case "DELETE_TAKE_PROFIT": // User deleted the Take Profit console.log("Take Profit removed"); // position.takeProfit will be null break; case "DELETE_STOP_LOSS": // User deleted the Stop Loss console.log("Stop Loss removed"); // position.stopLoss will be null break; } // Update your broker system with the new TP/SL values updatePositionTPSL(position); } } };

Position Modification Event Structure:

FieldTypeDescription
updatestringAlways "SHAPE_MODIFY" for TP/SL modifications
updateTypestringType of modification (see table below)
stopLossnumber | nullNew Stop Loss price (or null if deleted)
takeProfitnumber | nullNew Take Profit price (or null if deleted)
…other position fieldsAll original position fields are included

Update Types for Position Modifications:

updateTypeDescriptionWhen it occurs
"NEW_STOP_LOSS"First-time Stop Loss placementUser clicks red S/L button and sets a stop loss for the first time (previous stopLoss was 0 or null)
"STOP_LOSS"Existing Stop Loss modificationUser drags or modifies an existing stop loss line (previous stopLoss > 0)
"NEW_TAKE_PROFIT"First-time Take Profit placementUser clicks blue T/P button and sets a take profit for the first time (previous takeProfit was 0 or null)
"TAKE_PROFIT"Existing Take Profit modificationUser drags or modifies an existing take profit line (previous takeProfit > 0)
"DELETE_TAKE_PROFIT"Take Profit deletionUser removes the take profit from the position
"DELETE_STOP_LOSS"Stop Loss deletionUser removes the stop loss from the position

Complete Example:

// Set up positions with TP/SL buttons enabled chart.setBrokerAccounts({ accountList: [ { id: "demo", name: "Demo Account", balance: 10000, currency: "USDT" } ], orderBook: [], tradeBook: [], positions: [ { size: 0.05, size_currency: 0.05, price: 49500, amount: 2475, productId: "BYBIT:FUTURE:BTCUSDT", broker: "demo", productType: "FUTURE", currency: "USDT", id: "POS_001", underlying: "BYBIT:FUTURE:BTCUSDT", unPnl: 25, rPnl: 0, pnl: 25, security: { symbol: "BTCUSDT", exchange: "BYBIT", segment: "FUTURE", tick_size: 0.01, lot_size: 0.001, }, symbol: "BTCUSDT", segment: "FUTURE", exchange: "BYBIT", // Enable TP/SL buttons showStopLossButton: true, showTakeProfitButton: true, // Initial TP/SL values stopLoss: null, // No stop loss yet takeProfit: null, // No take profit yet } ] }); // Handle position modifications function handleTradingEvents({ eventType, message }) { const eventData = message; if (eventType === "MODIFY_POSITION") { const position = eventData.position; if (position.update === "SHAPE_MODIFY") { console.log("Position modified:", { updateType: position.updateType, stopLoss: position.stopLoss, takeProfit: position.takeProfit, productId: position.productId }); // Send to your broker API await brokerAPI.updatePositionTPSL({ positionId: position.id, stopLoss: position.stopLoss, takeProfit: position.takeProfit, updateType: position.updateType }); // Update the chart with the new position data const updatedPositions = currentPositions.map(p => p.id === position.id ? { ...p, stopLoss: position.stopLoss, takeProfit: position.takeProfit } : p ); chart.setBrokerAccounts({ accountList: currentAccounts, orderBook: currentOrders, tradeBook: currentTrades, positions: updatedPositions }); } } }

Exiting Positions with the X Button

Positions displayed on the chart include an X button that allows users to quickly exit (close) the position. When a user clicks this button, the chart emits a CLOSE_POSITION event. It does not emit a PLACE_ORDER — closing is a distinct action, and it is up to your integration to close the position with your broker however it sees fit (typically an offsetting market order).

CLOSE_POSITION message shape:

{ position, // The full position object being closed chartIdx, // Index of the chart (pane) the position belongs to }

The position object is the same position you supplied via setBrokerAccounts(), so it already carries size (positive = long, negative = short), productId, id, security, and the rest of the position fields you need to close it.

Example - Handling a Close Request:

// When the user clicks the X button, you receive: appCallback: ({ eventType, message }) => { if (eventType === "CLOSE_POSITION") { const { position, chartIdx } = message; console.log("Close position requested:", position.id, "on chart", chartIdx); // position.size > 0 → long position (close by selling) // position.size < 0 → short position (close by buying) } };

Handling Position Close Events:

async function handleTradingEvents({ eventType, message }) { switch (eventType) { case "CLOSE_POSITION": { const { position } = message; console.log("Closing position:", position.id); // Close the position with your broker. A common approach is to // submit an offsetting market order for the full position size. await brokerAPI.placeOrder({ symbol: position.symbol, productId: position.productId, side: position.size > 0 ? "sell" : "buy", // opposite of the position size: Math.abs(position.size), // full size to fully close orderType: "market", }); // After closing, remove the position from the chart const updatedPositions = currentPositions.filter( (p) => p.id !== position.id ); chart.setBrokerAccounts({ accountList: currentAccounts, orderBook: currentOrders, tradeBook: currentTrades, positions: updatedPositions, }); break; } case "MODIFY_POSITION": // ... handle position modifications ... break; } }
Important

Close Position Requirements:

  1. Distinct Event: The X button emits CLOSE_POSITION (message { position, chartIdx }), not PLACE_ORDER.
  2. Full Position: The event references the whole position — closing is expected to fully exit it, not partially.
  3. Your Broker Logic: How you actually close the position (offsetting market order, broker close endpoint, etc.) is up to your integration.
  4. Update Chart: After closing, update the chart by removing the position from the positions array via setBrokerAccounts().

Complete Trading Implementation Example

Here’s a comprehensive example showing the complete trading implementation with order management, modification handling, and broker data integration:

Complete Trading Chart Setup

// Complete trading implementation with all features class TradingChartManager { constructor() { this.chartInstance = null; this.currentOrderBook = []; this.currentTradeBook = []; this.currentPositions = []; this.currentAccountList = []; } async initialize() { // Create chart with trading enabled this.chartInstance = window.GoChartingSDK.createChart( "#chart-container", { symbol: "BYBIT:FUTURE:BTCUSDT", interval: "1D", datafeed: this.createDatafeed(), licenseKey: "YOUR_LICENSE_KEY", trading: { enableTrading: true, }, appCallback: ({ eventType, message }) => this.handleTradingEvent(eventType, message), onReady: (chartInstance) => { console.log(" Trading chart ready"); this.setupInitialBrokerData(); }, }, ); this.setupEventListeners(); } // Handle all trading events from the chart handleTradingEvent(eventType, message) { console.log(` Trading Event: ${eventType}`, message); switch (eventType) { case "PLACE_ORDER": this.addOrderToOrderBook(message); break; case "CANCEL_ORDER": this.removeOrderFromOrderBook(message); break; case "MODIFY_ORDER": this.modifyOrderInOrderBook(message); break; default: console.log("Unknown trading event:", eventType, message); } } // Add new order to orderbook addOrderToOrderBook(orderData) { const order = orderData.order || orderData; const security = orderData.security || {}; const ltp = orderData.ltp || this.getCurrentLTP(); const isMarketOrder = order.orderType === "market"; const executionPrice = isMarketOrder ? ltp : order.price; const newOrder = { orderId: `ORDER_${Date.now()}_${Math.random() .toString(36) .substr(2, 9)}`, datetime: new Date().toISOString(), timeStamp: Date.now(), status: isMarketOrder ? "filled" : "open", price: executionPrice, size: order.quantity || order.size, productId: order.symbol, remainingSize: isMarketOrder ? 0 : order.quantity || order.size, orderType: order.orderType, side: order.side, exchange: security.exchange || "BYBIT", symbol: security.symbol || "BTCUSDT", takeProfit: order.takeProfit || null, stopLoss: order.stopLoss || null, broker: "demo", productType: security.segment || "FUTURE", security: security, key: `demo-${order.symbol}-${Date.now()}`, validity: "DAY", isGC: true, }; this.currentOrderBook.push(newOrder); // For market orders, create position and trade if (isMarketOrder) { this.createPositionAndTrade(newOrder, ltp); } this.updateChartBrokerData(); console.log(" Order added to orderbook:", newOrder); } // Remove order from orderbook removeOrderFromOrderBook(orderData) { const orderId = orderData.orderId || orderData.order?.orderId; this.currentOrderBook = this.currentOrderBook.filter( (order) => order.orderId !== orderId, ); this.updateChartBrokerData(); console.log(" Order removed from orderbook:", orderId); } // Modify existing order modifyOrderInOrderBook(orderData) { const order = orderData.order || orderData; const orderId = order.orderId; const orderIndex = this.currentOrderBook.findIndex( (existingOrder) => existingOrder.orderId === orderId, ); if (orderIndex !== -1) { const existingOrder = this.currentOrderBook[orderIndex]; // Handle specific update types if (order.update) { switch (order.update) { case "DELETE_SL": existingOrder.stopLoss = null; console.log(" Deleted stop loss"); break; case "DELETE_TP": existingOrder.takeProfit = null; console.log(" Deleted take profit"); break; case "SHAPE_MODIFY": if (order.updateType === "TAKE_PROFIT") { existingOrder.takeProfit = order.takeProfit; console.log( " Updated take profit:", order.takeProfit, ); } else if (order.updateType === "STOP_LOSS") { existingOrder.stopLoss = order.stopLoss; console.log( " Updated stop loss:", order.stopLoss, ); } else if (order.updateType === "LIMIT_PRICE") { existingOrder.price = order.price; console.log(" Updated limit price:", order.price); } break; default: // Standard modifications if (order.price !== undefined) existingOrder.price = order.price; if (order.quantity !== undefined) { existingOrder.size = order.quantity; existingOrder.remainingSize = order.quantity; } break; } } existingOrder.modifiedAt = Date.now(); this.updateChartBrokerData(); console.log(" Order modified:", existingOrder); } } // Create position and trade for market orders createPositionAndTrade(order, executionPrice) { // Create trade record const trade = { tradeId: `TRADE_${Date.now()}_${Math.random() .toString(36) .substr(2, 9)}`, orderId: order.orderId, datetime: new Date().toISOString(), timeStamp: Date.now(), status: "filled", price: executionPrice, tradeSize: order.size, tradeValue: executionPrice * order.size, productId: order.productId, orderType: order.orderType, side: order.side, broker: "demo", productType: order.productType, security: order.security, fee: { currency: "USDT", cost: 0, rate: 0 }, key: `demo-${order.productId}-${Date.now()}`, isGC: true, }; this.currentTradeBook.push(trade); // Update or create position this.updatePosition(order, executionPrice); } // Update position based on trade updatePosition(order, executionPrice) { const existingPositionIndex = this.currentPositions.findIndex( (pos) => pos.productId === order.productId, ); if (existingPositionIndex !== -1) { // Update existing position const position = this.currentPositions[existingPositionIndex]; const currentSize = position.size || 0; const newSize = order.side === "buy" ? currentSize + order.size : currentSize - order.size; if (newSize === 0) { // Position closed this.currentPositions.splice(existingPositionIndex, 1); } else { // Update position position.size = newSize; position.price = executionPrice; // Simplified - should calculate average position.amount = newSize * executionPrice; } } else if (order.size > 0) { // Create new position const newPosition = { size: order.side === "buy" ? order.size : -order.size, size_currency: order.size, price: executionPrice, amount: order.size * executionPrice, productId: order.productId, broker: "demo", productType: order.productType, currency: "USDT", id: `POS_${Date.now()}`, underlying: order.productId, unPnl: 0, rPnl: 0, pnl: 0, security: order.security, symbol: order.symbol, segment: order.productType, exchange: order.exchange, key: `demo-${order.productId}-${Date.now()}`, isGC: true, }; this.currentPositions.push(newPosition); } } // Reset all broker data resetBroker() { this.currentOrderBook = []; this.currentTradeBook = []; this.currentPositions = []; this.updateChartBrokerData(); console.log(" Broker data reset - All data cleared"); } // Update chart with current broker data updateChartBrokerData() { if (!this.chartInstance) return; const brokerData = { accountList: this.currentAccountList, orderBook: this.currentOrderBook, tradeBook: this.currentTradeBook, positions: this.currentPositions, }; this.chartInstance.setBrokerAccounts(brokerData); } // Get current LTP (simulated) getCurrentLTP() { return 115234.5 + (Math.random() - 0.5) * 1000; // Simulated price } // Setup initial demo data setupInitialBrokerData() { this.currentAccountList = [ { account_id: "DEMO_001", AccountID: "DEMO_001", AccountType: "Demo Trading", label: "Demo Account", currency: "USD", balance: 100000, equity: 100000, margin: 0, freeMargin: 100000, }, ]; this.updateChartBrokerData(); } // Setup UI event listeners setupEventListeners() { // Buy button document.getElementById("buy-btn")?.addEventListener("click", () => { this.placeBuyOrder(); }); // Sell button document.getElementById("sell-btn")?.addEventListener("click", () => { this.placeSellOrder(); }); // Reset broker button document .getElementById("reset-broker-btn") ?.addEventListener("click", () => { this.resetBroker(); }); // Order type change document .getElementById("order-type") ?.addEventListener("change", (e) => { this.handleOrderTypeChange(e.target.value); }); } // Place buy order from form placeBuyOrder() { const orderData = this.getOrderDataFromForm(); orderData.side = "buy"; this.handleTradingEvent("PLACE_ORDER", { order: orderData, security: { symbol: "BTCUSDT", exchange: "BYBIT", segment: "FUTURE", }, ltp: this.getCurrentLTP(), }); } // Place sell order from form placeSellOrder() { const orderData = this.getOrderDataFromForm(); orderData.side = "sell"; this.handleTradingEvent("PLACE_ORDER", { order: orderData, security: { symbol: "BTCUSDT", exchange: "BYBIT", segment: "FUTURE", }, ltp: this.getCurrentLTP(), }); } // Get order data from form inputs getOrderDataFromForm() { return { symbol: "BYBIT:FUTURE:BTCUSDT", quantity: parseInt( document.getElementById("quantity")?.value || "100", ), orderType: document.getElementById("order-type")?.value || "market", price: parseFloat( document.getElementById("limit-price")?.value || "0", ), stopLoss: parseFloat(document.getElementById("stop-loss")?.value) || null, takeProfit: parseFloat(document.getElementById("take-profit")?.value) || null, }; } // Handle order type changes handleOrderTypeChange(orderType) { const limitPriceInput = document.getElementById("limit-price"); if (limitPriceInput) { limitPriceInput.disabled = orderType === "market"; if (orderType === "market") { limitPriceInput.value = ""; } } } // Create simple datafeed for demo createDatafeed() { return { getBars: async (symbolInfo, resolution, periodParams) => { // Return demo OHLCV data return { bars: [], meta: { noData: false } }; }, resolveSymbol: (symbolName, onResolve, onError) => { const parts = String(symbolName).split(":"); const exchange = parts[0] || "BYBIT"; const segment = parts.length >= 3 ? parts[1] : "FUTURE"; const symbol = parts[parts.length - 1] || "BTCUSDT"; const validIntervals = ["1", "5", "15", "30", "60", "1D"]; onResolve({ exchange, segment, symbol, name: "BTC / USDT PERPETUAL FUTURES", asset_type: "CRYPTO", source_id: symbol, pair: { from: "BTC", to: "USDT" }, tradeable: true, is_index: false, is_formula: false, delay_seconds: 0, data_status: "streaming", contract_size: 1, tick_size: 0.1, display_tick_size: 1, volume_size_increment: 0.001, max_tick_precision: 1, max_volume_precision: 3, quote_currency: "USDT", future_type: "PERP", supports: { footprint: true }, exchange_info: { name: exchange.toLowerCase(), code: exchange, zone: "UTC", hours: Array.from({ length: 7 }, () => ({ open: true })), valid_intervals: validIntervals, }, ticker: symbol, full_name: `${exchange}:${segment}:${symbol}`, description: "BTC / USDT PERPETUAL FUTURES", type: "crypto", session: "24x7", timezone: "UTC", has_intraday: true, has_daily: true, supported_resolutions: validIntervals, }); }, searchSymbols: (userInput, callback) => { callback([]); }, }; } } // Initialize trading chart const tradingManager = new TradingChartManager(); tradingManager.initialize();

Usage Example

Here’s a comprehensive example showing how to integrate all broker data structures:

// Create chart with trading enabled const chart = window.GoChartingSDK.createChart("#chart-container", { symbol: "BYBIT:FUTURE:BTCUSDT", interval: "1m", datafeed: myDatafeed, licenseKey: "YOUR_LICENSE_KEY", trading: { enableTrading: true, }, appCallback: handleTradingEvents, onReady: (chartInstance) => { // Initialize with broker data setupBrokerData(chartInstance); }, }); // Handle trading events from the chart — receives a single event object function handleTradingEvents({ eventType, message }) { switch (eventType) { case "PLACE_ORDER": console.log("Order placed:", message); addOrderToSystem(message.order); break; case "CANCEL_ORDER": console.log("Order cancelled:", message); removeOrderFromSystem(message.order); break; case "MODIFY_ORDER": console.log("Order modified:", message); updateOrderInSystem(message); break; } } // Set up initial broker data function setupBrokerData(chartInstance) { const brokerData = { accountList: [ { account_id: "LIVE_001", AccountID: "LIVE_001", AccountType: "Live Trading", label: "Live Trading Account", currency: "USD", balance: 50000, equity: 52500, margin: 2500, freeMargin: 47500, }, ], orderBook: [ { orderId: "ORD_001", datetime: new Date(), timeStamp: new Date().getTime(), status: "open", price: 45000, size: 0.1, productId: "BYBIT:FUTURE:BTCUSDT", remainingSize: 0.1, orderType: "limit", side: "buy", exchange: "BYBIT", symbol: "BTCUSDT", broker: "live", productType: "FUTURE", security: { symbol: "BTCUSDT", exchange: "BYBIT", segment: "FUTURE", tick_size: 0.01, lot_size: 0.001, }, fee: { currency: "USDT", cost: 0.0, rate: 0.001 }, key: "live-BYBIT:FUTURE:BTCUSDT-ORD_001", validity: "GTC", commissions: 0, isGC: true, }, ], tradeBook: [ { tradeId: "TRD_001", orderId: "ORD_FILLED_001", datetime: new Date(Date.now() - 7200000), timeStamp: new Date(Date.now() - 7200000).getTime(), status: "filled", price: 46000, tradeSize: 0.05, tradeValue: 2300, productId: "BYBIT:FUTURE:BTCUSDT", orderType: "limit", side: "buy", broker: "live", productType: "FUTURE", security: { symbol: "BTCUSDT", exchange: "BYBIT", segment: "FUTURE", tick_size: 0.01, lot_size: 0.001, }, fee: { currency: "USDT", cost: 2.3, rate: 0.001 }, key: "live-BYBIT:FUTURE:BTCUSDT-TRD_001", type: "tradeExecuted", isGC: true, }, ], positions: [ { size: 0.05, size_currency: 0.05, price: 46000, amount: 2300, productId: "BYBIT:FUTURE:BTCUSDT", broker: "live", productType: "FUTURE", currency: "USDT", id: "POS_001", underlying: "BYBIT:FUTURE:BTCUSDT", unPnl: 150, // Current unrealized P&L rPnl: 0, // Realized P&L pnl: 150, // Total P&L security: { symbol: "BTCUSDT", exchange: "BYBIT", segment: "FUTURE", tick_size: 0.01, lot_size: 0.001, }, symbol: "BTCUSDT", segment: "FUTURE", exchange: "BYBIT", key: "live-BYBIT:FUTURE:BTCUSDT-POS_001", isGC: true, }, ], }; // Set the broker data on the chart chartInstance.setBrokerAccounts(brokerData); console.log(" Broker data loaded successfully"); } // Add new order to the system and update chart function addOrderToSystem(orderData) { // Create order object in the required format const newOrder = { orderId: generateOrderId(), datetime: new Date(), timeStamp: new Date().getTime(), status: "open", price: orderData.price || 0, size: orderData.quantity || 0, productId: orderData.symbol, remainingSize: orderData.quantity || 0, orderType: orderData.orderType || "limit", side: orderData.side, exchange: "BYBIT", symbol: orderData.symbol.replace("BYBIT:FUTURE:", ""), broker: "live", productType: "FUTURE", security: { symbol: orderData.symbol.replace("BYBIT:FUTURE:", ""), exchange: "BYBIT", segment: "FUTURE", tick_size: 0.01, lot_size: 0.001, }, fee: { currency: "USDT", cost: 0.0, rate: 0.001 }, key: `live-${orderData.symbol}-${generateOrderId()}`, validity: "GTC", commissions: 0, isGC: true, }; // Add to your order management system // ... your order management logic ... // Update chart with new broker data updateChartBrokerData(); } // Update chart with current broker data function updateChartBrokerData() { const currentBrokerData = { accountList: getCurrentAccounts(), orderBook: getCurrentOrders(), tradeBook: getCurrentTrades(), positions: getCurrentPositions(), }; chart.setBrokerAccounts(currentBrokerData); } // Utility function to generate unique order IDs function generateOrderId() { return `ORD_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; }

Best Practices

Tip

Real-time Updates

Always call setBrokerAccounts() whenever your broker data changes:

// When order status changes function onOrderStatusChange(orderId, newStatus) { updateOrderStatus(orderId, newStatus); updateChartBrokerData(); // Update chart immediately } // When new trade is executed function onTradeExecuted(tradeData) { addTradeToHistory(tradeData); updatePositions(tradeData); updateChartBrokerData(); // Update chart immediately }

2. Data Validation

Validate your data before sending to the chart:

function validateBrokerData(data) { // Validate required fields if (!data.accountList || !Array.isArray(data.accountList)) { throw new Error("accountList is required and must be an array"); } // Validate order structure data.orderBook.forEach((order) => { if (!order.orderId || !order.symbol || !order.side) { throw new Error("Invalid order structure"); } }); return true; }

3. Performance Optimization

For large datasets, consider pagination or filtering:

function updateChartBrokerData() { const brokerData = { accountList: getCurrentAccounts(), orderBook: getCurrentOrders().slice(0, 100), // Limit to 100 recent orders tradeBook: getCurrentTrades().slice(0, 50), // Limit to 50 recent trades positions: getCurrentPositions(), // All positions (usually small) }; chart.setBrokerAccounts(brokerData); }

4. Error Handling

Always wrap setBrokerAccounts() calls in try-catch:

function updateChartBrokerData() { try { const brokerData = getBrokerData(); validateBrokerData(brokerData); chart.setBrokerAccounts(brokerData); console.log(" Chart updated successfully"); } catch (error) { console.error(" Failed to update chart:", error); // Handle error appropriately } }

Quick Reference

Order Modification Event Types

Update TypeUpdateTypeActionExample
DELETE_SL-Remove stop loss{ update: "DELETE_SL" }
DELETE_TP-Remove take profit{ update: "DELETE_TP" }
SHAPE_MODIFYTAKE_PROFITUpdate TP price{ update: "SHAPE_MODIFY", updateType: "TAKE_PROFIT", takeProfit: 125000 }
SHAPE_MODIFYSTOP_LOSSUpdate SL price{ update: "SHAPE_MODIFY", updateType: "STOP_LOSS", stopLoss: 110000 }
SHAPE_MODIFYLIMIT_PRICEUpdate limit price{ update: "SHAPE_MODIFY", updateType: "LIMIT_PRICE", price: 115500 }

Trading Panel Components

ComponentPurposeEvent
BUY ButtonPlace buy orderPLACE_ORDER with side: "buy"
SELL ButtonPlace sell orderPLACE_ORDER with side: "sell"
Reset BrokerClear all dataResets orderBook, tradeBook, positions

Order Status Flow

Market Order: Form → PLACE_ORDER → "filled" → Position + Trade Limit Order: Form → PLACE_ORDER → "open" → (waits for execution)

Required Data Structures

// Minimum required for setBrokerAccounts() { accountList: [{ account_id, currency, balance }], orderBook: [{ orderId, symbol, side, orderType, status, price, size }], tradeBook: [{ tradeId, orderId, price, tradeSize, side, status }], positions: [{ size, price, productId, symbol, pnl }] }
Last updated on