|
@@ -1,8 +1,9 @@
|
|
|
package sentio
|
|
|
|
|
|
import (
|
|
|
- "context"
|
|
|
"errors"
|
|
|
+ "fmt"
|
|
|
+ "strings"
|
|
|
"time"
|
|
|
)
|
|
|
|
|
@@ -12,24 +13,74 @@ var (
|
|
|
)
|
|
|
|
|
|
type Market interface {
|
|
|
+ Clock() Clock
|
|
|
+ IsOpen() bool
|
|
|
+ Cooldown() uint8
|
|
|
+
|
|
|
Connect(done chan struct{}) (chan MarketConnection, error)
|
|
|
- Subscribe(symbol string) error
|
|
|
+ Subscribe(symbols ...string) error
|
|
|
|
|
|
- IsMarketOpened() bool
|
|
|
- Time() Clock
|
|
|
+ Account() (MarketAccount, error)
|
|
|
|
|
|
- Buy(ctx context.Context, symbol string, ratio float64) (float64, Order, error)
|
|
|
- Sell(ctx context.Context, symbol string, ratio float64) (float64, Order, error)
|
|
|
- CancelOrder(id string) error
|
|
|
+ CreateOrder(symbol string, quantity uint, sl float64) (Order, error)
|
|
|
+ UpdateOrder(orderID string, sl float64) error
|
|
|
+ CloseOrder(orderID string) (Order, error)
|
|
|
|
|
|
- Orders() ([]Order, error)
|
|
|
+ Order(orderID string, nested bool) (Order, error)
|
|
|
+ Orders(criteria OrderListCriteria) ([]Order, error)
|
|
|
Portfolio() (Portfolio, error)
|
|
|
PortfolioHistory() ([]PortfolioRecord, error)
|
|
|
-
|
|
|
+ Quotes(symbols ...string) (map[string]Quote, error)
|
|
|
HistoricalBars(symbol string, interval time.Duration, from *time.Time) ([]Bar, error)
|
|
|
- Quote(symbol string) (*Quote, error)
|
|
|
+}
|
|
|
|
|
|
- Account() (MarketAccount, error)
|
|
|
- MaxBudget() float64
|
|
|
- Cooldown() uint8
|
|
|
+type OrderListCriteria struct {
|
|
|
+ Status string
|
|
|
+ Limit uint
|
|
|
+ Symbols []string
|
|
|
+ After *time.Time
|
|
|
+ Until *time.Time
|
|
|
+ Nested bool
|
|
|
+ Side *string
|
|
|
+}
|
|
|
+
|
|
|
+func (criteria OrderListCriteria) Values() map[string]string {
|
|
|
+ var values = make(map[string]string)
|
|
|
+
|
|
|
+ if criteria.Limit < 1 {
|
|
|
+ criteria.Limit = 500
|
|
|
+ }
|
|
|
+
|
|
|
+ if s := strings.TrimSpace(criteria.Status); s != "" {
|
|
|
+ values["status"] = s
|
|
|
+ }
|
|
|
+
|
|
|
+ if criteria.Symbols != nil && len(criteria.Symbols) > 0 {
|
|
|
+ values["symbols"] = strings.Join(criteria.Symbols, ",")
|
|
|
+ }
|
|
|
+
|
|
|
+ if criteria.After == nil {
|
|
|
+ t := time.Now().Add(-time.Hour * 24).Round(time.Hour * 24)
|
|
|
+ criteria.After = &t
|
|
|
+ }
|
|
|
+
|
|
|
+ if criteria.Until != nil && !criteria.Until.IsZero() {
|
|
|
+ values["until"] = criteria.Until.Format(time.RFC3339)
|
|
|
+ }
|
|
|
+
|
|
|
+ if criteria.Nested {
|
|
|
+ values["nested"] = "true"
|
|
|
+ } else {
|
|
|
+ values["nested"] = "false"
|
|
|
+ }
|
|
|
+
|
|
|
+ if criteria.Side != nil {
|
|
|
+ values["side"] = *criteria.Side
|
|
|
+ }
|
|
|
+
|
|
|
+ values["limit"] = fmt.Sprintf("%d", criteria.Limit)
|
|
|
+ values["after"] = criteria.After.Format(time.RFC3339)
|
|
|
+ values["direction"] = "asc"
|
|
|
+
|
|
|
+ return values
|
|
|
}
|