market.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package sentio
  2. import (
  3. "errors"
  4. "fmt"
  5. "strings"
  6. "time"
  7. )
  8. var (
  9. ErrMarketClosed = errors.New("market is closed")
  10. ErrTooSmallOrder = errors.New("too small order size")
  11. )
  12. type Market interface {
  13. Clock() Clock
  14. IsOpen() bool
  15. Cooldown() uint8
  16. Connect(done chan struct{}) (chan MarketConnection, error)
  17. Subscribe(symbols ...string) error
  18. Account() (MarketAccount, error)
  19. CreateOrder(symbol string, quantity uint, sl float64) (Order, error)
  20. UpdateOrder(orderID string, sl float64) error
  21. CloseOrder(orderID string) (Order, error)
  22. Order(orderID string, nested bool) (Order, error)
  23. Orders(criteria OrderListCriteria) ([]Order, error)
  24. Portfolio() (Portfolio, error)
  25. PortfolioHistory() ([]PortfolioRecord, error)
  26. Quotes(symbols ...string) (map[string]Quote, error)
  27. HistoricalBars(symbols []string, interval time.Duration, from *time.Time) (map[string][]Bar, error)
  28. }
  29. type OrderListCriteria struct {
  30. Status string
  31. Limit uint
  32. Symbols []string
  33. After *time.Time
  34. Until *time.Time
  35. Nested bool
  36. Side *string
  37. }
  38. func (criteria OrderListCriteria) Values() map[string]string {
  39. var values = make(map[string]string)
  40. if criteria.Limit < 1 {
  41. criteria.Limit = 500
  42. }
  43. if s := strings.TrimSpace(criteria.Status); s != "" {
  44. values["status"] = s
  45. }
  46. if criteria.Symbols != nil && len(criteria.Symbols) > 0 {
  47. values["symbols"] = strings.Join(criteria.Symbols, ",")
  48. }
  49. if criteria.After == nil {
  50. t := time.Now().Add(-time.Hour * 24).Round(time.Hour * 24)
  51. criteria.After = &t
  52. }
  53. if criteria.Until != nil && !criteria.Until.IsZero() {
  54. values["until"] = criteria.Until.In(time.UTC).Format(time.RFC3339)
  55. }
  56. if criteria.Nested {
  57. values["nested"] = "true"
  58. } else {
  59. values["nested"] = "false"
  60. }
  61. if criteria.Side != nil {
  62. values["side"] = *criteria.Side
  63. }
  64. values["limit"] = fmt.Sprintf("%d", criteria.Limit)
  65. values["after"] = criteria.After.In(time.UTC).Format(time.RFC3339)
  66. values["direction"] = "asc"
  67. return values
  68. }