Files
auto-trade/lib/autotrade/executable-order-quantity.ts

57 lines
1.6 KiB
TypeScript

export type ExecutableOrderSide = "buy" | "sell";
export interface ClampExecutableOrderQuantityParams {
side: ExecutableOrderSide;
requestedQuantity: number;
maxBuyQuantity?: number;
holdingQuantity?: number;
sellableQuantity?: number;
}
export interface ClampExecutableOrderQuantityResult {
ok: boolean;
quantity: number;
adjusted: boolean;
}
/**
* [목적]
* 주문 전 계좌 제약(매수가능/보유/매도가능)에 맞춰 최종 실행 수량을 순수 계산합니다.
*
* [입력 -> 처리 -> 결과]
* 요청 수량/사이드/제약값 -> 가능 최대 수량으로 clamp -> 실행 가능 여부와 수량 반환
*/
export function clampExecutableOrderQuantity(
params: ClampExecutableOrderQuantityParams,
): ClampExecutableOrderQuantityResult {
const requestedQuantity = Math.max(0, Math.floor(params.requestedQuantity));
if (requestedQuantity <= 0) {
return {
ok: false,
quantity: 0,
adjusted: false,
};
}
if (params.side === "buy") {
const maxBuyQuantity = Math.max(0, Math.floor(params.maxBuyQuantity ?? 0));
const quantity = Math.min(requestedQuantity, maxBuyQuantity);
return {
ok: quantity > 0,
quantity,
adjusted: quantity !== requestedQuantity,
};
}
const holdingQuantity = Math.max(0, Math.floor(params.holdingQuantity ?? 0));
const sellableQuantity = Math.max(0, Math.floor(params.sellableQuantity ?? 0));
const maxSellQuantity = Math.min(holdingQuantity, sellableQuantity);
const quantity = Math.min(requestedQuantity, maxSellQuantity);
return {
ok: quantity > 0,
quantity,
adjusted: quantity !== requestedQuantity,
};
}