refactor: rename Aster-prefixed universal types to clean names

- AsterOrder → Order
- AsterAccountSnapshot → AccountSnapshot
- AsterAccountPosition → AccountPosition
- AsterAccountAsset → AccountAsset
- AsterDepthLevel → DepthLevel
- AsterDepth → Depth
- AsterTicker → Ticker
- AsterKline → Kline

These types are the platform-agnostic contract used by all 8 exchanges,
not Aster-specific. Renamed across 63 files.
This commit is contained in:
discountry
2026-04-06 18:11:57 +08:00
parent 230c0d5e18
commit fda6bcad1d
62 changed files with 727 additions and 727 deletions
+7 -7
View File
@@ -1,6 +1,6 @@
import type { BasisArbConfig } from "../config";
import type { ExchangeAdapter, FundingRateSnapshot } from "../exchanges/adapter";
import type { AsterAccountSnapshot, AsterDepth, AsterSpotBookTicker } from "../exchanges/types";
import type { AccountSnapshot, Depth, AsterSpotBookTicker } from "../exchanges/types";
import { AsterSpotRestClient, AsterRestClient } from "../exchanges/aster/client";
import { createTradeLog, type TradeLogEntry } from "../logging/trade-log";
import { StrategyEventEmitter } from "./common/event-emitter";
@@ -155,7 +155,7 @@ export class BasisArbEngine {
private bootstrap(): void {
const log: LogHandler = (type, detail) => this.tradeLog.push(type, detail);
safeSubscribe<AsterDepth>(
safeSubscribe<Depth>(
this.exchange.watchDepth.bind(this.exchange, this.config.futuresSymbol),
(depth) => {
this.applyFuturesDepth(depth);
@@ -168,7 +168,7 @@ export class BasisArbEngine {
);
if (this.exchange.id === "nado" || this.exchange.id === "standx" || this.exchange.id === "binance") {
safeSubscribe<AsterDepth>(
safeSubscribe<Depth>(
this.exchange.watchDepth.bind(this.exchange, this.config.spotSymbol),
(depth) => {
this.applySpotDepth(depth);
@@ -196,7 +196,7 @@ export class BasisArbEngine {
);
}
safeSubscribe<AsterAccountSnapshot>(
safeSubscribe<AccountSnapshot>(
this.exchange.watchAccount.bind(this.exchange),
(snapshot) => {
this.applyAccountSnapshot(snapshot);
@@ -210,7 +210,7 @@ export class BasisArbEngine {
}
}
private applyFuturesDepth(depth: AsterDepth): void {
private applyFuturesDepth(depth: Depth): void {
if (!depth?.bids?.length || !depth?.asks?.length) {
return;
}
@@ -360,7 +360,7 @@ export class BasisArbEngine {
this.emitUpdate();
}
private applySpotDepth(depth: AsterDepth): void {
private applySpotDepth(depth: Depth): void {
if (!depth?.bids?.length || !depth?.asks?.length) {
return;
}
@@ -395,7 +395,7 @@ export class BasisArbEngine {
this.emitUpdate();
}
private applyAccountSnapshot(snapshot: AsterAccountSnapshot): void {
private applyAccountSnapshot(snapshot: AccountSnapshot): void {
const assets = Array.isArray(snapshot.assets) ? snapshot.assets : [];
const spotBalances: SpotBalanceStateEntry[] = [];
+10 -10
View File
@@ -1,5 +1,5 @@
import NodeWebSocket from "ws";
import type { AsterDepthLevel } from "../../exchanges/types";
import type { DepthLevel } from "../../exchanges/types";
import type { DepthImbalance } from "../../utils/depth";
const WebSocketCtor: typeof globalThis.WebSocket =
@@ -56,14 +56,14 @@ export type BinanceConnectionListener = (state: BinanceConnectionState) => void;
interface DepthUpdateEvent {
U: number;
u: number;
bids: AsterDepthLevel[];
asks: AsterDepthLevel[];
bids: DepthLevel[];
asks: DepthLevel[];
}
interface DepthSnapshotResponse {
lastUpdateId: number;
bids: AsterDepthLevel[];
asks: AsterDepthLevel[];
bids: DepthLevel[];
asks: DepthLevel[];
}
export class BinanceDepthTracker {
@@ -540,7 +540,7 @@ export class BinanceDepthTracker {
return true;
}
private applyLevels(book: Map<string, number>, levels: AsterDepthLevel[]): void {
private applyLevels(book: Map<string, number>, levels: DepthLevel[]): void {
for (const level of levels) {
const priceRaw = level?.[0];
const qtyRaw = level?.[1];
@@ -657,8 +657,8 @@ export class BinanceDepthTracker {
throw new Error("invalid lastUpdateId");
}
const bids = Array.isArray(json.bids) ? (json.bids as AsterDepthLevel[]) : [];
const asks = Array.isArray(json.asks) ? (json.asks as AsterDepthLevel[]) : [];
const bids = Array.isArray(json.bids) ? (json.bids as DepthLevel[]) : [];
const asks = Array.isArray(json.asks) ? (json.asks as DepthLevel[]) : [];
this.lastRestSyncAt = Date.now();
this.restConsecutiveFailures = 0;
this.restLastError = null;
@@ -697,8 +697,8 @@ export class BinanceDepthTracker {
const bidsRaw = Array.isArray(payload.b) ? payload.b : [];
const asksRaw = Array.isArray(payload.a) ? payload.a : [];
const bids = bidsRaw.filter((level): level is AsterDepthLevel => Array.isArray(level)) as AsterDepthLevel[];
const asks = asksRaw.filter((level): level is AsterDepthLevel => Array.isArray(level)) as AsterDepthLevel[];
const bids = bidsRaw.filter((level): level is DepthLevel => Array.isArray(level)) as DepthLevel[];
const asks = asksRaw.filter((level): level is DepthLevel => Array.isArray(level)) as DepthLevel[];
return { U, u, bids, asks };
} catch {
+13 -13
View File
@@ -1,6 +1,6 @@
import type { GridConfig, GridDirection } from "../config";
import type { ExchangeAdapter } from "../exchanges/adapter";
import type { AsterAccountSnapshot, AsterDepth, AsterOrder, AsterTicker } from "../exchanges/types";
import type { AccountSnapshot, Depth, Order, Ticker } from "../exchanges/types";
import { createTradeLog, type TradeLogEntry } from "../logging/trade-log";
import { decimalsOf } from "../utils/math";
import { extractMessage } from "../utils/errors";
@@ -51,7 +51,7 @@ export interface GridEngineSnapshot {
midPrice: number | null;
gridLines: GridLineSnapshot[];
desiredOrders: DesiredGridOrder[];
openOrders: AsterOrder[];
openOrders: Order[];
position: PositionSnapshot;
running: boolean;
stopReason: string | null;
@@ -115,10 +115,10 @@ export class GridEngine {
private lastAbsPositionAmt = 0;
private immediateCloseToPlace: Array<{ sourceLevel: number; targetLevel: number; side: "BUY" | "SELL"; price: string }> = [];
private accountSnapshot: AsterAccountSnapshot | null = null;
private depthSnapshot: AsterDepth | null = null;
private tickerSnapshot: AsterTicker | null = null;
private openOrders: AsterOrder[] = [];
private accountSnapshot: AccountSnapshot | null = null;
private depthSnapshot: Depth | null = null;
private tickerSnapshot: Ticker | null = null;
private openOrders: Order[] = [];
private position: PositionSnapshot = { positionAmt: 0, entryPrice: 0, unrealizedProfit: 0, markPrice: null };
private desiredOrders: DesiredGridOrder[] = [];
@@ -277,7 +277,7 @@ export class GridEngine {
private bootstrap(): void {
const log: LogHandler = (type, detail) => this.tradeLog.push(type, detail);
safeSubscribe<AsterAccountSnapshot>(
safeSubscribe<AccountSnapshot>(
this.exchange.watchAccount.bind(this.exchange),
(snapshot) => {
this.accountSnapshot = snapshot;
@@ -301,7 +301,7 @@ export class GridEngine {
}
);
safeSubscribe<AsterOrder[]>(
safeSubscribe<Order[]>(
this.exchange.watchOrders.bind(this.exchange),
(orders) => {
this.openOrders = Array.isArray(orders)
@@ -327,7 +327,7 @@ export class GridEngine {
}
);
safeSubscribe<AsterDepth>(
safeSubscribe<Depth>(
this.exchange.watchDepth.bind(this.exchange, this.config.symbol),
(depth) => {
this.depthSnapshot = depth;
@@ -345,7 +345,7 @@ export class GridEngine {
}
);
safeSubscribe<AsterTicker>(
safeSubscribe<Ticker>(
this.exchange.watchTicker.bind(this.exchange, this.config.symbol),
(ticker) => {
this.tickerSnapshot = ticker;
@@ -366,7 +366,7 @@ export class GridEngine {
);
}
private synchronizeLocks(orders: AsterOrder[] | null | undefined): void {
private synchronizeLocks(orders: Order[] | null | undefined): void {
const list = Array.isArray(orders) ? orders : [];
const FINAL = new Set(["FILLED", "CANCELED", "CANCELLED", "REJECTED", "EXPIRED"]);
Object.keys(this.pendings).forEach((type) => {
@@ -619,7 +619,7 @@ export class GridEngine {
const activeOrders = this.openOrders.filter((o) => this.isActiveLimitOrder(o));
// Build lookup for all recent orders by id (including non-active) to read final statuses
const allOrdersById = new Map<string, AsterOrder>();
const allOrdersById = new Map<string, Order>();
for (const o of this.openOrders) {
if (o.symbol !== this.config.symbol) continue;
allOrdersById.set(String(o.orderId), o);
@@ -1187,7 +1187,7 @@ export class GridEngine {
return `${side}:${price}:${intent}`;
}
private isActiveLimitOrder(o: AsterOrder): boolean {
private isActiveLimitOrder(o: Order): boolean {
if (o.symbol !== this.config.symbol) return false;
if (o.type !== "LIMIT") return false;
const s = String(o.status || "").toUpperCase();
+17 -17
View File
@@ -1,6 +1,6 @@
import type { TradingConfig } from "../config";
import type { ExchangeAdapter } from "../exchanges/adapter";
import type { AsterAccountSnapshot, AsterOrder, AsterTicker } from "../exchanges/types";
import type { AccountSnapshot, Order, Ticker } from "../exchanges/types";
import {
calcStopLossPrice,
calcTrailingActivationPrice,
@@ -30,11 +30,11 @@ export interface GuardianEngineSnapshot {
unrealized: number;
targetStopPrice: number | null;
trailingActivationPrice: number | null;
stopOrder: AsterOrder | null;
trailingOrder: AsterOrder | null;
stopOrder: Order | null;
trailingOrder: Order | null;
requiresStop: boolean;
tradeLog: TradeLogEntry[];
openOrders: AsterOrder[];
openOrders: Order[];
lastUpdated: number | null;
guardStatus: "idle" | "protecting" | "pending";
}
@@ -43,9 +43,9 @@ type GuardianEngineEvent = "update";
type GuardianEngineListener = (snapshot: GuardianEngineSnapshot) => void;
export class GuardianEngine {
private accountSnapshot: AsterAccountSnapshot | null = null;
private openOrders: AsterOrder[] = [];
private tickerSnapshot: AsterTicker | null = null;
private accountSnapshot: AccountSnapshot | null = null;
private openOrders: Order[] = [];
private tickerSnapshot: Ticker | null = null;
private readonly locks: OrderLockMap = {};
private readonly timers: OrderTimerMap = {};
@@ -101,7 +101,7 @@ export class GuardianEngine {
private bootstrap(): void {
const log: LogHandler = (type, detail) => this.tradeLog.push(type, detail);
safeSubscribe<AsterAccountSnapshot>(
safeSubscribe<AccountSnapshot>(
this.exchange.watchAccount.bind(this.exchange),
(snapshot) => {
this.accountSnapshot = snapshot;
@@ -114,7 +114,7 @@ export class GuardianEngine {
}
);
safeSubscribe<AsterOrder[]>(
safeSubscribe<Order[]>(
this.exchange.watchOrders.bind(this.exchange),
(orders) => {
this.synchronizeLocks(orders);
@@ -141,7 +141,7 @@ export class GuardianEngine {
}
);
safeSubscribe<AsterTicker>(
safeSubscribe<Ticker>(
this.exchange.watchTicker.bind(this.exchange, this.config.symbol),
(ticker) => {
this.tickerSnapshot = ticker;
@@ -155,7 +155,7 @@ export class GuardianEngine {
);
}
private synchronizeLocks(orders: AsterOrder[] | null | undefined): void {
private synchronizeLocks(orders: Order[] | null | undefined): void {
const list = Array.isArray(orders) ? orders : [];
Object.keys(this.pending).forEach((type) => {
const pendingId = this.pending[type];
@@ -261,8 +261,8 @@ export class GuardianEngine {
price: number;
stopPrice: number;
activationPrice: number;
currentStop?: AsterOrder;
currentTrailing?: AsterOrder;
currentStop?: Order;
currentTrailing?: Order;
}): Promise<void> {
const { position, direction, stopSide, price, stopPrice, activationPrice, currentStop, currentTrailing } = params;
@@ -416,7 +416,7 @@ export class GuardianEngine {
private async tryReplaceStop(
side: "BUY" | "SELL",
currentOrder: AsterOrder,
currentOrder: Order,
nextStopPrice: number,
lastPrice: number
): Promise<void> {
@@ -559,7 +559,7 @@ export class GuardianEngine {
}
}
private isProtectiveOrder(order: AsterOrder): boolean {
private isProtectiveOrder(order: Order): boolean {
if (order.symbol !== this.config.symbol) {
return false;
}
@@ -571,14 +571,14 @@ export class GuardianEngine {
return type === "STOP_MARKET" || hasStopPrice;
}
private findStopOrder(side: "BUY" | "SELL"): AsterOrder | undefined {
private findStopOrder(side: "BUY" | "SELL"): Order | undefined {
return this.openOrders.find((order) => {
const hasStopPrice = Number.isFinite(Number(order.stopPrice)) && Number(order.stopPrice) > 0;
return order.side === side && (order.type === "STOP_MARKET" || hasStopPrice);
});
}
private findTrailingOrder(side: "BUY" | "SELL"): AsterOrder | undefined {
private findTrailingOrder(side: "BUY" | "SELL"): Order | undefined {
return this.openOrders.find((order) => order.type === "TRAILING_STOP_MARKET" && order.side === side);
}
+20 -20
View File
@@ -1,11 +1,11 @@
import type { LiquidityMakerConfig } from "../config";
import type { ExchangeAdapter } from "../exchanges/adapter";
import type {
AsterAccountSnapshot,
AsterDepth,
AsterKline,
AsterOrder,
AsterTicker,
AccountSnapshot,
Depth,
Kline,
Order,
Ticker,
} from "../exchanges/types";
import { formatPriceToString } from "../utils/math";
import { createTradeLog } from "../logging/trade-log";
@@ -65,12 +65,12 @@ type MakerListener = (snapshot: LiquidityMakerEngineSnapshot) => void;
const EPS = 1e-5;
export class LiquidityMakerEngine {
private accountSnapshot: AsterAccountSnapshot | null = null;
private depthSnapshot: AsterDepth | null = null;
private tickerSnapshot: AsterTicker | null = null;
private lastKline: AsterKline | null = null;
private accountSnapshot: AccountSnapshot | null = null;
private depthSnapshot: Depth | null = null;
private tickerSnapshot: Ticker | null = null;
private lastKline: Kline | null = null;
private liveCandle: { startMs: number; open: number; close: number } | null = null;
private openOrders: AsterOrder[] = [];
private openOrders: Order[] = [];
private readonly locks: OrderLockMap = {};
private readonly timers: OrderTimerMap = {};
@@ -180,7 +180,7 @@ export class LiquidityMakerEngine {
private bootstrap(): void {
const log: LogHandler = (type, detail) => this.tradeLog.push(type, detail);
safeSubscribe<AsterAccountSnapshot>(
safeSubscribe<AccountSnapshot>(
this.exchange.watchAccount.bind(this.exchange),
(snapshot) => {
this.accountSnapshot = snapshot;
@@ -224,7 +224,7 @@ export class LiquidityMakerEngine {
}
);
safeSubscribe<AsterOrder[]>(
safeSubscribe<Order[]>(
this.exchange.watchOrders.bind(this.exchange),
(orders) => {
this.syncLocksWithOrders(orders);
@@ -232,7 +232,7 @@ export class LiquidityMakerEngine {
// 检测成交:对比上一轮的订单ID
const currentIds = new Set<string>();
const activeOrders: AsterOrder[] = [];
const activeOrders: Order[] = [];
if (Array.isArray(orders)) {
for (const order of orders) {
@@ -268,7 +268,7 @@ export class LiquidityMakerEngine {
}
);
safeSubscribe<AsterDepth>(
safeSubscribe<Depth>(
this.exchange.watchDepth.bind(this.exchange, this.config.symbol),
(depth) => {
this.depthSnapshot = depth;
@@ -282,7 +282,7 @@ export class LiquidityMakerEngine {
}
);
safeSubscribe<AsterTicker>(
safeSubscribe<Ticker>(
this.exchange.watchTicker.bind(this.exchange, this.config.symbol),
(ticker) => {
this.tickerSnapshot = ticker;
@@ -296,7 +296,7 @@ export class LiquidityMakerEngine {
}
);
safeSubscribe<AsterKline[]>(
safeSubscribe<Kline[]>(
this.exchange.watchKlines.bind(this.exchange, this.config.symbol, "1m"),
(klines) => {
if (!Array.isArray(klines) || !klines.length) return;
@@ -318,7 +318,7 @@ export class LiquidityMakerEngine {
}
/** 检测成交订单 */
private detectFills(orders: AsterOrder[] | null | undefined): void {
private detectFills(orders: Order[] | null | undefined): void {
if (!Array.isArray(orders)) return;
// 查找已成交或部分成交的订单
@@ -357,7 +357,7 @@ export class LiquidityMakerEngine {
}
}
private syncLocksWithOrders(orders: AsterOrder[] | null | undefined): void {
private syncLocksWithOrders(orders: Order[] | null | undefined): void {
const list = Array.isArray(orders) ? orders : [];
Object.keys(this.pending).forEach((type) => {
const pendingId = this.pending[type];
@@ -759,7 +759,7 @@ export class LiquidityMakerEngine {
* 更敏感的偏移判断:当一侧深度超出另一侧 depthImbalanceRatio 倍时,
* 取消订单簿较薄一端的订单
*/
private evaluateDepth(depth: AsterDepth): {
private evaluateDepth(depth: Depth): {
buySum: number;
sellSum: number;
skipBuySide: boolean;
@@ -1186,7 +1186,7 @@ export class LiquidityMakerEngine {
return position;
}
private getSpotBalances(snapshot: AsterAccountSnapshot | null = this.accountSnapshot): { baseAvailable: number; quoteAvailable: number; baseWallet: number } | null {
private getSpotBalances(snapshot: AccountSnapshot | null = this.accountSnapshot): { baseAvailable: number; quoteAvailable: number; baseWallet: number } | null {
const assets = snapshot?.assets ?? [];
if (!assets.length) return null;
const parsed = parseSymbolParts(this.config.symbol);
+14 -14
View File
@@ -1,10 +1,10 @@
import type { MakerConfig } from "../config";
import type { ExchangeAdapter } from "../exchanges/adapter";
import type {
AsterAccountSnapshot,
AsterDepth,
AsterOrder,
AsterTicker,
AccountSnapshot,
Depth,
Order,
Ticker,
} from "../exchanges/types";
import { formatPriceToString } from "../utils/math";
import { createTradeLog, type TradeLogEntry } from "../logging/trade-log";
@@ -47,7 +47,7 @@ export interface MakerEngineSnapshot {
pnl: number;
accountUnrealized: number;
sessionVolume: number;
openOrders: AsterOrder[];
openOrders: Order[];
desiredOrders: DesiredOrder[];
tradeLog: TradeLogEntry[];
lastUpdated: number | null;
@@ -66,10 +66,10 @@ const EPS = 1e-5;
const INSUFFICIENT_BALANCE_COOLDOWN_MS = 15_000;
export class MakerEngine {
private accountSnapshot: AsterAccountSnapshot | null = null;
private depthSnapshot: AsterDepth | null = null;
private tickerSnapshot: AsterTicker | null = null;
private openOrders: AsterOrder[] = [];
private accountSnapshot: AccountSnapshot | null = null;
private depthSnapshot: Depth | null = null;
private tickerSnapshot: Ticker | null = null;
private openOrders: Order[] = [];
private readonly locks: OrderLockMap = {};
private readonly timers: OrderTimerMap = {};
@@ -154,7 +154,7 @@ export class MakerEngine {
private bootstrap(): void {
const log: LogHandler = (type, detail) => this.tradeLog.push(type, detail);
safeSubscribe<AsterAccountSnapshot>(
safeSubscribe<AccountSnapshot>(
this.exchange.watchAccount.bind(this.exchange),
(snapshot) => {
this.accountSnapshot = snapshot;
@@ -178,7 +178,7 @@ export class MakerEngine {
}
);
safeSubscribe<AsterOrder[]>(
safeSubscribe<Order[]>(
this.exchange.watchOrders.bind(this.exchange),
(orders) => {
this.syncLocksWithOrders(orders);
@@ -211,7 +211,7 @@ export class MakerEngine {
}
);
safeSubscribe<AsterDepth>(
safeSubscribe<Depth>(
this.exchange.watchDepth.bind(this.exchange, this.config.symbol),
(depth) => {
this.depthSnapshot = depth;
@@ -229,7 +229,7 @@ export class MakerEngine {
}
);
safeSubscribe<AsterTicker>(
safeSubscribe<Ticker>(
this.exchange.watchTicker.bind(this.exchange, this.config.symbol),
(ticker) => {
this.tickerSnapshot = ticker;
@@ -250,7 +250,7 @@ export class MakerEngine {
// Maker strategy does not require realtime klines.
}
private syncLocksWithOrders(orders: AsterOrder[] | null | undefined): void {
private syncLocksWithOrders(orders: Order[] | null | undefined): void {
const list = Array.isArray(orders) ? orders : [];
Object.keys(this.pending).forEach((type) => {
const pendingId = this.pending[type];
+20 -20
View File
@@ -1,10 +1,10 @@
import type { MakerPointsConfig } from "../config";
import type { ExchangeAdapter } from "../exchanges/adapter";
import type {
AsterAccountSnapshot,
AsterDepth,
AsterOrder,
AsterTicker,
AccountSnapshot,
Depth,
Order,
Ticker,
} from "../exchanges/types";
import { formatPriceToString } from "../utils/math";
import { createTradeLog, type TradeLogEntry } from "../logging/trade-log";
@@ -59,7 +59,7 @@ export interface MakerPointsSnapshot {
pnl: number;
accountUnrealized: number;
sessionVolume: number;
openOrders: AsterOrder[];
openOrders: Order[];
desiredOrders: DesiredOrder[];
tradeLog: TradeLogEntry[];
lastUpdated: number | null;
@@ -102,10 +102,10 @@ const STANDX_MARGIN_MODE_MAX_ATTEMPTS = 10;
const ACCOUNT_STALE_REST_PROBE_MIN_INTERVAL_MS = 5_000;
export class MakerPointsEngine {
private accountSnapshot: AsterAccountSnapshot | null = null;
private depthSnapshot: AsterDepth | null = null;
private tickerSnapshot: AsterTicker | null = null;
private openOrders: AsterOrder[] = [];
private accountSnapshot: AccountSnapshot | null = null;
private depthSnapshot: Depth | null = null;
private tickerSnapshot: Ticker | null = null;
private openOrders: Order[] = [];
private readonly locks: OrderLockMap = {};
private readonly timers: OrderTimerMap = {};
@@ -298,7 +298,7 @@ export class MakerPointsEngine {
const log: LogHandler = (type, detail) => this.tradeLog.push(type, detail);
this.setupRestHealthProtection();
safeSubscribe<AsterAccountSnapshot>(
safeSubscribe<AccountSnapshot>(
this.exchange.watchAccount.bind(this.exchange),
(snapshot) => {
this.applyAccountSnapshot(snapshot);
@@ -310,7 +310,7 @@ export class MakerPointsEngine {
}
);
safeSubscribe<AsterOrder[]>(
safeSubscribe<Order[]>(
this.exchange.watchOrders.bind(this.exchange),
(orders) => {
this.syncLocksWithOrders(orders);
@@ -339,7 +339,7 @@ export class MakerPointsEngine {
}
);
safeSubscribe<AsterDepth>(
safeSubscribe<Depth>(
this.exchange.watchDepth.bind(this.exchange, this.config.symbol),
(depth) => {
this.depthSnapshot = depth;
@@ -358,7 +358,7 @@ export class MakerPointsEngine {
}
);
safeSubscribe<AsterTicker>(
safeSubscribe<Ticker>(
this.exchange.watchTicker.bind(this.exchange, this.config.symbol),
(ticker) => {
this.tickerSnapshot = ticker;
@@ -376,7 +376,7 @@ export class MakerPointsEngine {
this.setupConnectionProtection();
}
private applyAccountSnapshot(snapshot: AsterAccountSnapshot): void {
private applyAccountSnapshot(snapshot: AccountSnapshot): void {
this.accountSnapshot = snapshot;
// StandX: WS 推送使用本地接收时间戳;REST 快照使用响应里的 time 字段映射到 snapshot.updateTime
this.lastStandxAccountTime =
@@ -545,7 +545,7 @@ export class MakerPointsEngine {
}
}
private syncLocksWithOrders(orders: AsterOrder[] | null | undefined): void {
private syncLocksWithOrders(orders: Order[] | null | undefined): void {
const list = Array.isArray(orders) ? orders : [];
Object.keys(this.pending).forEach((type) => {
const pendingId = this.pending[type];
@@ -746,7 +746,7 @@ export class MakerPointsEngine {
ask1: number;
skipBuy: boolean;
skipSell: boolean;
depth: AsterDepth | null;
depth: Depth | null;
}): DesiredOrder[] {
const { bid1, ask1, skipBuy, skipSell, depth } = params;
@@ -837,7 +837,7 @@ export class MakerPointsEngine {
* 当深度从足够变为不足,或从不足变为足够时,需要触发重新计算
*/
private checkDepthStatusChanged(
depth: AsterDepth | null,
depth: Depth | null,
bid1: number,
ask1: number
): boolean {
@@ -879,7 +879,7 @@ export class MakerPointsEngine {
/**
* 当深度从“满足阈值”切换到“不满足阈值”时,立即触发一次主循环,优先撤销不再安全的挂单。
*/
private shouldTriggerImmediateDepthProtection(depth: AsterDepth | null): boolean {
private shouldTriggerImmediateDepthProtection(depth: Depth | null): boolean {
if (!depth) return false;
if (this.defenseMode || this.reconnectResetPending || this.stopLossProcessing) return false;
@@ -917,7 +917,7 @@ export class MakerPointsEngine {
/**
* 当盘口相对上次报价偏移超过 minRepriceBps 时,立即触发一次主循环,优先撤销旧报价。
*/
private shouldTriggerImmediateReprice(depth: AsterDepth | null): boolean {
private shouldTriggerImmediateReprice(depth: Depth | null): boolean {
if (!depth) return false;
if (this.defenseMode || this.reconnectResetPending || this.stopLossProcessing) return false;
@@ -1993,7 +1993,7 @@ export class MakerPointsEngine {
void poll();
}
private getStandxMarginMode(snapshot: AsterAccountSnapshot | null): string | null {
private getStandxMarginMode(snapshot: AccountSnapshot | null): string | null {
if (this.exchange.id !== "standx") return null;
const positions = snapshot?.positions ?? [];
const match = positions.find((pos) => pos.symbol === this.config.symbol);
+18 -18
View File
@@ -1,11 +1,11 @@
import type { MakerConfig } from "../config";
import type { ExchangeAdapter } from "../exchanges/adapter";
import type {
AsterAccountSnapshot,
AsterDepth,
AsterKline,
AsterOrder,
AsterTicker,
AccountSnapshot,
Depth,
Kline,
Order,
Ticker,
} from "../exchanges/types";
import { formatPriceToString } from "../utils/math";
import { createTradeLog } from "../logging/trade-log";
@@ -56,12 +56,12 @@ type MakerListener = (snapshot: OffsetMakerEngineSnapshot) => void;
const EPS = 1e-5;
export class OffsetMakerEngine {
private accountSnapshot: AsterAccountSnapshot | null = null;
private depthSnapshot: AsterDepth | null = null;
private tickerSnapshot: AsterTicker | null = null;
private lastKline: AsterKline | null = null;
private accountSnapshot: AccountSnapshot | null = null;
private depthSnapshot: Depth | null = null;
private tickerSnapshot: Ticker | null = null;
private lastKline: Kline | null = null;
private liveCandle: { startMs: number; open: number; close: number } | null = null;
private openOrders: AsterOrder[] = [];
private openOrders: Order[] = [];
private readonly locks: OrderLockMap = {};
private readonly timers: OrderTimerMap = {};
@@ -163,7 +163,7 @@ export class OffsetMakerEngine {
private bootstrap(): void {
const log: LogHandler = (type, detail) => this.tradeLog.push(type, detail);
safeSubscribe<AsterAccountSnapshot>(
safeSubscribe<AccountSnapshot>(
this.exchange.watchAccount.bind(this.exchange),
(snapshot) => {
this.accountSnapshot = snapshot;
@@ -207,7 +207,7 @@ export class OffsetMakerEngine {
}
);
safeSubscribe<AsterOrder[]>(
safeSubscribe<Order[]>(
this.exchange.watchOrders.bind(this.exchange),
(orders) => {
this.syncLocksWithOrders(orders);
@@ -236,7 +236,7 @@ export class OffsetMakerEngine {
}
);
safeSubscribe<AsterDepth>(
safeSubscribe<Depth>(
this.exchange.watchDepth.bind(this.exchange, this.config.symbol),
(depth) => {
this.depthSnapshot = depth;
@@ -250,7 +250,7 @@ export class OffsetMakerEngine {
}
);
safeSubscribe<AsterTicker>(
safeSubscribe<Ticker>(
this.exchange.watchTicker.bind(this.exchange, this.config.symbol),
(ticker) => {
this.tickerSnapshot = ticker;
@@ -264,7 +264,7 @@ export class OffsetMakerEngine {
}
);
safeSubscribe<AsterKline[]>(
safeSubscribe<Kline[]>(
this.exchange.watchKlines.bind(this.exchange, this.config.symbol, "1m"),
(klines) => {
if (!Array.isArray(klines) || !klines.length) return;
@@ -284,7 +284,7 @@ export class OffsetMakerEngine {
);
}
private syncLocksWithOrders(orders: AsterOrder[] | null | undefined): void {
private syncLocksWithOrders(orders: Order[] | null | undefined): void {
const list = Array.isArray(orders) ? orders : [];
Object.keys(this.pending).forEach((type) => {
const pendingId = this.pending[type];
@@ -600,7 +600,7 @@ export class OffsetMakerEngine {
}
}
private evaluateDepth(depth: AsterDepth): {
private evaluateDepth(depth: Depth): {
buySum: number;
sellSum: number;
skipBuySide: boolean;
@@ -1038,7 +1038,7 @@ export class OffsetMakerEngine {
return position;
}
private getSpotBalances(snapshot: AsterAccountSnapshot | null = this.accountSnapshot): { baseAvailable: number; quoteAvailable: number; baseWallet: number } | null {
private getSpotBalances(snapshot: AccountSnapshot | null = this.accountSnapshot): { baseAvailable: number; quoteAvailable: number; baseWallet: number } | null {
const assets = snapshot?.assets ?? [];
if (!assets.length) return null;
const parsed = parseSymbolParts(this.config.symbol);
+13 -13
View File
@@ -1,5 +1,5 @@
import type { ExchangeAdapter } from "../exchanges/adapter";
import type { AsterAccountSnapshot, AsterDepth, AsterOrder, AsterTicker } from "../exchanges/types";
import type { AccountSnapshot, Depth, Order, Ticker } from "../exchanges/types";
import { createTradeLog, type TradeLogEntry } from "../logging/trade-log";
import { marketClose, placeMarketOrder, placeStopLossOrder, unlockOperating } from "../core/order-coordinator";
import type { OrderLockMap, OrderPendingMap, OrderTimerMap } from "../core/order-coordinator";
@@ -55,9 +55,9 @@ export interface SwingEngineSnapshot {
stopLossTarget: number | null;
stopLossKillSwitch: boolean;
openOrders: AsterOrder[];
depth: AsterDepth | null;
ticker: AsterTicker | null;
openOrders: Order[];
depth: Depth | null;
ticker: Ticker | null;
tradeLog: TradeLogEntry[];
lastUpdated: number | null;
@@ -70,10 +70,10 @@ type SwingListener = (snapshot: SwingEngineSnapshot) => void;
const EPS = 1e-5;
export class SwingEngine {
private accountSnapshot: AsterAccountSnapshot | null = null;
private openOrders: AsterOrder[] = [];
private depthSnapshot: AsterDepth | null = null;
private tickerSnapshot: AsterTicker | null = null;
private accountSnapshot: AccountSnapshot | null = null;
private openOrders: Order[] = [];
private depthSnapshot: Depth | null = null;
private tickerSnapshot: Ticker | null = null;
private readonly locks: OrderLockMap = {};
private readonly timers: OrderTimerMap = {};
@@ -163,7 +163,7 @@ export class SwingEngine {
private bootstrap(): void {
const log: LogHandler = (type, detail) => this.tradeLog.push(type, detail);
safeSubscribe<AsterAccountSnapshot>(
safeSubscribe<AccountSnapshot>(
this.exchange.watchAccount.bind(this.exchange),
(snapshot) => {
this.accountSnapshot = snapshot;
@@ -192,7 +192,7 @@ export class SwingEngine {
}
);
safeSubscribe<AsterOrder[]>(
safeSubscribe<Order[]>(
this.exchange.watchOrders.bind(this.exchange),
(orders) => {
this.synchronizeLocks(orders);
@@ -214,7 +214,7 @@ export class SwingEngine {
}
);
safeSubscribe<AsterDepth>(
safeSubscribe<Depth>(
this.exchange.watchDepth.bind(this.exchange, this.config.symbol),
(depth) => {
this.depthSnapshot = depth;
@@ -227,7 +227,7 @@ export class SwingEngine {
}
);
safeSubscribe<AsterTicker>(
safeSubscribe<Ticker>(
this.exchange.watchTicker.bind(this.exchange, this.config.symbol),
(ticker) => {
this.tickerSnapshot = ticker;
@@ -241,7 +241,7 @@ export class SwingEngine {
);
}
private synchronizeLocks(orders: AsterOrder[] | null | undefined): void {
private synchronizeLocks(orders: Order[] | null | undefined): void {
const list = Array.isArray(orders) ? orders : [];
Object.keys(this.pending).forEach((type) => {
const pendingId = this.pending[type];
+20 -20
View File
@@ -2,11 +2,11 @@ import crypto from "crypto";
import type { TradingConfig } from "../config";
import type { ExchangeAdapter } from "../exchanges/adapter";
import type {
AsterAccountSnapshot,
AsterOrder,
AsterTicker,
AsterDepth,
AsterKline,
AccountSnapshot,
Order,
Ticker,
Depth,
Kline,
} from "../exchanges/types";
import {
calcStopLossPrice,
@@ -51,9 +51,9 @@ export interface TrendEngineSnapshot {
totalTrades: number;
sessionVolume: number;
tradeLog: TradeLogEntry[];
openOrders: AsterOrder[];
depth: AsterDepth | null;
ticker: AsterTicker | null;
openOrders: Order[];
depth: Depth | null;
ticker: Ticker | null;
lastUpdated: number | null;
lastOpenSignal: OpenOrderPlan;
}
@@ -68,11 +68,11 @@ type TrendEngineEvent = "update";
type TrendEngineListener = (snapshot: TrendEngineSnapshot) => void;
export class TrendEngine {
private accountSnapshot: AsterAccountSnapshot | null = null;
private openOrders: AsterOrder[] = [];
private depthSnapshot: AsterDepth | null = null;
private tickerSnapshot: AsterTicker | null = null;
private klineSnapshot: AsterKline[] = [];
private accountSnapshot: AccountSnapshot | null = null;
private openOrders: Order[] = [];
private depthSnapshot: Depth | null = null;
private tickerSnapshot: Ticker | null = null;
private klineSnapshot: Kline[] = [];
private readonly locks: OrderLockMap = {};
private readonly timers: OrderTimerMap = {};
@@ -164,7 +164,7 @@ export class TrendEngine {
private bootstrap(): void {
const log: LogHandler = (type, detail) => this.tradeLog.push(type, detail);
safeSubscribe<AsterAccountSnapshot>(
safeSubscribe<AccountSnapshot>(
this.exchange.watchAccount.bind(this.exchange),
(snapshot) => {
this.accountSnapshot = snapshot;
@@ -181,7 +181,7 @@ export class TrendEngine {
}
);
safeSubscribe<AsterOrder[]>(
safeSubscribe<Order[]>(
this.exchange.watchOrders.bind(this.exchange),
(orders) => {
this.synchronizeLocks(orders);
@@ -215,7 +215,7 @@ export class TrendEngine {
}
);
safeSubscribe<AsterDepth>(
safeSubscribe<Depth>(
this.exchange.watchDepth.bind(this.exchange, this.config.symbol),
(depth) => {
this.depthSnapshot = depth;
@@ -228,7 +228,7 @@ export class TrendEngine {
}
);
safeSubscribe<AsterTicker>(
safeSubscribe<Ticker>(
this.exchange.watchTicker.bind(this.exchange, this.config.symbol),
(ticker) => {
this.tickerSnapshot = ticker;
@@ -241,7 +241,7 @@ export class TrendEngine {
}
);
safeSubscribe<AsterKline[]>(
safeSubscribe<Kline[]>(
this.exchange.watchKlines.bind(this.exchange, this.config.symbol, this.config.klineInterval),
(klines) => {
this.klineSnapshot = Array.isArray(klines) ? klines : [];
@@ -258,7 +258,7 @@ export class TrendEngine {
);
}
private synchronizeLocks(orders: AsterOrder[] | null | undefined): void {
private synchronizeLocks(orders: Order[] | null | undefined): void {
const list = Array.isArray(orders) ? orders : [];
Object.keys(this.pending).forEach((type) => {
const pendingId = this.pending[type];
@@ -834,7 +834,7 @@ export class TrendEngine {
private async tryReplaceStop(
side: "BUY" | "SELL",
currentOrder: AsterOrder,
currentOrder: Order,
nextStopPrice: number,
lastPrice: number
): Promise<void> {