69 lines
1.8 KiB
TypeScript
69 lines
1.8 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import { clampExecutableOrderQuantity } from "../../lib/autotrade/executable-order-quantity";
|
|
import {
|
|
estimateBuyUnitCost,
|
|
estimateOrderCost,
|
|
resolveExecutionCostProfile,
|
|
} from "../../lib/autotrade/execution-cost";
|
|
|
|
test("SELL 차단: 보유 없음/매도가능 없음", () => {
|
|
const result = clampExecutableOrderQuantity({
|
|
side: "sell",
|
|
requestedQuantity: 1,
|
|
holdingQuantity: 0,
|
|
sellableQuantity: 0,
|
|
});
|
|
|
|
assert.equal(result.ok, false);
|
|
assert.equal(result.quantity, 0);
|
|
});
|
|
|
|
test("SELL 제한: 보유보다 큰 수량 또는 매도가능 부족 시 clamp", () => {
|
|
const result = clampExecutableOrderQuantity({
|
|
side: "sell",
|
|
requestedQuantity: 5,
|
|
holdingQuantity: 10,
|
|
sellableQuantity: 3,
|
|
});
|
|
|
|
assert.equal(result.ok, true);
|
|
assert.equal(result.quantity, 3);
|
|
assert.equal(result.adjusted, true);
|
|
});
|
|
|
|
test("BUY 제한: 최대 매수 가능 수량으로 clamp", () => {
|
|
const result = clampExecutableOrderQuantity({
|
|
side: "buy",
|
|
requestedQuantity: 4,
|
|
maxBuyQuantity: 2,
|
|
});
|
|
|
|
assert.equal(result.ok, true);
|
|
assert.equal(result.quantity, 2);
|
|
assert.equal(result.adjusted, true);
|
|
});
|
|
|
|
test("수수료/세금 추정: buy/sell 순액 계산", () => {
|
|
const profile = resolveExecutionCostProfile();
|
|
const buyUnitCost = estimateBuyUnitCost(10_000, profile);
|
|
const buy = estimateOrderCost({
|
|
side: "buy",
|
|
price: 10_000,
|
|
quantity: 10,
|
|
profile,
|
|
});
|
|
const sell = estimateOrderCost({
|
|
side: "sell",
|
|
price: 10_000,
|
|
quantity: 10,
|
|
profile,
|
|
});
|
|
|
|
assert.ok(buyUnitCost > 10_000);
|
|
assert.ok(buy.netAmount > buy.grossAmount);
|
|
assert.ok(sell.netAmount < sell.grossAmount);
|
|
assert.ok(sell.taxAmount >= 0);
|
|
});
|
|
|