瀏覽代碼

QQQ15

- add nodelay version
Alexey Kim 2 周之前
父節點
當前提交
c1c5f7f00a
共有 1 個文件被更改,包括 157 次插入0 次删除
  1. 157 0
      strategy/alpaca/qqq15_nodelay/strategy.go

+ 157 - 0
strategy/alpaca/qqq15_nodelay/strategy.go

@@ -0,0 +1,157 @@
+package main
+
+import (
+	"git.beejay.kim/Gshopper/sentio"
+	"time"
+)
+
+var Strategy = alpacaQQQ{}
+
+type alpacaQQQ struct{}
+
+func (s alpacaQQQ) Name() string {
+	return "Alpaca: QQQ [TQQQ : SQQQ]"
+}
+
+func (s alpacaQQQ) Model() string {
+	return "qqq15"
+}
+
+func (s alpacaQQQ) MarketId() string {
+	return "alpaca"
+}
+
+func (s alpacaQQQ) PositionSymbols() map[sentio.Side]string {
+	return map[sentio.Side]string{
+		sentio.BASE:  "QQQ",
+		sentio.LONG:  "TQQQ",
+		sentio.SHORT: "SQQQ",
+	}
+}
+
+func (s alpacaQQQ) Interval() uint8 {
+	return 5
+}
+
+func (s alpacaQQQ) Cooldown(periods uint8) time.Duration {
+	return time.Minute * time.Duration(s.Interval()*periods)
+}
+
+func (s alpacaQQQ) Handle(market sentio.Market, ts time.Time, proba float64) ([]sentio.StrategyOrder, error) {
+	var (
+		portfolio sentio.Portfolio
+		orders    []sentio.StrategyOrder
+		now       = market.Time().Now()
+		err       error
+	)
+
+	// skip too early trades
+	if now.Hour() == 9 && now.Minute() < 45 {
+		return orders, nil
+	}
+
+	if portfolio, err = market.Portfolio(); err != nil {
+		return nil, err
+	}
+
+	for side, symbol := range s.PositionSymbols() {
+		var (
+			position sentio.Position
+			ok       bool
+		)
+
+		// no need to trade BASE quote
+		if sentio.BASE == side {
+			continue
+		}
+
+		if portfolio != nil {
+			position, ok = portfolio.Get(symbol)
+			ok = ok && position != nil && position.GetSize() != 0
+		} else {
+			ok = false
+		}
+
+		// Close positions before market closed
+		if ok && now.Hour() == 15 && now.Minute() > 55 {
+			return []sentio.StrategyOrder{{
+				Symbol: symbol,
+				Action: sentio.OrderSell,
+				Ratio:  1,
+			}}, nil
+		}
+
+		if proba < 0 {
+			continue
+		}
+
+		// Close LONG position
+		if ok && sentio.LONG == side && proba < 1.0008 {
+			return []sentio.StrategyOrder{{
+				Symbol: symbol,
+				Action: sentio.OrderSell,
+				Ratio:  1,
+			}}, nil
+		}
+
+		// Close SHORT position
+		if ok && sentio.SHORT == side && proba > .9998 {
+			return []sentio.StrategyOrder{{
+				Symbol: symbol,
+				Action: sentio.OrderSell,
+				Ratio:  1,
+			}}, nil
+		}
+
+		// Prevent BUYs on closing market
+		if now.Hour() == 15 && now.Minute() > 46 {
+			continue
+		}
+
+		if sentio.LONG == side && proba > 1 {
+			size := float64(0)
+
+			if ok && position.GetAvgPrice()/position.GetCurrentPrice() > 1.002 {
+				// extra position with cheaper price
+				size = .4
+			} else if !ok && proba > 1.0008 {
+				// new trade position
+				size = .6
+			}
+
+			if size > 0 {
+				orders = append(orders, sentio.StrategyOrder{
+					Symbol: symbol,
+					Action: sentio.OrderBuy,
+					Ratio:  size,
+				})
+			}
+
+			continue
+		}
+
+		if sentio.SHORT == side && proba < 1 {
+			size := float64(0)
+
+			if ok && position.GetAvgPrice()/position.GetCurrentPrice() > 1.002 {
+				// extra position with cheaper price
+				size = .4
+			} else if !ok && proba < .9990 {
+				// new trade position
+				size = .6
+			}
+
+			if size > 0 {
+				orders = append(orders, sentio.StrategyOrder{
+					Symbol: symbol,
+					Action: sentio.OrderBuy,
+					Ratio:  size,
+				})
+			}
+
+			continue
+		}
+	}
+
+	return orders, nil
+}