Browse Source

BaseStrategy

- refactoring
Alexey Kim 3 days ago
parent
commit
e814296a3a
3 changed files with 165 additions and 159 deletions
  1. 136 148
      strategy.go
  2. 13 4
      strategy/alpaca/qqq15/strategy.go
  3. 16 7
      strategy/alpaca/qqq15_nodelay/strategy.go

+ 136 - 148
strategy.go

@@ -1,9 +1,6 @@
 package sentio
 
 import (
-	"errors"
-	"git.beejay.kim/Gshopper/sentio/indicator"
-	"math"
 	"time"
 )
 
@@ -20,148 +17,139 @@ type Strategy interface {
 	Handle(market Market, probability Probability) error
 }
 
-const (
-	ATR_MULTIPLIER = 1.5
-	ATR_PERIOD     = 5
-	ATR_HHV        = 4
-
-	ATR_STOPLOSS_THRESHOLD   = 1
-	EXTRA_POSITION_THRESHOLD = 1.002
-)
-
-type BaseStrategy struct {
-	Strategy
-}
-
-func (strategy BaseStrategy) Symbols() []string {
-	var symbols []string
-
-	for side, s := range strategy.PositionSymbols() {
-		if BASE == side {
-			continue
-		}
-
-		symbols = append(symbols, s)
-	}
-
-	return symbols
-}
-
-func (strategy BaseStrategy) CloseAllOrders(market Market) error {
-	var (
-		symbols = strategy.Symbols()
-		orders  []Order
-		err     error
-	)
-
-	if orders, err = market.Orders(OrderListCriteria{
-		Status:  "open",
-		Symbols: symbols,
-		Nested:  true,
-	}); err != nil {
-		return err
-	}
-
-	for i := range orders {
-		if _, err = market.CloseOrder(orders[i].GetId()); err != nil {
-			return err
-		}
-	}
-
-	return nil
-}
-
-func (strategy BaseStrategy) AtrStopLoss(market Market, symbols ...string) (map[string]float64, error) {
-	var (
-		stoplosses map[string]float64
-		bars       map[string][]Bar
-		err        error
-	)
-
-	if bars, err = market.HistoricalBars(symbols, time.Minute, nil); err != nil {
-		return nil, err
-	}
-
-	if bars == nil || len(bars) < ATR_PERIOD {
-		return nil, errors.New("AtrStopLoss: could not calculate stoploss for too short timeseries")
-	}
-
-	stoplosses = make(map[string]float64)
-	for s := range bars {
-		h := make([]float64, len(bars[s]))
-		l := make([]float64, len(bars[s]))
-		c := make([]float64, len(bars[s]))
-
-		for i := range bars[s] {
-			h[i] = bars[s][i].High
-			l[i] = bars[s][i].Low
-			c[i] = bars[s][i].Close
-		}
-
-		trailing := indicator.AtrTrailingStopLoss(h, l, c, ATR_PERIOD, ATR_MULTIPLIER, ATR_HHV)
-		stoplosses[s] = trailing[len(trailing)-1]
-	}
-
-	return stoplosses, nil
-}
-
-func (strategy BaseStrategy) CreateOrder(m Market, t Side, proba Probability, p Portfolio, q map[string]Quote, sl map[string]float64) error {
-	var (
-		symbol    = strategy.PositionSymbols()[t]
-		position  Position
-		account   MarketAccount
-		has       = false
-		threshold float64
-		size      uint
-		ok        bool
-		err       error
-	)
-
-	// ensure portfolio
-	position, has = p.Get(symbol)
-
-	// define threshold
-	if threshold, ok = strategy.PositionProbabilities()[t]; !ok {
-		threshold = -1
-	}
-
-	if threshold == -1 || symbol == "" {
-		return nil
-	}
-
-	// Prevent Market.CreateOrder when BidPrice less than ATR_STOPLOSS_THRESHOLD
-	if q[symbol].BidPrice/sl[symbol] < ATR_STOPLOSS_THRESHOLD {
-		return nil
-	}
-
-	if account, err = m.Account(); err != nil {
-		return err
-	}
-
-	if account.GetCash() < q[symbol].BidPrice {
-		return ErrTooSmallOrder
-	}
-
-	if !has && proba.Value > threshold {
-
-		// create a new order
-		if size = uint(math.Floor(account.GetCash() * .7 / q[symbol].BidPrice)); size < 1 {
-			return ErrTooSmallOrder
-		}
-
-		_, err = m.CreateOrder(symbol, size, sl[symbol])
-		return err
-
-	} else if has && position.GetAvgPrice()/position.GetCurrentPrice() > EXTRA_POSITION_THRESHOLD {
-
-		// create an extra position
-		if size = uint(math.Floor(account.GetCash() * .5 / q[symbol].BidPrice)); size < 1 {
-			return ErrTooSmallOrder
-		}
-
-		_, err = m.CreateOrder(symbol, size, sl[symbol])
-		return err
-	}
-
-	return nil
-}
+//type BaseStrategy struct {
+//	Strategy
+//}
+//
+//func (strategy BaseStrategy) Symbols() []string {
+//	var symbols []string
+//
+//	for side, s := range strategy.PositionSymbols() {
+//		if BASE == side {
+//			continue
+//		}
+//
+//		symbols = append(symbols, s)
+//	}
+//
+//	return symbols
+//}
+//
+//func (strategy BaseStrategy) CloseAllOrders(market Market) error {
+//	var (
+//		symbols = strategy.Symbols()
+//		orders  []Order
+//		err     error
+//	)
+//
+//	if orders, err = market.Orders(OrderListCriteria{
+//		Status:  "open",
+//		Symbols: symbols,
+//		Nested:  true,
+//	}); err != nil {
+//		return err
+//	}
+//
+//	for i := range orders {
+//		if _, err = market.CloseOrder(orders[i].GetId()); err != nil {
+//			return err
+//		}
+//	}
+//
+//	return nil
+//}
+//
+//func (strategy BaseStrategy) AtrStopLoss(market Market, symbols ...string) (map[string]float64, error) {
+//	var (
+//		stoplosses map[string]float64
+//		bars       map[string][]Bar
+//		err        error
+//	)
+//
+//	if bars, err = market.HistoricalBars(symbols, time.Minute, nil); err != nil {
+//		return nil, err
+//	}
+//
+//	if bars == nil || len(bars) < ATR_PERIOD {
+//		return nil, errors.New("AtrStopLoss: could not calculate stoploss for too short timeseries")
+//	}
+//
+//	stoplosses = make(map[string]float64)
+//	for s := range bars {
+//		h := make([]float64, len(bars[s]))
+//		l := make([]float64, len(bars[s]))
+//		c := make([]float64, len(bars[s]))
+//
+//		for i := range bars[s] {
+//			h[i] = bars[s][i].High
+//			l[i] = bars[s][i].Low
+//			c[i] = bars[s][i].Close
+//		}
+//
+//		trailing := indicator.AtrTrailingStopLoss(h, l, c, ATR_PERIOD, ATR_MULTIPLIER, ATR_HHV)
+//		stoplosses[s] = trailing[len(trailing)-1]
+//	}
+//
+//	return stoplosses, nil
+//}
+//
+//func (strategy BaseStrategy) CreateOrder(m Market, t Side, proba Probability, p Portfolio, q map[string]Quote, sl map[string]float64) error {
+//	var (
+//		symbol    = strategy.PositionSymbols()[t]
+//		position  Position
+//		account   MarketAccount
+//		has       = false
+//		threshold float64
+//		size      uint
+//		ok        bool
+//		err       error
+//	)
+//
+//	// ensure portfolio
+//	position, has = p.Get(symbol)
+//
+//	// define threshold
+//	if threshold, ok = strategy.PositionProbabilities()[t]; !ok {
+//		threshold = -1
+//	}
+//
+//	if threshold == -1 || symbol == "" {
+//		return nil
+//	}
+//
+//	// Prevent Market.CreateOrder when BidPrice less than ATR_STOPLOSS_THRESHOLD
+//	if q[symbol].BidPrice/sl[symbol] < ATR_STOPLOSS_THRESHOLD {
+//		return nil
+//	}
+//
+//	if account, err = m.Account(); err != nil {
+//		return err
+//	}
+//
+//	if account.GetCash() < q[symbol].BidPrice {
+//		return ErrTooSmallOrder
+//	}
+//
+//	if !has && proba.Value > threshold {
+//
+//		// create a new order
+//		if size = uint(math.Floor(account.GetCash() * .7 / q[symbol].BidPrice)); size < 1 {
+//			return ErrTooSmallOrder
+//		}
+//
+//		_, err = m.CreateOrder(symbol, size, sl[symbol])
+//		return err
+//
+//	} else if has && position.GetAvgPrice()/position.GetCurrentPrice() > EXTRA_POSITION_THRESHOLD {
+//
+//		// create an extra position
+//		if size = uint(math.Floor(account.GetCash() * .5 / q[symbol].BidPrice)); size < 1 {
+//			return ErrTooSmallOrder
+//		}
+//
+//		_, err = m.CreateOrder(symbol, size, sl[symbol])
+//		return err
+//	}
+//
+//	return nil
+//}

