order.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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. t sentio.Side,
  11. proba sentio.Probability,
  12. q map[string]sentio.Quote,
  13. sl map[string]float64,
  14. ) error {
  15. var (
  16. symbol string
  17. orders []sentio.Order
  18. account sentio.MarketAccount
  19. has = false
  20. avgPrice float64
  21. threshold float64
  22. size uint
  23. ok bool
  24. err error
  25. )
  26. if symbol, ok = s.PositionSymbols()[t]; !ok {
  27. return errors.New("`CreateOrder`: unknown Side for the current strategy")
  28. }
  29. if orders, err = m.Orders(sentio.OrderListCriteria{
  30. Status: "open",
  31. Symbols: []string{symbol},
  32. }); err != nil {
  33. return err
  34. }
  35. has = len(orders) > 0
  36. for i := range orders {
  37. avgPrice += orders[i].GetEntryPrice()
  38. }
  39. if has {
  40. avgPrice = avgPrice / float64(len(orders))
  41. }
  42. // define threshold
  43. if threshold, ok = s.PositionProbabilities()[t]; !ok {
  44. return nil
  45. }
  46. // Prevent cases when order will be closed ASAP they were opened.
  47. // Also, Alpaca requires at least 0.01 gap against base_price
  48. if sl[symbol] >= q[symbol].BidPrice-0.011 {
  49. return sentio.ErrHighStoploss
  50. }
  51. if account, err = m.Account(); err != nil {
  52. return err
  53. }
  54. if account.GetCash() < q[symbol].BidPrice {
  55. return sentio.ErrTooSmallOrder
  56. }
  57. if !has && ((sentio.LONG == t && proba.Value > threshold) || (sentio.SHORT == t && proba.Value < threshold)) {
  58. // create a new order
  59. if size = uint(math.Floor(account.GetCash() * .7 / q[symbol].BidPrice)); size < 1 {
  60. return sentio.ErrTooSmallOrder
  61. }
  62. _, err = m.CreateOrder(symbol, size, sl[symbol])
  63. return err
  64. } else if has && avgPrice/q[symbol].BidPrice > 1.002 {
  65. // create an extra position
  66. if size = uint(math.Floor(account.GetCash() * .5 / q[symbol].BidPrice)); size < 1 {
  67. return sentio.ErrTooSmallOrder
  68. }
  69. _, err = m.CreateOrder(symbol, size, sl[symbol])
  70. return err
  71. }
  72. return nil
  73. }
  74. func CloseAllOrders(m sentio.Market, s sentio.Strategy) error {
  75. var (
  76. symbols = Symbols(s)
  77. orders []sentio.Order
  78. err error
  79. )
  80. if orders, err = m.Orders(sentio.OrderListCriteria{
  81. Status: "open",
  82. Symbols: symbols,
  83. }); err != nil {
  84. return err
  85. }
  86. for i := range orders {
  87. if _, err = m.CloseOrder(orders[i]); err != nil {
  88. return err
  89. }
  90. }
  91. return nil
  92. }