-
Notifications
You must be signed in to change notification settings - Fork 263
Add metrics for trade tracking. #574
base: master
Are you sure you want to change the base?
Changes from 1 commit
51b70ac
2d78a35
92018eb
7a113bb
69bc642
40c5d20
79364e7
6876075
ebdc97a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -166,6 +166,7 @@ func MakeMetricsTrackerCli( | |
| operationalBufferNonNativePct float64, | ||
| simMode bool, | ||
| fixedIterations uint64, | ||
| handler *plugins.TradeMetricsHandler, | ||
| ) (*MetricsTracker, error) { | ||
| props := commonProps{ | ||
| CliVersion: version, | ||
|
|
@@ -215,7 +216,7 @@ func MakeMetricsTrackerCli( | |
| botStartTime: botStartTime, | ||
| isDisabled: isDisabled, | ||
| updateEventSentTime: nil, | ||
| handler: plugins.MakeTradeMetricsHandler(), | ||
| handler: handler, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
| cliVersion: version, | ||
| }, nil | ||
| } | ||
|
|
@@ -236,6 +237,7 @@ func MakeMetricsTrackerGui( | |
| goVersion string, | ||
| guiVersion string, | ||
| isDisabled bool, | ||
| handler *plugins.TradeMetricsHandler, | ||
| ) (*MetricsTracker, error) { | ||
| props := commonProps{ | ||
| CliVersion: version, | ||
|
|
@@ -262,6 +264,7 @@ func MakeMetricsTrackerGui( | |
| botStartTime: botStartTime, | ||
| isDisabled: isDisabled, | ||
| updateEventSentTime: nil, | ||
| handler: handler, | ||
| cliVersion: version, | ||
| }, nil | ||
| } | ||
|
|
@@ -372,52 +375,7 @@ func (mt *MetricsTracker) SendEvent(eventType string, eventPropsInterface interf | |
| return nil | ||
| } | ||
|
|
||
| // ComputeTradeMetrics computes various trade metrics and outputs a map that can be combined with other metrics. | ||
| func (mt *MetricsTracker) ComputeTradeMetrics() map[string]interface{} { | ||
| // TODO NS Ensure proper locking around trades on metrics handler | ||
| trades := mt.handler.GetTrades() | ||
| mt.handler.Reset() | ||
|
|
||
| totalBaseVolume := 0.0 | ||
| totalQuoteVolume := 0.0 | ||
| totalPrice := 0.0 | ||
| netBaseVolume := 0.0 | ||
| netQuoteVolume := 0.0 | ||
|
|
||
| numTrades := float64(len(trades)) | ||
| for _, t := range trades { | ||
| base := t.Volume.AsFloat() | ||
| price := t.Price.AsFloat() | ||
| quote := base * price | ||
|
|
||
| totalBaseVolume += base | ||
| totalPrice += price | ||
| totalQuoteVolume += quote | ||
|
|
||
| if t.OrderAction.IsBuy() { | ||
| netBaseVolume += base | ||
| netQuoteVolume -= quote | ||
| } else { | ||
| netBaseVolume -= base | ||
| netQuoteVolume -= quote | ||
| } | ||
| } | ||
|
|
||
| avgTradeSizeBase := totalBaseVolume / numTrades | ||
| avgTradeSizeQuote := totalQuoteVolume / numTrades | ||
| avgTradePrice := totalPrice / numTrades | ||
|
|
||
| tradeMetrics := map[string]interface{}{ | ||
| "total_base_volume": totalBaseVolume, | ||
| "total_quote_volume": totalQuoteVolume, | ||
| "net_base_volume": netBaseVolume, | ||
| "net_quote_volume": netQuoteVolume, | ||
| "num_trades": numTrades, | ||
| "avg_trade_size_base": avgTradeSizeBase, | ||
| "avg_trade_size_quote": avgTradeSizeQuote, | ||
| "avg_trade_price": avgTradePrice, | ||
| "vwap": totalQuoteVolume / totalBaseVolume, | ||
| } | ||
|
|
||
| return tradeMetrics | ||
| // GetHandler returns the TradeMetricsHandler | ||
| func (mt *MetricsTracker) GetHandler() *plugins.TradeMetricsHandler { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can remove this (as commented above) |
||
| return mt.handler | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,20 @@ type TradeMetricsHandler struct { | |
| trades []model.Trade | ||
| } | ||
|
|
||
| // TradeMetrics stores the computed trade-related metrics. | ||
| // TODO DS Pre-pend interval__ to all JSON fields. | ||
| type TradeMetrics struct { | ||
| totalBaseVolume float64 `json:"total_base_volume"` | ||
| totalQuoteVolume float64 `json:"total_quote_volume"` | ||
| netBaseVolume float64 `json:"net_base_volume"` | ||
| netQuoteVolume float64 `json:"net_quote_volume"` | ||
| numTrades float64 `json:"num_trades"` | ||
| avgTradeSizeBase float64 `json:"avg_trade_size_base"` | ||
| avgTradeSizeQuote float64 `json:"avg_trade_size_quote"` | ||
| avgTradePrice float64 `json:"avg_trade_price"` | ||
| vwap float64 `json:"vwap"` | ||
| } | ||
|
|
||
| // MakeTradeMetricsHandler is a factory method for the TradeMetricsHandler | ||
| func MakeTradeMetricsHandler() *TradeMetricsHandler { | ||
debnil marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return &TradeMetricsHandler{ | ||
|
|
@@ -32,3 +46,55 @@ func (h *TradeMetricsHandler) HandleFill(trade model.Trade) error { | |
| h.trades = append(h.trades, trade) | ||
| return nil | ||
| } | ||
|
|
||
| // ComputeTradeMetrics computes trade-related metrics. | ||
| func (h *TradeMetricsHandler) ComputeTradeMetrics(secondsSinceLastUpdate float64) TradeMetrics { | ||
| trades := h.GetTrades() | ||
| h.Reset() | ||
|
|
||
| // Note that we don't consider fees right now, as we don't have the infrastructure to understand fee units when tracking trades. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks |
||
| totalBaseVolume := 0.0 | ||
| totalQuoteVolume := 0.0 | ||
| totalPrice := 0.0 | ||
| netBaseVolume := 0.0 | ||
| netQuoteVolume := 0.0 | ||
|
|
||
| numTrades := float64(len(trades)) | ||
| for _, t := range trades { | ||
| base := t.Volume.AsFloat() | ||
| price := t.Price.AsFloat() | ||
| quote := base * price | ||
|
|
||
| totalBaseVolume += base | ||
| totalPrice += price | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't think the math works out this way for price to get avgTradePrice should be not sure if I had suggested adding this, but if I had that is wrong. |
||
| totalQuoteVolume += quote | ||
|
|
||
| if t.OrderAction.IsBuy() { | ||
| netBaseVolume += base | ||
| netQuoteVolume -= quote | ||
| } else { | ||
| netBaseVolume -= base | ||
| netQuoteVolume -= quote | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. may be a typo, should be |
||
| } | ||
| } | ||
|
|
||
| avgTradeSizeBase := totalBaseVolume / numTrades | ||
| avgTradeSizeQuote := totalQuoteVolume / numTrades | ||
| avgTradePrice := totalPrice / numTrades | ||
| avgTradeThroughputBase := totalBaseVolume / secondsSinceLastUpdate | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we rename this to |
||
| avgTradeThroughputQuote := totalQuoteVolume / secondsSinceLastUpdate | ||
|
|
||
| tradeMetrics := TradeMetrics{ | ||
| totalBaseVolume: totalBaseVolume, | ||
| totalQuoteVolume: totalQuoteVolume, | ||
| netBaseVolume: netBaseVolume, | ||
| netQuoteVolume: netQuoteVolume, | ||
| numTrades: numTrades, | ||
| avgTradeSizeBase: avgTradeSizeBase, | ||
| avgTradeSizeQuote: avgTradeSizeQuote, | ||
| avgTradePrice: avgTradePrice, | ||
| vwap: totalQuoteVolume / totalBaseVolume, | ||
| } | ||
|
|
||
| return tradeMetrics | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should not pull the metricsHandler from within the metricsTracker but pass it directly to this function. i.e. we don't need the
GetHandler()method on metricsTracker either.this registration of the handler should happen before the
if strategyFillHandlers != nil {paragraph. we want the strategy handlers to always be last because we execute the handler in the order in which they are added as well. I should have added this as a comment, can you please add this as well (that "handlers are executed in the order in which they are added")?