package util import ( "errors" "git.beejay.kim/Gshopper/sentio" "math" ) func CreateOrder( m sentio.Market, s sentio.Strategy, t sentio.Side, proba sentio.Probability, q map[string]sentio.Quote, sl map[string]float64, ) error { var ( symbol string orders []sentio.Order account sentio.MarketAccount has = false avgPrice float64 threshold float64 size uint ok bool err error ) if symbol, ok = s.PositionSymbols()[t]; !ok { return errors.New("`CreateOrder`: unknown Side for the current strategy") } if orders, err = m.Orders(sentio.OrderListCriteria{ Status: "open", Symbols: []string{symbol}, }); err != nil { return err } has = len(orders) > 0 for i := range orders { avgPrice += orders[i].GetEntryPrice() } if has { avgPrice = avgPrice / float64(len(orders)) } // define threshold if threshold, ok = s.PositionProbabilities()[t]; !ok { return nil } // Prevent cases when order will be closed ASAP they were opened. // Also, Alpaca requires at least 0.01 gap against base_price if sl[symbol] >= q[symbol].BidPrice-0.011 { return sentio.ErrHighStoploss } if account, err = m.Account(); err != nil { return err } if account.GetCash() < q[symbol].BidPrice { return sentio.ErrTooSmallOrder } if !has && ((sentio.LONG == t && proba.Value > threshold) || (sentio.SHORT == t && 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 && avgPrice/q[symbol].BidPrice > 1.002 { // 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 } func CloseAllOrders(m sentio.Market, s sentio.Strategy) error { var ( symbols = Symbols(s) orders []sentio.Order err error ) if orders, err = m.Orders(sentio.OrderListCriteria{ Status: "open", Symbols: symbols, }); err != nil { return err } for i := range orders { if _, err = m.CloseOrder(orders[i]); err != nil { return err } } return nil }