Alexey Kim 6 ay önce
ebeveyn
işleme
09e84dacd8
4 değiştirilmiş dosya ile 139 ekleme ve 0 silme
  1. 20 0
      market.go
  2. 15 0
      order.go
  3. 52 0
      tif.go
  4. 52 0
      tif_test.go

+ 20 - 0
market.go

@@ -0,0 +1,20 @@
+package sentio
+
+import "context"
+
+type Market interface {
+	Connect(done chan struct{}) (chan int, error)
+	Subscribe(symbol string) error
+
+	IsMarketOpened() bool
+
+	Buy(ctx context.Context, symbol string, amount float64) (Order, error)
+	Sell(ctx context.Context, symbol string) (Order, error)
+	CancelOrder(id string) error
+
+	Orders() ([]Order, error)
+	Portfolio() (Portfolio, error)
+
+	AvailableCash() (float64, error)
+	MaxBudget() float64
+}

+ 15 - 0
order.go

@@ -0,0 +1,15 @@
+package sentio
+
+type Order interface {
+	Market() string
+	AccountId() string
+
+	GetId() string
+	GetSymbol() string
+	GetAction() OrderAction
+	GetTimeInForce() TimeInForce
+	GetSize() int
+	GetPrice() float64
+	GetCurrency() string
+	GetStatus() string
+}

+ 52 - 0
tif.go

@@ -0,0 +1,52 @@
+package sentio
+
+import (
+	"fmt"
+	"strings"
+)
+
+// TimeInForce Specifies how long the order remains in effect. Absence of this field is interpreted as DAY.
+// See more at https://www.onixs.biz/fix-dictionary/4.2/tagNum_59.html
+type TimeInForce int
+
+var tifs = map[TimeInForce]string{
+	TIFDay:                "DAY",
+	TIFGoodTillCancel:     "GTC",
+	TIFOpenPriceGuarantee: "OPG",
+	TIFImmediateOrCancel:  "IOC",
+	TIFFillOrKill:         "FOK",
+	TIFGoodTillCrossing:   "GTX",
+	TIFGoodTillDate:       "GTD",
+}
+
+func (tif TimeInForce) String() string {
+	t, ok := tifs[tif]
+	if !ok {
+		return "undefined"
+	}
+
+	return t
+}
+
+func ParseTimeInForce(s string) (TimeInForce, error) {
+	s = strings.TrimSpace(s)
+	s = strings.ToUpper(s)
+
+	for t, l := range tifs {
+		if s == l {
+			return t, nil
+		}
+	}
+
+	return -1, fmt.Errorf("`tif.Parse`: undefined TimeInForce `%s`", s)
+}
+
+const (
+	TIFDay                TimeInForce = 0
+	TIFGoodTillCancel     TimeInForce = 1
+	TIFOpenPriceGuarantee TimeInForce = 2
+	TIFImmediateOrCancel  TimeInForce = 3
+	TIFFillOrKill         TimeInForce = 4
+	TIFGoodTillCrossing   TimeInForce = 5
+	TIFGoodTillDate       TimeInForce = 6
+)

+ 52 - 0
tif_test.go

@@ -0,0 +1,52 @@
+package sentio
+
+import "testing"
+
+func TestParseTimeInForce(t *testing.T) {
+	tests := []struct {
+		name    string
+		arg     string
+		want    TimeInForce
+		wantErr bool
+	}{
+		{
+			name:    "DAY",
+			arg:     "day",
+			want:    TIFDay,
+			wantErr: false,
+		},
+		{
+			name:    "DAY",
+			arg:     "Day",
+			want:    TIFDay,
+			wantErr: false,
+		},
+		{
+			name:    "DAY",
+			arg:     " day",
+			want:    TIFDay,
+			wantErr: false,
+		},
+		{
+			name:    "Unknown",
+			arg:     "D ay",
+			want:    -1,
+			wantErr: true,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := ParseTimeInForce(tt.arg)
+
+			if (err != nil) != tt.wantErr {
+				t.Errorf("ParseTimeInForce() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+
+			if got != tt.want {
+				t.Errorf("ParseTimeInForce() got = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}