diff options
Diffstat (limited to 'db')
-rw-r--r-- | db/report_lines.go | 140 |
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 @@ | |||
1 | package db | ||
2 | |||
3 | import ( | ||
4 | "encoding/json" | ||
5 | "fmt" | ||
6 | "time" | ||
7 | |||
8 | "github.com/go-redis/redis" | ||
9 | "github.com/shopspring/decimal" | ||
10 | ) | ||
11 | |||
12 | type PortfolioStep string | ||
13 | |||
14 | const SELL_BEGIN PortfolioStep = "process_sell_all__1_all_sell_begin" | ||
15 | const SELL_END PortfolioStep = "process_sell_all__1_all_sell_end" | ||
16 | const BUY_BEGIN PortfolioStep = "process_sell_all__3_all_buy_begin" | ||
17 | const BUY_END PortfolioStep = "process_sell_all__3_all_buy_end" | ||
18 | const INTERMADIATE_STATE PortfolioStep = "process_print_balances__1_print_balances_begin" | ||
19 | |||
20 | type ViewBalances struct { | ||
21 | Id int64 | ||
22 | Date time.Time | ||
23 | ReportId int64 | ||
24 | MarketId int64 | ||
25 | Payload struct { | ||
26 | Report | ||
27 | } | ||
28 | } | ||
29 | |||
30 | type Report struct { | ||
31 | Tag PortfolioStep | ||
32 | Date time.Time | ||
33 | Balances ReportBalances | ||
34 | Tickers ReportTickers | ||
35 | } | ||
36 | |||
37 | type ReportTickers struct { | ||
38 | Currency string | ||
39 | Balances map[string]decimal.Decimal | ||
40 | Rates BTCRates | ||
41 | Total decimal.Decimal | ||
42 | } | ||
43 | |||
44 | func (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 | |||
52 | type BTCRates map[string]decimal.Decimal | ||
53 | |||
54 | func (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 | |||
62 | type 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 | |||
69 | func RedisReportKey(marketConfigId int64, timestamp, entity string) string { | ||
70 | return fmt.Sprintf("/cryptoportfolio/%v/%v/%v", marketConfigId, timestamp, entity) | ||
71 | } | ||
72 | |||
73 | func 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 | |||
108 | func 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 | |||
129 | func 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 | } | ||