+ 13 - 4
strategy/alpaca/qqq15/strategy.go

@@ -8,6 +8,15 @@ import (
 	"time"
 )
 
+const (
+	ATR_MULTIPLIER = 1.5
+	ATR_PERIOD     = 5
+	ATR_HHV        = 4
+
+	ATR_STOPLOSS_THRESHOLD   = 1
+	EXTRA_POSITION_THRESHOLD = 1.002
+)
+
 var Strategy = qqq{}
 
 type qqq struct{}
@@ -190,7 +199,7 @@ func (strategy qqq) AtrStopLoss(market sentio.Market, symbols ...string) (map[st
 		return nil, err
 	}
 
-	if bars == nil || len(bars) < sentio.ATR_PERIOD {
+	if bars == nil || len(bars) < ATR_PERIOD {
 		return nil, errors.New("AtrStopLoss: could not calculate stoploss for too short timeseries")
 	}
 
@@ -206,7 +215,7 @@ func (strategy qqq) AtrStopLoss(market sentio.Market, symbols ...string) (map[st
 			c[i] = bars[s][i].Close
 		}
 
-		trailing := indicator.AtrTrailingStopLoss(h, l, c, sentio.ATR_PERIOD, sentio.ATR_MULTIPLIER, sentio.ATR_HHV)
+		trailing := indicator.AtrTrailingStopLoss(h, l, c, ATR_PERIOD, ATR_MULTIPLIER, ATR_HHV)
 		stoplosses[s] = trailing[len(trailing)-1]
 	}
 
@@ -238,7 +247,7 @@ func (strategy qqq) CreateOrder(m sentio.Market, t sentio.Side, proba sentio.Pro
 	}
 
 	// Prevent Market.CreateOrder when BidPrice less than ATR_STOPLOSS_THRESHOLD
-	if q[symbol].BidPrice/sl[symbol] < sentio.ATR_STOPLOSS_THRESHOLD {
+	if q[symbol].BidPrice/sl[symbol] < ATR_STOPLOSS_THRESHOLD {
 		return nil
 	}
 
@@ -260,7 +269,7 @@ func (strategy qqq) CreateOrder(m sentio.Market, t sentio.Side, proba sentio.Pro
 		_, err = m.CreateOrder(symbol, size, sl[symbol])
 		return err
 
-	} else if has && position.GetAvgPrice()/position.GetCurrentPrice() > sentio.EXTRA_POSITION_THRESHOLD {
+	} else if has && position.GetAvgPrice()/position.GetCurrentPrice() > EXTRA_POSITION_THRESHOLD {
 
 		// create an extra position
 		if size = uint(math.Floor(account.GetCash() * .5 / q[symbol].BidPrice)); size < 1 {

+ 16 - 7
strategy/alpaca/qqq15_nodelay/strategy.go

@@ -8,6 +8,15 @@ import (
 	"time"
 )
 
+const (
+	ATR_MULTIPLIER = 1.5
+	ATR_PERIOD     = 5
+	ATR_HHV        = 4
+
+	ATR_STOPLOSS_THRESHOLD   = 1
+	EXTRA_POSITION_THRESHOLD = 1.002
+)
+
 var Strategy = qqq{}
 
 type qqq struct{}
@@ -190,12 +199,12 @@ func (strategy qqq) AtrStopLoss(market sentio.Market, symbols ...string) (map[st
 		return nil, err
 	}
 
-	if bars == nil || len(bars) < sentio.ATR_PERIOD {
-		return nil, errors.New("AtrStopLoss: could not calculate stoploss for too short timeseries")
-	}
-
 	stoplosses = make(map[string]float64)
 	for s := range bars {
+		if bars == nil || len(bars[s]) < ATR_PERIOD {
+			return nil, errors.New("AtrStopLoss: could not calculate stoploss for too short timeseries")
+		}
+
 		h := make([]float64, len(bars[s]))
 		l := make([]float64, len(bars[s]))
 		c := make([]float64, len(bars[s]))
@@ -206,7 +215,7 @@ func (strategy qqq) AtrStopLoss(market sentio.Market, symbols ...string) (map[st
 			c[i] = bars[s][i].Close
 		}
 
-		trailing := indicator.AtrTrailingStopLoss(h, l, c, sentio.ATR_PERIOD, sentio.ATR_MULTIPLIER, sentio.ATR_HHV)
+		trailing := indicator.AtrTrailingStopLoss(h, l, c, ATR_PERIOD, ATR_MULTIPLIER, ATR_HHV)
 		stoplosses[s] = trailing[len(trailing)-1]
 	}
 
@@ -238,7 +247,7 @@ func (strategy qqq) CreateOrder(m sentio.Market, t sentio.Side, proba sentio.Pro
 	}
 
 	// Prevent Market.CreateOrder when BidPrice less than ATR_STOPLOSS_THRESHOLD
-	if q[symbol].BidPrice/sl[symbol] < sentio.ATR_STOPLOSS_THRESHOLD {
+	if q[symbol].BidPrice/sl[symbol] < ATR_STOPLOSS_THRESHOLD {
 		return nil
 	}
 
@@ -260,7 +269,7 @@ func (strategy qqq) CreateOrder(m sentio.Market, t sentio.Side, proba sentio.Pro
 		_, err = m.CreateOrder(symbol, size, sl[symbol])
 		return err
 
-	} else if has && position.GetAvgPrice()/position.GetCurrentPrice() > sentio.EXTRA_POSITION_THRESHOLD {
+	} else if has && position.GetAvgPrice()/position.GetCurrentPrice() > EXTRA_POSITION_THRESHOLD {
 
 		// create an extra position
 		if size = uint(math.Floor(account.GetCash() * .5 / q[symbol].BidPrice)); size < 1 {