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.

πŸš€ 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 appCallback: (eventType, message, onClose) => { if (eventType === "PLACE_ORDER") { // Handle order placement placeOrder(message.order); 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)
  • 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: [ { id: "ORD_001", symbol: "AAPL", side: "buy", quantity: 100, price: 150.50, status: "open", type: "limit", }, ], tradeBook: [], positions: [ { id: "POS_001", symbol: "AAPL", side: "long", quantity: 50, entryPrice: 148.25, currentPrice: 150.50, }, ], }); }

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) | "STOP_LOSS" // Modify existing stop loss price | "NEW_STOP_LOSS" // Add new stop loss (first time) | "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, eventData) { 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, eventData) { 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, eventData) => { // Handle all trading events console.log("Trading event:", eventType, eventData); }, });

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", 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, eventData) { switch (eventType) { case "PLACE_ORDER": // Send order to your broker API placeBrokerOrder(eventData); break; case "CANCEL_ORDER": // Cancel order through broker API cancelBrokerOrder(eventData.orderId); break; } }

🎨 UI Features

Context Menu Options

When 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_idstringβœ…Unique account identifier
AccountIDstringβœ…Alternative account ID (for compatibility)
AccountTypestring❌Account type (Demo, Live, Paper)
labelstring❌Display name for the account
currencystringβœ…Base currency (USD, EUR, etc.)
balancenumberβœ…Current account balance
equitynumber❌Account equity value
marginnumber❌Used margin amount
freeMarginnumber❌Available 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
orderIdstringβœ…Unique order identifier
datetimeDateβœ…Order creation date
timeStampnumberβœ…Order timestamp in milliseconds
statusstringβœ…Order status: β€œopen”, β€œfilled”, β€œcancelled”
pricenumberβœ…Order price (0 for market orders)
sizenumberβœ…Order quantity
productIdstringβœ…Full symbol identifier
remainingSizenumberβœ…Remaining unfilled quantity
orderTypestringβœ…Order type: β€œlimit”, β€œmarket”, β€œstop”, β€œstopLimit”
sidestringβœ…Order side: β€œbuy”, β€œsell”
exchangestringβœ…Exchange name
symbolstringβœ…Base symbol name
brokerstringβœ…Broker identifier
productTypestringβœ…Product type: β€œFUTURE”, β€œSPOT”, β€œOPTION”
securityobjectβœ…Security information object
feeobject❌Fee structure
takeProfitnumber❌Take profit price
stopLossnumber❌Stop loss price
stopPricenumber❌Stop 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
tradeIdstringβœ…Unique trade identifier
orderIdstringβœ…Associated order ID
datetimeDateβœ…Trade execution date
timeStampnumberβœ…Trade timestamp in milliseconds
statusstringβœ…Trade status: β€œfilled”, β€œpartial”
pricenumberβœ…Execution price
tradeSizenumberβœ…Trade quantity
tradeValuenumberβœ…Trade value (price Γ— quantity)
productIdstringβœ…Full symbol identifier
orderTypestringβœ…Original order type
sidestringβœ…Trade side: β€œbuy”, β€œsell”
brokerstringβœ…Broker identifier
productTypestringβœ…Product type: β€œFUTURE”, β€œSPOT”, β€œOPTION”
securityobjectβœ…Security information object
feeobject❌Fee structure
takerOrMakerstringβŒβ€œtaker” or β€œmaker”
spreadnumber❌Bid-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
sizenumberβœ…Net position size (positive = long, negative = short)
size_currencynumberβœ…Position quantity in base currency
pricenumberβœ…Average entry price
amountnumberβœ…Position value (price Γ— quantity)
productIdstringβœ…Full symbol identifier
brokerstringβœ…Broker identifier
productTypestringβœ…Product type: β€œFUTURE”, β€œSPOT”, β€œOPTION”
currencystringβœ…Position currency
idstringβœ…Position identifier
underlyingstringβœ…Underlying asset identifier
unPnlnumberβœ…Unrealized profit/loss
rPnlnumberβœ…Realized profit/loss
pnlnumberβœ…Total profit/loss
securityobjectβœ…Security information object
symbolstringβœ…Base symbol name
segmentstringβœ…Market segment
exchangestringβœ…Exchange name
positionsobject❌Detailed position breakdown
pnlMultipliernumber❌PnL calculation multiplier
showStopLossButtonboolean❌Enable Stop Loss button on position line (default: false)
showTakeProfitButtonboolean❌Enable Take Profit button on position line (default: false)
stopLossnumber❌Current Stop Loss price for the position
takeProfitnumber❌Current 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, eventData) => { if (eventType === "MODIFY_POSITION") { const position = eventData.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, eventData) { 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 will trigger a PLACE_ORDER event with the following characteristics:

Exit Order Behavior:

  • Side: Opposite of the position side
    • Long position (buy) β†’ Exit order has side: "sell"
    • Short position (sell) β†’ Exit order has side: "buy"
  • Size/Quantity: Same as the position size (to fully close the position)
  • Order Type: Typically a market order for immediate execution

Example - Exiting a Long Position:

// Original position const position = { size: 0.05, // Long position (positive size) price: 49500, productId: "BYBIT:FUTURE:BTCUSDT", // ... other fields }; // When user clicks X button, you receive: appCallback: (eventType, eventData) => { if (eventType === "PLACE_ORDER") { console.log("Exit order:", eventData); // { // side: "sell", // Opposite of long position // size: 0.05, // Same as position size // orderType: "market", // Market order for immediate exit // productId: "BYBIT:FUTURE:BTCUSDT", // // ... other order fields // } } };

Example - Exiting a Short Position:

// Original position const position = { size: -0.05, // Short position (negative size) price: 49500, productId: "BYBIT:FUTURE:BTCUSDT", // ... other fields }; // When user clicks X button, you receive: appCallback: (eventType, eventData) => { if (eventType === "PLACE_ORDER") { console.log("Exit order:", eventData); // { // side: "buy", // Opposite of short position // size: 0.05, // Absolute value of position size // orderType: "market", // Market order for immediate exit // productId: "BYBIT:FUTURE:BTCUSDT", // // ... other order fields // } } };

Handling Position Exit Orders:

function handleTradingEvents(eventType, eventData) { switch (eventType) { case "PLACE_ORDER": const order = eventData; // Check if this is a position exit order // (You can identify it by matching the size with an existing position) const existingPosition = findPositionByProductId(order.productId); if (existingPosition && Math.abs(existingPosition.size) === order.size && isOppositeSide(existingPosition, order)) { // This is a position exit order console.log("Closing position:", existingPosition.id); // Execute the exit order await brokerAPI.placeOrder({ symbol: order.symbol, side: order.side, size: order.size, orderType: "market", productId: order.productId }); // After execution, remove the position from the chart const updatedPositions = currentPositions.filter( p => p.id !== existingPosition.id ); chart.setBrokerAccounts({ accountList: currentAccounts, orderBook: currentOrders, tradeBook: [...currentTrades, newTrade], positions: updatedPositions }); } else { // Regular order placement await brokerAPI.placeOrder(order); } break; case "MODIFY_POSITION": // ... handle position modifications ... break; } } // Helper function to check if order side is opposite to position function isOppositeSide(position, order) { if (position.size > 0) { // Long position, exit should be sell return order.side === "sell"; } else if (position.size < 0) { // Short position, exit should be buy return order.side === "buy"; } return false; }
Important

Exit Order Requirements:

  1. Position Identification: The exit order will have the same productId as the position being closed
  2. Size Matching: The order size will exactly match the position size (absolute value)
  3. Market Orders: Exit orders are typically market orders for immediate execution
  4. Full Exit: The X button creates an order to fully close the position (not partial exit)
  5. Update Chart: After executing the exit order, update the chart by removing the position from the positions array

🎯 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", 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) => { onResolve({ name: symbolName, ticker: symbolName, description: "Demo Symbol", type: "crypto", session: "24x7", timezone: "Etc/UTC", tick_size: 0.01, // Minimum price movement has_intraday: true, supported_resolutions: ["1", "5", "15", "30", "60", "1D"], }); }, 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", enableTrading: true, appCallback: handleTradingEvents, onReady: (chartInstance) => { // Initialize with broker data setupBrokerData(chartInstance); }, }); // Handle trading events from the chart function handleTradingEvents(eventType, eventData) { switch (eventType) { case "CREATE_ORDER": console.log("Order creation requested:", eventData); break; case "PLACE_ORDER": console.log("Order placed:", eventData); addOrderToSystem(eventData); break; case "CANCEL_ORDER": console.log("Order cancelled:", eventData); removeOrderFromSystem(eventData.orderId); break; case "MODIFY_ORDER": console.log("Order modified:", eventData); updateOrderInSystem(eventData); 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