Files
ritmex-bot/src/exchanges/order-handlers.ts
T
discountry 345ad11ba3 refactor: enhance order handling and tracking in GridEngine
- Introduced a clientOrderId system for better order identification.
- Updated order creation logic to ensure unique clientOrderIds.
- Improved order cancellation methods to maintain accurate current orders.
- Added tests for new clientOrderId functionality and level state tracking.
- Ensured that desired orders have an intent field set for clarity.
- Enhanced snapshot functionality to include level states for grid lines.
2026-04-06 20:05:03 +08:00

148 lines
5.0 KiB
TypeScript

import type { Order, CreateOrderParams, TimeInForce } from "./types";
import type {
BaseOrderIntent,
ClosePositionIntent,
LimitOrderIntent,
MarketOrderIntent,
StopOrderIntent,
TrailingStopOrderIntent,
} from "./order-schema";
import { toStringBoolean } from "./order-schema";
export interface OrderHandlerConfig {
exchangeName: string;
defaultLimitTimeInForce: TimeInForce | "GTX";
defaultMarketTimeInForce?: TimeInForce;
defaultCloseTimeInForce?: TimeInForce;
defaultStopTimeInForce?: TimeInForce;
defaultStopTriggerType?: "UNSPECIFIED" | "TAKE_PROFIT" | "STOP_LOSS";
supportsTrailingStop: boolean;
supportsTriggerType: boolean;
stopDefaultReduceOnly?: boolean;
stopDefaultClosePosition?: boolean;
closeDefaultClosePosition?: boolean;
stopPriceAsPrice?: boolean;
}
export interface OrderHandlers {
createLimitOrder(intent: LimitOrderIntent): Promise<Order>;
createMarketOrder(intent: MarketOrderIntent): Promise<Order>;
createStopOrder(intent: StopOrderIntent): Promise<Order>;
createTrailingStopOrder(intent: TrailingStopOrderIntent): Promise<Order>;
createClosePositionOrder(intent: ClosePositionIntent): Promise<Order>;
}
function applyCommonFields(params: CreateOrderParams, intent: BaseOrderIntent): CreateOrderParams {
if (params.quantity === undefined) {
params.quantity = intent.quantity;
}
if (params.timeInForce === undefined && intent.timeInForce) {
params.timeInForce = intent.timeInForce;
}
if (intent.reduceOnly !== undefined) {
params.reduceOnly = toStringBoolean(intent.reduceOnly);
}
if (intent.closePosition !== undefined) {
params.closePosition = toStringBoolean(intent.closePosition);
}
if (intent.clientOrderId !== undefined) {
params.clientOrderId = intent.clientOrderId;
}
return params;
}
export function createOrderHandlers(config: OrderHandlerConfig): OrderHandlers {
return {
async createLimitOrder(intent: LimitOrderIntent): Promise<Order> {
const params: CreateOrderParams = applyCommonFields(
{
symbol: intent.symbol,
side: intent.side,
type: "LIMIT",
quantity: intent.quantity,
price: intent.price,
timeInForce: intent.timeInForce ?? config.defaultLimitTimeInForce,
slPrice: intent.slPrice,
tpPrice: intent.tpPrice,
},
intent,
);
return intent.adapter.createOrder(params);
},
async createMarketOrder(intent: MarketOrderIntent): Promise<Order> {
const params: CreateOrderParams = applyCommonFields(
{
symbol: intent.symbol,
side: intent.side,
type: "MARKET",
quantity: intent.quantity,
timeInForce: intent.timeInForce ?? config.defaultMarketTimeInForce,
},
intent,
);
return intent.adapter.createOrder(params);
},
async createStopOrder(intent: StopOrderIntent): Promise<Order> {
const params: CreateOrderParams = applyCommonFields(
{
symbol: intent.symbol,
side: intent.side,
type: "STOP_MARKET",
quantity: intent.quantity,
stopPrice: intent.stopPrice,
timeInForce: intent.timeInForce ?? (config.defaultStopTimeInForce ?? "GTC"),
triggerType: config.supportsTriggerType ? (intent.triggerType ?? config.defaultStopTriggerType) : undefined,
price: config.stopPriceAsPrice ? intent.stopPrice : undefined,
},
intent,
);
if (config.stopDefaultReduceOnly && intent.reduceOnly === undefined) {
params.reduceOnly = "true";
}
if (config.stopDefaultClosePosition && intent.closePosition === undefined) {
params.closePosition = "true";
}
return intent.adapter.createOrder(params);
},
async createTrailingStopOrder(intent: TrailingStopOrderIntent): Promise<Order> {
if (!config.supportsTrailingStop) {
throw new Error(`${config.exchangeName} does not support trailing stop orders`);
}
const params: CreateOrderParams = applyCommonFields(
{
symbol: intent.symbol,
side: intent.side,
type: "TRAILING_STOP_MARKET",
quantity: intent.quantity,
activationPrice: intent.activationPrice,
callbackRate: intent.callbackRate,
timeInForce: intent.timeInForce ?? "GTC",
},
intent,
);
return intent.adapter.createOrder(params);
},
async createClosePositionOrder(intent: ClosePositionIntent): Promise<Order> {
const params: CreateOrderParams = applyCommonFields(
{
symbol: intent.symbol,
side: intent.side,
type: "MARKET",
quantity: intent.quantity,
reduceOnly: "true",
timeInForce: intent.timeInForce ?? config.defaultCloseTimeInForce,
},
intent,
);
if (config.closeDefaultClosePosition && intent.closePosition === undefined) {
params.closePosition = "true";
}
return intent.adapter.createOrder(params);
},
};
}