package trade import ( "fmt" "sig-pub/pkg/strategy" "sig-pub/pkg/types" "sig-pub/pkg/types/decimals" "time" "github.com/govalues/decimal" ) const ( PriceDriverInterval = types.Interval1m // 价格更新使用1分钟k线 ) type SigTradeStrategy struct { closeParam *CloseStrategyInput } func NewSigTradeStrategy() *SigTradeStrategy { return &SigTradeStrategy{} } func (s *SigTradeStrategy) New() strategy.ISigStrategy { return &SigTradeStrategy{} } func (s *SigTradeStrategy) Meta() strategy.StrategyMeta { return strategy.StrategyMeta{ Name: "SigTradeStrategy", Desc: "默认交易策略", Input: []types.InputArg{ // 交易参数 {Name: "maxPosPct", Type: types.InputTypeUFloat, Desc: "单笔交易最大仓位占比"}, {Name: "maxExposurePct", Type: types.InputTypeUFloat, Desc: "最大总敞口占比"}, {Name: "maxLots", Type: types.InputTypeUInt, Desc: "最大手数/数量"}, // 平仓止损参数 {Name: "stopLossPct", Type: types.InputTypeUFloat, Desc: "固定止损比例"}, {Name: "takeProfitPct", Type: types.InputTypeUFloat, Desc: "固定止盈比例"}, {Name: "profitRetracePcts", Type: types.InputTypeUFloats2D, Desc: "基于最高利润回撤触发平仓 (例如 [[0.01, 0.3], [0.02, 0.2]] 最高利润超过1%时30%回撤则触发平仓, 最高利润超过2%时20%回撤就触发平仓)"}, {Name: "closeOnSideReverse", Type: types.InputTypeBool, Desc: "交易信号和持单方向相反时是否进行平仓"}, {Name: "fee", Type: types.InputTypeBool, Desc: "计算止盈止损时是否包含手续费"}, // 风险评估参数... }, } } // 校验参数, 并根据参数初始化策略 func (s *SigTradeStrategy) Init(input types.Input) (err error) { s.closeParam = new(CloseStrategyInput) input.DecodeInput(s.closeParam) if s.closeParam.StopLossPct < 0 { err = fmt.Errorf("stopLossPct can't less zero") return } return } // 需要的各周期最小数据k线数 func (s *SigTradeStrategy) CandlePeriods(ctx strategy.IInstanceIntervalSigStrategyContext) (tradeInsts []string, iPeriods *types.IntervalState[int16]) { iPeriods = types.NewIntervalState[int16]() iPeriods.Set(PriceDriverInterval, 1) return } // RishAssess 信号风险评估, 是否进行交易 func (s *SigTradeStrategy) RishAssess(ctx strategy.IInstanceIntervalSigStrategyContext, account ITradeAccount, sigInstId string, sigSide types.Side) (doTrade bool, cause Cause, err error) { return true, 0, nil } // TradeAssess 生成下单参数(交易量/方向/杠杆) // 控制滑点, 仓位管理 // 持仓中币种不能改变杠杆 func (s *SigTradeStrategy) TradeAssess(ctx strategy.IInstanceIntervalSigStrategyContext, account ITradeAccount, sigInstId string, sigSide types.Side) (tickets []TradeTicket, err error) { if pos := account.GetPosition(sigInstId); pos != nil { // 已持仓不能下反方向单, todo 副账户做反方向单,对冲(viceAccount) if pos.Side != sigSide { return } } k := ctx.Get(sigInstId, PriceDriverInterval, 0) price := decimals.MustToFloat64(k.Close) ta := TradeTicket{ TradeType: TradeTypeOpen, InstId: sigInstId, Side: sigSide, Price: price, Leverage: 1, Qty: decimal.MustParse("0.02"), Interval: string(k.Interval), Ktime: k.Interval.MustAddMul(k.Ts, 1), Ctime: time.Now().UnixMilli(), } tickets = append(tickets, ta) return }