package trade import ( "sig-pub/pkg/types" "github.com/spf13/cast" ) type Cause int32 const ( // _ Cause = iota CauseCloseStoploss Cause = 1001 // 平仓:固定止损 CauseCloseTakeprofit Cause = 1002 // 平仓:固定止盈 CauseCloseReverseSingal Cause = 1003 // 平仓:策略反向信号 CauseCloseTrailing Cause = 1004 // 平仓:移动止损基于最高利润点回撤百分比 CauseRiskAlreadyTrade Cause = 2001 // 风控:已有持仓 CauseRiskSideAlreadyTrade Cause = 2002 // 风控:相同方向已有持仓 ) func (c Cause) String() string { switch c { default: return "" case CauseCloseStoploss: return "stoploss" case CauseCloseTakeprofit: return "takeprofit" } } type Trade struct { Id int64 // 交易id Side types.Side // 交易方向 Qty float64 // 交易量 Price float64 // 开仓价格 Fee float64 // 开仓手续费 Time int64 // 开仓时间 ClosePrice float64 // 平仓价格 CloseFee float64 // 平仓手续费 CloseTs int64 // 平仓时间 CloseCause Cause // 平仓原因 ["stoploss", "takeprofit", "trailing", "retrace", "signal"](“止损”、“止盈”、“动态跟踪”、“回撤”、“信号”) Pnl float64 // 盈利/亏损 pnl = (t.ClosePrice-t.Price)*t.Qty - t.Fee - t.CloseFee HoldTime string // 持仓时间 } // Position 持仓仓位 type Position struct { TradeId int64 // 交易订单id Status int32 // 1.交易中 2.持仓中 3.已平仓 Side types.Side // 交易方向 Qty float64 // 交易量 EntryPx float64 // 入场价格 EntryTs int64 // 入场时间 PeakPx float64 // highest (for long) or lowest (for short) observed price since entry Fee float64 // 手续费 FeeRate float64 // 手续费率 State map[string]any // 持仓持久化状态 } func (pos *Position) SetState(k string, v any) { if pos.State == nil { pos.State = make(map[string]any) } pos.State[k] = v } func (pos *Position) GetState(k string) (v any, ok bool) { if pos.State == nil { return } v, ok = pos.State[k] return } func (pos *Position) GetStateF64(k string) (f float64, ok bool) { if pos.State == nil { return } v, ok := pos.State[k] if !ok { return } f, err := cast.ToFloat64E(v) ok = err == nil return }