2
0

order.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package util
  2. import (
  3. "errors"
  4. "git.beejay.kim/Gshopper/sentio"
  5. "math"
  6. )
  7. func CreateOrder(
  8. m sentio.Market,
  9. s sentio.Strategy,
  10. action sentio.Action,
  11. quotes map[string]sentio.Quote,
  12. rm sentio.RiskManager,
  13. ) error {
  14. var (
  15. symbol string
  16. account sentio.MarketAccount
  17. size uint
  18. side sentio.Side
  19. bid float64
  20. tp float64
  21. sl float64
  22. ok bool
  23. err error
  24. )
  25. if side = sentio.ActionToSide(action); sentio.BASE == side {
  26. return errors.New("`CreateOrder`: do nothing while `sentio.BASE`")
  27. }
  28. if symbol, ok = s.PositionSymbols()[side]; !ok {
  29. return errors.New("`CreateOrder`: unknown Side for the current strategy")
  30. }
  31. bid = sentio.ToFixed(quotes[symbol].BidPrice, 2)
  32. tp = sentio.ToFixed(rm.TakeProfit(symbol, bid, false), 2)
  33. sl = sentio.ToFixed(rm.StopLoss(symbol, bid, false), 2)
  34. // Prevent orders those have too small expected profit
  35. if tp < bid+0.02 {
  36. return sentio.ErrLowTakeProfit
  37. }
  38. // Prevent cases when order will be closed ASAP they were opened.
  39. // Also, Alpaca requires at least 0.01 gap against base_price
  40. if sl > bid-0.01 {
  41. return sentio.ErrHighStoploss
  42. }
  43. if account, err = m.Account(); err != nil {
  44. return err
  45. }
  46. var (
  47. cash = account.GetCash()
  48. ratio float64
  49. )
  50. if budget := m.MaxBudget(); budget > 0 && cash > budget {
  51. cash = budget
  52. }
  53. if cash < bid {
  54. return sentio.ErrTooSmallOrder
  55. }
  56. if ratio = rm.GetOrderSize(symbol, bid); ratio <= 0 {
  57. return sentio.ErrRiskManagementPrevent
  58. }
  59. // create a new order
  60. if size = uint(math.Floor(cash * ratio / bid)); size < 1 {
  61. return sentio.ErrTooSmallOrder
  62. }
  63. _, err = m.CreateOrder(symbol, 0, size, rm)
  64. return err
  65. }
  66. func CloseAllOrders(m sentio.Market, s sentio.Strategy) error {
  67. var (
  68. symbols = Symbols(s)
  69. orders []sentio.Order
  70. err error
  71. )
  72. if orders, err = m.Orders(sentio.OrderListCriteria{
  73. Status: "open",
  74. Symbols: symbols,
  75. }); err != nil {
  76. return err
  77. }
  78. for i := range orders {
  79. if _, err = m.CloseOrder(orders[i], nil); err != nil {
  80. return err
  81. }
  82. }
  83. return nil
  84. }