Skip to main content

Trading

Supplying orders & positions to chart

You have to implement these 2 providers in order to show orders and positions on chart:

OrderProvider

To integrate trading orders

OrderProvider.observeOrders
OrderProvider.observeOrders(symbol: string, dataCallback: (orders: OrderWithId[]) => void): void

Observes the order lines updates. We expect to be the full list of orders - no partial updates, for now the full list will be replaced.

Parameters
symbol: string
dataCallback: (orders: OrderWithId[]) => void
Returns
void
OrderProvider.observeExecutedOrders
OrderProvider.observeExecutedOrders(symbol: string, dataCallback: (orders: ExecutedOrder[]) => void): void

Observes the executed orders. We expect to be the full list of executed orders - no partial updates, for now the full list will be replaced.

Parameters
symbol: string
dataCallback: (orders: ExecutedOrder[]) => void
Returns
void
OrderProvider.createOrder
OrderProvider.createOrder(symbol: string, order: Order): Promise<string>

Creates new order We expect creating "id" for order inside this method If you create protection order, please don't forget to link it to original order by "protectionOrderIds" field

Parameters
symbol: string
order: Order
Returns
Promise<string>
OrderProvider.createOcoOrders
OrderProvider.createOcoOrders(symbol: string, parentOrderId: string, orders: [Order, Order]): Promise<[string, string]>

Creates new OCO orders We expect creating "ids" for the orders inside this method TODO: right now OCO orders is not fully supported by chart, so instead of orders will be passed [undefined, undefined]

Parameters
symbol: string
- current instrument's symbol
parentOrderId: string
- id of the order from which OCO orders will be created
orders: [Order, Order]
- array of two orders, which will be created as OCO orders
Returns
Promise<[string, string]>
OrderProvider.updateOrder
OrderProvider.updateOrder(symbol: string, order: OrderWithId): Promise<void>

Updates single order

Parameters
symbol: string
order: OrderWithId
Returns
Promise<void>
OrderProvider.deleteOrder
OrderProvider.deleteOrder(symbol: string, order: OrderWithId): Promise<void>

Deletes single order Please, take a look at "protectionOrdersIds" field: if order with type "original" order was deleted, protection orders should be deleted too.

Parameters
symbol: string
order: OrderWithId
Returns
Promise<void>

PositionProvider

To integrate trading positions

PositionProvider.observePositions
PositionProvider.observePositions(symbol: string, dataCallback: (positions: Position[]) => void): void

Parameters
symbol: string
dataCallback: (positions: Position[]) => void
Returns
void
PositionProvider.closePosition
PositionProvider.closePosition(symbol: string, id: string): Promise<void>

Parameters
symbol: string
id: string
Returns
Promise<void>
PositionProvider.closePositionWithOcoOrders
PositionProvider.closePositionWithOcoOrders(symbol: string, parentPositionId: string, orders: [Order, Order]): Promise<[string, string]>

Closes position with new OCO orders We expect creating "ids" for the orders inside this method TODO: right now OCO orders is not fully supported by chart, so instead of orders will be passed [undefined, undefined]

Parameters
symbol: string
- current instrument's symbol
parentPositionId: string
orders: [Order, Order]
- array of two orders, which will be created as OCO orders
Returns
Promise<[string, string]>

Configuration For "OCO" orders

OCO - One Cancels Other. It's just two linked orders which are created simultaneously and if one of them is executed - other is cancelled automatically.

Right now OCO orders is not fully supported by chart, which means that there is no UI for issuing OCO orders. But you can use your own UI to issue OCO orders.

You just need to specify canCreateOCO: true property in model for order or position which are supplied by your providers.

export interface OrderData {
orderType: OrderType;
side: 'buy' | 'sell';
quantity: number;
limitPrice?: number;
stopPrice?: number;
canCreateOCO?: boolean;
// used to render order items in DOM with custom [data-{name}] attributes
// these data attributes can be used for customization in external projects
data?: Record<string, string>;
}
export interface Position {
id: string;
side: 'buy' | 'sell';
type: 'original';
quantity: number;
price: number;
pl: number;
canCreateOCO?: boolean;
protectionOrderIds?: [StopLossId | undefined, TakeProfitId | undefined];
// used to render position items in DOM with custom [data-{name}] attributes
// these data attributes can be used for customization in external projects
data?: Record<string, string>;
}

Configuration For "Stop Loss" and "Take Profit" orders

Firstly, you should implement positionProvider and orderProvider on its side. Orders and positions have the ability to create protection orders (stop loss and take profit). After the order is created on the UI and the price is selected, the createOrder function of the provider is called, which contains the newly created protection order with the following information:

export interface OrderData {
orderType: OrderType;
side: 'buy' | 'sell';
quantity: number;
limitPrice?: number;
stopPrice?: number;
canCreateOCO?: boolean;
// used to render order items in DOM with custom [data-{name}] attributes
// these data attributes can be used for customization in external projects
data?: Record<string, string>;
}
export interface ProtectionOrder extends OrderData {
type: ProtectionOrderType;
originalItemId: string;
}

Take a look at protection order example:

{
id: "protection_order_1",
limitPrice: 229.2863986896831,
orderType: "limit",
originalItemId: "order_1",
quantity: 100,
side: "sell",
type: "tp"
}

Each protection order has connection with it's parent - original order, by originalItemId field.

Similarly, original order has field protectionOrderIds. Take a look:

{
id : "order_1",
limitPrice : 225.0514097391597 ,
orderType : "limit",
quantity : 100,
side : "buy",
stopPrice : 225.0514097391597,
type : "original",
protectionOrderIds: [undefined, "protection_order_1"];
}

You should store this order on your side in the storage (at the your discretion), and can change it as convenient.

Also, you should remember, that if you delete protection order, you should also remove connection from original order by editing protectionOrderIds field. And if you delete original order, don't forget to remove protection orders instances from your store.

The same behavior is supported for Positions. After changing the order, you need to send all orders to the observeOrders method, and they will be displayed on the chart with new data

If you correctly applied rules above, you will see the following:

Configuration For "Trading"

You can configure trading using the following interface from ChartReactConfig#trading

export interface PartialTradingConfig {
/**
* Use it, if you want to hide/show Trading tab from settings
*/
enabled?: boolean;
addNewOrderEnabled?: boolean;
showPriceAsLabels?: boolean;
rightOffset?: number;
takeProfitStopLossEnabled?: boolean;
defaultOrderQuantity?: number;
maxOrderQuantity?: number;
currency?: string;
orderTypes?: PartialOrderTypes;
}