Browse Source

Initial commit

Alexey Kim 6 months ago
commit
5f45b73a75
8 changed files with 132 additions and 0 deletions
  1. 1 0
      .gitignore
  2. 5 0
      go.mod
  3. 2 0
      go.sum
  4. 6 0
      portfolio.go
  5. 12 0
      position.go
  6. 40 0
      side.go
  7. 52 0
      side_test.go
  8. 14 0
      strategy.go

+ 1 - 0
.gitignore

@@ -0,0 +1 @@
+.idea

+ 5 - 0
go.mod

@@ -0,0 +1,5 @@
+module git.beejay.kim/Gshopper/sentio
+
+go 1.22.2
+
+require github.com/hashicorp/go-version v1.7.0

+ 2 - 0
go.sum

@@ -0,0 +1,2 @@
+github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
+github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=

+ 6 - 0
portfolio.go

@@ -0,0 +1,6 @@
+package main
+
+type Portfolio interface {
+	// Get returns Position of the symbol if exists in Portfolio
+	Get(symbol string) (Position, bool)
+}

+ 12 - 0
position.go

@@ -0,0 +1,12 @@
+package main
+
+type Position interface {
+	// GetSize returns the total size of the position
+	GetSize() float64
+
+	// GetAvgPrice returns the average cost of each share in the position when purchased
+	GetAvgPrice() float64
+
+	// GetSymbol returns the ticker symbol of the traded contract
+	GetSymbol() string
+}

+ 40 - 0
side.go

@@ -0,0 +1,40 @@
+package main
+
+import (
+	"errors"
+	"strings"
+)
+
+type Side int
+
+const (
+	LONG Side = iota
+	SHORT
+)
+
+var sides = map[Side]string{
+	LONG:  "LONG",
+	SHORT: "SHORT",
+}
+
+func (s Side) String() string {
+	side, ok := sides[s]
+	if ok {
+		return side
+	}
+
+	return "undefined"
+}
+
+func SideFromString(s string) (Side, error) {
+	s = strings.TrimSpace(s)
+	s = strings.ToUpper(s)
+
+	for side, s2 := range sides {
+		if s == s2 {
+			return side, nil
+		}
+	}
+
+	return -1, errors.New("unknown Side")
+}

+ 52 - 0
side_test.go

@@ -0,0 +1,52 @@
+package main
+
+import "testing"
+
+func TestSideFromString(t *testing.T) {
+	tests := []struct {
+		arg     string
+		want    Side
+		wantErr bool
+	}{
+		{
+			arg:     "short",
+			want:    SHORT,
+			wantErr: false,
+		},
+		{
+			arg:     "Short",
+			want:    SHORT,
+			wantErr: false,
+		},
+		{
+			arg:     " short ",
+			want:    SHORT,
+			wantErr: false,
+		},
+		{
+			arg:     "ShOrT",
+			want:    SHORT,
+			wantErr: false,
+		},
+		{
+			arg:     "šhort",
+			want:    -1,
+			wantErr: true,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run("TestSideFromString", func(t *testing.T) {
+			got, err := SideFromString(tt.arg)
+
+			if (err != nil) != tt.wantErr {
+				t.Errorf("SideFromString() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+
+			if got != tt.want {
+				t.Errorf("SideFromString() got = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}

+ 14 - 0
strategy.go

@@ -0,0 +1,14 @@
+package main
+
+import "github.com/hashicorp/go-version"
+
+type Strategy interface {
+	Name() string
+	Version() *version.Version
+
+	Model() string
+	PositionSymbols() map[Side]string
+
+	ShouldClosePositions(portfolio Portfolio, proba float64) []string
+	ShouldOpenPosition(portfolio Portfolio, proba float64) (*string, float64)
+}