| 
					
				 | 
			
			
				@@ -6,76 +6,87 @@ import ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"math" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-func CreateOrder( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const TradingRange = .02 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func NewOrder( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	m sentio.Market, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	s sentio.Strategy, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	action sentio.Action, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	quotes map[string]sentio.Quote, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	rm sentio.RiskManager, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-) error { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+) (opts sentio.OrderOptions, err error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	var ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		symbol  string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		account sentio.MarketAccount 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		size    uint 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		side    sentio.Side 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		bid     float64 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		tp      float64 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		sl      float64 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		ok      bool 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		err     error 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		side sentio.Side 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		bid  float64 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		ok   bool 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if side = sentio.ActionToSide(action); sentio.BASE == side { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return errors.New("`CreateOrder`: do nothing while `sentio.BASE`") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		err = errors.New("`CreateOrder`: do nothing while `sentio.BASE`") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if symbol, ok = s.PositionSymbols()[side]; !ok { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return errors.New("`CreateOrder`: unknown Side for the current strategy") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if opts.Symbol, ok = s.PositionSymbols()[side]; !ok { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		err = errors.New("`CreateOrder`: unknown Side for the current strategy") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	bid = sentio.ToFixed(quotes[symbol].BidPrice, 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	tp = sentio.ToFixed(rm.TakeProfit(symbol, bid, false), 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	sl = sentio.ToFixed(rm.StopLoss(symbol, bid, false), 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	bid = sentio.ToFixed(quotes[opts.Symbol].BidPrice, 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	opts.Action = sentio.Action_BUY 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	opts.TakeProfit = sentio.ToFixed(rm.TakeProfit(opts.Symbol, bid), 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	opts.StopLoss = sentio.ToFixed(rm.StopLoss(opts.Symbol, bid), 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// Prevent orders those have too small expected profit 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if tp < bid+0.02 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return sentio.ErrLowTakeProfit 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if opts.TakeProfit < bid+TradingRange { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		err = sentio.ErrLowTakeProfit 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// Prevent cases when order will be closed ASAP they were opened. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// Also, Alpaca requires at least 0.01 gap against base_price 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if sl > bid-0.01 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return sentio.ErrHighStoploss 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if opts.StopLoss > bid-TradingRange { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		err = sentio.ErrHighStoploss 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if account, err = m.Account(); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// Invert OrderOptions if we will do SHORT for BASE symbol 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if sentio.SHORT == side && s.PositionSymbols()[sentio.BASE] == opts.Symbol { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		tmp := opts.StopLoss 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		opts.StopLoss = opts.TakeProfit 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		opts.TakeProfit = tmp 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		opts.Action = sentio.Action_SELL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	var ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		cash  = account.GetCash(false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		ratio float64 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		account sentio.MarketAccount 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		cash    float64 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		ratio   float64 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if account, err = m.Account(); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	cash = account.GetCash(false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if budget := m.MaxBudget(); budget > 0 && cash > budget { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		cash = budget 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if cash < bid { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return sentio.ErrTooSmallOrder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if cash <= bid { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		err = sentio.ErrTooSmallOrder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if ratio = rm.GetOrderSize(symbol, bid); ratio <= 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return sentio.ErrRiskManagementPrevent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if ratio = rm.GetOrderSize(opts.Symbol, bid); ratio <= 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		err = sentio.ErrRiskManagementPrevent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	// create a new order 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if size = uint(math.Floor(cash * ratio / bid)); size < 1 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return sentio.ErrTooSmallOrder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if opts.Size = uint(math.Floor(cash * ratio / bid)); opts.Size < 1 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		err = sentio.ErrTooSmallOrder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	_, err = m.CreateOrder(symbol, 0, size, rm) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return opts, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func CloseAllOrders(m sentio.Market, s sentio.Strategy) error { 
			 |