This commit is contained in:
discountry
2025-09-23 01:26:49 +08:00
commit 667ede7ca8
26 changed files with 7836 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
export function formatNumber(value: number | null | undefined, digits = 4, fallback = "-"): string {
if (value == null || Number.isNaN(value)) return fallback;
return Number(value).toFixed(digits);
}
export function formatTrendLabel(trend: "做多" | "做空" | "无信号"): string {
return trend;
}
+11
View File
@@ -0,0 +1,11 @@
export function toPrice1Decimal(price: number): number {
return Math.floor(price * 10) / 10;
}
export function toQty3Decimal(qty: number): number {
return Math.floor(qty * 1000) / 1000;
}
export function isNearlyZero(value: number, epsilon = 1e-5): boolean {
return Math.abs(value) < epsilon;
}
+43
View File
@@ -0,0 +1,43 @@
import { AsterAccountSnapshot, AsterKline } from "../exchanges/types";
export interface PositionSnapshot {
positionAmt: number;
entryPrice: number;
unrealizedProfit: number;
}
export function getPosition(snapshot: AsterAccountSnapshot | null, symbol: string): PositionSnapshot {
if (!snapshot) {
return { positionAmt: 0, entryPrice: 0, unrealizedProfit: 0 };
}
const pos = snapshot.positions?.find((p) => p.symbol === symbol);
if (!pos) {
return { positionAmt: 0, entryPrice: 0, unrealizedProfit: 0 };
}
return {
positionAmt: Number(pos.positionAmt),
entryPrice: Number(pos.entryPrice),
unrealizedProfit: Number(pos.unrealizedProfit),
};
}
export function getSMA(values: AsterKline[], length: number): number | null {
if (!values || values.length < length) return null;
const closes = values.slice(-length).map((k) => Number(k.close));
const sum = closes.reduce((acc, current) => acc + current, 0);
return sum / closes.length;
}
export function calcStopLossPrice(entryPrice: number, qty: number, side: "long" | "short", loss: number): number {
if (side === "long") {
return entryPrice - loss / qty;
}
return entryPrice + loss / Math.abs(qty);
}
export function calcTrailingActivationPrice(entryPrice: number, qty: number, side: "long" | "short", profit: number): number {
if (side === "long") {
return entryPrice + profit / qty;
}
return entryPrice - profit / Math.abs(qty);
}