From 9e5123155ca3f7cf4e50ad2a20d762915da9a9b9 Mon Sep 17 00:00:00 2001 From: lychiyu Date: Tue, 30 Jul 2024 22:53:59 +0800 Subject: [PATCH] =?UTF-8?q?[fix]=20=E4=BF=AE=E5=A4=8D=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/ccinr.yaml | 20 +++++----- pkg/strategy/ccinr/strategy.go | 71 ++++++++++++++++++++-------------- 2 files changed, 53 insertions(+), 38 deletions(-) diff --git a/config/ccinr.yaml b/config/ccinr.yaml index db06784..272b74f 100644 --- a/config/ccinr.yaml +++ b/config/ccinr.yaml @@ -21,13 +21,9 @@ exchangeStrategies: - OPUSDT - OMUSDT - WIFUSDT -# - BNBUSDT -# - BTCUSDT -# - ETHUSDT -# - SOLUSDT -# - DYDXUSDT -# - XRPUSDT -# - PEOPLEUSDT + - DYDXUSDT + - XRPUSDT + - PEOPLEUSDT # - STXUSDT # - WLDUSDT # - FILUSDT @@ -35,9 +31,14 @@ exchangeStrategies: # - MKRUSDT # - NOTUSDT # - ENSUSDT +# - BNBUSDT +# - BTCUSDT +# - ETHUSDT +# - SOLUSDT + interval: 1m - nrInterval: 5m - cciInterval: 15m + nrInterval: 1m + cciInterval: 5m atrInterval: 1h nrCount: 4 cciWindow: 20 @@ -53,6 +54,7 @@ exchangeStrategies: amount: 20 placePriceType: 2 lossType: 1 + profitOrderType: 0 # recalculate: false # dry_run: false # # quantity: 3 diff --git a/pkg/strategy/ccinr/strategy.go b/pkg/strategy/ccinr/strategy.go index c0c392e..9d5a1d7 100644 --- a/pkg/strategy/ccinr/strategy.go +++ b/pkg/strategy/ccinr/strategy.go @@ -10,6 +10,7 @@ import ( "git.qtrade.icu/lychiyu/qbtrade/pkg/strategy/common" "git.qtrade.icu/lychiyu/qbtrade/pkg/types" log "github.com/sirupsen/logrus" + "strconv" "strings" "sync" ) @@ -28,23 +29,24 @@ type Strategy struct { markets map[string]types.Market //Symbol string `json:"symbol"` - Symbols []string `json:"symbols"` - Interval types.Interval `json:"interval"` - NRInterval types.Interval `json:"nrInterval"` - CCIInterval types.Interval `json:"cciInterval"` - ATRInterval types.Interval `json:"atrInterval"` - NrCount int `json:"nrCount"` - StrictMode bool `json:"strictMode"` - PlacePriceType int `json:"placePriceType"` - LossType int `json:"lossType"` - DryRun bool `json:"dryRun"` - CCIWindow int `json:"cciWindow"` - ATRWindow int `json:"atrWindow"` - LongCCI fixedpoint.Value `json:"longCCI"` - ShortCCI fixedpoint.Value `json:"shortCCI"` - Leverage fixedpoint.Value `json:"leverage"` - ProfitRange fixedpoint.Value `json:"profitRange"` - LossRange fixedpoint.Value `json:"lossRange"` + Symbols []string `json:"symbols"` + Interval types.Interval `json:"interval"` + NRInterval types.Interval `json:"nrInterval"` + CCIInterval types.Interval `json:"cciInterval"` + ATRInterval types.Interval `json:"atrInterval"` + NrCount int `json:"nrCount"` + StrictMode bool `json:"strictMode"` + PlacePriceType int `json:"placePriceType"` + LossType int `json:"lossType"` + ProfitOrderType int `json:"profitOrderType"` + DryRun bool `json:"dryRun"` + CCIWindow int `json:"cciWindow"` + ATRWindow int `json:"atrWindow"` + LongCCI fixedpoint.Value `json:"longCCI"` + ShortCCI fixedpoint.Value `json:"shortCCI"` + Leverage fixedpoint.Value `json:"leverage"` + ProfitRange fixedpoint.Value `json:"profitRange"` + LossRange fixedpoint.Value `json:"lossRange"` qbtrade.QuantityOrAmount @@ -162,7 +164,7 @@ func (s *Strategy) getPlacePrice(ctx context.Context, kline types.KLine) fixedpo symbol := kline.Symbol placePrice := fixedpoint.Value(0) - midPrice := (kline.High.Add(kline.Low)).Div(fixedpoint.Value(2.0)) + midPrice := (kline.High.Add(kline.Low)).Div(fixedpoint.One * 2) switch s.PlacePriceType { case 0: if s.TradeType[symbol] == "long" { @@ -200,32 +202,43 @@ func (s *Strategy) generateOrders(ctx context.Context, kline types.KLine) ([]typ // 获取下单价格 placePrice := s.getPlacePrice(ctx, kline) + // 止盈订单类型 + profitOrderType := types.OrderTypeTakeProfitMarket + if s.ProfitOrderType == 1 { + profitOrderType = types.OrderTypeStopMarket + } + // 计算止损止盈价格,以ATR为基准或者固定百分比 lossPrice := fixedpoint.Value(0) profitPrice := fixedpoint.Value(0) - lastATR := s.atr[symbol].Last(0) + lastATR, err := strconv.ParseFloat(strconv.FormatFloat(s.atr[symbol].Last(0), 'f', 6, 64), 64) + if err != nil { + log.WithError(err).Error("failed parse atr last value float") + lastATR = 0.0 + } if s.TradeType[symbol] == "long" { - if s.LossType == 0 { + if s.LossType == 0 || s.atr[symbol].Last(0) == 0.0 { lossPrice = placePrice.Sub(placePrice.Mul(s.LossRange)) profitPrice = placePrice.Add(placePrice.Mul(s.ProfitRange)) } else if s.LossType == 1 { - lossPrice = placePrice.Sub(fixedpoint.Value(lastATR)) - profitPrice = placePrice.Add(fixedpoint.Value(lastATR * 2)) + lossPrice = placePrice.Sub(fixedpoint.Value(1e8 * lastATR)) + profitPrice = placePrice.Add(fixedpoint.Value(1e8 * lastATR * 2)) } } else if s.TradeType[symbol] == "short" { - if s.LossType == 0 { + if s.LossType == 0 || s.atr[symbol].Last(0) == 0.0 { lossPrice = placePrice.Add(placePrice.Mul(s.LossRange)) profitPrice = placePrice.Sub(placePrice.Mul(s.ProfitRange)) } else if s.LossType == 1 { - lossPrice = placePrice.Add(fixedpoint.Value(lastATR)) - profitPrice = placePrice.Sub(fixedpoint.Value(lastATR * 2)) + lossPrice = placePrice.Add(fixedpoint.Value(1e8 * lastATR)) + profitPrice = placePrice.Sub(fixedpoint.Value(1e8 * lastATR * 2)) } } // 下单数量 placeQuantity := s.QuantityOrAmount.CalculateQuantity(placePrice).Mul(s.Leverage) - log.Infof(fmt.Sprintf("will place order, price %v, quantity %v, lossprice %v, profitprice: %v", - placePrice.Float64(), placeQuantity.Float64(), lossPrice.Float64(), profitPrice.Float64())) + log.Infof(fmt.Sprintf("will place order, price %v, quantity %v, lossprice %v, profitprice: %v, atr: %v", + placePrice.Float64(), placeQuantity.Float64(), lossPrice.Float64(), profitPrice.Float64(), + lastATR)) s.ShortOrder[symbol] = types.SubmitOrder{ Symbol: symbol, @@ -241,7 +254,7 @@ func (s *Strategy) generateOrders(ctx context.Context, kline types.KLine) ([]typ s.ShortProfitOrder[symbol] = types.SubmitOrder{ Symbol: symbol, Side: types.SideTypeBuy, - Type: types.OrderTypeStopMarket, + Type: profitOrderType, PositionSide: types.PositionSideTypeShort, StopPrice: profitPrice, TimeInForce: types.TimeInForceGTC, @@ -274,7 +287,7 @@ func (s *Strategy) generateOrders(ctx context.Context, kline types.KLine) ([]typ s.LongProfitOrder[symbol] = types.SubmitOrder{ Symbol: symbol, Side: types.SideTypeSell, - Type: types.OrderTypeStopMarket, + Type: profitOrderType, PositionSide: types.PositionSideTypeLong, StopPrice: profitPrice, TimeInForce: types.TimeInForceGTC,