2
0

order.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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), 2)
  36. sl = sentio.ToFixed(rm.StopLoss(symbol, bid), 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. // create a new order
  53. if size = uint(math.Floor(account.GetCash() * .9 / bid)); size < 1 {
  54. return sentio.ErrTooSmallOrder
  55. }
  56. _, err = m.CreateOrder(symbol, size, rm)
  57. return err
  58. }
  59. func CloseAllOrders(m sentio.Market, s sentio.Strategy) error {
  60. var (
  61. symbols = Symbols(s)
  62. orders []sentio.Order
  63. err error
  64. )
  65. if orders, err = m.Orders(sentio.OrderListCriteria{
  66. Status: "open",
  67. Symbols: symbols,
  68. }); err != nil {
  69. return err
  70. }
  71. for i := range orders {
  72. if _, err = m.CloseOrder(orders[i]); err != nil {
  73. return err
  74. }
  75. }
  76. return nil
  77. }