Add demo trading page, trader snapshot service and trading tables
Add trading_symbols, trading_analyses, trading_orders and trading_events. The new trader service publishes account, position and open-order snapshots of the Binance demo account to Redis every 3s. The /trading page shows engine status, start/stop, balances, positions, the symbol list with angle selection, open orders and the event timeline.
This commit is contained in:
1 parent
154fe2b687
commit
005943a54c
12 files changed
+1289
-3
No files matched your search
@@ -0,0 +1,138 @@
|
||||
import type { Effort } from "@/apis/settings"
|
||||
import { http } from "@/http"
|
||||
|
||||
export type Angle = "short" | "long"
|
||||
|
||||
export const ANGLE_LABELS: Record<Angle, string> = { short: "短线(24h 内平仓)", long: "长线(12–48h 平仓)" }
|
||||
|
||||
/** 以下数值字段都是币安返回的十进制字符串,避免浮点误差 */
|
||||
export interface SnapshotPosition {
|
||||
symbol: string
|
||||
side: "LONG" | "SHORT"
|
||||
amount: string
|
||||
entry_price: string
|
||||
break_even_price: string
|
||||
mark_price: string
|
||||
unrealized_pnl: string
|
||||
liquidation_price: string
|
||||
notional: string
|
||||
margin: string
|
||||
leverage: number
|
||||
margin_type: string
|
||||
}
|
||||
|
||||
export interface SnapshotOrder {
|
||||
symbol: string
|
||||
client_id: string
|
||||
side: "BUY" | "SELL"
|
||||
type: string
|
||||
price: string
|
||||
quantity: string
|
||||
filled: string
|
||||
reduce_only: boolean
|
||||
time: number
|
||||
}
|
||||
|
||||
export interface SnapshotAlgoOrder {
|
||||
symbol: string
|
||||
client_id: string
|
||||
side: "BUY" | "SELL"
|
||||
type: string
|
||||
trigger_price: string
|
||||
quantity: string
|
||||
close_position: boolean
|
||||
reduce_only: boolean
|
||||
time: number
|
||||
}
|
||||
|
||||
export interface Snapshot {
|
||||
updated_at: string
|
||||
/** 最近一次成功同步币安的时间 */
|
||||
synced_at: string | null
|
||||
error: string | null
|
||||
account: { wallet_balance: string, margin_balance: string, available_balance: string, unrealized_pnl: string } | null
|
||||
positions: SnapshotPosition[]
|
||||
orders: SnapshotOrder[]
|
||||
algo_orders: SnapshotAlgoOrder[]
|
||||
}
|
||||
|
||||
export interface TradingStatus {
|
||||
configured: boolean
|
||||
running: boolean
|
||||
running_changed_at: string | null
|
||||
provider_id: number | null
|
||||
reasoning_effort: Effort | null
|
||||
/** trader 进程离线时为空 */
|
||||
snapshot: Snapshot | null
|
||||
today: { analyses: number, limit: number, input_tokens: number, output_tokens: number }
|
||||
}
|
||||
|
||||
export interface TradingSymbol {
|
||||
symbol: string
|
||||
angle: Angle
|
||||
added_at: string
|
||||
analysis_requested_at: string | null
|
||||
analyzing: boolean
|
||||
plan_status: "pending" | "open" | null
|
||||
}
|
||||
|
||||
export interface SymbolOption {
|
||||
symbol: string
|
||||
base: string
|
||||
}
|
||||
|
||||
export interface TradingEvent {
|
||||
id: number
|
||||
created_at: string
|
||||
symbol: string | null
|
||||
analysis_id: number | null
|
||||
kind: string
|
||||
level: "info" | "warn" | "error"
|
||||
message: string
|
||||
data: Record<string, unknown> | null
|
||||
}
|
||||
|
||||
/** 本程序下的单;其他是用户手动下的 */
|
||||
export function isOwnOrder(clientId: string) {
|
||||
return /^ap\d+$/.test(clientId)
|
||||
}
|
||||
|
||||
export function getStatus(): Promise<TradingStatus> {
|
||||
return http.get("/trading/status")
|
||||
}
|
||||
|
||||
export function startTrading(): Promise<TradingStatus> {
|
||||
return http.post("/trading/start")
|
||||
}
|
||||
|
||||
export function stopTrading(): Promise<TradingStatus> {
|
||||
return http.post("/trading/stop")
|
||||
}
|
||||
|
||||
export function patchConfig(body: { provider_id?: number | null, reasoning_effort?: Effort | null }): Promise<TradingStatus> {
|
||||
return http.patch("/trading/config", body)
|
||||
}
|
||||
|
||||
export function listSymbolOptions(): Promise<SymbolOption[]> {
|
||||
return http.get("/trading/symbol-options")
|
||||
}
|
||||
|
||||
export function listSymbols(): Promise<TradingSymbol[]> {
|
||||
return http.get("/trading/symbols")
|
||||
}
|
||||
|
||||
export function addSymbol(symbol: string, angle: Angle): Promise<void> {
|
||||
return http.post("/trading/symbols", { symbol, angle })
|
||||
}
|
||||
|
||||
export function patchSymbol(symbol: string, angle: Angle): Promise<void> {
|
||||
return http.patch(`/trading/symbols/${symbol}`, { angle })
|
||||
}
|
||||
|
||||
export function deleteSymbol(symbol: string): Promise<void> {
|
||||
return http.delete(`/trading/symbols/${symbol}`)
|
||||
}
|
||||
|
||||
export function listEvents(params: { symbol?: string, before?: number, limit?: number }): Promise<TradingEvent[]> {
|
||||
return http.get("/trading/events", { params })
|
||||
}
|
||||
Reference in new issue
Block a user