diff --git a/config/exchange.toml b/config/exchange.toml index 4d567a5..c0a42b7 100644 --- a/config/exchange.toml +++ b/config/exchange.toml @@ -18,8 +18,8 @@ receiveBuffer = 4096 marketSubscribeLimit = 16 consumeBatch = 1024 consumeLater = 2000 # 时间到达later或者数据累计到batch触发consume -# httpProxy = "http://192.168.1.5:7890" -httpProxy = "http://10.255.183.209:7890" +httpProxy = "http://192.168.1.5:7890" +# httpProxy = "http://10.255.183.209:7890" # 模拟盘API交易地址如下: # REST:https://www.okx.com diff --git a/internal/trading/backtest/account.go b/internal/trading/backtest/account.go index 1e24301..b094c5f 100644 --- a/internal/trading/backtest/account.go +++ b/internal/trading/backtest/account.go @@ -124,7 +124,7 @@ func (a *Account) ClosePosition(index int, kline types.Kline, ts int64, cause st } t = a.Simulator.ExecuteMarket(closeSide, pos.Qty, kline, ts) - t.Cause = cause + t.CloseCause = cause // apply cash change if closeSide == pb.Side_SELL { // selling a long position -> receive cash diff --git a/internal/trading/backtest/types.go b/internal/trading/backtest/types.go index 1c65fac..40cfb53 100644 --- a/internal/trading/backtest/types.go +++ b/internal/trading/backtest/types.go @@ -15,12 +15,17 @@ type Position struct { } type Trade struct { - Side Side - Qty float64 - Price float64 - Fee float64 - Ts int64 - Cause string // close reason or 'open' for open trades, ["stoploss", "takeprofit", "trailing", "retrace", "signal"](“止损”、“止盈”、“动态跟踪”、“回撤”、“信号”) + Id int64 // 交易id + Side pb.Side // 交易方向 + Status int32 // 1.交易中 2.持仓中 3.已平仓 + Qty float64 // 交易量 + Price float64 // 开仓价格 + Fee float64 // 开仓手续费 + Ts int64 // 开仓时间 + ClosePrice float64 // 平仓价格 + CloseFee float64 // 平仓手续费 + CloseTs int64 // 平仓时间 + CloseCause string // 平仓原因 ["stoploss", "takeprofit", "trailing", "retrace", "signal"](“止损”、“止盈”、“动态跟踪”、“回撤”、“信号”) } type BacktestResult struct { diff --git a/internal/trading/okx/account_holder.go b/internal/trading/okx/account_holder.go new file mode 100644 index 0000000..6279683 --- /dev/null +++ b/internal/trading/okx/account_holder.go @@ -0,0 +1,4 @@ +package okx + +type OkxAccountHolder struct { +} diff --git a/pkg/trade/account.go b/pkg/trade/account.go new file mode 100644 index 0000000..b4b63ed --- /dev/null +++ b/pkg/trade/account.go @@ -0,0 +1,14 @@ +package trade + +import ( + "sig-pub/api/pb" + + "github.com/govalues/decimal" +) + +type IAccountHolder interface { + Exchange() pb.ExchangeType + GetValueCash() decimal.Decimal // 获取账户总市值 + GetTradeCash() decimal.Decimal // 获取可交易空闲资金 + GetOpenTrades() []int64 // 获取未平仓交易单 +} diff --git a/pkg/trader/error.go b/pkg/trade/error.go similarity index 92% rename from pkg/trader/error.go rename to pkg/trade/error.go index 581debc..1de626e 100644 --- a/pkg/trader/error.go +++ b/pkg/trade/error.go @@ -1,4 +1,4 @@ -package trader +package trade type ErrorCode int32 diff --git a/internal/trading/backtest/risk_strategy.go b/pkg/trade/risk_strategy.go similarity index 78% rename from internal/trading/backtest/risk_strategy.go rename to pkg/trade/risk_strategy.go index 93107aa..ff20ed6 100644 --- a/internal/trading/backtest/risk_strategy.go +++ b/pkg/trade/risk_strategy.go @@ -1,10 +1,15 @@ -package backtest +package trade import ( "sig-pub/api/pb" "sig-pub/pkg/indicator" + "sig-pub/pkg/types" ) +type IRickStrategy interface { + OnSingle(signalSide types.Side) +} + // RickStrategy 风险管理策略 type RickStrategy struct { indicatorCtx indicator.IIndicatorContext @@ -18,5 +23,5 @@ func (s *RickStrategy) OnSingle(signalSide pb.Side) (side pb.Side) { ts := k.Ts _, _ = price, ts - return + return signalSide } diff --git a/pkg/trader/indicator.go b/pkg/trader/indicator.go deleted file mode 100644 index 3aeb674..0000000 --- a/pkg/trader/indicator.go +++ /dev/null @@ -1,34 +0,0 @@ -package trader - -import ( - "sig-pub/pkg/types" - - "github.com/govalues/decimal" -) - -// 定义 -// Dependes() []IndicatorDef // 需要订阅的指标列表(包括k线, 实时k线/关闭k线) -type IndicatorDef struct { - IndicatorName string - Intervals []types.Interval -} - -// 指标定义接口 -type Indicator interface { - Meta() IndicatorMeta - // init id, 计算完成 publish 时使用id, - // exchange: 封装indicator访问, 封装历史k线访问 - // args: 动态指标参数定义, 执行时创建 - Init(ctx Context, exchange any, args map[string]any) (code ErrorCode, err error) // 初始化指标参数, 上下文 - Update(kline types.Kline) (err error) // 驱动k线数据, 待驱动k线到达后, 再待subscribe计算完成后执行 - Emit(func(klineTs int64, indicators map[string]decimal.Decimal)) // 指标计算完成后发送, 由指标执行器进行存储或分发 -} - -// 窗口函数 -type SeriesWindow interface { - Range(count int) // 当前k到 -} - -// 指标能力 -type Context interface { -} diff --git a/pkg/trader/strategy.go b/pkg/trader/strategy.go deleted file mode 100644 index 916c69a..0000000 --- a/pkg/trader/strategy.go +++ /dev/null @@ -1,42 +0,0 @@ -package trader - -import "sig-pub/pkg/types" - -type StrategyName string - -// 下单策略接口 -type Strategy interface { - Meta() StrategyMeta - // init id, 计算完成 publish 时使用id, - // exchange: 封装indicator访问, 封装历史k线访问 - // args: 动态策略参数, 执行时创建 - Init(ctx StrategyContext, args map[string]any) (code ErrorCode, err error) - Update(ctx StrategyContext, kline types.Kline) (code ErrorCode, err error) - // Emit() // 下单: sell/buy -> 持单,双方向?, score(分数权重) -} - -type StrategyMeta struct { - // Id string `json:"id"` // 策略注册/执行器系统分配 - Name string - Desc string - SubIntervals []types.Interval // 订阅k线周期 -} - -// KlineServiceClient -// IndicatorClient.Sub(MACD5) stream[Indicator] -// IndicatorClient.Sub(ALMA) stream[Indicator] -// - -// 持单策略接口,动态止盈/止损/加仓/减仓 -type OrderStrategy interface { -} - -// 策略外部访问能力 -type StrategyContext interface { - Previous(offset int) types.Kline - Range(offset int) []types.Kline -} - -// 策略a -type StrategyA struct { -} diff --git a/pkg/trader/strategy_trend_trace.go b/pkg/trader/strategy_trend_trace.go deleted file mode 100644 index 12a53ac..0000000 --- a/pkg/trader/strategy_trend_trace.go +++ /dev/null @@ -1,78 +0,0 @@ -package trader - -import ( - "fmt" - "sig-pub/pkg/types" - "sig-pub/pkg/types/series" - "sig-pub/pkg/zlog" - - "github.com/spf13/cast" -) - -// stateful -type StrategyTrendTrace struct { - intervalDatas map[types.Interval]*series.LimitFloats - - argBaseLine int -} - -func NewStrategyTrendTrace() *StrategyTrendTrace { - return &StrategyTrendTrace{} -} - -func (StrategyTrendTrace) Meta() StrategyMeta { - return StrategyMeta{ - SubIntervals: []types.Interval{ - types.Interval5m, types.Interval15m, types.Interval1d, - }, - } -} - -func (s *StrategyTrendTrace) initArgs(args map[string]string) (err error) { - - return -} - -func (s *StrategyTrendTrace) Init(ctx StrategyContext, args map[string]string) (code ErrorCode, err error) { - s.argBaseLine, err = cast.ToIntE(args["baseLine"]) - if err != nil { - return - } - if s.argBaseLine <= 0 { - - } - - s.intervalDatas = map[types.Interval]*series.LimitFloats{ - types.Interval5m: series.NewLimitFloats(s.argBaseLine), - types.Interval15m: series.NewLimitFloats(s.argBaseLine), - types.Interval1d: series.NewLimitFloats(s.argBaseLine), - } - return -} - -func (s *StrategyTrendTrace) Update(ctx StrategyContext, kline types.Kline) (code ErrorCode, err error) { - data, ok := s.intervalDatas[kline.Interval] - if !ok { - zlog.Warningf("ignore interval kline: %v", kline.Interval) - return - } - - v, ok := kline.Close.Float64() - if !ok { - code = ErrorCodeKline - err = fmt.Errorf("kline close value error: %#v", kline) - return - } - data.Push(v) - - // calc klines - s.caculate() - return -} - -func (s *StrategyTrendTrace) caculate() { - // 5m判断趋势, 15m/1h 确认趋势 - datas5m := s.intervalDatas[types.Interval5m] - minV, maxV := datas5m.MinMax() - _, _ = minV, maxV -} diff --git a/pkg/trader/trader_meta.go b/pkg/trader/trader_meta.go deleted file mode 100644 index f54b592..0000000 --- a/pkg/trader/trader_meta.go +++ /dev/null @@ -1,66 +0,0 @@ -package trader - -import "github.com/spf13/cast" - -// 指标注册/执行器系统分配 -// k线频率, 执行时指定 -// 指标数据(频率)存储, 实时计算 ? -type IndicatorMeta struct { - Name string - Desc string - Args []Arg -} - -type Arg struct { - Name string - Desc string - ArgType ArgType // 参数类型 - Options []ArgOption // 单选/多选选项列表 -} - -type ArgOption struct { - Name string - Desc string -} - -// CastValidate 数据类型校验 -func (t Arg) CastValidate(v string) bool { - switch t.ArgType { - default: - return false - case ArgTypeString: - return true - case ArgTypeInt: - fallthrough - case ArgTypeUInt: - if r, e := cast.ToIntE(v); e != nil { - return false - } else if t.ArgType == ArgTypeUInt { - return r >= 0 - } - return true - case ArgTypeFloat: - fallthrough - case ArgTypeUFloat: - if r, e := cast.ToFloat64E(v); e != nil { - return false - } else if t.ArgType == ArgTypeUFloat { - return r >= 0 - } - return true - } -} - -// 参数类型 -type ArgType int8 - -const ( - _ ArgType = iota - ArgTypeString - ArgTypeInt - ArgTypeUInt - ArgTypeFloat - ArgTypeUFloat - ArgTypeSelect // 单选 - ArgTypeCheckBox // 多选 -)