| 
					
				 | 
			
			
				@@ -1,10 +1,9 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 package main 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	"errors" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"git.beejay.kim/Gshopper/sentio" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"git.beejay.kim/Gshopper/sentio/indicator" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	"math" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"git.beejay.kim/Gshopper/sentio/util" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"time" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -12,9 +11,6 @@ const ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	ATR_MULTIPLIER = 1.5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	ATR_PERIOD     = 5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	ATR_HHV        = 4 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	ATR_STOPLOSS_THRESHOLD   = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	EXTRA_POSITION_THRESHOLD = 1.002 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 var Strategy = qqq{} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -60,11 +56,10 @@ func (strategy qqq) PositionProbabilities() map[sentio.Side]float64 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func (strategy qqq) Handle(market sentio.Market, probability sentio.Probability) error { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	var ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		now        = market.Clock().Now() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		symbols    = strategy.Symbols() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		symbols    = util.Symbols(strategy) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		stoplosses map[string]float64 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		quotes     map[string]sentio.Quote 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		orders     []sentio.Order 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		portfolio  sentio.Portfolio 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		err        error 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -75,19 +70,18 @@ func (strategy qqq) Handle(market sentio.Market, probability sentio.Probability) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// close all orders before market close 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if now.Hour() == 15 && now.Minute() > 50 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return strategy.CloseAllOrders(market) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return util.CloseAllOrders(market, strategy) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// retrieve running orders 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if orders, err = market.Orders(sentio.OrderListCriteria{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		Status:  "open", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		Symbols: symbols, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		Nested:  true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	}); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if stoplosses, err = strategy.AtrStopLoss(market, symbols...); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if stoplosses, err = indicator.AtrTrailingStopLoss(market, 1, ATR_PERIOD, ATR_MULTIPLIER, ATR_HHV, symbols...); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -111,7 +105,7 @@ func (strategy qqq) Handle(market sentio.Market, probability sentio.Probability) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if f, ok := stoplosses[orders[i].GetId()]; ok && f > 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if f, ok := stoplosses[orders[i].GetSymbol()]; ok && f > 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if err = market.UpdateOrder(orders[i].GetId(), f); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -134,10 +128,6 @@ func (strategy qqq) Handle(market sentio.Market, probability sentio.Probability) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if portfolio, err = market.Portfolio(); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if quotes, err = market.Quotes(symbols...); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -147,138 +137,5 @@ func (strategy qqq) Handle(market sentio.Market, probability sentio.Probability) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		t = sentio.LONG 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	return strategy.CreateOrder(market, t, probability, portfolio, quotes, stoplosses) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-func (strategy qqq) Symbols() []string { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	var symbols []string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	for side, s := range strategy.PositionSymbols() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if sentio.BASE == side { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		symbols = append(symbols, s) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	return symbols 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-func (strategy qqq) CloseAllOrders(market sentio.Market) error { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	var ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		symbols = strategy.Symbols() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		orders  []sentio.Order 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		err     error 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if orders, err = market.Orders(sentio.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 qqq) AtrStopLoss(market sentio.Market, symbols ...string) (map[string]float64, error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	var ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		stoplosses map[string]float64 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		bars       map[string][]sentio.Bar 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		err        error 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if bars, err = market.HistoricalBars(symbols, time.Minute, nil); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return nil, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	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])) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		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 qqq) CreateOrder(m sentio.Market, t sentio.Side, proba sentio.Probability, p sentio.Portfolio, q map[string]sentio.Quote, sl map[string]float64) error { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	var ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		symbol    = strategy.PositionSymbols()[t] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		position  sentio.Position 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		account   sentio.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 sentio.ErrTooSmallOrder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if !has && proba.Value > threshold { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// create a new order 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if size = uint(math.Floor(account.GetCash() * .7 / q[symbol].BidPrice)); size < 1 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return sentio.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 sentio.ErrTooSmallOrder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		_, err = m.CreateOrder(symbol, size, sl[symbol]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	return nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return util.CreateOrder(market, strategy, t, probability, quotes, stoplosses) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |