order.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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. if !rm.EnsureVolatility(symbol) {
  32. return sentio.ErrLowVolatility
  33. }
  34. bid = sentio.ToFixed(quotes[symbol].BidPrice, 2)
  35. tp = sentio.ToFixed(rm.TakeProfit(symbol, bid, false), 2)
  36. sl = sentio.ToFixed(rm.StopLoss(symbol, bid, false), 2)
  37. // Prevent orders those have too small expected profit
  38. if tp < bid+0.02 {
  39. return sentio.ErrLowTakeProfit
  40. }
  41. // Prevent cases when order will be closed ASAP they were opened.
  42. // Also, Alpaca requires at least 0.01 gap against base_price
  43. if sl > bid-0.01 {
  44. return sentio.ErrHighStoploss
  45. }
  46. if account, err = m.Account(); err != nil {
  47. return err
  48. }
  49. if account.GetCash() < bid {
  50. return sentio.ErrTooSmallOrder
  51. }
  52. ratio := .9
  53. if action == sentio.Action_BUY || action == sentio.Action_SELL {
  54. ratio = .4
  55. }
  56. // create a new order
  57. if size = uint(math.Floor(account.GetCash() * ratio / bid)); size < 1 {
  58. return sentio.ErrTooSmallOrder
  59. }
  60. _, err = m.CreateOrder(symbol, size, rm)
  61. return err
  62. }
  63. func CloseAllOrders(m sentio.Market, s sentio.Strategy) error {
  64. var (
  65. symbols = Symbols(s)
  66. orders []sentio.Order
  67. err error
  68. )
  69. if orders, err = m.Orders(sentio.OrderListCriteria{
  70. Status: "open",
  71. Symbols: symbols,
  72. }); err != nil {
  73. return err
  74. }
  75. for i := range orders {
  76. if _, err = m.CloseOrder(orders[i]); err != nil {
  77. return err
  78. }
  79. }
  80. return nil
  81. }