π 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 orderMODIFY_ORDER- User modifies an existing orderCANCEL_ORDER- User cancels an orderMODIFY_POSITION- User modifies a position (TP/SL)EXIT_ALL_POSITIONS- User requests to exit all positionsCANCEL_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): voidBrokerAccountData 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 pricePosition 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
taskfield 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 orderupdate: "DELETE_TP"- Delete take profit from order
Shape Modifications
update: "SHAPE_MODIFY", updateType: "TAKE_PROFIT"- Update take profit priceupdate: "SHAPE_MODIFY", updateType: "STOP_LOSS"- Update stop loss priceupdate: "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 positionupdate: "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 priceupdate: "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:
- Right-click on chart β See βBuyβ and βSellβ options
- Hover over price levels β See trading options in CrossHair menu
- 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:
| Field | Type | Required | Description |
|---|---|---|---|
account_id | string | β | Unique account identifier |
AccountID | string | β | Alternative account ID (for compatibility) |
AccountType | string | β | Account type (Demo, Live, Paper) |
label | string | β | Display name for the account |
currency | string | β | Base currency (USD, EUR, etc.) |
balance | number | β | Current account balance |
equity | number | β | Account equity value |
margin | number | β | Used margin amount |
freeMargin | number | β | 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:
| Field | Type | Required | Description |
|---|---|---|---|
orderId | string | β | Unique order identifier |
datetime | Date | β | Order creation date |
timeStamp | number | β | Order timestamp in milliseconds |
status | string | β | Order status: βopenβ, βfilledβ, βcancelledβ |
price | number | β | Order price (0 for market orders) |
size | number | β | Order quantity |
productId | string | β | Full symbol identifier |
remainingSize | number | β | Remaining unfilled quantity |
orderType | string | β | Order type: βlimitβ, βmarketβ, βstopβ, βstopLimitβ |
side | string | β | Order side: βbuyβ, βsellβ |
exchange | string | β | Exchange name |
symbol | string | β | Base symbol name |
broker | string | β | Broker identifier |
productType | string | β | Product type: βFUTUREβ, βSPOTβ, βOPTIONβ |
security | object | β | Security information object |
fee | object | β | Fee structure |
takeProfit | number | β | Take profit price |
stopLoss | number | β | Stop loss price |
stopPrice | number | β | 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:
| Field | Type | Required | Description |
|---|---|---|---|
tradeId | string | β | Unique trade identifier |
orderId | string | β | Associated order ID |
datetime | Date | β | Trade execution date |
timeStamp | number | β | Trade timestamp in milliseconds |
status | string | β | Trade status: βfilledβ, βpartialβ |
price | number | β | Execution price |
tradeSize | number | β | Trade quantity |
tradeValue | number | β | Trade value (price Γ quantity) |
productId | string | β | Full symbol identifier |
orderType | string | β | Original order type |
side | string | β | Trade side: βbuyβ, βsellβ |
broker | string | β | Broker identifier |
productType | string | β | Product type: βFUTUREβ, βSPOTβ, βOPTIONβ |
security | object | β | Security information object |
fee | object | β | Fee structure |
takerOrMaker | string | β | βtakerβ or βmakerβ |
spread | number | β | 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:
| Field | Type | Required | Description |
|---|---|---|---|
size | number | β | Net position size (positive = long, negative = short) |
size_currency | number | β | Position quantity in base currency |
price | number | β | Average entry price |
amount | number | β | Position value (price Γ quantity) |
productId | string | β | Full symbol identifier |
broker | string | β | Broker identifier |
productType | string | β | Product type: βFUTUREβ, βSPOTβ, βOPTIONβ |
currency | string | β | Position currency |
id | string | β | Position identifier |
underlying | string | β | Underlying asset identifier |
unPnl | number | β | Unrealized profit/loss |
rPnl | number | β | Realized profit/loss |
pnl | number | β | Total profit/loss |
security | object | β | Security information object |
symbol | string | β | Base symbol name |
segment | string | β | Market segment |
exchange | string | β | Exchange name |
positions | object | β | Detailed position breakdown |
pnlMultiplier | number | β | PnL calculation multiplier |
showStopLossButton | boolean | β | Enable Stop Loss button on position line (default: false) |
showTakeProfitButton | boolean | β | Enable Take Profit button on position line (default: false) |
stopLoss | number | β | Current Stop Loss price for the position |
takeProfit | number | β | 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:
| Field | Type | Description |
|---|---|---|
update | string | Always "SHAPE_MODIFY" for TP/SL modifications |
updateType | string | Type of modification (see table below) |
stopLoss | number | null | New Stop Loss price (or null if deleted) |
takeProfit | number | null | New Take Profit price (or null if deleted) |
| β¦other position fields | All original position fields are included |
Update Types for Position Modifications:
| updateType | Description | When it occurs |
|---|---|---|
"NEW_STOP_LOSS" | First-time Stop Loss placement | User 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 modification | User drags or modifies an existing stop loss line (previous stopLoss > 0) |
"NEW_TAKE_PROFIT" | First-time Take Profit placement | User 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 modification | User drags or modifies an existing take profit line (previous takeProfit > 0) |
"DELETE_TAKE_PROFIT" | Take Profit deletion | User removes the take profit from the position |
"DELETE_STOP_LOSS" | Stop Loss deletion | User 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"
- Long position (buy) β Exit order has
- 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;
}Exit Order Requirements:
- Position Identification: The exit order will have the same
productIdas the position being closed - Size Matching: The order size will exactly match the position size (absolute value)
- Market Orders: Exit orders are typically market orders for immediate execution
- Full Exit: The X button creates an order to fully close the position (not partial exit)
- Update Chart: After executing the exit order, update the chart by removing the position from the
positionsarray
π― 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
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 Type | UpdateType | Action | Example |
|---|---|---|---|
DELETE_SL | - | Remove stop loss | { update: "DELETE_SL" } |
DELETE_TP | - | Remove take profit | { update: "DELETE_TP" } |
SHAPE_MODIFY | TAKE_PROFIT | Update TP price | { update: "SHAPE_MODIFY", updateType: "TAKE_PROFIT", takeProfit: 125000 } |
SHAPE_MODIFY | STOP_LOSS | Update SL price | { update: "SHAPE_MODIFY", updateType: "STOP_LOSS", stopLoss: 110000 } |
SHAPE_MODIFY | LIMIT_PRICE | Update limit price | { update: "SHAPE_MODIFY", updateType: "LIMIT_PRICE", price: 115500 } |
Trading Panel Components
| Component | Purpose | Event |
|---|---|---|
| π BUY Button | Place buy order | PLACE_ORDER with side: "buy" |
| π SELL Button | Place sell order | PLACE_ORDER with side: "sell" |
| π Reset Broker | Clear all data | Resets 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 }]
}π Related Documentation
- Chart API - Chart creation with
createChart() - Events API - Complete event documentation
- Configuration API - Trading configuration options
- TypeScript Types - Order, Trade, Position, Account types
- Examples - Working code examples