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. 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. var (
  53. limit float64
  54. ratio float64
  55. )
  56. if limit, ratio = rm.GetOrderSize(symbol, bid); ratio <= 0 {
  57. return sentio.ErrRiskManagementPrevent
  58. }
  59. // create a new order
  60. if size = uint(math.Floor(account.GetCash() * ratio / limit)); 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]); err != nil {
  80. return err
  81. }
  82. }
  83. return nil
  84. }