123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- package util
- import (
- "errors"
- "git.beejay.kim/Gshopper/sentio"
- "math"
- )
- func CreateOrder(
- m sentio.Market,
- s sentio.Strategy,
- action sentio.Action,
- quotes map[string]sentio.Quote,
- rm sentio.RiskManager,
- ) error {
- var (
- symbol string
- account sentio.MarketAccount
- size uint
- side sentio.Side
- bid float64
- tp float64
- sl float64
- ok bool
- err error
- )
- if side = sentio.ActionToSide(action); sentio.BASE == side {
- return errors.New("`CreateOrder`: do nothing while `sentio.BASE`")
- }
- if symbol, ok = s.PositionSymbols()[side]; !ok {
- return 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)
- // Prevent orders those have too small expected profit
- if tp < bid+0.02 {
- return sentio.ErrLowTakeProfit
- }
- // 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 account, err = m.Account(); err != nil {
- return err
- }
- var (
- cash = account.GetCash(false)
- ratio float64
- )
- if budget := m.MaxBudget(); budget > 0 && cash > budget {
- cash = budget
- }
- if cash < bid {
- return sentio.ErrTooSmallOrder
- }
- if ratio = rm.GetOrderSize(symbol, bid); ratio <= 0 {
- return sentio.ErrRiskManagementPrevent
- }
- // create a new order
- if size = uint(math.Floor(cash * ratio / bid)); size < 1 {
- return sentio.ErrTooSmallOrder
- }
- _, err = m.CreateOrder(symbol, 0, size, rm)
- return err
- }
- 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], nil); err != nil {
- return err
- }
- }
- return nil
- }
|