From 35850953ac7140fc8fb734dc8a3804670d52b1fb Mon Sep 17 00:00:00 2001 From: aforaleka Date: Wed, 10 Apr 2024 22:06:33 -0400 Subject: [PATCH 1/4] add missing fields in place/cancel order events --- .../state/manager/V4StateManagerAdaptor.kt | 8 ++++- .../utils/AnalyticsUtils.kt | 29 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/state/manager/V4StateManagerAdaptor.kt b/src/commonMain/kotlin/exchange.dydx.abacus/state/manager/V4StateManagerAdaptor.kt index 835a843b5..bb972f0a0 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/state/manager/V4StateManagerAdaptor.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/state/manager/V4StateManagerAdaptor.kt @@ -1174,7 +1174,13 @@ class V4StateManagerAdaptor( override fun cancelOrder(orderId: String, callback: TransactionCallback) { val payload = cancelOrderPayload(orderId) - val analyticsPayload = analyticsUtils.formatCancelOrderPayload(payload) + val subaccount = stateMachine.state?.subaccount(subaccountNumber) + val existingOrder = subaccount?.orders?.firstOrNull { it.id == orderId } + val analyticsPayload = ParsingHelper.merge( + analyticsUtils.formatCancelOrderPayload(payload), + if (existingOrder != null) analyticsUtils.formatOrder(existingOrder) else mapOf() + )?.toIMap() + submitCancelOrder(orderId, callback, payload, analyticsPayload) } diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/utils/AnalyticsUtils.kt b/src/commonMain/kotlin/exchange.dydx.abacus/utils/AnalyticsUtils.kt index 433f5c797..2360491db 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/utils/AnalyticsUtils.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/utils/AnalyticsUtils.kt @@ -31,11 +31,40 @@ class AnalyticsUtils { "size" to payload.size, "subaccountNumber" to payload.subaccountNumber, "timeInForce" to payload.timeInForce, + "inferredTimeInForce" to calculateOrderTimeInForce(payload), "triggerPrice" to payload.triggerPrice, "type" to payload.type, ) as IMap? } + /** + * Infer time in force from order params for analytics, mirroring v4-clients + * @param payload HumanReadablePlaceOrderPayload + */ + private fun calculateOrderTimeInForce( + payload: HumanReadablePlaceOrderPayload + ): String? { + return when (payload.type) { + "MARKET" -> payload.timeInForce ?: "FOK" + "LIMIT" -> { + when (payload.timeInForce) { + "GTT" -> if (payload.postOnly == true) "POST_ONLY" else "GTT" + else -> payload.timeInForce + } + } + + "STOP_LIMIT", "TAKE_PROFIT" -> { + when (payload.execution) { + "DEFAULT" -> "GTT" + else -> payload.execution + } + } + + "STOP_MARKET", "TAKE_PROFIT_MARKET" -> payload.execution + else -> payload.timeInForce ?: payload.execution + } + } + /** * Format Cancel Order Payload for `TradeCancelOrder` Analytic Event * @param payload HumanReadableCancelOrderPayload From cd007701c75a10c82cb985e1056f1d2df76cfa6a Mon Sep 17 00:00:00 2001 From: aforaleka Date: Thu, 11 Apr 2024 13:53:22 -0400 Subject: [PATCH 2/4] format --- .../state/manager/V4StateManagerAdaptor.kt | 2 +- .../kotlin/exchange.dydx.abacus/utils/AnalyticsUtils.kt | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/state/manager/V4StateManagerAdaptor.kt b/src/commonMain/kotlin/exchange.dydx.abacus/state/manager/V4StateManagerAdaptor.kt index bb972f0a0..231d436b9 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/state/manager/V4StateManagerAdaptor.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/state/manager/V4StateManagerAdaptor.kt @@ -1178,7 +1178,7 @@ class V4StateManagerAdaptor( val existingOrder = subaccount?.orders?.firstOrNull { it.id == orderId } val analyticsPayload = ParsingHelper.merge( analyticsUtils.formatCancelOrderPayload(payload), - if (existingOrder != null) analyticsUtils.formatOrder(existingOrder) else mapOf() + if (existingOrder != null) analyticsUtils.formatOrder(existingOrder) else mapOf(), )?.toIMap() submitCancelOrder(orderId, callback, payload, analyticsPayload) diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/utils/AnalyticsUtils.kt b/src/commonMain/kotlin/exchange.dydx.abacus/utils/AnalyticsUtils.kt index 2360491db..afd2d41d5 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/utils/AnalyticsUtils.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/utils/AnalyticsUtils.kt @@ -70,7 +70,10 @@ class AnalyticsUtils { * @param payload HumanReadableCancelOrderPayload * @param fromSlTpDialog Boolean */ - fun formatCancelOrderPayload(payload: HumanReadableCancelOrderPayload, fromSlTpDialog: Boolean? = false,): IMap? { + fun formatCancelOrderPayload( + payload: HumanReadableCancelOrderPayload, + fromSlTpDialog: Boolean? = false, + ): IMap? { return iMapOf( "fromSlTpDialog" to fromSlTpDialog, "subaccountNumber" to payload.subaccountNumber, From a7e6595959f1af3c003a334e0f281a96eefbebc1 Mon Sep 17 00:00:00 2001 From: aforaleka Date: Thu, 11 Apr 2024 15:16:31 -0400 Subject: [PATCH 3/4] add mid market price --- .../state/manager/V4StateManagerAdaptor.kt | 36 ++++++++++------ .../v2/supervisor/SubaccountSupervisor.kt | 18 +++++--- .../utils/AnalyticsUtils.kt | 42 +++++++++++++++++-- 3 files changed, 74 insertions(+), 22 deletions(-) diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/state/manager/V4StateManagerAdaptor.kt b/src/commonMain/kotlin/exchange.dydx.abacus/state/manager/V4StateManagerAdaptor.kt index 231d436b9..0c05cb198 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/state/manager/V4StateManagerAdaptor.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/state/manager/V4StateManagerAdaptor.kt @@ -1162,13 +1162,15 @@ class V4StateManagerAdaptor( override fun commitPlaceOrder(callback: TransactionCallback): HumanReadablePlaceOrderPayload { val payload = placeOrderPayload() - val analyticsPayload = analyticsUtils.formatPlaceOrderPayload(payload) + val midMarketPrice = stateMachine.state?.marketOrderbook(payload.marketId)?.midPrice + val analyticsPayload = analyticsUtils.placeOrderAnalyticsPayload(payload, midMarketPrice) return submitPlaceOrder(callback, payload, analyticsPayload) } override fun commitClosePosition(callback: TransactionCallback): HumanReadablePlaceOrderPayload { val payload = closePositionPayload() - val analyticsPayload = analyticsUtils.formatPlaceOrderPayload(payload, true) + val midMarketPrice = stateMachine.state?.marketOrderbook(payload.marketId)?.midPrice + val analyticsPayload = analyticsUtils.placeOrderAnalyticsPayload(payload, midMarketPrice, true) return submitPlaceOrder(callback, payload, analyticsPayload) } @@ -1176,10 +1178,10 @@ class V4StateManagerAdaptor( val payload = cancelOrderPayload(orderId) val subaccount = stateMachine.state?.subaccount(subaccountNumber) val existingOrder = subaccount?.orders?.firstOrNull { it.id == orderId } - val analyticsPayload = ParsingHelper.merge( - analyticsUtils.formatCancelOrderPayload(payload), - if (existingOrder != null) analyticsUtils.formatOrder(existingOrder) else mapOf(), - )?.toIMap() + val analyticsPayload = analyticsUtils.cancelOrderAnalyticsPayload( + payload, + existingOrder + ) submitCancelOrder(orderId, callback, payload, analyticsPayload) } @@ -1187,18 +1189,26 @@ class V4StateManagerAdaptor( override fun commitTriggerOrders(callback: TransactionCallback): HumanReadableTriggerOrdersPayload { val payloads = triggerOrdersPayload() - payloads.cancelOrderPayloads.forEach { - val analyticsPayload = analyticsUtils.formatCancelOrderPayload(it, true) - submitCancelOrder(it.orderId, callback, it, analyticsPayload, true) + payloads.cancelOrderPayloads.forEach {payload -> + val subaccount = stateMachine.state?.subaccount(subaccountNumber) + val existingOrder = subaccount?.orders?.firstOrNull { it.id == payload.orderId } + val analyticsPayload = analyticsUtils.cancelOrderAnalyticsPayload( + payload, + existingOrder, + true + ) + submitCancelOrder(payload.orderId, callback, payload, analyticsPayload, true) } - payloads.placeOrderPayloads.forEach { - val analyticsPayload = analyticsUtils.formatPlaceOrderPayload( - it, + payloads.placeOrderPayloads.forEach { payload -> + val midMarketPrice = stateMachine.state?.marketOrderbook(payload.marketId)?.midPrice + val analyticsPayload = analyticsUtils.placeOrderAnalyticsPayload( + payload, + midMarketPrice, isClosePosition = false, fromSlTpDialog = true, ) - submitPlaceOrder(callback, it, analyticsPayload, true) + submitPlaceOrder(callback, payload, analyticsPayload, true) } if (payloads.cancelOrderPayloads.isEmpty() && payloads.placeOrderPayloads.isEmpty()) { diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/state/v2/supervisor/SubaccountSupervisor.kt b/src/commonMain/kotlin/exchange.dydx.abacus/state/v2/supervisor/SubaccountSupervisor.kt index d9ae30d8e..668e6a2e0 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/state/v2/supervisor/SubaccountSupervisor.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/state/v2/supervisor/SubaccountSupervisor.kt @@ -737,7 +737,8 @@ internal class SubaccountSupervisor( callback: TransactionCallback ): HumanReadablePlaceOrderPayload { val orderPayload = placeOrderPayload(currentHeight) - val analyticsPayload = analyticsUtils.formatPlaceOrderPayload(orderPayload, false) + val midMarketPrice = stateMachine.state?.marketOrderbook(orderPayload.marketId)?.midPrice + val analyticsPayload = analyticsUtils.placeOrderAnalyticsPayload(orderPayload, midMarketPrice, false) val isIsolatedMarginOrder = helper.parser.asInt(orderPayload.subaccountNumber) != subaccountNumber val transferPayload = @@ -751,14 +752,17 @@ internal class SubaccountSupervisor( callback: TransactionCallback ): HumanReadablePlaceOrderPayload { val payload = closePositionPayload(currentHeight) - val analyticsPayload = analyticsUtils.formatPlaceOrderPayload(payload, true) + val midMarketPrice = stateMachine.state?.marketOrderbook(payload.marketId)?.midPrice + val analyticsPayload = analyticsUtils.placeOrderAnalyticsPayload(payload, midMarketPrice, true) return submitPlaceOrder(callback, payload, analyticsPayload) } internal fun cancelOrder(orderId: String, callback: TransactionCallback): HumanReadableCancelOrderPayload { val payload = cancelOrderPayload(orderId) - val analyticsPayload = analyticsUtils.formatCancelOrderPayload(payload) + val subaccount = stateMachine.state?.subaccount(subaccountNumber) + val existingOrder = subaccount?.orders?.firstOrNull { it.id == orderId } + val analyticsPayload = analyticsUtils.cancelOrderAnalyticsPayload(payload, existingOrder) return submitCancelOrder(orderId, callback, payload, analyticsPayload) } @@ -770,13 +774,17 @@ internal class SubaccountSupervisor( val payloads = triggerOrdersPayload(currentHeight) payloads.cancelOrderPayloads.forEach { payload -> - val analyticsPayload = analyticsUtils.formatCancelOrderPayload(payload, true) + val subaccount = stateMachine.state?.subaccount(subaccountNumber) + val existingOrder = subaccount?.orders?.firstOrNull { it.id == payload.orderId } + val analyticsPayload = analyticsUtils.cancelOrderAnalyticsPayload(payload, existingOrder, true) submitCancelOrder(payload.orderId, callback, payload, analyticsPayload, true) } payloads.placeOrderPayloads.forEach { payload -> - val analyticsPayload = analyticsUtils.formatPlaceOrderPayload( + val midMarketPrice = stateMachine.state?.marketOrderbook(payload.marketId)?.midPrice + val analyticsPayload = analyticsUtils.placeOrderAnalyticsPayload( payload, + midMarketPrice, isClosePosition = false, fromSlTpDialog = true, ) diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/utils/AnalyticsUtils.kt b/src/commonMain/kotlin/exchange.dydx.abacus/utils/AnalyticsUtils.kt index afd2d41d5..b5c7496df 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/utils/AnalyticsUtils.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/utils/AnalyticsUtils.kt @@ -3,14 +3,37 @@ package exchange.dydx.abacus.utils import exchange.dydx.abacus.output.SubaccountOrder import exchange.dydx.abacus.state.manager.HumanReadableCancelOrderPayload import exchange.dydx.abacus.state.manager.HumanReadablePlaceOrderPayload +import kollections.toIMap class AnalyticsUtils { + /** + * Format Place Order Payload and add additional details for `TradePlaceOrder` Analytic Events + * @param payload HumanReadablePlaceOrderPayload + * @param midMarketPrice Double? + * @param isClosePosition Boolean? + * @param fromSlTpDialog Boolean? + */ + fun placeOrderAnalyticsPayload( + payload: HumanReadablePlaceOrderPayload, + midMarketPrice: Double?, + isClosePosition: Boolean? = false, + fromSlTpDialog: Boolean? = false, + ): IMap? { + return ParsingHelper.merge( + formatPlaceOrderPayload(payload, isClosePosition, fromSlTpDialog), + iMapOf( + "inferredTimeInForce" to calculateOrderTimeInForce(payload), + "midMarketPrice" to midMarketPrice + ) as IMap? + )?.toIMap() + } + /** * Format Place Order Payload for `TradePlaceOrder` Analytic Event * @param payload HumanReadablePlaceOrderPayload * @param isClosePosition Boolean */ - fun formatPlaceOrderPayload( + private fun formatPlaceOrderPayload( payload: HumanReadablePlaceOrderPayload, isClosePosition: Boolean? = false, fromSlTpDialog: Boolean? = false, @@ -31,7 +54,6 @@ class AnalyticsUtils { "size" to payload.size, "subaccountNumber" to payload.subaccountNumber, "timeInForce" to payload.timeInForce, - "inferredTimeInForce" to calculateOrderTimeInForce(payload), "triggerPrice" to payload.triggerPrice, "type" to payload.type, ) as IMap? @@ -66,11 +88,23 @@ class AnalyticsUtils { } /** - * Format Cancel Order Payload for `TradeCancelOrder` Analytic Event + * Format Cancel Order Payload and add order details for `TradeCancelOrder` Analytic Events * @param payload HumanReadableCancelOrderPayload + * @param existingOrder SubaccountOrder? * @param fromSlTpDialog Boolean */ - fun formatCancelOrderPayload( + fun cancelOrderAnalyticsPayload( + payload: HumanReadableCancelOrderPayload, + existingOrder: SubaccountOrder?, + fromSlTpDialog: Boolean? = false, + ): IMap? { + return ParsingHelper.merge( + formatCancelOrderPayload(payload, fromSlTpDialog), + if (existingOrder != null) formatOrder(existingOrder) else mapOf(), + )?.toIMap() + } + + private fun formatCancelOrderPayload( payload: HumanReadableCancelOrderPayload, fromSlTpDialog: Boolean? = false, ): IMap? { From 7bcdacbc997cdee6b278c2045b643deabfbc9f95 Mon Sep 17 00:00:00 2001 From: aforaleka Date: Thu, 11 Apr 2024 15:17:02 -0400 Subject: [PATCH 4/4] version --- build.gradle.kts | 2 +- .../state/manager/V4StateManagerAdaptor.kt | 6 +++--- .../kotlin/exchange.dydx.abacus/utils/AnalyticsUtils.kt | 6 +++--- v4_abacus.podspec | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 6a94e593a..53546a38f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -48,7 +48,7 @@ allprojects { } group = "exchange.dydx.abacus" -version = "1.6.40" +version = "1.6.41" repositories { google() diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/state/manager/V4StateManagerAdaptor.kt b/src/commonMain/kotlin/exchange.dydx.abacus/state/manager/V4StateManagerAdaptor.kt index 0c05cb198..4007e8014 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/state/manager/V4StateManagerAdaptor.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/state/manager/V4StateManagerAdaptor.kt @@ -1180,7 +1180,7 @@ class V4StateManagerAdaptor( val existingOrder = subaccount?.orders?.firstOrNull { it.id == orderId } val analyticsPayload = analyticsUtils.cancelOrderAnalyticsPayload( payload, - existingOrder + existingOrder, ) submitCancelOrder(orderId, callback, payload, analyticsPayload) @@ -1189,13 +1189,13 @@ class V4StateManagerAdaptor( override fun commitTriggerOrders(callback: TransactionCallback): HumanReadableTriggerOrdersPayload { val payloads = triggerOrdersPayload() - payloads.cancelOrderPayloads.forEach {payload -> + payloads.cancelOrderPayloads.forEach { payload -> val subaccount = stateMachine.state?.subaccount(subaccountNumber) val existingOrder = subaccount?.orders?.firstOrNull { it.id == payload.orderId } val analyticsPayload = analyticsUtils.cancelOrderAnalyticsPayload( payload, existingOrder, - true + true, ) submitCancelOrder(payload.orderId, callback, payload, analyticsPayload, true) } diff --git a/src/commonMain/kotlin/exchange.dydx.abacus/utils/AnalyticsUtils.kt b/src/commonMain/kotlin/exchange.dydx.abacus/utils/AnalyticsUtils.kt index b5c7496df..0e7227a1a 100644 --- a/src/commonMain/kotlin/exchange.dydx.abacus/utils/AnalyticsUtils.kt +++ b/src/commonMain/kotlin/exchange.dydx.abacus/utils/AnalyticsUtils.kt @@ -23,8 +23,8 @@ class AnalyticsUtils { formatPlaceOrderPayload(payload, isClosePosition, fromSlTpDialog), iMapOf( "inferredTimeInForce" to calculateOrderTimeInForce(payload), - "midMarketPrice" to midMarketPrice - ) as IMap? + "midMarketPrice" to midMarketPrice, + ) as IMap?, )?.toIMap() } @@ -97,7 +97,7 @@ class AnalyticsUtils { payload: HumanReadableCancelOrderPayload, existingOrder: SubaccountOrder?, fromSlTpDialog: Boolean? = false, - ): IMap? { + ): IMap? { return ParsingHelper.merge( formatCancelOrderPayload(payload, fromSlTpDialog), if (existingOrder != null) formatOrder(existingOrder) else mapOf(), diff --git a/v4_abacus.podspec b/v4_abacus.podspec index 9d763aa39..275771f2d 100644 --- a/v4_abacus.podspec +++ b/v4_abacus.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |spec| spec.name = 'v4_abacus' - spec.version = '1.6.40' + spec.version = '1.6.41' spec.homepage = 'https://github.com/dydxprotocol/v4-abacus' spec.source = { :http=> ''} spec.authors = ''