2
0

strategy.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package main
  2. import (
  3. "git.beejay.kim/Gshopper/sentio"
  4. "git.beejay.kim/Gshopper/sentio/indicator"
  5. "git.beejay.kim/Gshopper/sentio/util"
  6. )
  7. const (
  8. ATR_MULTIPLIER = 3
  9. ATR_PERIOD = 21
  10. ATR_HHV = 10
  11. )
  12. var Strategy = qqq{}
  13. type qqq struct{}
  14. func (strategy qqq) Name() string {
  15. return "Alpaca: QQQ [TQQQ : SQQQ]"
  16. }
  17. func (strategy qqq) Model() string {
  18. return "qqq200"
  19. }
  20. func (strategy qqq) MarketId() string {
  21. return "alpaca"
  22. }
  23. func (strategy qqq) Interval() uint8 {
  24. return 1
  25. }
  26. func (strategy qqq) PositionSymbols() map[sentio.Side]string {
  27. return map[sentio.Side]string{
  28. sentio.BASE: "QQQ",
  29. sentio.LONG: "TQQQ",
  30. sentio.SHORT: "SQQQ",
  31. }
  32. }
  33. func (strategy qqq) PositionProbabilities() map[sentio.Side]float32 {
  34. return map[sentio.Side]float32{
  35. sentio.BASE: -1,
  36. sentio.LONG: 1.000097,
  37. sentio.SHORT: .999867,
  38. }
  39. }
  40. func (strategy qqq) Handle(market sentio.Market, probability *sentio.Probability) error {
  41. var (
  42. now = market.Clock().Now()
  43. stamp *sentio.Probability_Stamp
  44. symbols = util.Symbols(strategy)
  45. stoplosses map[string]float64
  46. quotes map[string]sentio.Quote
  47. orders []sentio.Order
  48. ok bool
  49. err error
  50. )
  51. // skip too early orders
  52. if now.Hour() == 9 && now.Minute() < 50 {
  53. return nil
  54. }
  55. // close all orders before market close
  56. if now.Hour() == 15 && now.Minute() > 50 {
  57. return util.CloseAllOrders(market, strategy)
  58. }
  59. if stamp, ok = probability.First(); !ok {
  60. return nil
  61. }
  62. // retrieve running orders
  63. if orders, err = market.Orders(sentio.OrderListCriteria{
  64. Status: "open",
  65. Symbols: symbols,
  66. }); err != nil {
  67. return err
  68. }
  69. if stoplosses, err = indicator.AtrTrailingStopLoss(market, 1, ATR_PERIOD, ATR_MULTIPLIER, ATR_HHV, symbols...); err != nil {
  70. return err
  71. }
  72. // update stoplosses or close running orders
  73. hasClosedOrders := false
  74. for i := range orders {
  75. if strategy.PositionSymbols()[sentio.LONG] == orders[i].GetSymbol() &&
  76. stamp.Value < strategy.PositionProbabilities()[sentio.LONG] {
  77. if _, err = market.CloseOrder(orders[i]); err != nil {
  78. return err
  79. }
  80. hasClosedOrders = true
  81. continue
  82. }
  83. if strategy.PositionSymbols()[sentio.SHORT] == orders[i].GetSymbol() &&
  84. stamp.Value > strategy.PositionProbabilities()[sentio.SHORT] {
  85. if _, err = market.CloseOrder(orders[i]); err != nil {
  86. return err
  87. }
  88. hasClosedOrders = true
  89. continue
  90. }
  91. if f, ok := stoplosses[orders[i].GetSymbol()]; ok && f > 0 {
  92. if err = market.UpdateOrder(orders[i].GetId(), f); err != nil {
  93. return err
  94. }
  95. continue
  96. }
  97. }
  98. // Prevent new orders if we just closed one
  99. if hasClosedOrders || len(orders) > 0 {
  100. return nil
  101. }
  102. // Prevent BUYs on closing market
  103. if now.Hour() == 15 && now.Minute() > 46 {
  104. return nil
  105. }
  106. // Prevent Market.CreateOrder while probability is not clear
  107. if stamp.Value == 1 || stamp.Value < 0 {
  108. return nil
  109. }
  110. if quotes, err = market.Quotes(symbols...); err != nil {
  111. return err
  112. }
  113. var t = sentio.SHORT
  114. if stamp.Value > 1 {
  115. t = sentio.LONG
  116. }
  117. return util.CreateOrder(market, strategy, t, probability, quotes, stoplosses)
  118. }