Skip to content

Commit

Permalink
analytics: add missing fields in place/cancel order events (#301)
Browse files Browse the repository at this point in the history
* add missing fields in place/cancel order events

* format

* add mid market price

* version
  • Loading branch information
aforaleka authored Apr 11, 2024
1 parent 3b13ccb commit 2cb681a
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 20 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ allprojects {
}

group = "exchange.dydx.abacus"
version = "1.6.40"
version = "1.6.41"

repositories {
google()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1162,37 +1162,53 @@ 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)
}

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 = analyticsUtils.cancelOrderAnalyticsPayload(
payload,
existingOrder,
)

submitCancelOrder(orderId, callback, payload, analyticsPayload)
}

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()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand All @@ -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)
}
Expand All @@ -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,
)
Expand Down
72 changes: 69 additions & 3 deletions src/commonMain/kotlin/exchange.dydx.abacus/utils/AnalyticsUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, Any>? {
return ParsingHelper.merge(
formatPlaceOrderPayload(payload, isClosePosition, fromSlTpDialog),
iMapOf(
"inferredTimeInForce" to calculateOrderTimeInForce(payload),
"midMarketPrice" to midMarketPrice,
) as IMap<String, Any>?,
)?.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,
Expand All @@ -37,11 +60,54 @@ class AnalyticsUtils {
}

/**
* Format Cancel Order Payload for `TradeCancelOrder` Analytic Event
* 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 and add order details for `TradeCancelOrder` Analytic Events
* @param payload HumanReadableCancelOrderPayload
* @param existingOrder SubaccountOrder?
* @param fromSlTpDialog Boolean
*/
fun formatCancelOrderPayload(payload: HumanReadableCancelOrderPayload, fromSlTpDialog: Boolean? = false,): IMap<String, Any>? {
fun cancelOrderAnalyticsPayload(
payload: HumanReadableCancelOrderPayload,
existingOrder: SubaccountOrder?,
fromSlTpDialog: Boolean? = false,
): IMap<String, Any>? {
return ParsingHelper.merge(
formatCancelOrderPayload(payload, fromSlTpDialog),
if (existingOrder != null) formatOrder(existingOrder) else mapOf(),
)?.toIMap()
}

private fun formatCancelOrderPayload(
payload: HumanReadableCancelOrderPayload,
fromSlTpDialog: Boolean? = false,
): IMap<String, Any>? {
return iMapOf(
"fromSlTpDialog" to fromSlTpDialog,
"subaccountNumber" to payload.subaccountNumber,
Expand Down
2 changes: 1 addition & 1 deletion v4_abacus.podspec
Original file line number Diff line number Diff line change
@@ -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 = ''
Expand Down

0 comments on commit 2cb681a

Please sign in to comment.