aboutsummaryrefslogtreecommitdiff
path: root/db
diff options
context:
space:
mode:
Diffstat (limited to 'db')
-rw-r--r--db/report_lines.go140
1 files changed, 140 insertions, 0 deletions
diff --git a/db/report_lines.go b/db/report_lines.go
new file mode 100644
index 0000000..274be57
--- /dev/null
+++ b/db/report_lines.go
@@ -0,0 +1,140 @@
1package db
2
3import (
4 "encoding/json"
5 "fmt"
6 "time"
7
8 "github.com/go-redis/redis"
9 "github.com/shopspring/decimal"
10)
11
12type PortfolioStep string
13
14const SELL_BEGIN PortfolioStep = "process_sell_all__1_all_sell_begin"
15const SELL_END PortfolioStep = "process_sell_all__1_all_sell_end"
16const BUY_BEGIN PortfolioStep = "process_sell_all__3_all_buy_begin"
17const BUY_END PortfolioStep = "process_sell_all__3_all_buy_end"
18const INTERMADIATE_STATE PortfolioStep = "process_print_balances__1_print_balances_begin"
19
20type ViewBalances struct {
21 Id int64
22 Date time.Time
23 ReportId int64
24 MarketId int64
25 Payload struct {
26 Report
27 }
28}
29
30type Report struct {
31 Tag PortfolioStep
32 Date time.Time
33 Balances ReportBalances
34 Tickers ReportTickers
35}
36
37type ReportTickers struct {
38 Currency string
39 Balances map[string]decimal.Decimal
40 Rates BTCRates
41 Total decimal.Decimal
42}
43
44func (r ReportTickers) GetBTCRate(currency string) decimal.Decimal {
45 if currency == "BTC" {
46 return decimal.NewFromFloat(1.0)
47 }
48
49 return r.Rates[currency]
50}
51
52type BTCRates map[string]decimal.Decimal
53
54func (b BTCRates) Rate(currency string) decimal.Decimal {
55 if currency == "BTC" {
56 return decimal.NewFromFloat(1.0)
57 }
58
59 return b[currency]
60}
61
62type ReportBalances map[string]struct {
63 Total decimal.Decimal
64 MarginTotal decimal.Decimal `json:"margin_total"`
65 MarginInPosition decimal.Decimal `json:"margin_in_position"`
66 MarginAvailable decimal.Decimal `json:"margin_available"`
67}
68
69func RedisReportKey(marketConfigId int64, timestamp, entity string) string {
70 return fmt.Sprintf("/cryptoportfolio/%v/%v/%v", marketConfigId, timestamp, entity)
71}
72
73func GetLatestReport(marketConfig MarketConfig) (Report, error) {
74 var reportPayload Report
75 var err error
76 var key string
77
78 // Get balance.
79 key = RedisReportKey(marketConfig.Id, "latest", "balance")
80
81 payload, err := Redis.Get(key).Bytes()
82 if err == redis.Nil {
83 return Report{}, fmt.Errorf("cannot find '%s' redis key", key)
84 } else if err != nil {
85 return Report{}, err
86 }
87
88 // Get date.
89 key = RedisReportKey(marketConfig.Id, "latest", "date")
90 dateString, err := Redis.Get(key).Result()
91
92 if err == redis.Nil {
93 return Report{}, fmt.Errorf("cannot find '%s' redis key", key)
94 } else if err != nil {
95 return Report{}, err
96 }
97
98 reportPayload.Date, err = time.Parse("2006-01-02T15:04:05", dateString)
99 if err != nil {
100 return Report{}, err
101 }
102
103 err = json.Unmarshal(payload, &reportPayload)
104
105 return reportPayload, err
106}
107
108func GetPortfolioMilestones(marketConfig MarketConfig, step PortfolioStep, limit int) ([]Report, error) {
109 viewBalances := make([]ViewBalances, 0)
110 reports := make([]Report, 0)
111
112 err := DB.
113 Model(&viewBalances).
114 Where("market_id = ?", marketConfig.Id).
115 Where("payload @> ?", fmt.Sprintf(`{"tag": "%s", "checkpoint": "%s"}`, step, "begin")).
116 OrderExpr("date DESC").Limit(limit).Select()
117 if err != nil {
118 return nil, err
119 }
120
121 for _, reportLine := range viewBalances {
122 reportLine.Payload.Report.Date = reportLine.Date
123 reports = append(reports, reportLine.Payload.Report)
124 }
125
126 return reports, nil
127}
128
129func GetLastPortfolioBegin(marketConfig MarketConfig) (*Report, error) {
130 reports, err := GetPortfolioMilestones(marketConfig, BUY_END, 1)
131 if err != nil {
132 return nil, nil
133 }
134
135 if len(reports) == 0 {
136 return nil, nil
137 }
138
139 return &reports[0], nil
140}