/
models.go
183 lines (165 loc) · 4.8 KB
/
models.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
package vespyr
import (
"time"
"github.com/go-pg/pg/orm"
"github.com/montanaflynn/stats"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
)
// CandlestickModel is a candlestick's representation in a database.
type CandlestickModel struct {
tableName struct{} `sql:"candlesticks"`
ID int64
CreatedAt time.Time
UpdatedAt time.Time
StartTime time.Time
EndTime time.Time
Low float64
High float64
Open float64
Close float64
Volume float64
Direction CandlestickDirection
Product Product
}
// MeanPrice returns the mean price for the candlestick period.
func (m *CandlestickModel) MeanPrice() (float64, error) {
price, err := stats.Mean([]float64{
m.Open,
m.High,
m.Low,
m.Close,
})
if err != nil {
return 0, errors.Wrapf(err, "error calculating candlestick mean")
}
return price, nil
}
func (m *CandlestickModel) BeforeInsert(db orm.DB) error {
m.CreatedAt = time.Now()
return nil
}
func (m *CandlestickModel) BeforeUpdate(db orm.DB) error {
m.UpdatedAt = time.Now()
return nil
}
// MarketOrderModel contains metadata about market orders that were
// placed.
type MarketOrderModel struct {
tableName struct{} `sql:"market_orders"`
ID int64
CreatedAt time.Time
UpdatedAt time.Time
TradingStrategyID int64
ExchangeID string
Product Product
Side string
Cost float64
CostCurrency string
FilledSize float64
SizeCurrency string
Fees float64
FeesCurrency string
}
func (m *MarketOrderModel) BeforeInsert(db orm.DB) error {
m.CreatedAt = time.Now()
return nil
}
func (m *MarketOrderModel) BeforeUpdate(db orm.DB) error {
m.UpdatedAt = time.Now()
return nil
}
// TradingStrategyModel contains metadata for a trading strategy.
type TradingStrategyModel struct {
tableName struct{} `sql:"trading_strategies"`
ID int64
CreatedAt time.Time
UpdatedAt time.Time
DeactivatedAt time.Time
LastTickAt time.Time
NextTickAt time.Time
Product Product
HistoryTicks uint
State string
InitialBudget float64
Budget float64
BudgetCurrency string
Invested float64
InvestedCurrency string
TickSizeMinutes uint
TradingStrategy string
TradingStrategyData []byte
}
func (m *TradingStrategyModel) BeforeInsert(db orm.DB) error {
m.CreatedAt = time.Now()
return nil
}
func (m *TradingStrategyModel) BeforeUpdate(db orm.DB) error {
m.UpdatedAt = time.Now()
return nil
}
// Copy returns a copy of the current model.
func (t *TradingStrategyModel) Copy() *TradingStrategyModel {
return &TradingStrategyModel{
ID: t.ID,
Product: t.Product,
HistoryTicks: t.HistoryTicks,
State: t.State,
InitialBudget: t.InitialBudget,
Budget: t.Budget,
BudgetCurrency: t.BudgetCurrency,
Invested: t.Invested,
InvestedCurrency: t.InvestedCurrency,
TickSizeMinutes: t.TickSizeMinutes,
TradingStrategy: t.TradingStrategy,
TradingStrategyData: t.TradingStrategyData,
}
}
// SetStrategy sets the underlying trading strategy.
func (t *TradingStrategyModel) SetStrategy(s StrategyInterface) error {
switch s.(type) {
case *EMACrossoverStrategy:
t.TradingStrategy = TradingStrategyEMACrossover
case *RSIStrategy:
t.TradingStrategy = TradingStrategyRSI
case *S1Strategy:
t.TradingStrategy = TradingStrategyS1
default:
return errors.Errorf("error: unknown trading strategy")
}
s.SetTradingStrategy(t)
b, err := yaml.Marshal(s)
if err != nil {
return errors.Wrapf(err, "error YAML marshalling trading strategy: %s", t.TradingStrategy)
}
t.TradingStrategyData = b
return nil
}
// Strategy returns the underlying trading strategy.
func (t *TradingStrategyModel) Strategy() (StrategyInterface, error) {
switch t.TradingStrategy {
case TradingStrategyEMACrossover:
var strategy EMACrossoverStrategy
if err := yaml.Unmarshal(t.TradingStrategyData, &strategy); err != nil {
return nil, errors.Wrapf(err, "error YAML unmarshaling trading strategy data")
}
strategy.SetTradingStrategy(t)
return &strategy, nil
case TradingStrategyRSI:
var strategy RSIStrategy
if err := yaml.Unmarshal(t.TradingStrategyData, &strategy); err != nil {
return nil, errors.Wrapf(err, "error YAML unmarshaling trading strategy data")
}
strategy.SetTradingStrategy(t)
return &strategy, nil
case TradingStrategyS1:
var strategy S1Strategy
if err := yaml.Unmarshal(t.TradingStrategyData, &strategy); err != nil {
return nil, errors.Wrapf(err, "error YAML unmarshaling trading strategy data")
}
strategy.SetTradingStrategy(t)
return &strategy, nil
default:
return nil, errors.Errorf("error: unknown trading strategy: %s", t.TradingStrategy)
}
}