diff --git a/src/dist/cfg/log4j2.xml b/src/dist/cfg/log4j2.xml
index 226fec133..41c5c9222 100644
--- a/src/dist/cfg/log4j2.xml
+++ b/src/dist/cfg/log4j2.xml
@@ -466,6 +466,11 @@
# Multi Limit Order
+
+
+
+
diff --git a/src/main/kotlin/com/lykke/matching/engine/config/spring/InputQueueListenerConfig.kt b/src/main/kotlin/com/lykke/matching/engine/config/spring/InputQueueListenerConfig.kt
index 2bd64a62a..0e5e53402 100644
--- a/src/main/kotlin/com/lykke/matching/engine/config/spring/InputQueueListenerConfig.kt
+++ b/src/main/kotlin/com/lykke/matching/engine/config/spring/InputQueueListenerConfig.kt
@@ -5,6 +5,7 @@ import com.lykke.matching.engine.incoming.preprocessor.impl.CashInOutPreprocesso
import com.lykke.matching.engine.incoming.preprocessor.impl.CashTransferPreprocessor
import com.lykke.matching.engine.incoming.preprocessor.impl.LimitOrderCancelOperationPreprocessor
import com.lykke.matching.engine.incoming.preprocessor.impl.LimitOrderMassCancelOperationPreprocessor
+import com.lykke.matching.engine.incoming.preprocessor.impl.MultilimitOrderPreprocessor
import com.lykke.matching.engine.incoming.preprocessor.impl.SingleLimitOrderPreprocessor
import com.lykke.matching.engine.messages.MessageWrapper
import com.lykke.utils.logging.ThrottlingLogger
@@ -38,6 +39,17 @@ open class InputQueueListenerConfig {
"CashInOutInputQueueListener")
}
+ @Bean
+ open fun multilimitOrderListener(multilimitOrderInputQueue: BlockingQueue,
+ multilimitOrderPreprocessor: MultilimitOrderPreprocessor,
+ @Qualifier("multiLimitOrderPreProcessingLogger")
+ logger: ThrottlingLogger): InputQueueListener {
+ return InputQueueListener(multilimitOrderInputQueue,
+ multilimitOrderPreprocessor,
+ logger,
+ "MultilimitOrderListener")
+ }
+
@Bean
open fun limitOrderCancelInputQueueListener(limitOrderCancelInputQueue: BlockingQueue,
limitOrderCancelOperationPreprocessor: LimitOrderCancelOperationPreprocessor,
diff --git a/src/main/kotlin/com/lykke/matching/engine/config/spring/LoggerConfig.kt b/src/main/kotlin/com/lykke/matching/engine/config/spring/LoggerConfig.kt
index 1ba35d650..98fd22dab 100644
--- a/src/main/kotlin/com/lykke/matching/engine/config/spring/LoggerConfig.kt
+++ b/src/main/kotlin/com/lykke/matching/engine/config/spring/LoggerConfig.kt
@@ -34,6 +34,11 @@ open class LoggerConfig {
return LoggerFactory.getLogger("AppStarter")
}
+ @Bean
+ open fun multiLimitOrderPreProcessingLogger(): ThrottlingLogger {
+ return ThrottlingLogger.getLogger("MultiLimitOrderPreProcessing")
+ }
+
@Bean
open fun singleLimitOrderPreProcessingLogger(): ThrottlingLogger {
return ThrottlingLogger.getLogger("SingleLimitOrderPreProcessing")
diff --git a/src/main/kotlin/com/lykke/matching/engine/config/spring/QueueConfig.kt b/src/main/kotlin/com/lykke/matching/engine/config/spring/QueueConfig.kt
index 3d46124a5..b129b6cdb 100644
--- a/src/main/kotlin/com/lykke/matching/engine/config/spring/QueueConfig.kt
+++ b/src/main/kotlin/com/lykke/matching/engine/config/spring/QueueConfig.kt
@@ -97,6 +97,12 @@ open class QueueConfig {
return LinkedBlockingQueue()
}
+ @Bean
+ @InputQueue
+ open fun multilimitOrderInputQueue(): BlockingQueue {
+ return LinkedBlockingQueue()
+ }
+
@Bean
@InputQueue
open fun cashInOutInputQueue(): BlockingQueue {
diff --git a/src/main/kotlin/com/lykke/matching/engine/daos/LimitOrder.kt b/src/main/kotlin/com/lykke/matching/engine/daos/LimitOrder.kt
index 331e7ada3..c586d0556 100644
--- a/src/main/kotlin/com/lykke/matching/engine/daos/LimitOrder.kt
+++ b/src/main/kotlin/com/lykke/matching/engine/daos/LimitOrder.kt
@@ -4,6 +4,7 @@ import com.lykke.matching.engine.daos.fee.v2.NewLimitOrderFeeInstruction
import com.lykke.matching.engine.daos.order.OrderTimeInForce
import com.lykke.matching.engine.daos.order.LimitOrderType
import com.lykke.matching.engine.daos.v2.LimitOrderFeeInstruction
+import com.lykke.matching.engine.utils.NumberUtils
import org.nustaq.serialization.annotations.Version
import java.io.Serializable
import java.math.BigDecimal
@@ -104,4 +105,35 @@ class LimitOrder(id: String,
fun isExpired(date: Date): Boolean {
return hasExpiryTime() && !expiryTime!!.after(date)
}
+
+ override fun toString(): String {
+ return "id: $externalId" +
+ if(previousExternalId != null) ", previousExternalId: $previousExternalId" else "" +
+ if(parentOrderExternalId != null) ", parentOrderExternalId: $previousExternalId" else "" +
+ if(childOrderExternalId != null) ", childOrderExternalId: $childOrderExternalId" else "" +
+
+ ", type: $type" +
+ ", client: $clientId" +
+ ", assetPair: $assetPairId" +
+ ", status: $status" +
+
+ ", volume: ${NumberUtils.roundForPrint(volume)}" +
+ (if (reservedLimitVolume != null) ", reservedLimitVolume: $reservedLimitVolume" else "") +
+ ", remainingVolume: $remainingVolume" +
+ ", price: ${NumberUtils.roundForPrint(price)}" +
+ (if (lowerLimitPrice != null) ", lowerLimitPrice: ${NumberUtils.roundForPrint(lowerLimitPrice)}" else "") +
+ (if (lowerPrice != null) ", lowerPrice: ${NumberUtils.roundForPrint(lowerPrice)}" else "") +
+ (if (upperLimitPrice != null) ", upperLimitPrice: ${NumberUtils.roundForPrint(upperLimitPrice)}" else "") +
+ (if (upperPrice != null) ", upperPrice: ${NumberUtils.roundForPrint(upperPrice)}" else "") +
+
+ ", createdAt: $createdAt" +
+ (if (statusDate != null) ", statusDate: $statusDate" else "") +
+ (if (registered != null) ", registered: $registered" else "") +
+ (if (lastMatchTime != null) ", lastMatchTime: $lastMatchTime" else "") +
+
+ ", fee: $fee" +
+ ", fees: $fees" +
+ (if (timeInForce != null) ", timeInForce: $timeInForce" else "") +
+ (if (expiryTime != null) ", expiryTime: $expiryTime" else "")
+ }
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/lykke/matching/engine/daos/context/LimitOrderMassCancelOperationContext.kt b/src/main/kotlin/com/lykke/matching/engine/daos/context/LimitOrderMassCancelOperationContext.kt
index fbdc39d23..4d4340943 100644
--- a/src/main/kotlin/com/lykke/matching/engine/daos/context/LimitOrderMassCancelOperationContext.kt
+++ b/src/main/kotlin/com/lykke/matching/engine/daos/context/LimitOrderMassCancelOperationContext.kt
@@ -3,7 +3,7 @@ package com.lykke.matching.engine.daos.context
import com.lykke.matching.engine.deduplication.ProcessedMessage
import com.lykke.matching.engine.messages.MessageType
-class LimitOrderMassCancelOperationContext(val uid: String,
+data class LimitOrderMassCancelOperationContext(val uid: String,
val messageId: String,
val clientId: String?,
val processedMessage: ProcessedMessage,
diff --git a/src/main/kotlin/com/lykke/matching/engine/daos/context/MultilimitOrderContext.kt b/src/main/kotlin/com/lykke/matching/engine/daos/context/MultilimitOrderContext.kt
new file mode 100644
index 000000000..49d21ff82
--- /dev/null
+++ b/src/main/kotlin/com/lykke/matching/engine/daos/context/MultilimitOrderContext.kt
@@ -0,0 +1,13 @@
+package com.lykke.matching.engine.daos.context
+
+import com.lykke.matching.engine.daos.Asset
+import com.lykke.matching.engine.daos.AssetPair
+import com.lykke.matching.engine.daos.MultiLimitOrder
+import com.lykke.matching.engine.services.validators.MultilimitOrderValidationResult
+
+data class MultilimitOrderContext(val assetPair: AssetPair?,
+ val baseAsset: Asset?,
+ val quotingAsset: Asset?,
+ val isTrustedClient: Boolean,
+ val multiLimitOrder: MultiLimitOrder,
+ var multilimitOrderValidationResult: MultilimitOrderValidationResult? = null)
diff --git a/src/main/kotlin/com/lykke/matching/engine/daos/context/SingleLimitOrderContext.kt b/src/main/kotlin/com/lykke/matching/engine/daos/context/SingleLimitOrderContext.kt
index 52a1e683d..f0b534953 100644
--- a/src/main/kotlin/com/lykke/matching/engine/daos/context/SingleLimitOrderContext.kt
+++ b/src/main/kotlin/com/lykke/matching/engine/daos/context/SingleLimitOrderContext.kt
@@ -5,9 +5,8 @@ import com.lykke.matching.engine.daos.AssetPair
import com.lykke.matching.engine.daos.LimitOrder
import com.lykke.matching.engine.deduplication.ProcessedMessage
import com.lykke.matching.engine.services.validators.impl.OrderValidationResult
-import com.lykke.matching.engine.utils.NumberUtils
-class SingleLimitOrderContext(val messageId: String,
+data class SingleLimitOrderContext(val messageId: String,
val limitOrder: LimitOrder,
val isCancelOrders: Boolean,
val assetPair: AssetPair?,
@@ -30,25 +29,10 @@ class SingleLimitOrderContext(val messageId: String,
builder.processedMessage)
override fun toString(): String {
- val order = this.limitOrder
-
- return "id: ${limitOrder.externalId}" +
- ", messageId: $messageId" +
- ", type: ${order.type}" +
- ", client: ${order.clientId}" +
+ return ", messageId: $messageId" +
", isTrustedClient: $isTrustedClient" +
- ", assetPair: ${order.assetPairId}" +
- ", volume: ${NumberUtils.roundForPrint(order.volume)}" +
- ", price: ${NumberUtils.roundForPrint(order.price)}" +
- (if (order.lowerLimitPrice != null) ", lowerLimitPrice: ${NumberUtils.roundForPrint(order.lowerLimitPrice)}" else "") +
- (if (order.lowerPrice != null) ", lowerPrice: ${NumberUtils.roundForPrint(order.lowerPrice)}" else "") +
- (if (order.upperLimitPrice != null) ", upperLimitPrice: ${NumberUtils.roundForPrint(order.upperLimitPrice)}" else "") +
- (if (order.upperPrice != null) ", upperPrice: ${NumberUtils.roundForPrint(order.upperPrice)}" else "") +
", cancel: $isCancelOrders" +
- ", fee: ${order.fee}" +
- ", fees: ${order.fees}" +
- (if (order.timeInForce != null) ", timeInForce=${order.timeInForce}" else "") +
- (if (order.expiryTime != null) ", expiryTime=${order.expiryTime}" else "")
+ ", limitOrder: $limitOrder"
}
class Builder {
diff --git a/src/main/kotlin/com/lykke/matching/engine/incoming/MessageRouter.kt b/src/main/kotlin/com/lykke/matching/engine/incoming/MessageRouter.kt
index e5b7708a1..cd637444c 100644
--- a/src/main/kotlin/com/lykke/matching/engine/incoming/MessageRouter.kt
+++ b/src/main/kotlin/com/lykke/matching/engine/incoming/MessageRouter.kt
@@ -12,6 +12,7 @@ class MessageRouter(
private val cashTransferInputQueue: BlockingQueue,
private val limitOrderCancelInputQueue: BlockingQueue,
private val limitOrderMassCancelInputQueue: BlockingQueue,
+ private val multilimitOrderInputQueue: BlockingQueue,
val preProcessedMessageQueue: BlockingQueue
) {
fun process(wrapper: MessageWrapper) {
@@ -21,6 +22,7 @@ class MessageRouter(
MessageType.LIMIT_ORDER.type -> limitOrderInputQueue.put(wrapper)
MessageType.LIMIT_ORDER_CANCEL.type -> limitOrderCancelInputQueue.put(wrapper)
MessageType.LIMIT_ORDER_MASS_CANCEL.type -> limitOrderMassCancelInputQueue.put(wrapper)
+ MessageType.MULTI_LIMIT_ORDER.type -> multilimitOrderInputQueue.put(wrapper)
else -> preProcessedMessageQueue.put(wrapper)
}
diff --git a/src/main/kotlin/com/lykke/matching/engine/incoming/listener/InputQueueListener.kt b/src/main/kotlin/com/lykke/matching/engine/incoming/listener/InputQueueListener.kt
index 9e932ce53..118ba2ed0 100644
--- a/src/main/kotlin/com/lykke/matching/engine/incoming/listener/InputQueueListener.kt
+++ b/src/main/kotlin/com/lykke/matching/engine/incoming/listener/InputQueueListener.kt
@@ -6,6 +6,7 @@ import com.lykke.utils.logging.MetricsLogger
import com.lykke.utils.logging.ThrottlingLogger
import java.util.concurrent.BlockingQueue
import javax.annotation.PostConstruct
+import javax.annotation.PreDestroy
class InputQueueListener(private val inputQueue: BlockingQueue,
private val preProcessor: MessagePreprocessor,
@@ -20,14 +21,34 @@ class InputQueueListener(private val inputQueue: BlockingQueue,
@PostConstruct
fun init() = start()
+ @PreDestroy
+ fun shutdown() {
+ this.interrupt()
+ }
+
override fun run() {
while (true) {
try {
- preProcessor.preProcess(inputQueue.take())
+ if(!process()) {
+ return
+ }
} catch (e: Exception) {
logger.error(ERROR_MESSAGE, e)
METRICS_LOGGER.logError(ERROR_MESSAGE, e)
}
}
}
+
+
+ private fun process(): Boolean {
+ try {
+ val messageWrapper = inputQueue.take()
+ preProcessor.preProcess(messageWrapper)
+ } catch(e: InterruptedException) {
+ this.interrupt()
+ return false
+ }
+
+ return true
+ }
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/lykke/matching/engine/incoming/parsers/data/MultilimitOrderParsedData.kt b/src/main/kotlin/com/lykke/matching/engine/incoming/parsers/data/MultilimitOrderParsedData.kt
new file mode 100644
index 000000000..126f19d99
--- /dev/null
+++ b/src/main/kotlin/com/lykke/matching/engine/incoming/parsers/data/MultilimitOrderParsedData.kt
@@ -0,0 +1,5 @@
+package com.lykke.matching.engine.incoming.parsers.data
+
+import com.lykke.matching.engine.messages.MessageWrapper
+
+class MultilimitOrderParsedData(messageWrapper: MessageWrapper, val inputAssetPairId: String) : ParsedData(messageWrapper)
\ No newline at end of file
diff --git a/src/main/kotlin/com/lykke/matching/engine/incoming/parsers/impl/MultilimitOrderContextParser.kt b/src/main/kotlin/com/lykke/matching/engine/incoming/parsers/impl/MultilimitOrderContextParser.kt
new file mode 100644
index 000000000..ad5225189
--- /dev/null
+++ b/src/main/kotlin/com/lykke/matching/engine/incoming/parsers/impl/MultilimitOrderContextParser.kt
@@ -0,0 +1,173 @@
+package com.lykke.matching.engine.incoming.parsers.impl
+
+import com.lykke.matching.engine.daos.LimitOrder
+import com.lykke.matching.engine.daos.MultiLimitOrder
+import com.lykke.matching.engine.daos.context.MultilimitOrderContext
+import com.lykke.matching.engine.daos.fee.v2.NewLimitOrderFeeInstruction
+import com.lykke.matching.engine.daos.order.LimitOrderType
+import com.lykke.matching.engine.daos.order.OrderTimeInForce
+import com.lykke.matching.engine.daos.v2.LimitOrderFeeInstruction
+import com.lykke.matching.engine.deduplication.ProcessedMessage
+import com.lykke.matching.engine.fee.listOfLimitOrderFee
+import com.lykke.matching.engine.holders.ApplicationSettingsHolder
+import com.lykke.matching.engine.holders.AssetsHolder
+import com.lykke.matching.engine.holders.AssetsPairsHolder
+import com.lykke.matching.engine.holders.UUIDHolder
+import com.lykke.matching.engine.incoming.parsers.ContextParser
+import com.lykke.matching.engine.incoming.parsers.data.MultilimitOrderParsedData
+import com.lykke.matching.engine.messages.MessageWrapper
+import com.lykke.matching.engine.messages.ProtocolMessages
+import com.lykke.matching.engine.order.OrderCancelMode
+import com.lykke.matching.engine.order.OrderStatus
+import com.lykke.utils.logging.ThrottlingLogger
+import org.springframework.beans.factory.annotation.Qualifier
+import org.springframework.stereotype.Component
+import java.math.BigDecimal
+import java.util.*
+
+@Component
+class MultilimitOrderContextParser(
+ @Qualifier("multiLimitOrderPreProcessingLogger")
+ val logger: ThrottlingLogger,
+ val applicationSettingsHolder: ApplicationSettingsHolder,
+ val assertPairsHolder: AssetsPairsHolder,
+ val assetsHolder: AssetsHolder,
+ val uuid: UUIDHolder) : ContextParser {
+ override fun parse(messageWrapper: MessageWrapper): MultilimitOrderParsedData {
+ val message = parseMultiLimitOrder(messageWrapper.byteArray)
+ val trustedClient = applicationSettingsHolder.isTrustedClient(message.clientId)
+ messageWrapper.messageId = if (message.hasMessageId()) message.messageId else message.uid.toString()
+ messageWrapper.context = getContext(messageWrapper.messageId!!, trustedClient, message)
+ messageWrapper.timestamp = message.timestamp
+ messageWrapper.parsedMessage = message
+ messageWrapper.id = message.uid
+ messageWrapper.processedMessage = if (trustedClient) {
+ null
+ } else {
+ ProcessedMessage(messageWrapper.type, messageWrapper.timestamp!!, messageWrapper.messageId!!)
+ }
+
+ return MultilimitOrderParsedData(messageWrapper, message.assetPairId)
+ }
+
+ private fun parseMultiLimitOrder(array: ByteArray): ProtocolMessages.MultiLimitOrder {
+ return ProtocolMessages.MultiLimitOrder.parseFrom(array)
+ }
+
+ private fun getContext(messageId: String,
+ trustedClient: Boolean,
+ message: ProtocolMessages.MultiLimitOrder): MultilimitOrderContext {
+ val assetPair = assertPairsHolder.getAssetPairAllowNulls(message.assetPairId)
+ val baseAsset = assetPair?.let {
+ assetsHolder.getAssetAllowNulls(it.baseAssetId)
+ }
+
+ val quotingAsset = assetPair?.let {
+ assetsHolder.getAssetAllowNulls(it.quotingAssetId)
+ }
+
+ return MultilimitOrderContext(assetPair,
+ baseAsset,
+ quotingAsset,
+ trustedClient,
+ readMultiLimitOrder(messageId, message, trustedClient))
+ }
+
+ private fun readMultiLimitOrder(messageId: String,
+ message: ProtocolMessages.MultiLimitOrder,
+ isTrustedClient: Boolean): MultiLimitOrder {
+ logger.debug("Got ${if (!isTrustedClient) "client " else ""}multi limit order id: ${message.uid}, " +
+ (if (messageId != message.uid) "messageId: $messageId, " else "") +
+ "client ${message.clientId}, " +
+ "assetPair: ${message.assetPairId}, " +
+ "ordersCount: ${message.ordersCount}, " +
+ (if (message.hasCancelAllPreviousLimitOrders()) "cancelPrevious: ${message.cancelAllPreviousLimitOrders}, " else "") +
+ (if (message.hasCancelMode()) "cancelMode: ${message.cancelMode}" else ""))
+
+ val clientId = message.clientId
+ val messageUid = message.uid
+ val assetPairId = message.assetPairId
+ val cancelAllPreviousLimitOrders = message.cancelAllPreviousLimitOrders
+ val cancelMode = if (message.hasCancelMode()) OrderCancelMode.getByExternalId(message.cancelMode) else OrderCancelMode.NOT_EMPTY_SIDE
+ val now = Date()
+ var cancelBuySide = cancelMode == OrderCancelMode.BUY_SIDE || cancelMode == OrderCancelMode.BOTH_SIDES
+ var cancelSellSide = cancelMode == OrderCancelMode.SELL_SIDE || cancelMode == OrderCancelMode.BOTH_SIDES
+
+ val buyReplacements = mutableMapOf()
+ val sellReplacements = mutableMapOf()
+ val orders = ArrayList()
+ message.ordersList.forEach { currentOrder ->
+
+ val type = if (currentOrder.hasType()) LimitOrderType.getByExternalId(currentOrder.type) else LimitOrderType.LIMIT
+ val status = when (type) {
+ LimitOrderType.LIMIT -> OrderStatus.InOrderBook
+ LimitOrderType.STOP_LIMIT -> OrderStatus.Pending
+ }
+ val price = if (currentOrder.hasPrice()) BigDecimal.valueOf(currentOrder.price) else BigDecimal.ZERO
+ val lowerLimitPrice = if (currentOrder.hasLowerLimitPrice()) BigDecimal.valueOf(currentOrder.lowerLimitPrice) else null
+ val lowerPrice = if (currentOrder.hasLowerPrice()) BigDecimal.valueOf(currentOrder.lowerPrice) else null
+ val upperLimitPrice = if (currentOrder.hasUpperLimitPrice()) BigDecimal.valueOf(currentOrder.upperLimitPrice) else null
+ val upperPrice = if (currentOrder.hasUpperPrice()) BigDecimal.valueOf(currentOrder.upperPrice) else null
+ val feeInstruction = if (currentOrder.hasFee()) LimitOrderFeeInstruction.create(currentOrder.fee) else null
+ val feeInstructions = NewLimitOrderFeeInstruction.create(currentOrder.feesList)
+ val previousExternalId = if (currentOrder.hasOldUid()) currentOrder.oldUid else null
+
+ val order = LimitOrder(uuid.getNextValue(),
+ currentOrder.uid,
+ message.assetPairId,
+ message.clientId,
+ BigDecimal.valueOf(currentOrder.volume),
+ price,
+ status.name,
+ now,
+ Date(message.timestamp),
+ now,
+ BigDecimal.valueOf(currentOrder.volume),
+ null,
+ fee = feeInstruction,
+ fees = listOfLimitOrderFee(feeInstruction, feeInstructions),
+ type = type,
+ lowerLimitPrice = lowerLimitPrice,
+ lowerPrice = lowerPrice,
+ upperLimitPrice = upperLimitPrice,
+ upperPrice = upperPrice,
+ previousExternalId = previousExternalId,
+ timeInForce = if (currentOrder.hasTimeInForce()) OrderTimeInForce.getByExternalId(currentOrder.timeInForce) else null,
+ expiryTime = if (currentOrder.hasExpiryTime()) Date(currentOrder.expiryTime) else null,
+ parentOrderExternalId = null,
+ childOrderExternalId = null
+ )
+
+ if (!isTrustedClient) {
+ logger.debug("Incoming limit order (message id: $messageId): $order")
+ }
+
+ orders.add(order)
+ previousExternalId?.let {
+ (if (order.isBuySide()) buyReplacements else sellReplacements)[it] = order
+ }
+
+ if (cancelAllPreviousLimitOrders && cancelMode == OrderCancelMode.NOT_EMPTY_SIDE) {
+ if (isBuyOrder(currentOrder)) {
+ cancelBuySide = true
+ } else {
+ cancelSellSide = true
+ }
+ }
+ }
+
+ return MultiLimitOrder(messageUid,
+ clientId,
+ assetPairId,
+ orders,
+ cancelAllPreviousLimitOrders,
+ cancelBuySide,
+ cancelSellSide,
+ cancelMode,
+ buyReplacements,
+ sellReplacements)
+ }
+
+ private fun isBuyOrder(currentOrder: ProtocolMessages.MultiLimitOrder.Order) =
+ currentOrder.volume > 0
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/lykke/matching/engine/incoming/preprocessor/impl/MultilimitOrderPreprocessor.kt b/src/main/kotlin/com/lykke/matching/engine/incoming/preprocessor/impl/MultilimitOrderPreprocessor.kt
new file mode 100644
index 000000000..502ec5758
--- /dev/null
+++ b/src/main/kotlin/com/lykke/matching/engine/incoming/preprocessor/impl/MultilimitOrderPreprocessor.kt
@@ -0,0 +1,118 @@
+package com.lykke.matching.engine.incoming.preprocessor.impl
+
+import com.lykke.matching.engine.daos.context.MultilimitOrderContext
+import com.lykke.matching.engine.daos.order.LimitOrderType
+import com.lykke.matching.engine.holders.MessageProcessingStatusHolder
+import com.lykke.matching.engine.incoming.parsers.ContextParser
+import com.lykke.matching.engine.incoming.parsers.data.MultilimitOrderParsedData
+import com.lykke.matching.engine.incoming.preprocessor.AbstractMessagePreprocessor
+import com.lykke.matching.engine.messages.MessageStatus
+import com.lykke.matching.engine.messages.MessageWrapper
+import com.lykke.matching.engine.messages.ProtocolMessages
+import com.lykke.matching.engine.services.validators.MultilimitOrderValidationResult
+import com.lykke.matching.engine.services.validators.common.OrderValidationUtils
+import com.lykke.matching.engine.services.validators.impl.OrderValidationException
+import com.lykke.matching.engine.services.validators.impl.OrderValidationResult
+import com.lykke.matching.engine.services.validators.input.LimitOrderInputValidator
+import com.lykke.matching.engine.services.validators.input.OrderInputValidator
+import com.lykke.matching.engine.utils.order.MessageStatusUtils
+import com.lykke.utils.logging.ThrottlingLogger
+import org.springframework.beans.factory.annotation.Qualifier
+import org.springframework.stereotype.Component
+import java.util.*
+import java.util.concurrent.BlockingQueue
+import java.util.stream.Stream
+
+@Component
+class MultilimitOrderPreprocessor(private val messageProcessingStatusHolder: MessageProcessingStatusHolder,
+ private val limitOrderInputValidator: LimitOrderInputValidator,
+ private val orderInputValidator: OrderInputValidator,
+ multilimitOrderContextParser: ContextParser,
+ preProcessedMessageQueue: BlockingQueue,
+ @Qualifier("multiLimitOrderPreProcessingLogger")
+ private val logger: ThrottlingLogger) : AbstractMessagePreprocessor(multilimitOrderContextParser,
+ messageProcessingStatusHolder, preProcessedMessageQueue, logger) {
+ override fun preProcessParsedData(parsedData: MultilimitOrderParsedData): Boolean {
+ val context = parsedData.messageWrapper.context as MultilimitOrderContext
+ if (messageProcessingStatusHolder.isTradeDisabled(context.assetPair)) {
+ writeResponse(parsedData.messageWrapper,
+ context.multiLimitOrder.assetPairId,
+ MessageStatus.MESSAGE_PROCESSING_DISABLED)
+ return false
+ }
+
+ context.multilimitOrderValidationResult = getValidationResult(parsedData)
+ return processValidationResult(parsedData)
+ }
+
+ fun writeResponse(messageWrapper: MessageWrapper, assetPairId: String, status: MessageStatus, message: String? = null) {
+ messageWrapper.writeMultiLimitOrderResponse(ProtocolMessages.MultiLimitOrderResponse.newBuilder()
+ .setStatus(status.type)
+ .setAssetPairId(assetPairId))
+ }
+
+ private fun processValidationResult(parsedData: MultilimitOrderParsedData): Boolean {
+ val context = parsedData.messageWrapper.context as MultilimitOrderContext
+
+ val multilimitOrderValidationResult = context.multilimitOrderValidationResult
+ val fatallyInvalidValidationResult = Stream.concat(Stream.of(multilimitOrderValidationResult!!.globalValidationResult),
+ multilimitOrderValidationResult.inputValidationResultByOrderId?.values?.stream()
+ ?: Stream.empty())
+ .filter { it.isFatalInvalid }
+ .findFirst()
+
+ if (fatallyInvalidValidationResult.isPresent) {
+ logger.error("Fatal validation error occurred, ${fatallyInvalidValidationResult.get().message} " +
+ "Error details: $context")
+ writeResponse(parsedData.messageWrapper,
+ context.multiLimitOrder.assetPairId,
+ MessageStatusUtils.toMessageStatus(fatallyInvalidValidationResult.get().status!!),
+ fatallyInvalidValidationResult.get().message)
+ return false
+ }
+
+ //if global non fatal validation occurs - all orders should has this validation error
+ if (!multilimitOrderValidationResult.globalValidationResult.isValid) {
+ val validationResultByOrderId = HashMap()
+
+ context.multiLimitOrder.orders.forEach {
+ validationResultByOrderId[it.id] = multilimitOrderValidationResult.globalValidationResult
+ }
+
+ context.multilimitOrderValidationResult = MultilimitOrderValidationResult(multilimitOrderValidationResult.globalValidationResult, validationResultByOrderId)
+ }
+
+ return true
+ }
+
+ private fun getValidationResult(parsedData: MultilimitOrderParsedData): MultilimitOrderValidationResult {
+ val context = parsedData.messageWrapper.context as MultilimitOrderContext
+ val orderValidationResultByOrderId = HashMap()
+
+ try {
+ orderInputValidator.validateAsset(context.assetPair, parsedData.inputAssetPairId)
+ } catch (e: OrderValidationException) {
+ val fatalInvalid = OrderValidationUtils.isFatalInvalid(e)
+ return MultilimitOrderValidationResult(OrderValidationResult(false, fatalInvalid, e.message, e.orderStatus))
+ }
+
+
+ for (order in context.multiLimitOrder.orders) {
+ try {
+ when (order.type) {
+ LimitOrderType.LIMIT -> limitOrderInputValidator.validateLimitOrder(context.isTrustedClient,
+ order,
+ context.assetPair,
+ null,
+ context.baseAsset)
+ LimitOrderType.STOP_LIMIT -> limitOrderInputValidator.validateStopOrder(order, context.assetPair, order.assetPairId, context.baseAsset)
+ }
+ } catch (e: OrderValidationException) {
+ val fatalInvalid = OrderValidationUtils.isFatalInvalid(e)
+ orderValidationResultByOrderId[order.id] = OrderValidationResult(false, fatalInvalid, e.message, e.orderStatus)
+ }
+ }
+
+ return MultilimitOrderValidationResult(OrderValidationResult(true), orderValidationResultByOrderId)
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/lykke/matching/engine/incoming/preprocessor/impl/SingleLimitOrderPreprocessor.kt b/src/main/kotlin/com/lykke/matching/engine/incoming/preprocessor/impl/SingleLimitOrderPreprocessor.kt
index f80a4f8ff..3eba926fd 100644
--- a/src/main/kotlin/com/lykke/matching/engine/incoming/preprocessor/impl/SingleLimitOrderPreprocessor.kt
+++ b/src/main/kotlin/com/lykke/matching/engine/incoming/preprocessor/impl/SingleLimitOrderPreprocessor.kt
@@ -8,7 +8,7 @@ import com.lykke.matching.engine.incoming.parsers.impl.SingleLimitOrderContextPa
import com.lykke.matching.engine.incoming.preprocessor.AbstractMessagePreprocessor
import com.lykke.matching.engine.messages.MessageStatus
import com.lykke.matching.engine.messages.MessageWrapper
-import com.lykke.matching.engine.order.OrderStatus
+import com.lykke.matching.engine.services.validators.common.OrderValidationUtils
import com.lykke.matching.engine.services.validators.impl.OrderValidationException
import com.lykke.matching.engine.services.validators.impl.OrderValidationResult
import com.lykke.matching.engine.services.validators.input.LimitOrderInputValidator
@@ -64,13 +64,9 @@ class SingleLimitOrderPreprocessor(singleLimitOrderContextParser: SingleLimitOrd
LimitOrderType.STOP_LIMIT -> limitOrderInputValidator.validateStopOrder(singleLimitOrderParsedData)
}
} catch (e: OrderValidationException) {
- return OrderValidationResult(false, isFatalInvalid(e), e.message, e.orderStatus)
+ return OrderValidationResult(false, OrderValidationUtils.isFatalInvalid(e), e.message, e.orderStatus)
}
return OrderValidationResult(true)
}
-
- private fun isFatalInvalid(validationException: OrderValidationException): Boolean {
- return validationException.orderStatus == OrderStatus.UnknownAsset
- }
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/lykke/matching/engine/order/process/LimitOrderProcessor.kt b/src/main/kotlin/com/lykke/matching/engine/order/process/LimitOrderProcessor.kt
index 033edf862..2f2c522d6 100644
--- a/src/main/kotlin/com/lykke/matching/engine/order/process/LimitOrderProcessor.kt
+++ b/src/main/kotlin/com/lykke/matching/engine/order/process/LimitOrderProcessor.kt
@@ -16,14 +16,12 @@ import com.lykke.matching.engine.outgoing.messages.v2.enums.TradeRole
import com.lykke.matching.engine.services.validators.business.LimitOrderBusinessValidator
import com.lykke.matching.engine.services.validators.impl.OrderValidationException
import com.lykke.matching.engine.services.validators.impl.OrderValidationResult
-import com.lykke.matching.engine.services.validators.input.LimitOrderInputValidator
import com.lykke.matching.engine.utils.NumberUtils
import org.springframework.stereotype.Component
import java.math.BigDecimal
@Component
-class LimitOrderProcessor(private val limitOrderInputValidator: LimitOrderInputValidator,
- private val limitOrderBusinessValidator: LimitOrderBusinessValidator,
+class LimitOrderProcessor(private val limitOrderBusinessValidator: LimitOrderBusinessValidator,
private val applicationSettingsHolder: ApplicationSettingsHolder,
private val matchingEngine: MatchingEngine,
private val matchingResultHandlingHelper: MatchingResultHandlingHelper) : OrderProcessor {
@@ -45,25 +43,7 @@ class LimitOrderProcessor(private val limitOrderInputValidator: LimitOrderInputV
if (preProcessorValidationResult != null && !preProcessorValidationResult.isValid) {
return preProcessorValidationResult
}
- // fixme: input validator will be moved from the business thread after multilimit order context release
- val inputValidationResult = performInputValidation(orderContext)
- return if (!inputValidationResult.isValid) inputValidationResult else performBusinessValidation(orderContext)
- }
-
- private fun performInputValidation(orderContext: LimitOrderExecutionContext): OrderValidationResult {
- val order = orderContext.order
- val assetPair = orderContext.executionContext.assetPairsById[order.assetPairId]
- val baseAsset = assetPair?.let { orderContext.executionContext.assetsById[assetPair.baseAssetId] }
- try {
- limitOrderInputValidator.validateLimitOrder(applicationSettingsHolder.isTrustedClient(order.clientId),
- order,
- assetPair,
- order.assetPairId,
- baseAsset)
- } catch (e: OrderValidationException) {
- return OrderValidationResult(false, false, e.message, e.orderStatus)
- }
- return OrderValidationResult(true)
+ return performBusinessValidation(orderContext)
}
private fun performBusinessValidation(orderContext: LimitOrderExecutionContext): OrderValidationResult {
diff --git a/src/main/kotlin/com/lykke/matching/engine/order/process/StopLimitOrderProcessor.kt b/src/main/kotlin/com/lykke/matching/engine/order/process/StopLimitOrderProcessor.kt
index 0b558cc54..4d97a4abd 100644
--- a/src/main/kotlin/com/lykke/matching/engine/order/process/StopLimitOrderProcessor.kt
+++ b/src/main/kotlin/com/lykke/matching/engine/order/process/StopLimitOrderProcessor.kt
@@ -13,14 +13,12 @@ import com.lykke.matching.engine.outgoing.messages.LimitOrderWithTrades
import com.lykke.matching.engine.services.validators.business.StopOrderBusinessValidator
import com.lykke.matching.engine.services.validators.impl.OrderValidationException
import com.lykke.matching.engine.services.validators.impl.OrderValidationResult
-import com.lykke.matching.engine.services.validators.input.LimitOrderInputValidator
import com.lykke.matching.engine.utils.NumberUtils
import org.springframework.stereotype.Component
import java.math.BigDecimal
@Component
-class StopLimitOrderProcessor(private val limitOrderInputValidator: LimitOrderInputValidator,
- private val stopOrderBusinessValidator: StopOrderBusinessValidator,
+class StopLimitOrderProcessor(private val stopOrderBusinessValidator: StopOrderBusinessValidator,
private val applicationSettingsHolder: ApplicationSettingsHolder,
private val limitOrderProcessor: LimitOrderProcessor,
private val uuidHolder: UUIDHolder) : OrderProcessor {
@@ -41,18 +39,7 @@ class StopLimitOrderProcessor(private val limitOrderInputValidator: LimitOrderIn
if (preProcessorValidationResult != null && !preProcessorValidationResult.isValid) {
return preProcessorValidationResult
}
- // fixme: input validator will be moved from the business thread after multilimit order context release
- val inputValidationResult = performInputValidation(orderContext)
- return if (!inputValidationResult.isValid) inputValidationResult else performBusinessValidation(orderContext)
- }
-
- private fun performInputValidation(orderContext: StopLimitOrderContext): OrderValidationResult {
- try {
- limitOrderInputValidator.validateStopOrder(orderContext)
- } catch (e: OrderValidationException) {
- return OrderValidationResult(false, false, e.message, e.orderStatus)
- }
- return OrderValidationResult(true)
+ return performBusinessValidation(orderContext)
}
private fun performBusinessValidation(orderContext: StopLimitOrderContext): OrderValidationResult {
diff --git a/src/main/kotlin/com/lykke/matching/engine/services/MultiLimitOrderService.kt b/src/main/kotlin/com/lykke/matching/engine/services/MultiLimitOrderService.kt
index c55dd908e..645241c5d 100644
--- a/src/main/kotlin/com/lykke/matching/engine/services/MultiLimitOrderService.kt
+++ b/src/main/kotlin/com/lykke/matching/engine/services/MultiLimitOrderService.kt
@@ -1,28 +1,13 @@
package com.lykke.matching.engine.services
-import com.lykke.matching.engine.daos.fee.v2.NewLimitOrderFeeInstruction
-import com.lykke.matching.engine.daos.AssetPair
import com.lykke.matching.engine.daos.LimitOrder
-import com.lykke.matching.engine.daos.MultiLimitOrder
-import com.lykke.matching.engine.daos.order.OrderTimeInForce
-import com.lykke.matching.engine.daos.order.LimitOrderType
-import com.lykke.matching.engine.fee.listOfLimitOrderFee
-import com.lykke.matching.engine.holders.AssetsHolder
-import com.lykke.matching.engine.holders.AssetsPairsHolder
+import com.lykke.matching.engine.daos.context.MultilimitOrderContext
import com.lykke.matching.engine.holders.BalancesHolder
import com.lykke.matching.engine.messages.MessageStatus
import com.lykke.matching.engine.messages.MessageType
import com.lykke.matching.engine.messages.MessageWrapper
import com.lykke.matching.engine.messages.ProtocolMessages
-import com.lykke.matching.engine.order.OrderCancelMode
-import com.lykke.matching.engine.order.OrderStatus
-import com.lykke.matching.engine.utils.NumberUtils
import com.lykke.matching.engine.utils.order.MessageStatusUtils
-import com.lykke.matching.engine.daos.v2.LimitOrderFeeInstruction
-import com.lykke.matching.engine.deduplication.ProcessedMessage
-import com.lykke.matching.engine.holders.MessageProcessingStatusHolder
-import com.lykke.matching.engine.holders.ApplicationSettingsHolder
-import com.lykke.matching.engine.holders.UUIDHolder
import com.lykke.matching.engine.order.transaction.ExecutionContextFactory
import com.lykke.matching.engine.order.process.GenericLimitOrdersProcessor
import com.lykke.matching.engine.order.process.StopOrderBookProcessor
@@ -31,7 +16,6 @@ import com.lykke.matching.engine.order.process.PreviousLimitOrdersProcessor
import com.lykke.matching.engine.services.utils.MultiOrderFilter
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
-import java.math.BigDecimal
import java.util.Date
@Service
@@ -40,50 +24,34 @@ class MultiLimitOrderService(private val executionContextFactory: ExecutionConte
private val stopOrderBookProcessor: StopOrderBookProcessor,
private val executionDataApplyService: ExecutionDataApplyService,
private val previousLimitOrdersProcessor: PreviousLimitOrdersProcessor,
- private val assetsHolder: AssetsHolder,
- private val assetsPairsHolder: AssetsPairsHolder,
- private val balancesHolder: BalancesHolder,
- private val applicationSettingsHolder: ApplicationSettingsHolder,
- private val messageProcessingStatusHolder: MessageProcessingStatusHolder,
- private val uuidHolder: UUIDHolder) : AbstractService {
+ private val balancesHolder: BalancesHolder) : AbstractService {
companion object {
private val LOGGER = LoggerFactory.getLogger(MultiLimitOrderService::class.java.name)
}
override fun processMessage(messageWrapper: MessageWrapper) {
- if (messageWrapper.parsedMessage == null) {
- parseMessage(messageWrapper)
- }
processMultiOrder(messageWrapper)
}
private fun processMultiOrder(messageWrapper: MessageWrapper) {
- val message = messageWrapper.parsedMessage!! as ProtocolMessages.MultiLimitOrder
- val assetPair = assetsPairsHolder.getAssetPairAllowNulls(message.assetPairId)
- if (assetPair == null) {
- LOGGER.info("Unable to process message (${messageWrapper.messageId}): unknown asset pair ${message.assetPairId}")
- writeResponse(messageWrapper, MessageStatus.UNKNOWN_ASSET)
- return
- }
-
- if (messageProcessingStatusHolder.isTradeDisabled(assetPair)) {
- writeResponse(messageWrapper, MessageStatus.MESSAGE_PROCESSING_DISABLED)
- return
- }
+ val context = messageWrapper.context as MultilimitOrderContext
- val isTrustedClient = applicationSettingsHolder.isTrustedClient(message.clientId)
-
- val multiLimitOrder = readMultiLimitOrder(messageWrapper.messageId!!, message, isTrustedClient, assetPair)
val now = Date()
+ val ordersToProcess = getOrdersToProcess(context, now)
+
+ val multiLimitOrder = context.multiLimitOrder
val executionContext = executionContextFactory.create(messageWrapper.messageId!!,
messageWrapper.id!!,
MessageType.MULTI_LIMIT_ORDER,
messageWrapper.processedMessage,
- mapOf(Pair(assetPair.assetPairId, assetPair)),
+ mapOf(Pair(context.assetPair!!.assetPairId, context.assetPair)),
now,
- LOGGER)
+ LOGGER,
+ mapOf(Pair(context.baseAsset!!.assetId, context.baseAsset),
+ Pair(context.quotingAsset!!.assetId, context.quotingAsset)),
+ context.multilimitOrderValidationResult?.inputValidationResultByOrderId ?: emptyMap())
previousLimitOrdersProcessor.cancelAndReplaceOrders(multiLimitOrder.clientId,
multiLimitOrder.assetPairId,
@@ -94,7 +62,7 @@ class MultiLimitOrderService(private val executionContextFactory: ExecutionConte
multiLimitOrder.sellReplacements,
executionContext)
- val processedOrders = genericLimitOrdersProcessor.processOrders(multiLimitOrder.orders, executionContext)
+ val processedOrders = genericLimitOrdersProcessor.processOrders(ordersToProcess, executionContext)
stopOrderBookProcessor.checkAndExecuteStopLimitOrders(executionContext)
val persisted = executionDataApplyService.persistAndSendEvents(messageWrapper, executionContext)
@@ -129,152 +97,29 @@ class MultiLimitOrderService(private val executionContextFactory: ExecutionConte
}
- private fun readMultiLimitOrder(messageId: String,
- message: ProtocolMessages.MultiLimitOrder,
- isTrustedClient: Boolean,
- assetPair: AssetPair): MultiLimitOrder {
- LOGGER.debug("Got ${if (!isTrustedClient) "client " else ""}multi limit order id: ${message.uid}, " +
- (if (messageId != message.uid) "messageId: $messageId, " else "") +
- "client ${message.clientId}, " +
- "assetPair: ${message.assetPairId}, " +
- "ordersCount: ${message.ordersCount}, " +
- (if (message.hasCancelAllPreviousLimitOrders()) "cancelPrevious: ${message.cancelAllPreviousLimitOrders}, " else "") +
- (if (message.hasCancelMode()) "cancelMode: ${message.cancelMode}" else ""))
-
- val clientId = message.clientId
- val messageUid = message.uid
- val assetPairId = message.assetPairId
- val cancelAllPreviousLimitOrders = message.cancelAllPreviousLimitOrders
- val cancelMode = if (message.hasCancelMode()) OrderCancelMode.getByExternalId(message.cancelMode) else OrderCancelMode.NOT_EMPTY_SIDE
- val now = Date()
- var cancelBuySide = cancelMode == OrderCancelMode.BUY_SIDE || cancelMode == OrderCancelMode.BOTH_SIDES
- var cancelSellSide = cancelMode == OrderCancelMode.SELL_SIDE || cancelMode == OrderCancelMode.BOTH_SIDES
+ fun getOrdersToProcess(context: MultilimitOrderContext, now: Date): List {
+ val multiLimitOrder = context.multiLimitOrder
+ val baseAssetAvailableBalance = balancesHolder.getAvailableBalance(multiLimitOrder.clientId, context.assetPair!!.baseAssetId)
+ val quotingAssetAvailableBalance = balancesHolder.getAvailableBalance(multiLimitOrder.clientId, context.assetPair.quotingAssetId)
- val buyReplacements = mutableMapOf()
- val sellReplacements = mutableMapOf()
-
- val baseAssetAvailableBalance = balancesHolder.getAvailableBalance(clientId, assetPair.baseAssetId)
- val quotingAssetAvailableBalance = balancesHolder.getAvailableBalance(clientId, assetPair.quotingAssetId)
-
- val filter = MultiOrderFilter(isTrustedClient,
+ val filter = MultiOrderFilter(context.isTrustedClient,
baseAssetAvailableBalance,
quotingAssetAvailableBalance,
- assetsHolder.getAsset(assetPair.quotingAssetId).accuracy,
+ context.quotingAsset!!.accuracy,
now,
- message.ordersList.size,
+ multiLimitOrder.orders.size,
LOGGER)
- message.ordersList.forEach { currentOrder ->
- if (!isTrustedClient) {
- LOGGER.debug("Incoming limit order (message id: $messageId): ${getIncomingOrderInfo(currentOrder)}")
- }
- val type = if (currentOrder.hasType()) LimitOrderType.getByExternalId(currentOrder.type) else LimitOrderType.LIMIT
- val status = when(type) {
- LimitOrderType.LIMIT -> OrderStatus.InOrderBook
- LimitOrderType.STOP_LIMIT -> OrderStatus.Pending
- }
- val price = if (currentOrder.hasPrice()) BigDecimal.valueOf(currentOrder.price) else BigDecimal.ZERO
- val lowerLimitPrice = if (currentOrder.hasLowerLimitPrice()) BigDecimal.valueOf(currentOrder.lowerLimitPrice) else null
- val lowerPrice = if (currentOrder.hasLowerPrice()) BigDecimal.valueOf(currentOrder.lowerPrice) else null
- val upperLimitPrice = if (currentOrder.hasUpperLimitPrice()) BigDecimal.valueOf(currentOrder.upperLimitPrice) else null
- val upperPrice = if (currentOrder.hasUpperPrice()) BigDecimal.valueOf(currentOrder.upperPrice) else null
- val feeInstruction = if (currentOrder.hasFee()) LimitOrderFeeInstruction.create(currentOrder.fee) else null
- val feeInstructions = NewLimitOrderFeeInstruction.create(currentOrder.feesList)
- val previousExternalId = if (currentOrder.hasOldUid()) currentOrder.oldUid else null
-
- val order = LimitOrder(uuidHolder.getNextValue(),
- currentOrder.uid,
- message.assetPairId,
- message.clientId,
- BigDecimal.valueOf(currentOrder.volume),
- price,
- status.name,
- now,
- Date(message.timestamp),
- now,
- BigDecimal.valueOf(currentOrder.volume),
- null,
- fee = feeInstruction,
- fees = listOfLimitOrderFee(feeInstruction, feeInstructions),
- type = type,
- lowerLimitPrice = lowerLimitPrice,
- lowerPrice = lowerPrice,
- upperLimitPrice = upperLimitPrice,
- upperPrice = upperPrice,
- previousExternalId = previousExternalId,
- timeInForce = if (currentOrder.hasTimeInForce()) OrderTimeInForce.getByExternalId(currentOrder.timeInForce) else null,
- expiryTime = if (currentOrder.hasExpiryTime()) Date(currentOrder.expiryTime) else null,
- parentOrderExternalId = null,
- childOrderExternalId = null)
-
+ for (order in multiLimitOrder.orders) {
filter.checkAndAdd(order)
- previousExternalId?.let {
- (if (order.isBuySide()) buyReplacements else sellReplacements)[it] = order
- }
-
- if (cancelAllPreviousLimitOrders && cancelMode == OrderCancelMode.NOT_EMPTY_SIDE) {
- if (currentOrder.volume > 0) {
- cancelBuySide = true
- } else {
- cancelSellSide = true
- }
- }
}
- return MultiLimitOrder(messageUid,
- clientId,
- assetPairId,
- filter.getResult(),
- cancelAllPreviousLimitOrders,
- cancelBuySide,
- cancelSellSide,
- cancelMode,
- buyReplacements,
- sellReplacements)
+ return filter.getResult()
}
- private fun getIncomingOrderInfo(incomingOrder: ProtocolMessages.MultiLimitOrder.Order): String {
- return "id: ${incomingOrder.uid}" +
- (if (incomingOrder.hasType()) ", type: ${incomingOrder.type}" else "") +
- ", volume: ${NumberUtils.roundForPrint(incomingOrder.volume)}" +
- (if (incomingOrder.hasPrice()) ", price: ${NumberUtils.roundForPrint(incomingOrder.price)}" else "") +
- (if (incomingOrder.hasLowerLimitPrice()) ", lowerLimitPrice: ${NumberUtils.roundForPrint(incomingOrder.lowerLimitPrice)}" else "") +
- (if (incomingOrder.hasLowerPrice()) ", lowerPrice: ${NumberUtils.roundForPrint(incomingOrder.lowerPrice)}" else "") +
- (if (incomingOrder.hasUpperLimitPrice()) ", upperLimitPrice: ${NumberUtils.roundForPrint(incomingOrder.upperLimitPrice)}" else "") +
- (if (incomingOrder.hasUpperPrice()) ", upperPrice: ${NumberUtils.roundForPrint(incomingOrder.upperPrice)}" else "") +
- (if (incomingOrder.hasOldUid()) ", oldUid: ${incomingOrder.oldUid}" else "") +
- (if (incomingOrder.hasTimeInForce()) ", timeInForce: ${incomingOrder.timeInForce}" else "") +
- (if (incomingOrder.hasExpiryTime()) ", expiryTime: ${incomingOrder.expiryTime}" else "") +
- (if (incomingOrder.hasFee()) ", fee: ${getIncomingFeeInfo(incomingOrder.fee)}" else "") +
- (if (incomingOrder.feesCount > 0) ", fees: ${incomingOrder.feesList.asSequence().map { getIncomingFeeInfo(incomingOrder.fee) }.joinToString(", ")}" else "")
- }
-
- private fun getIncomingFeeInfo(incomingFee: ProtocolMessages.LimitOrderFee): String {
- return "type: ${incomingFee.type}, " +
- (if (incomingFee.hasMakerSize()) ", makerSize: ${NumberUtils.roundForPrint(incomingFee.makerSize)}" else "") +
- (if (incomingFee.hasTakerSize()) ", takerSize: ${NumberUtils.roundForPrint(incomingFee.takerSize)}" else "") +
- (if (incomingFee.hasSourceClientId()) ", sourceClientId: ${incomingFee.sourceClientId}" else "") +
- (if (incomingFee.hasTargetClientId()) ", targetClientId: ${incomingFee.targetClientId}" else "") +
- (if (incomingFee.hasMakerSizeType()) ", makerSizeType: ${incomingFee.makerSizeType}" else "") +
- (if (incomingFee.hasTakerSizeType()) ", takerSizeType: ${incomingFee.takerSizeType}" else "") +
- (if (incomingFee.hasMakerFeeModificator()) ", makerFeeModificator: ${NumberUtils.roundForPrint(incomingFee.makerFeeModificator)}" else "") +
- (if (incomingFee.assetIdCount > 0) ", assetIds: ${incomingFee.assetIdList}}" else "")
- }
-
- private fun parseMultiLimitOrder(array: ByteArray): ProtocolMessages.MultiLimitOrder {
- return ProtocolMessages.MultiLimitOrder.parseFrom(array)
- }
override fun parseMessage(messageWrapper: MessageWrapper) {
- val message = parseMultiLimitOrder(messageWrapper.byteArray)
- messageWrapper.messageId = if (message.hasMessageId()) message.messageId else message.uid.toString()
- messageWrapper.timestamp = message.timestamp
- messageWrapper.parsedMessage = message
- messageWrapper.id = message.uid
- messageWrapper.processedMessage = if (applicationSettingsHolder.isTrustedClient(message.clientId))
- null
- else
- ProcessedMessage(messageWrapper.type, messageWrapper.timestamp!!, messageWrapper.messageId!!)
+ //nothing to do
}
fun writeResponse(messageWrapper: MessageWrapper, responseBuilder: ProtocolMessages.MultiLimitOrderResponse.Builder) {
diff --git a/src/main/kotlin/com/lykke/matching/engine/services/validators/MultilimitOrderValidationResult.kt b/src/main/kotlin/com/lykke/matching/engine/services/validators/MultilimitOrderValidationResult.kt
new file mode 100644
index 000000000..331c2613f
--- /dev/null
+++ b/src/main/kotlin/com/lykke/matching/engine/services/validators/MultilimitOrderValidationResult.kt
@@ -0,0 +1,6 @@
+package com.lykke.matching.engine.services.validators
+
+import com.lykke.matching.engine.services.validators.impl.OrderValidationResult
+
+data class MultilimitOrderValidationResult (val globalValidationResult: OrderValidationResult,
+ val inputValidationResultByOrderId: Map? = null)
\ No newline at end of file
diff --git a/src/main/kotlin/com/lykke/matching/engine/services/validators/business/OrderBusinessValidator.kt b/src/main/kotlin/com/lykke/matching/engine/services/validators/business/OrderBusinessValidator.kt
new file mode 100644
index 000000000..04915e96b
--- /dev/null
+++ b/src/main/kotlin/com/lykke/matching/engine/services/validators/business/OrderBusinessValidator.kt
@@ -0,0 +1,10 @@
+package com.lykke.matching.engine.services.validators.business
+
+import com.lykke.matching.engine.daos.LimitOrder
+import java.math.BigDecimal
+import java.util.*
+
+interface OrderBusinessValidator {
+ fun validateBalance(availableBalance: BigDecimal, limitVolume: BigDecimal)
+ fun validateExpiration(order: LimitOrder, orderProcessingTime: Date)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/lykke/matching/engine/services/validators/business/impl/LimitOrderBusinessValidatorImpl.kt b/src/main/kotlin/com/lykke/matching/engine/services/validators/business/impl/LimitOrderBusinessValidatorImpl.kt
index 79cec45d4..3c681200a 100644
--- a/src/main/kotlin/com/lykke/matching/engine/services/validators/business/impl/LimitOrderBusinessValidatorImpl.kt
+++ b/src/main/kotlin/com/lykke/matching/engine/services/validators/business/impl/LimitOrderBusinessValidatorImpl.kt
@@ -5,16 +5,15 @@ import com.lykke.matching.engine.holders.OrderBookMaxTotalSizeHolder
import com.lykke.matching.engine.order.OrderStatus
import com.lykke.matching.engine.services.AssetOrderBook
import com.lykke.matching.engine.services.validators.business.LimitOrderBusinessValidator
+import com.lykke.matching.engine.services.validators.business.OrderBusinessValidator
import com.lykke.matching.engine.services.validators.common.OrderValidationUtils
import com.lykke.matching.engine.services.validators.impl.OrderValidationException
import org.springframework.stereotype.Component
import java.math.BigDecimal
import java.util.Date
-
@Component
-class LimitOrderBusinessValidatorImpl(private val orderBookMaxTotalSizeHolder: OrderBookMaxTotalSizeHolder)
- : LimitOrderBusinessValidator {
-
+class LimitOrderBusinessValidatorImpl(private val orderBusinessValidatorImpl: OrderBusinessValidator,
+ private val orderBookMaxTotalSizeHolder: OrderBookMaxTotalSizeHolder): LimitOrderBusinessValidator {
override fun performValidation(isTrustedClient: Boolean, order: LimitOrder,
availableBalance: BigDecimal,
limitVolume: BigDecimal,
@@ -24,12 +23,12 @@ class LimitOrderBusinessValidatorImpl(private val orderBookMaxTotalSizeHolder: O
OrderValidationUtils.validateOrderBookTotalSize(currentOrderBookTotalSize, orderBookMaxTotalSizeHolder.get())
if (!isTrustedClient) {
- OrderValidationUtils.validateBalance(availableBalance, limitVolume)
+ orderBusinessValidatorImpl.validateBalance(availableBalance, limitVolume)
}
validatePreviousOrderNotFound(order)
validateNotEnoughFounds(order)
- OrderValidationUtils.validateExpiration(order, date)
+ orderBusinessValidatorImpl.validateExpiration(order, date)
}
private fun validatePreviousOrderNotFound(order: LimitOrder) {
diff --git a/src/main/kotlin/com/lykke/matching/engine/services/validators/business/impl/OrderBusinessValidatorImpl.kt b/src/main/kotlin/com/lykke/matching/engine/services/validators/business/impl/OrderBusinessValidatorImpl.kt
new file mode 100644
index 000000000..4b086baa7
--- /dev/null
+++ b/src/main/kotlin/com/lykke/matching/engine/services/validators/business/impl/OrderBusinessValidatorImpl.kt
@@ -0,0 +1,24 @@
+package com.lykke.matching.engine.services.validators.business.impl
+
+import com.lykke.matching.engine.daos.LimitOrder
+import com.lykke.matching.engine.order.OrderStatus
+import com.lykke.matching.engine.services.validators.business.OrderBusinessValidator
+import com.lykke.matching.engine.services.validators.impl.OrderValidationException
+import org.springframework.stereotype.Component
+import java.math.BigDecimal
+import java.util.*
+
+@Component
+class OrderBusinessValidatorImpl: OrderBusinessValidator {
+ override fun validateBalance(availableBalance: BigDecimal, limitVolume: BigDecimal) {
+ if (availableBalance < limitVolume) {
+ throw OrderValidationException(OrderStatus.NotEnoughFunds, "not enough funds to reserve")
+ }
+ }
+
+ override fun validateExpiration(order: LimitOrder, orderProcessingTime: Date) {
+ if (order.isExpired(orderProcessingTime)) {
+ throw OrderValidationException(OrderStatus.Cancelled, "expired")
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/lykke/matching/engine/services/validators/business/impl/StopOrderBusinessValidatorImpl.kt b/src/main/kotlin/com/lykke/matching/engine/services/validators/business/impl/StopOrderBusinessValidatorImpl.kt
index 52f741110..6fe3db769 100644
--- a/src/main/kotlin/com/lykke/matching/engine/services/validators/business/impl/StopOrderBusinessValidatorImpl.kt
+++ b/src/main/kotlin/com/lykke/matching/engine/services/validators/business/impl/StopOrderBusinessValidatorImpl.kt
@@ -2,6 +2,7 @@ package com.lykke.matching.engine.services.validators.business.impl
import com.lykke.matching.engine.daos.LimitOrder
import com.lykke.matching.engine.holders.OrderBookMaxTotalSizeHolder
+import com.lykke.matching.engine.services.validators.business.OrderBusinessValidator
import com.lykke.matching.engine.services.validators.business.StopOrderBusinessValidator
import com.lykke.matching.engine.services.validators.common.OrderValidationUtils
import org.springframework.stereotype.Component
@@ -9,7 +10,8 @@ import java.math.BigDecimal
import java.util.Date
@Component
-class StopOrderBusinessValidatorImpl(private val orderBookMaxTotalSizeHolder: OrderBookMaxTotalSizeHolder)
+class StopOrderBusinessValidatorImpl(private val orderBusinessValidator: OrderBusinessValidator,
+ private val orderBookMaxTotalSizeHolder: OrderBookMaxTotalSizeHolder)
: StopOrderBusinessValidator {
override fun performValidation(availableBalance: BigDecimal,
limitVolume: BigDecimal,
@@ -17,7 +19,7 @@ class StopOrderBusinessValidatorImpl(private val orderBookMaxTotalSizeHolder: Or
orderProcessingTime: Date,
currentOrderBookTotalSize: Int) {
OrderValidationUtils.validateOrderBookTotalSize(currentOrderBookTotalSize, orderBookMaxTotalSizeHolder.get())
- OrderValidationUtils.validateBalance(availableBalance, limitVolume)
- OrderValidationUtils.validateExpiration(order, orderProcessingTime)
+ orderBusinessValidator.validateBalance(availableBalance, limitVolume)
+ orderBusinessValidator.validateExpiration(order, orderProcessingTime)
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/lykke/matching/engine/services/validators/common/OrderValidationUtils.kt b/src/main/kotlin/com/lykke/matching/engine/services/validators/common/OrderValidationUtils.kt
index b76cae793..a2629bd67 100644
--- a/src/main/kotlin/com/lykke/matching/engine/services/validators/common/OrderValidationUtils.kt
+++ b/src/main/kotlin/com/lykke/matching/engine/services/validators/common/OrderValidationUtils.kt
@@ -1,35 +1,16 @@
package com.lykke.matching.engine.services.validators.common
-import com.lykke.matching.engine.daos.AssetPair
-import com.lykke.matching.engine.daos.LimitOrder
-import com.lykke.matching.engine.daos.Order
import com.lykke.matching.engine.order.OrderStatus
import com.lykke.matching.engine.services.validators.impl.OrderValidationException
import com.lykke.utils.logging.MetricsLogger
-import java.math.BigDecimal
-import java.util.Date
class OrderValidationUtils {
companion object {
-
private val METRICS_LOGGER = MetricsLogger.getLogger()
- fun checkMinVolume(order: Order, assetPair: AssetPair): Boolean {
- val volume = order.getAbsVolume()
- val minVolume = if (order.isStraight()) assetPair.minVolume else assetPair.minInvertedVolume
- return minVolume == null || volume >= minVolume
- }
-
- fun validateBalance(availableBalance: BigDecimal, limitVolume: BigDecimal) {
- if (availableBalance < limitVolume) {
- throw OrderValidationException(OrderStatus.NotEnoughFunds, "not enough funds to reserve")
- }
- }
- fun validateExpiration(order: LimitOrder, orderProcessingTime: Date) {
- if (order.isExpired(orderProcessingTime)) {
- throw OrderValidationException(OrderStatus.Cancelled, "expired")
- }
+ fun isFatalInvalid(validationException: OrderValidationException): Boolean {
+ return validationException.orderStatus == OrderStatus.UnknownAsset
}
fun validateOrderBookTotalSize(currentOrderBookTotalSize: Int, orderBookMaxTotalSize: Int?) {
diff --git a/src/main/kotlin/com/lykke/matching/engine/services/validators/impl/MarketOrderValidatorImpl.kt b/src/main/kotlin/com/lykke/matching/engine/services/validators/impl/MarketOrderValidatorImpl.kt
index 9f030d0ce..ad44eb04b 100644
--- a/src/main/kotlin/com/lykke/matching/engine/services/validators/impl/MarketOrderValidatorImpl.kt
+++ b/src/main/kotlin/com/lykke/matching/engine/services/validators/impl/MarketOrderValidatorImpl.kt
@@ -10,7 +10,7 @@ import com.lykke.matching.engine.holders.AssetsHolder
import com.lykke.matching.engine.holders.AssetsPairsHolder
import com.lykke.matching.engine.order.OrderStatus
import com.lykke.matching.engine.services.validators.MarketOrderValidator
-import com.lykke.matching.engine.services.validators.common.OrderValidationUtils
+import com.lykke.matching.engine.services.validators.input.OrderInputValidator
import com.lykke.matching.engine.utils.NumberUtils
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
@@ -22,7 +22,8 @@ import java.util.concurrent.PriorityBlockingQueue
class MarketOrderValidatorImpl
@Autowired constructor(private val assetsPairsHolder: AssetsPairsHolder,
private val assetsHolder: AssetsHolder,
- private val applicationSettingsHolder: ApplicationSettingsHolder) : MarketOrderValidator {
+ private val applicationSettingsHolder: ApplicationSettingsHolder,
+ private val orderInputValidator: OrderInputValidator) : MarketOrderValidator {
companion object {
private val LOGGER = LoggerFactory.getLogger(MarketOrderValidatorImpl::class.java.name)
@@ -61,7 +62,7 @@ class MarketOrderValidatorImpl
throw OrderValidationException(OrderStatus.InvalidVolume, message)
}
- if (!OrderValidationUtils.checkMinVolume(order, assetsPairsHolder.getAssetPair(order.assetPairId))) {
+ if (!orderInputValidator.checkMinVolume(order, assetsPairsHolder.getAssetPair(order.assetPairId))) {
LOGGER.info("Too small volume for $order")
throw OrderValidationException(OrderStatus.TooSmallVolume)
}
diff --git a/src/main/kotlin/com/lykke/matching/engine/services/validators/impl/OrderValidationResult.kt b/src/main/kotlin/com/lykke/matching/engine/services/validators/impl/OrderValidationResult.kt
index 048d3aa1f..3bc3fc3e3 100644
--- a/src/main/kotlin/com/lykke/matching/engine/services/validators/impl/OrderValidationResult.kt
+++ b/src/main/kotlin/com/lykke/matching/engine/services/validators/impl/OrderValidationResult.kt
@@ -2,7 +2,7 @@ package com.lykke.matching.engine.services.validators.impl
import com.lykke.matching.engine.order.OrderStatus
-class OrderValidationResult(val isValid: Boolean,
+data class OrderValidationResult(val isValid: Boolean,
val isFatalInvalid: Boolean = false,
val message: String? = null,
val status: OrderStatus? = null)
diff --git a/src/main/kotlin/com/lykke/matching/engine/services/validators/input/LimitOrderInputValidator.kt b/src/main/kotlin/com/lykke/matching/engine/services/validators/input/LimitOrderInputValidator.kt
index cc0746d50..98323a543 100644
--- a/src/main/kotlin/com/lykke/matching/engine/services/validators/input/LimitOrderInputValidator.kt
+++ b/src/main/kotlin/com/lykke/matching/engine/services/validators/input/LimitOrderInputValidator.kt
@@ -4,7 +4,6 @@ import com.lykke.matching.engine.daos.Asset
import com.lykke.matching.engine.daos.AssetPair
import com.lykke.matching.engine.daos.LimitOrder
import com.lykke.matching.engine.incoming.parsers.data.SingleLimitOrderParsedData
-import com.lykke.matching.engine.order.process.context.StopLimitOrderContext
interface LimitOrderInputValidator {
fun validateLimitOrder(singleLimitOrderParsedData: SingleLimitOrderParsedData)
@@ -12,7 +11,10 @@ interface LimitOrderInputValidator {
fun validateLimitOrder(isTrustedClient: Boolean,
order: LimitOrder,
assetPair: AssetPair?,
- assetPairId: String,
+ assetPairId: String?,
baseAsset: Asset?)
- fun validateStopOrder(stopLimitOrderContext: StopLimitOrderContext)
+ fun validateStopOrder(limitOrder: LimitOrder,
+ assetPair: AssetPair?,
+ assetPairId: String,
+ baseAsset: Asset?)
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/lykke/matching/engine/services/validators/input/OrderInputValidator.kt b/src/main/kotlin/com/lykke/matching/engine/services/validators/input/OrderInputValidator.kt
new file mode 100644
index 000000000..266ebb37e
--- /dev/null
+++ b/src/main/kotlin/com/lykke/matching/engine/services/validators/input/OrderInputValidator.kt
@@ -0,0 +1,9 @@
+package com.lykke.matching.engine.services.validators.input
+
+import com.lykke.matching.engine.daos.AssetPair
+import com.lykke.matching.engine.daos.Order
+
+interface OrderInputValidator {
+ fun checkMinVolume(order: Order, assetPair: AssetPair): Boolean
+ fun validateAsset(assetPair: AssetPair?, assetPairId: String)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/lykke/matching/engine/services/validators/input/impl/LimitOrderInputValidatorImpl.kt b/src/main/kotlin/com/lykke/matching/engine/services/validators/input/impl/LimitOrderInputValidatorImpl.kt
index 1809a23b8..dd4565285 100644
--- a/src/main/kotlin/com/lykke/matching/engine/services/validators/input/impl/LimitOrderInputValidatorImpl.kt
+++ b/src/main/kotlin/com/lykke/matching/engine/services/validators/input/impl/LimitOrderInputValidatorImpl.kt
@@ -8,16 +8,16 @@ import com.lykke.matching.engine.fee.checkFee
import com.lykke.matching.engine.holders.ApplicationSettingsHolder
import com.lykke.matching.engine.incoming.parsers.data.SingleLimitOrderParsedData
import com.lykke.matching.engine.order.OrderStatus
-import com.lykke.matching.engine.order.process.context.StopLimitOrderContext
-import com.lykke.matching.engine.services.validators.common.OrderValidationUtils
import com.lykke.matching.engine.services.validators.impl.OrderValidationException
import com.lykke.matching.engine.services.validators.input.LimitOrderInputValidator
+import com.lykke.matching.engine.services.validators.input.OrderInputValidator
import com.lykke.matching.engine.utils.NumberUtils
import org.springframework.stereotype.Component
import java.math.BigDecimal
@Component
-class LimitOrderInputValidatorImpl(val applicationSettingsHolder: ApplicationSettingsHolder) : LimitOrderInputValidator {
+class LimitOrderInputValidatorImpl(val applicationSettingsHolder: ApplicationSettingsHolder,
+ val orderInputValidator: OrderInputValidator) : LimitOrderInputValidator {
override fun validateLimitOrder(singleLimitOrderParsedData: SingleLimitOrderParsedData) {
val singleLimitContext = singleLimitOrderParsedData.messageWrapper.context as SingleLimitOrderContext
@@ -31,13 +31,13 @@ class LimitOrderInputValidatorImpl(val applicationSettingsHolder: ApplicationSet
override fun validateLimitOrder(isTrustedClient: Boolean,
order: LimitOrder,
assetPair: AssetPair?,
- assetPairId: String,
+ assetPairId: String?,
baseAsset: Asset?) {
if (!isTrustedClient) {
validateFee(order)
}
- validateAsset(assetPair, assetPairId)
+ assetPairId?.let { orderInputValidator.validateAsset(assetPair, assetPairId) }
validatePrice(order)
validateVolume(order, assetPair!!)
validateMaxValue(order, assetPair)
@@ -56,20 +56,11 @@ class LimitOrderInputValidatorImpl(val applicationSettingsHolder: ApplicationSet
singleLimitContext.baseAsset)
}
- override fun validateStopOrder(stopLimitOrderContext: StopLimitOrderContext) {
- val assetPair = stopLimitOrderContext.executionContext.assetPairsById[stopLimitOrderContext.order.assetPairId]
- val baseAsset = assetPair?.let { stopLimitOrderContext.executionContext.assetsById[assetPair.baseAssetId] }
- validateStopOrder(stopLimitOrderContext.order,
- assetPair,
- stopLimitOrderContext.order.assetPairId,
- baseAsset)
- }
-
- private fun validateStopOrder(limitOrder: LimitOrder,
- assetPair: AssetPair?,
- assetPairId: String,
- baseAsset: Asset?) {
- validateAsset(assetPair, assetPairId)
+ override fun validateStopOrder(limitOrder: LimitOrder,
+ assetPair: AssetPair?,
+ assetPairId: String,
+ baseAsset: Asset?) {
+ orderInputValidator.validateAsset(assetPair, assetPairId)
validateFee(limitOrder)
validateLimitPrices(limitOrder)
validateVolume(limitOrder, assetPair!!)
@@ -78,15 +69,6 @@ class LimitOrderInputValidatorImpl(val applicationSettingsHolder: ApplicationSet
validateStopPricesAccuracy(limitOrder, assetPair)
}
- private fun validateAsset(assetPair: AssetPair?, assetPairId: String) {
- if (assetPair == null) {
- throw OrderValidationException(OrderStatus.UnknownAsset, "Unable to find asset pair $assetPairId")
- }
-
- if (applicationSettingsHolder.isAssetDisabled(assetPair.baseAssetId) || applicationSettingsHolder.isAssetDisabled(assetPair.quotingAssetId)) {
- throw OrderValidationException(OrderStatus.DisabledAsset, "disabled asset")
- }
- }
private fun validateFee(order: LimitOrder) {
if (order.fee != null && order.fees?.size ?: 0 > 1 || !checkFee(null, order.fees)) {
@@ -133,12 +115,11 @@ class LimitOrderInputValidatorImpl(val applicationSettingsHolder: ApplicationSet
}
private fun validateVolume(limitOrder: LimitOrder, assetPair: AssetPair) {
-
if (NumberUtils.equalsIgnoreScale(BigDecimal.ZERO, limitOrder.volume)) {
throw OrderValidationException(OrderStatus.InvalidVolume, "volume can not be equal to zero")
}
- if (!OrderValidationUtils.checkMinVolume(limitOrder, assetPair)) {
+ if (!orderInputValidator.checkMinVolume(limitOrder, assetPair)) {
throw OrderValidationException(OrderStatus.TooSmallVolume, "volume is too small")
}
}
diff --git a/src/main/kotlin/com/lykke/matching/engine/services/validators/input/impl/OrderInputValidatorImpl.kt b/src/main/kotlin/com/lykke/matching/engine/services/validators/input/impl/OrderInputValidatorImpl.kt
new file mode 100644
index 000000000..508877cc9
--- /dev/null
+++ b/src/main/kotlin/com/lykke/matching/engine/services/validators/input/impl/OrderInputValidatorImpl.kt
@@ -0,0 +1,30 @@
+package com.lykke.matching.engine.services.validators.input.impl
+
+import com.lykke.matching.engine.daos.AssetPair
+import com.lykke.matching.engine.daos.Order
+import com.lykke.matching.engine.holders.ApplicationSettingsHolder
+import com.lykke.matching.engine.order.OrderStatus
+import com.lykke.matching.engine.services.validators.impl.OrderValidationException
+import com.lykke.matching.engine.services.validators.input.OrderInputValidator
+import org.springframework.stereotype.Component
+
+@Component
+class OrderInputValidatorImpl(val applicationSettingsHolder: ApplicationSettingsHolder): OrderInputValidator {
+ override fun validateAsset(assetPair: AssetPair?, assetPairId: String) {
+ if (assetPair == null) {
+ throw OrderValidationException(OrderStatus.UnknownAsset, "Unable to find asset pair $assetPairId")
+ }
+
+ if (applicationSettingsHolder.isAssetDisabled(assetPair.baseAssetId) || applicationSettingsHolder.isAssetDisabled(assetPair.quotingAssetId)) {
+ throw OrderValidationException(OrderStatus.DisabledAsset, "disabled asset")
+ }
+ }
+
+ override fun checkMinVolume(order: Order, assetPair: AssetPair): Boolean {
+ val volume = order.getAbsVolume()
+ val minVolume = if (order.isStraight()) assetPair.minVolume else assetPair.minInvertedVolume
+ return minVolume == null || volume >= minVolume
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/test/kotlin/com/lykke/matching/engine/config/TestApplicationContext.kt b/src/test/kotlin/com/lykke/matching/engine/config/TestApplicationContext.kt
index a85765a26..4733f7cb8 100644
--- a/src/test/kotlin/com/lykke/matching/engine/config/TestApplicationContext.kt
+++ b/src/test/kotlin/com/lykke/matching/engine/config/TestApplicationContext.kt
@@ -21,6 +21,7 @@ import com.lykke.matching.engine.incoming.parsers.ContextParser
import com.lykke.matching.engine.incoming.parsers.impl.*
import com.lykke.matching.engine.incoming.preprocessor.impl.CashInOutPreprocessor
import com.lykke.matching.engine.incoming.preprocessor.impl.CashTransferPreprocessor
+import com.lykke.matching.engine.incoming.preprocessor.impl.MultilimitOrderPreprocessor
import com.lykke.matching.engine.incoming.preprocessor.impl.SingleLimitOrderPreprocessor
import com.lykke.matching.engine.matching.MatchingEngine
import com.lykke.matching.engine.messages.MessageWrapper
@@ -60,10 +61,12 @@ import com.lykke.matching.engine.services.validators.input.LimitOrderInputValida
import com.lykke.matching.engine.services.validators.input.CashInOutOperationInputValidator
import com.lykke.matching.engine.services.validators.input.CashTransferOperationInputValidator
import com.lykke.matching.engine.services.validators.input.LimitOrderCancelOperationInputValidator
+import com.lykke.matching.engine.services.validators.input.OrderInputValidator
import com.lykke.matching.engine.services.validators.input.impl.CashInOutOperationInputValidatorImpl
import com.lykke.matching.engine.services.validators.input.impl.CashTransferOperationInputValidatorImpl
import com.lykke.matching.engine.services.validators.input.impl.LimitOrderInputValidatorImpl
import com.lykke.matching.engine.services.validators.input.impl.LimitOrderCancelOperationInputValidatorImpl
+import com.lykke.matching.engine.services.validators.input.impl.OrderInputValidatorImpl
import com.lykke.matching.engine.services.validators.settings.SettingValidator
import com.lykke.matching.engine.services.validators.settings.impl.DisabledFunctionalitySettingValidator
import com.lykke.matching.engine.services.validators.settings.impl.MessageProcessingSwitchSettingValidator
@@ -279,11 +282,22 @@ open class TestApplicationContext {
outgoingEventProcessor)
}
+ @Bean
+ fun orderInputValidator(applicationSettingsHolder: ApplicationSettingsHolder): OrderInputValidator {
+ return OrderInputValidatorImpl(applicationSettingsHolder)
+ }
+
+ @Bean
+ fun orderBusinessValidator(): OrderBusinessValidator {
+ return OrderBusinessValidatorImpl()
+ }
+
@Bean
open fun marketOrderValidator(assetsPairsHolder: AssetsPairsHolder,
assetsHolder: AssetsHolder,
- applicationSettingsHolder: ApplicationSettingsHolder): MarketOrderValidator {
- return MarketOrderValidatorImpl(assetsPairsHolder, assetsHolder, applicationSettingsHolder)
+ applicationSettingsHolder: ApplicationSettingsHolder,
+ orderInputValidator: OrderInputValidator): MarketOrderValidator {
+ return MarketOrderValidatorImpl(assetsPairsHolder, assetsHolder, applicationSettingsHolder, orderInputValidator)
}
@Bean
@@ -370,20 +384,13 @@ open class TestApplicationContext {
assetsHolder: AssetsHolder,
assetsPairsHolder: AssetsPairsHolder,
balancesHolder: BalancesHolder,
- applicationSettingsHolder: ApplicationSettingsHolder,
- messageProcessingStatusHolder: MessageProcessingStatusHolder,
- testUUIDHolder: TestUUIDHolder): MultiLimitOrderService {
+ applicationSettingsHolder: ApplicationSettingsHolder): MultiLimitOrderService {
return MultiLimitOrderService(executionContextFactory,
genericLimitOrdersProcessor,
stopOrderBookProcessor,
executionDataApplyService,
previousLimitOrdersProcessor,
- assetsHolder,
- assetsPairsHolder,
- balancesHolder,
- applicationSettingsHolder,
- messageProcessingStatusHolder,
- testUUIDHolder)
+ balancesHolder)
}
@Bean
@@ -569,11 +576,12 @@ open class TestApplicationContext {
@Bean
open fun messageBuilder(cashTransferContextParser: CashTransferContextParser,
cashInOutContextParser: CashInOutContextParser,
- singleLimitOrderContextParser: SingleLimitOrderContextParser,
+ singleLimitOrderPreprocessor: SingleLimitOrderPreprocessor,
limitOrderCancelOperationContextParser: ContextParser,
- limitOrderMassCancelOperationContextParser: ContextParser): MessageBuilder {
- return MessageBuilder(singleLimitOrderContextParser, cashInOutContextParser, cashTransferContextParser,
- limitOrderCancelOperationContextParser, limitOrderMassCancelOperationContextParser)
+ limitOrderMassCancelOperationContextParser: ContextParser,
+ multilimitOrderPreprocessor: MultilimitOrderPreprocessor): MessageBuilder {
+ return MessageBuilder(singleLimitOrderPreprocessor, cashInOutContextParser, cashTransferContextParser,
+ limitOrderCancelOperationContextParser, limitOrderMassCancelOperationContextParser, multilimitOrderPreprocessor)
}
@Bean
@@ -614,23 +622,34 @@ open class TestApplicationContext {
}
@Bean
- open fun limitOrderInputValidator(applicationSettingsHolder: ApplicationSettingsHolder): LimitOrderInputValidator {
- return LimitOrderInputValidatorImpl(applicationSettingsHolder)
+ open fun multilimitOrderContextParser(applicationSettingsHolder: ApplicationSettingsHolder,
+ assetsPairsHolder: AssetsPairsHolder,
+ assetsHolder: AssetsHolder,
+ uuidHolder: UUIDHolder): MultilimitOrderContextParser {
+ return MultilimitOrderContextParser(ThrottlingLogger.getLogger("multilimitOrder"), applicationSettingsHolder, assetsPairsHolder, assetsHolder, uuidHolder)
}
@Bean
- fun orderBookMaxTotalSizeHolder(): OrderBookMaxTotalSizeHolder {
- return OrderBookMaxTotalSizeHolderImpl(null)
+ open fun limitOrderInputValidator(applicationSettingsHolder: ApplicationSettingsHolder,
+ orderInputValidator: OrderInputValidator): LimitOrderInputValidator {
+ return LimitOrderInputValidatorImpl(applicationSettingsHolder, orderInputValidator)
+ }
+
+ @Bean
+ open fun limitOrderBusinessValidator(orderBusinessValidator: OrderBusinessValidator,
+ orderBookMaxTotalSizeHolder: OrderBookMaxTotalSizeHolder): LimitOrderBusinessValidator {
+ return LimitOrderBusinessValidatorImpl(orderBusinessValidator, orderBookMaxTotalSizeHolder)
}
@Bean
- open fun limitOrderBusinessValidator(orderBookMaxTotalSizeHolder: OrderBookMaxTotalSizeHolder): LimitOrderBusinessValidator {
- return LimitOrderBusinessValidatorImpl(orderBookMaxTotalSizeHolder)
+ fun orderBookMaxTotalSizeHolder(): OrderBookMaxTotalSizeHolder {
+ return OrderBookMaxTotalSizeHolderImpl(null)
}
@Bean
- open fun stopOrderBusinessValidatorImpl(orderBookMaxTotalSizeHolder: OrderBookMaxTotalSizeHolder): StopOrderBusinessValidatorImpl {
- return StopOrderBusinessValidatorImpl(orderBookMaxTotalSizeHolder)
+ open fun stopOrderBusinessValidatorImpl(orderBusinessValidator: OrderBusinessValidator,
+ orderBookMaxTotalSizeHolder: OrderBookMaxTotalSizeHolder): StopOrderBusinessValidatorImpl {
+ return StopOrderBusinessValidatorImpl(orderBusinessValidator, orderBookMaxTotalSizeHolder)
}
@Bean
@@ -697,6 +716,21 @@ open class TestApplicationContext {
ThrottlingLogger.getLogger("limitOrder"))
}
+ @Bean
+ open fun multiltilimitOrderPreprocessor(messageProcessingStatusHolder: MessageProcessingStatusHolder,
+ limitOrderInputValidator: LimitOrderInputValidator,
+ multilimitOrderContextParser: MultilimitOrderContextParser,
+ preProcessedMessageQueue: BlockingQueue,
+ orderInputValidator: OrderInputValidator
+ ): MultilimitOrderPreprocessor {
+ return MultilimitOrderPreprocessor(messageProcessingStatusHolder,
+ limitOrderInputValidator,
+ orderInputValidator,
+ multilimitOrderContextParser,
+ preProcessedMessageQueue,
+ ThrottlingLogger.getLogger("multilimitOrder"))
+ }
+
@Bean
open fun expiryOrdersQueue() = ExpiryOrdersQueue()
@@ -712,6 +746,7 @@ open class TestApplicationContext {
cashTransferInputQueue,
limitOrderCancelInputQueue,
limitOrderMassCancelInputQueue,
+ preProcessedMessageQueue,
preProcessedMessageQueue)
}
diff --git a/src/test/kotlin/com/lykke/matching/engine/config/TestExecutionContext.kt b/src/test/kotlin/com/lykke/matching/engine/config/TestExecutionContext.kt
index eb536db0f..33759b955 100644
--- a/src/test/kotlin/com/lykke/matching/engine/config/TestExecutionContext.kt
+++ b/src/test/kotlin/com/lykke/matching/engine/config/TestExecutionContext.kt
@@ -170,7 +170,7 @@ open class TestExecutionContext {
applicationSettingsHolder: ApplicationSettingsHolder,
matchingEngine: MatchingEngine,
matchingResultHandlingHelper: MatchingResultHandlingHelper): LimitOrderProcessor {
- return LimitOrderProcessor(limitOrderInputValidator,
+ return LimitOrderProcessor(
limitOrderBusinessValidator,
applicationSettingsHolder,
matchingEngine,
@@ -178,12 +178,11 @@ open class TestExecutionContext {
}
@Bean
- open fun stopLimitOrdersProcessor(limitOrderInputValidator: LimitOrderInputValidator,
- stopOrderBusinessValidator: StopOrderBusinessValidator,
+ open fun stopLimitOrdersProcessor(stopOrderBusinessValidator: StopOrderBusinessValidator,
applicationSettingsHolder: ApplicationSettingsHolder,
limitOrderProcessor: LimitOrderProcessor,
uuidHolder: UUIDHolder): StopLimitOrderProcessor {
- return StopLimitOrderProcessor(limitOrderInputValidator,
+ return StopLimitOrderProcessor(
stopOrderBusinessValidator,
applicationSettingsHolder,
limitOrderProcessor,
diff --git a/src/test/kotlin/com/lykke/matching/engine/incoming/preprocessor/impl/MultilimitOrerPreprocessorTest.kt b/src/test/kotlin/com/lykke/matching/engine/incoming/preprocessor/impl/MultilimitOrerPreprocessorTest.kt
new file mode 100644
index 000000000..f57df24ae
--- /dev/null
+++ b/src/test/kotlin/com/lykke/matching/engine/incoming/preprocessor/impl/MultilimitOrerPreprocessorTest.kt
@@ -0,0 +1,66 @@
+package com.lykke.matching.engine.incoming.preprocessor.impl
+
+import com.lykke.matching.engine.AbstractTest
+import com.lykke.matching.engine.config.TestApplicationContext
+import com.lykke.matching.engine.daos.IncomingLimitOrder
+import com.lykke.matching.engine.daos.order.LimitOrderType
+import com.lykke.matching.engine.messages.MessageStatus
+import com.lykke.matching.engine.messages.MessageWrapper
+import com.lykke.matching.engine.messages.ProtocolMessages
+import com.lykke.matching.engine.socket.TestClientHandler
+import com.lykke.matching.engine.utils.MessageBuilder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.annotation.DirtiesContext
+import org.springframework.test.context.junit4.SpringRunner
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
+
+@RunWith(SpringRunner::class)
+@SpringBootTest(classes = [(TestApplicationContext::class)])
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
+class MultilimitOrerPreprocessorTest: AbstractTest() {
+
+ @Autowired
+ private lateinit var messageBuilder: MessageBuilder
+
+ @Test
+ fun testLimitMultiOrderWithUnknownAssetPair() {
+ //preprocessing is performed during message building
+ val messageWrapper = messageBuilder.buildMultiLimitOrderWrapper(pair = "UnknownAsset",
+ clientId = "Client1",
+ orders = listOf(IncomingLimitOrder(100.0, 1.2),
+ IncomingLimitOrder(100.0, 1.3)),
+ cancel = false)
+
+ assertResponse(messageWrapper)
+ }
+
+ @Test
+ fun testStopMultiOrderWithUnknownAssetPair() {
+ //preprocessing is performed during message building
+ val messageWrapper = messageBuilder.buildMultiLimitOrderWrapper(pair = "UnknownAsset",
+
+ clientId = "Client1",
+ orders = listOf(IncomingLimitOrder(100.0, 1.2, type = LimitOrderType.STOP_LIMIT),
+ IncomingLimitOrder(100.0, 1.3, type = LimitOrderType.STOP_LIMIT)),
+ cancel = false)
+
+ assertResponse(messageWrapper)
+ }
+
+ private fun assertResponse(messageWrapper: MessageWrapper) {
+ val clientHandler = messageWrapper.clientHandler!! as TestClientHandler
+ assertEquals(1, clientHandler.responses.size)
+
+ val response = clientHandler.responses.single()
+ assertTrue(response is ProtocolMessages.MultiLimitOrderResponse)
+ response as ProtocolMessages.MultiLimitOrderResponse
+ assertEquals(MessageStatus.UNKNOWN_ASSET.type, response.status)
+
+ assertEquals(0, clientsEventsQueue.size)
+ assertEquals(0, trustedClientsEventsQueue.size)
+ }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/com/lykke/matching/engine/incoming/preprocessor/impl/SingleLimitOrderPreprocessorTest.kt b/src/test/kotlin/com/lykke/matching/engine/incoming/preprocessor/impl/SingleLimitOrderPreprocessorTest.kt
index 9968730a0..26ae2f9a8 100644
--- a/src/test/kotlin/com/lykke/matching/engine/incoming/preprocessor/impl/SingleLimitOrderPreprocessorTest.kt
+++ b/src/test/kotlin/com/lykke/matching/engine/incoming/preprocessor/impl/SingleLimitOrderPreprocessorTest.kt
@@ -4,6 +4,7 @@ import com.lykke.matching.engine.AbstractTest
import com.lykke.matching.engine.config.TestApplicationContext
import com.lykke.matching.engine.daos.order.LimitOrderType
import com.lykke.matching.engine.messages.MessageStatus
+import com.lykke.matching.engine.messages.MessageWrapper
import com.lykke.matching.engine.messages.ProtocolMessages
import com.lykke.matching.engine.socket.TestClientHandler
import com.lykke.matching.engine.utils.MessageBuilder
@@ -21,17 +22,18 @@ import kotlin.test.assertTrue
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class SingleLimitOrderPreprocessorTest: AbstractTest() {
- @Autowired
- private lateinit var singleLimitOrderPreprocessor: SingleLimitOrderPreprocessor
-
@Autowired
private lateinit var messageBuilder: MessageBuilder
@Test
fun testOrderWithUnknownAssetPair() {
+ //preprocessing is performed during message building
val messageWrapper = messageBuilder.buildLimitOrderWrapper(MessageBuilder.buildLimitOrder(assetId = "UnknownAssetPair"))
- singleLimitOrderPreprocessor.preProcess(messageWrapper)
+ assertResponse(messageWrapper)
+ }
+
+ fun assertResponse(messageWrapper: MessageWrapper) {
val clientHandler = messageWrapper.clientHandler!! as TestClientHandler
assertEquals(1, clientHandler.responses.size)
@@ -47,16 +49,7 @@ class SingleLimitOrderPreprocessorTest: AbstractTest() {
fun testStopOrderWithUnknownAssetPair() {
val messageWrapper = messageBuilder.buildLimitOrderWrapper(MessageBuilder.buildLimitOrder(assetId = "UnknownAssetPair",
type = LimitOrderType.STOP_LIMIT, lowerPrice = 1.0, lowerLimitPrice = 1.0))
- singleLimitOrderPreprocessor.preProcess(messageWrapper)
-
- val clientHandler = messageWrapper.clientHandler!! as TestClientHandler
- assertEquals(1, clientHandler.responses.size)
- val response = clientHandler.responses.single()
- assertTrue(response is ProtocolMessages.NewResponse)
- response as ProtocolMessages.NewResponse
- assertEquals(MessageStatus.UNKNOWN_ASSET.type, response.status)
-
- assertEquals(0, clientsEventsQueue.size)
+ assertResponse(messageWrapper)
}
}
\ No newline at end of file
diff --git a/src/test/kotlin/com/lykke/matching/engine/performance/AbstractPerformanceTest.kt b/src/test/kotlin/com/lykke/matching/engine/performance/AbstractPerformanceTest.kt
index 9224e5fb7..2ac8eecc0 100644
--- a/src/test/kotlin/com/lykke/matching/engine/performance/AbstractPerformanceTest.kt
+++ b/src/test/kotlin/com/lykke/matching/engine/performance/AbstractPerformanceTest.kt
@@ -25,7 +25,11 @@ import com.lykke.matching.engine.holders.StopOrdersDatabaseAccessorsHolder
import com.lykke.matching.engine.holders.TestUUIDHolder
import com.lykke.matching.engine.incoming.parsers.impl.LimitOrderCancelOperationContextParser
import com.lykke.matching.engine.incoming.parsers.impl.LimitOrderMassCancelOperationContextParser
+import com.lykke.matching.engine.incoming.parsers.impl.MultilimitOrderContextParser
+import com.lykke.matching.engine.incoming.preprocessor.impl.MultilimitOrderPreprocessor
+import com.lykke.matching.engine.incoming.preprocessor.impl.SingleLimitOrderPreprocessor
import com.lykke.matching.engine.matching.MatchingEngine
+import com.lykke.matching.engine.messages.MessageWrapper
import com.lykke.matching.engine.notification.BalanceUpdateHandlerTest
import com.lykke.matching.engine.order.ExecutionDataApplyService
import com.lykke.matching.engine.order.ExecutionPersistenceService
@@ -49,9 +53,11 @@ import com.lykke.matching.engine.outgoing.senders.impl.SpecializedEventSendersHo
import com.lykke.matching.engine.outgoing.senders.impl.OutgoingEventProcessorImpl
import com.lykke.matching.engine.services.*
import com.lykke.matching.engine.services.validators.business.impl.LimitOrderBusinessValidatorImpl
+import com.lykke.matching.engine.services.validators.business.impl.OrderBusinessValidatorImpl
import com.lykke.matching.engine.services.validators.business.impl.StopOrderBusinessValidatorImpl
import com.lykke.matching.engine.services.validators.impl.MarketOrderValidatorImpl
import com.lykke.matching.engine.services.validators.input.impl.LimitOrderInputValidatorImpl
+import com.lykke.matching.engine.services.validators.input.impl.OrderInputValidatorImpl
import com.lykke.matching.engine.utils.MessageBuilder
import com.lykke.utils.logging.ThrottlingLogger
import org.mockito.Mockito
@@ -179,7 +185,9 @@ abstract class AbstractPerformanceTest {
feeProcessor = FeeProcessor(assetsHolder, assetsPairsHolder, genericLimitOrderService)
val messageSequenceNumberHolder = MessageSequenceNumberHolder(TestMessageSequenceNumberDatabaseAccessor())
- val limitOrderInputValidator = LimitOrderInputValidatorImpl(applicationSettingsHolder)
+ val orderInputValidator = OrderInputValidatorImpl(applicationSettingsHolder)
+ val orderBusinessValidator = OrderBusinessValidatorImpl()
+ val limitOrderInputValidator = LimitOrderInputValidatorImpl(applicationSettingsHolder, orderInputValidator)
singleLimitOrderContextParser = SingleLimitOrderContextParser(assetsPairsHolder,
assetsHolder,
applicationSettingsHolder,
@@ -188,11 +196,16 @@ abstract class AbstractPerformanceTest {
cashInOutContextParser = CashInOutContextParser(assetsHolder, uuidHolder)
cashTransferContextParser = CashTransferContextParser(assetsHolder, uuidHolder)
- messageBuilder = MessageBuilder(singleLimitOrderContextParser,
+ messageBuilder = MessageBuilder(SingleLimitOrderPreprocessor(singleLimitOrderContextParser, LinkedBlockingQueue(), messageProcessingStatusHolder, ThrottlingLogger.getLogger("test")),
cashInOutContextParser,
cashTransferContextParser,
LimitOrderCancelOperationContextParser(),
- LimitOrderMassCancelOperationContextParser())
+ LimitOrderMassCancelOperationContextParser(),
+ MultilimitOrderPreprocessor(messageProcessingStatusHolder, limitOrderInputValidator,
+ orderInputValidator,
+ MultilimitOrderContextParser(ThrottlingLogger.getLogger("test"),
+ applicationSettingsHolder, assetsPairsHolder, assetsHolder, uuidHolder),
+ LinkedBlockingQueue(), ThrottlingLogger.getLogger("test")))
genericStopLimitOrderService = GenericStopLimitOrderService(stopOrdersDatabaseAccessorsHolder, expiryOrdersQueue)
@@ -217,14 +230,14 @@ abstract class AbstractPerformanceTest {
val matchingEngine = MatchingEngine(genericLimitOrderService, feeProcessor, uuidHolder)
- val limitOrderProcessor = LimitOrderProcessor(limitOrderInputValidator,
- LimitOrderBusinessValidatorImpl(OrderBookMaxTotalSizeHolderImpl(null)),
+ val limitOrderProcessor = LimitOrderProcessor(
+ LimitOrderBusinessValidatorImpl(orderBusinessValidator, OrderBookMaxTotalSizeHolderImpl(null)),
applicationSettingsHolder,
matchingEngine,
matchingResultHandlingHelper)
- val stopOrderProcessor = StopLimitOrderProcessor(limitOrderInputValidator,
- StopOrderBusinessValidatorImpl(OrderBookMaxTotalSizeHolderImpl(null)),
+ val stopOrderProcessor = StopLimitOrderProcessor(
+ StopOrderBusinessValidatorImpl(orderBusinessValidator, OrderBookMaxTotalSizeHolderImpl(null)),
applicationSettingsHolder,
limitOrderProcessor,
uuidHolder)
@@ -246,14 +259,9 @@ abstract class AbstractPerformanceTest {
stopOrderBookProcessor,
executionDataApplyService,
previousLimitOrdersProcessor,
- assetsHolder,
- assetsPairsHolder,
- balancesHolder,
- applicationSettingsHolder,
- messageProcessingStatusHolder,
- uuidHolder)
+ balancesHolder)
- val marketOrderValidator = MarketOrderValidatorImpl(assetsPairsHolder, assetsHolder, applicationSettingsHolder)
+ val marketOrderValidator = MarketOrderValidatorImpl(assetsPairsHolder, assetsHolder, applicationSettingsHolder, orderInputValidator)
marketOrderService = MarketOrderService(matchingEngine,
executionContextFactory,
stopOrderBookProcessor,
diff --git a/src/test/kotlin/com/lykke/matching/engine/performance/MultiLimitOrderServicePerformanceTest.kt b/src/test/kotlin/com/lykke/matching/engine/performance/MultiLimitOrderServicePerformanceTest.kt
index cb84d95b2..41c28d657 100644
--- a/src/test/kotlin/com/lykke/matching/engine/performance/MultiLimitOrderServicePerformanceTest.kt
+++ b/src/test/kotlin/com/lykke/matching/engine/performance/MultiLimitOrderServicePerformanceTest.kt
@@ -5,7 +5,6 @@ import com.lykke.matching.engine.daos.AssetPair
import com.lykke.matching.engine.daos.IncomingLimitOrder
import com.lykke.matching.engine.daos.setting.AvailableSettingGroup
import com.lykke.matching.engine.utils.MessageBuilder
-import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMultiLimitOrderWrapper
import com.lykke.matching.engine.utils.PrintUtils
import org.junit.Ignore
import org.junit.Test
@@ -56,7 +55,7 @@ class MultiLimitOrderServicePerformanceTest: AbstractPerformanceTest() {
initServices()
counter.executeAction {
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1",
orders = listOf(IncomingLimitOrder(0.1, 2.0),
IncomingLimitOrder(0.1, 1.5),
IncomingLimitOrder(0.09, 1.3),
@@ -74,7 +73,7 @@ class MultiLimitOrderServicePerformanceTest: AbstractPerformanceTest() {
initServices()
counter.executeAction { multiLimitOrderService.processMessage(
- buildMultiLimitOrderWrapper(pair = "EURUSD",
+ messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD",
clientId = "Client1",
orders = listOf(IncomingLimitOrder(100.0, 1.2),
IncomingLimitOrder(100.0, 1.3)),
@@ -88,13 +87,13 @@ class MultiLimitOrderServicePerformanceTest: AbstractPerformanceTest() {
counter.executeAction {
multiLimitOrderService
- .processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders = listOf(IncomingLimitOrder(100.0, 1.2),
+ .processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders = listOf(IncomingLimitOrder(100.0, 1.2),
IncomingLimitOrder(100.0, 1.3)),
cancel = false))
}
counter.executeAction {
multiLimitOrderService
- .processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders = listOf(IncomingLimitOrder(100.0, 1.4),
+ .processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders = listOf(IncomingLimitOrder(100.0, 1.4),
IncomingLimitOrder(100.0, 1.5)),
cancel = false))
}
@@ -107,15 +106,15 @@ class MultiLimitOrderServicePerformanceTest: AbstractPerformanceTest() {
initServices()
counter.executeAction { multiLimitOrderService
- .processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
+ .processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
listOf(IncomingLimitOrder(100.0, 1.2), IncomingLimitOrder(100.0, 1.3)),
cancel = false))}
counter.executeAction { multiLimitOrderService
- .processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
+ .processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
listOf(IncomingLimitOrder(100.0, 1.4), IncomingLimitOrder(100.0, 1.5)),
cancel = false))}
counter.executeAction { multiLimitOrderService
- .processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
+ .processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
listOf(IncomingLimitOrder(100.0, 2.0), IncomingLimitOrder(100.0, 2.1)), cancel = true))}
return counter.getAverageTime()
@@ -125,13 +124,13 @@ class MultiLimitOrderServicePerformanceTest: AbstractPerformanceTest() {
val counter = ActionTimeCounter()
initServices()
- counter.executeAction { multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders = listOf(IncomingLimitOrder(100.0, 1.3),
+ counter.executeAction { multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders = listOf(IncomingLimitOrder(100.0, 1.3),
IncomingLimitOrder(100.0, 1.2)),
cancel = false)) }
singleLimitOrderService.processMessage(messageBuilder.buildLimitOrderWrapper(MessageBuilder.buildLimitOrder(clientId = "Client2", price = 1.25, volume = -150.0)))
- counter.executeAction { multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1",
+ counter.executeAction { multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1",
orders = listOf(IncomingLimitOrder(10.0, 1.3),
IncomingLimitOrder(100.0, 1.26),
IncomingLimitOrder(100.0, 1.2)), cancel = true)) }
@@ -143,14 +142,14 @@ class MultiLimitOrderServicePerformanceTest: AbstractPerformanceTest() {
val counter = ActionTimeCounter()
initServices()
- counter.executeAction { multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders = listOf(IncomingLimitOrder(-100.0, 1.2),
+ counter.executeAction { multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders = listOf(IncomingLimitOrder(-100.0, 1.2),
IncomingLimitOrder(-100.0, 1.3)),
cancel = false)) }
singleLimitOrderService.processMessage(messageBuilder.buildLimitOrderWrapper(MessageBuilder.buildLimitOrder(clientId = "Client2", price = 1.25, volume = 150.0)))
- counter.executeAction { multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1",
+ counter.executeAction { multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1",
orders = listOf(IncomingLimitOrder(-10.0, 1.2),
IncomingLimitOrder(-10.0, 1.24),
IncomingLimitOrder(-10.0, 1.29),
@@ -168,15 +167,15 @@ class MultiLimitOrderServicePerformanceTest: AbstractPerformanceTest() {
testBalanceHolderWrapper.updateBalance("Client5", "TIME", 1000.0)
testBalanceHolderWrapper.updateBalance("Client2", "TIME", 1000.0)
- counter.executeAction { multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "TIMEUSD", clientId = "Client5", orders =
+ counter.executeAction { multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "TIMEUSD", clientId = "Client5", orders =
listOf(IncomingLimitOrder(-100.0, 26.955076)),
cancel = false)) }
- counter.executeAction {multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "TIMEUSD", clientId = "Client5", orders =
+ counter.executeAction {multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "TIMEUSD", clientId = "Client5", orders =
listOf(IncomingLimitOrder(0.69031943, 26.915076)),
cancel = false))}
singleLimitOrderService.processMessage(messageBuilder.buildLimitOrderWrapper(MessageBuilder.buildLimitOrder(assetId = "TIMEUSD", clientId = "Client2", price = 26.88023, volume = -26.0)))
- counter.executeAction {multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "TIMEUSD", clientId = "Client5",
+ counter.executeAction {multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "TIMEUSD", clientId = "Client5",
orders = listOf(IncomingLimitOrder(10.0, 26.915076), IncomingLimitOrder(10.0, 26.875076)), cancel = true))}
return counter.getAverageTime()
@@ -192,22 +191,22 @@ class MultiLimitOrderServicePerformanceTest: AbstractPerformanceTest() {
singleLimitOrderService.processMessage(messageBuilder.buildLimitOrderWrapper(MessageBuilder.buildLimitOrder(assetId = "BTCEUR", clientId = "Client2", price = 3629.355, volume = 0.19259621)))
- counter.executeAction { multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5", orders =
+ counter.executeAction { multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5", orders =
listOf(IncomingLimitOrder(-0.00574996, 3628.707)), cancel = true)) }
- counter.executeAction { multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5",
+ counter.executeAction { multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5",
orders = listOf(IncomingLimitOrder(-0.01431186, 3624.794),
IncomingLimitOrder(-0.02956591, 3626.591)), cancel = true))}
- counter.executeAction {multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5", orders =
+ counter.executeAction {multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5", orders =
listOf(IncomingLimitOrder(-0.04996673, 3625.855)), cancel = true))}
- counter.executeAction {multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5",
+ counter.executeAction {multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5",
orders = listOf(IncomingLimitOrder(-0.00628173, 3622.865),
IncomingLimitOrder(-0.01280207, 3625.489),
IncomingLimitOrder(-0.02201331, 3627.41),
IncomingLimitOrder(-0.02628901, 3629.139)), cancel = true))}
- counter.executeAction {multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5", orders =
+ counter.executeAction {multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5", orders =
listOf(IncomingLimitOrder(-0.01708411, 3626.11)), cancel = true))}
- counter.executeAction {multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5", orders =
+ counter.executeAction {multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5", orders =
listOf(IncomingLimitOrder(-0.00959341, 3625.302)), cancel = true))}
return counter.getAverageTime()
@@ -228,12 +227,12 @@ class MultiLimitOrderServicePerformanceTest: AbstractPerformanceTest() {
singleLimitOrderService.processMessage(messageBuilder.buildLimitOrderWrapper(MessageBuilder.buildLimitOrder(clientId = "Client2", assetId = "BTCCHF", uid = "1", price = 4384.15, volume = -0.26070853)))
- counter.executeAction { multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "BTCCHF", clientId = "Client3", orders =
+ counter.executeAction { multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "BTCCHF", clientId = "Client3", orders =
listOf(IncomingLimitOrder(0.00643271, 4390.84),
IncomingLimitOrder(0.01359005, 4387.87),
IncomingLimitOrder(0.02033985, 4384.811)), cancel = true)) }
- counter.executeAction { multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "BTCCHF", clientId = "Client3",
+ counter.executeAction { multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "BTCCHF", clientId = "Client3",
orders = listOf(IncomingLimitOrder(0.01691068, 4387.21)), cancel = true))}
return counter.getAverageTime()
@@ -252,7 +251,7 @@ class MultiLimitOrderServicePerformanceTest: AbstractPerformanceTest() {
primaryOrdersDatabaseAccessor.addLimitOrder(MessageBuilder.buildLimitOrder(clientId = client, assetId = "BTCEUR", price = 4722.0, volume = 0.14825226))
initServices()
- counter.executeAction { multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = marketMaker, orders =
+ counter.executeAction { multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = marketMaker, orders =
listOf(IncomingLimitOrder(-0.4435, 4721.403)), cancel = true)) }
return counter.getAverageTime()
@@ -273,7 +272,7 @@ class MultiLimitOrderServicePerformanceTest: AbstractPerformanceTest() {
initServices()
- counter.executeAction { multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(clientId = marketMaker, pair = "EURUSD",
+ counter.executeAction { multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(clientId = marketMaker, pair = "EURUSD",
orders = listOf(IncomingLimitOrder(-2.0, 1.1)), cancel = false)) }
return counter.getAverageTime()
@@ -282,10 +281,10 @@ class MultiLimitOrderServicePerformanceTest: AbstractPerformanceTest() {
fun testCancelPreviousOrderWithSameUid(): Double {
val counter = ActionTimeCounter()
- counter.executeAction { multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1",
+ counter.executeAction { multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1",
orders = listOf(IncomingLimitOrder(-9.0, 0.4875, uid = "order1")), cancel = true)) }
- counter.executeAction { multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1",
+ counter.executeAction { multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1",
orders = listOf(IncomingLimitOrder(-10.0, 0.4880, uid = "order1")), cancel = true)) }
return counter.getAverageTime()
diff --git a/src/test/kotlin/com/lykke/matching/engine/services/ClientMultiLimitOrderTest.kt b/src/test/kotlin/com/lykke/matching/engine/services/ClientMultiLimitOrderTest.kt
index fd4f9db1f..53300b4f0 100644
--- a/src/test/kotlin/com/lykke/matching/engine/services/ClientMultiLimitOrderTest.kt
+++ b/src/test/kotlin/com/lykke/matching/engine/services/ClientMultiLimitOrderTest.kt
@@ -21,7 +21,6 @@ import com.lykke.matching.engine.outgoing.messages.v2.events.ExecutionEvent
import com.lykke.matching.engine.utils.MessageBuilder
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildLimitOrder
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildLimitOrderFeeInstructions
-import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMultiLimitOrderWrapper
import com.lykke.matching.engine.utils.assertEquals
import com.lykke.matching.engine.utils.getSetting
import org.junit.Before
@@ -79,22 +78,9 @@ class ClientMultiLimitOrderTest : AbstractTest() {
initServices()
}
- @Test
- fun testUnknownAssetPair() {
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("UnknownAssetPair", "Client1",
- listOf(IncomingLimitOrder(-0.1, 10000.0),
- IncomingLimitOrder(-0.1, 11000.0),
- IncomingLimitOrder(0.1, 9000.0),
- IncomingLimitOrder(0.1, 8000.0))))
- assertEquals(0, clientsEventsQueue.size)
- assertEquals(0, trustedClientsEventsQueue.size)
- assertOrderBookSize("UnknownAssetPair", false, 0)
- assertOrderBookSize("UnknownAssetPair", true, 0)
- }
-
@Test
fun testAdd() {
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "Client1",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "Client1",
listOf(
IncomingLimitOrder(-0.1, 10000.0, "1"),
IncomingLimitOrder(-0.2, 10500.0, "2"),
@@ -146,7 +132,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
@Test
fun testAddOneSide() {
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "Client1",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "Client1",
listOf(
IncomingLimitOrder(-0.1, 10000.0),
IncomingLimitOrder(-0.2, 10500.0)
@@ -192,7 +178,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
clearMessageQueues()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "Client1",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "Client1",
listOf(
IncomingLimitOrder(-0.1, 10000.0),
IncomingLimitOrder(-0.2, 10500.0),
@@ -252,7 +238,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
clearMessageQueues()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "Client1",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "Client1",
listOf(
IncomingLimitOrder(-0.1, 10000.0),
IncomingLimitOrder(-0.2, 10500.0),
@@ -289,7 +275,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
@Test
fun testAddNotEnoughFundsOrder() {
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "Client1",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "Client1",
listOf(
IncomingLimitOrder(-0.1, 10000.0, "1"),
IncomingLimitOrder(-0.2, 10500.0, "2"),
@@ -345,7 +331,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
initServices()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "TrustedClient", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "TrustedClient", listOf(
IncomingLimitOrder(-0.3, 10800.0, "3"),
IncomingLimitOrder(-0.4, 10900.0, "2"),
IncomingLimitOrder(0.1, 9500.0, "6"),
@@ -357,7 +343,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
fees = buildLimitOrderFeeInstructions(FeeType.CLIENT_FEE, makerSize = 0.05, targetClientId = "TargetClient", assetIds = listOf("BTC"))
)))
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "Client2", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "Client2", listOf(
IncomingLimitOrder(-0.1, 10000.0, "5"),
IncomingLimitOrder(-0.5, 11000.0, "1"),
IncomingLimitOrder(0.3, 9000.0, "8"),
@@ -366,7 +352,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
clearMessageQueues()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "Client1", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "Client1", listOf(
IncomingLimitOrder(-0.1, 11500.0, "14"),
IncomingLimitOrder(0.05, 11000.0, "12"),
IncomingLimitOrder(0.2, 10800.0, "13"),
@@ -442,7 +428,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
@Test
fun testNegativeSpread() {
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "Client1", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "Client1", listOf(
IncomingLimitOrder(-0.1, 10000.0),
IncomingLimitOrder(0.1, 10100.0)
)))
@@ -468,7 +454,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
singleLimitOrderService.processMessage(messageBuilder.buildLimitOrderWrapper(buildLimitOrder(clientId = "Client2", assetId = "BTCUSD", volume = -0.3, price = 9500.0)))
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "Client1", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "Client1", listOf(
IncomingLimitOrder(0.1, 9000.0),
IncomingLimitOrder(0.1, 8000.0),
IncomingLimitOrder(0.1, 7000.0)
@@ -476,7 +462,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
clearMessageQueues()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "Client1", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "Client1", listOf(
IncomingLimitOrder(0.1, 10000.0),
IncomingLimitOrder(0.01, 9500.0),
IncomingLimitOrder(0.1, 9000.0),
@@ -500,7 +486,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
}
private fun setOrder() {
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "Client1", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "Client1", listOf(
IncomingLimitOrder(-0.4, 9200.0),
IncomingLimitOrder(-0.3, 9100.0),
IncomingLimitOrder(-0.2, 9000.0),
@@ -514,7 +500,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
fun testEmptyOrderWithCancelPreviousBothSides() {
setOrder()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "Client1", orders = emptyList(),
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "Client1", orders = emptyList(),
cancel = true, cancelMode = OrderCancelMode.BOTH_SIDES))
assertOrderBookSize("BTCUSD", true, 0)
@@ -537,7 +523,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
fun testOneSideOrderWithCancelPreviousBothSides() {
setOrder()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "Client1",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "Client1",
listOf(IncomingLimitOrder(-0.4, 9100.0, "1"),
IncomingLimitOrder(-0.3, 9000.0, "2")),
cancel = true, cancelMode = OrderCancelMode.BOTH_SIDES))
@@ -557,7 +543,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
fun testBothSidesOrderWithCancelPreviousOneSide() {
setOrder()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "Client1",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "Client1",
listOf(IncomingLimitOrder(-0.01, 9100.0, "1"),
IncomingLimitOrder(-0.009, 9000.0, "2"),
IncomingLimitOrder(0.2, 7900.0, "3")),
@@ -581,7 +567,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
testOrderBookWrapper.addLimitOrder(buildLimitOrder(uid = "ClientOrder", clientId = "Client2", assetId = "BTCUSD", volume = -0.1, price = 8000.0))
initServices()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "Client1", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "Client1", listOf(
IncomingLimitOrder(-0.4, 9300.0, "Ask-ToReplace-2"),
IncomingLimitOrder(-0.3, 9200.0, "Ask-ToReplace-1"),
IncomingLimitOrder(-0.2, 9100.0, "Ask-ToCancel-2"),
@@ -592,7 +578,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
)))
clearMessageQueues()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "Client1", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "Client1", listOf(
IncomingLimitOrder(-0.2, 9400.0, "NotFoundPrevious-1", oldUid = "NotExist-1"),
IncomingLimitOrder(-0.2, 9300.0, "ask2", oldUid = "Ask-ToReplace-2"),
IncomingLimitOrder(-0.3, 9200.0, "ask3", oldUid = "Ask-ToReplace-1"),
@@ -682,7 +668,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
@Test
fun testAddLimitOrderWithSameReserveSum() {
//Do not send balance update if balances didn't change
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("EURUSD", "Client2", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("EURUSD", "Client2", listOf(
IncomingLimitOrder(100.0, 1.2, "1"),
IncomingLimitOrder(100.0, 1.3, "2")
)))
@@ -705,7 +691,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
assertEquals(1, event.balanceUpdates?.size)
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("EURUSD", "Client2", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("EURUSD", "Client2", listOf(
IncomingLimitOrder(100.0, 1.2, "3", oldUid = "1"),
IncomingLimitOrder(100.0, 1.3, "4", oldUid = "2")
)))
@@ -732,7 +718,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
testOrderBookWrapper.addLimitOrder(buildLimitOrder(uid = "orderWithAnotherClient", assetId = "BTCUSD", clientId = "Client2",
volume = 1.0, price = 1.0))
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "BTCUSD", clientId = "Client1",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "BTCUSD", clientId = "Client1",
orders = listOf(IncomingLimitOrder(oldUid = "orderWithAnotherPair", volume = 1.1, price = 1.0),
IncomingLimitOrder(oldUid = "orderWithAnotherClient", volume = 1.1, price = 1.0)), cancel = false))
@@ -792,7 +778,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
initServices()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(clientId = "Client4", pair = "BTCUSD",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(clientId = "Client4", pair = "BTCUSD",
orders = listOf(IncomingLimitOrder(volume = 2.0, price = -4.0, uid = "IncomingInvalidPrice"),
IncomingLimitOrder(volume = 2.0, type = LimitOrderType.STOP_LIMIT, upperLimitPrice = 206.0, upperPrice = 210.0, uid = "Incoming-1", oldUid = "ToReplace"),
IncomingLimitOrder(volume = 0.5, price = 220.0, uid = "Incoming-2")), cancel = true, cancelMode = OrderCancelMode.SELL_SIDE))
@@ -920,7 +906,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
testOrderBookWrapper.addLimitOrder(buildLimitOrder(clientId = "TrustedClient", assetId = "EURUSD", volume = -9.0, price = 1.1))
testOrderBookWrapper.addLimitOrder(buildLimitOrder(clientId = "Client1", assetId = "EURUSD", volume = -5.0, price = 1.2))
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("EURUSD", "Client2",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("EURUSD", "Client2",
listOf(IncomingLimitOrder(volume = 1.0, price = 1.4, uid = "matched1"),
IncomingLimitOrder(volume = 3.0, price = 1.3, uid = "matched2"),
IncomingLimitOrder(volume = 5.0, price = 1.2, uid = "rejectedAfterMatching",
@@ -976,7 +962,7 @@ class ClientMultiLimitOrderTest : AbstractTest() {
testOrderBookWrapper.addLimitOrder(buildLimitOrder(clientId = "Client1", assetId = "EURUSD", volume = -5.0, price = 1.2))
testOrderBookWrapper.addLimitOrder(buildLimitOrder(clientId = "Client1", assetId = "EURUSD", volume = -3.0, price = 1.4))
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("EURUSD", "Client2",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("EURUSD", "Client2",
listOf(IncomingLimitOrder(volume = 1.0, price = 1.4),
IncomingLimitOrder(volume = 3.0, price = 1.3),
IncomingLimitOrder(volume = 5.0, price = 1.2))))
diff --git a/src/test/kotlin/com/lykke/matching/engine/services/InvalidBalanceTest.kt b/src/test/kotlin/com/lykke/matching/engine/services/InvalidBalanceTest.kt
index e127745f5..28fd6df1b 100644
--- a/src/test/kotlin/com/lykke/matching/engine/services/InvalidBalanceTest.kt
+++ b/src/test/kotlin/com/lykke/matching/engine/services/InvalidBalanceTest.kt
@@ -19,7 +19,6 @@ import com.lykke.matching.engine.utils.MessageBuilder
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildLimitOrder
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMarketOrder
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMarketOrderWrapper
-import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMultiLimitOrderWrapper
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -219,7 +218,7 @@ class InvalidBalanceTest : AbstractTest() {
applicationSettingsCache.createOrUpdateSettingValue(AvailableSettingGroup.TRUSTED_CLIENTS, "Client1", "Client1", true)
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("ETHUSD", "Client1", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("ETHUSD", "Client1", listOf(
IncomingLimitOrder(-0.1, 1000.0, "1"),
IncomingLimitOrder(-0.05, 1010.0, "2"),
IncomingLimitOrder(-0.1, 1100.0, "3")
@@ -265,7 +264,7 @@ class InvalidBalanceTest : AbstractTest() {
initServices()
applicationSettingsCache.createOrUpdateSettingValue(AvailableSettingGroup.TRUSTED_CLIENTS, "Client1", "Client1", true)
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("ETHUSD", "Client1",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("ETHUSD", "Client1",
listOf(IncomingLimitOrder(-0.05, 1010.0, "1"))))
testBalanceHolderWrapper.updateBalance("Client1", "ETH", 0.04)
testSettingDatabaseAccessor.clear()
diff --git a/src/test/kotlin/com/lykke/matching/engine/services/LimitOrderMassCancelServiceTest.kt b/src/test/kotlin/com/lykke/matching/engine/services/LimitOrderMassCancelServiceTest.kt
index c6e02012d..9d72f72f3 100644
--- a/src/test/kotlin/com/lykke/matching/engine/services/LimitOrderMassCancelServiceTest.kt
+++ b/src/test/kotlin/com/lykke/matching/engine/services/LimitOrderMassCancelServiceTest.kt
@@ -18,7 +18,6 @@ import com.lykke.matching.engine.outgoing.messages.LimitOrdersReport
import com.lykke.matching.engine.outgoing.messages.v2.events.ExecutionEvent
import com.lykke.matching.engine.utils.MessageBuilder
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildLimitOrder
-import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMultiLimitOrderWrapper
import com.lykke.matching.engine.utils.assertEquals
import com.lykke.matching.engine.utils.getSetting
import org.junit.Before
@@ -95,14 +94,13 @@ class LimitOrderMassCancelServiceTest : AbstractTest() {
lowerLimitPrice = 101.0,
lowerPrice = 100.0)))
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("EURUSD", "TrustedClient", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("EURUSD", "TrustedClient", listOf(
IncomingLimitOrder(-5.0, 1.3, "m1"),
IncomingLimitOrder(5.0, 1.1, "m2")
)))
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "TrustedClient", listOf(
- IncomingLimitOrder(-1.0, 8500.0, "m3")
- )))
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "TrustedClient", listOf(
+ IncomingLimitOrder(-1.0, 8500.0, "m3"))))
assertOrderBookSize("BTCUSD", false, 3)
assertOrderBookSize("BTCUSD", true, 1)
diff --git a/src/test/kotlin/com/lykke/matching/engine/services/MinRemainingVolumeTest.kt b/src/test/kotlin/com/lykke/matching/engine/services/MinRemainingVolumeTest.kt
index c421e9ab8..ccf833ff6 100644
--- a/src/test/kotlin/com/lykke/matching/engine/services/MinRemainingVolumeTest.kt
+++ b/src/test/kotlin/com/lykke/matching/engine/services/MinRemainingVolumeTest.kt
@@ -16,7 +16,6 @@ import com.lykke.matching.engine.utils.MessageBuilder
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildLimitOrder
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMarketOrder
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMarketOrderWrapper
-import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMultiLimitOrderWrapper
import com.lykke.matching.engine.utils.getSetting
import org.junit.Before
import org.junit.Test
@@ -165,7 +164,7 @@ class MinRemainingVolumeTest : AbstractTest() {
testBalanceHolderWrapper.updateBalance("TrustedClient", "USD", 1800.0)
initServices()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "TrustedClient", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "TrustedClient", listOf(
IncomingLimitOrder(0.11, 9000.0),
IncomingLimitOrder(0.0891, 8900.0))))
@@ -193,7 +192,7 @@ class MinRemainingVolumeTest : AbstractTest() {
singleLimitOrderService.processMessage(messageBuilder.buildLimitOrderWrapper(buildLimitOrder(clientId = "Client1", assetId = "BTCUSD", volume = 0.1, price = 6900.0)))
clearMessageQueues()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "TrustedClient", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "TrustedClient", listOf(
IncomingLimitOrder(-0.11, 6800.0, "order1"),
IncomingLimitOrder(-0.0909, 6900.0, "order2"))))
diff --git a/src/test/kotlin/com/lykke/matching/engine/services/MultiLimitOrderServiceTest.kt b/src/test/kotlin/com/lykke/matching/engine/services/MultiLimitOrderServiceTest.kt
index 6782f05b7..333cdef88 100644
--- a/src/test/kotlin/com/lykke/matching/engine/services/MultiLimitOrderServiceTest.kt
+++ b/src/test/kotlin/com/lykke/matching/engine/services/MultiLimitOrderServiceTest.kt
@@ -17,7 +17,6 @@ import com.lykke.matching.engine.outgoing.messages.v2.events.ExecutionEvent
import com.lykke.matching.engine.utils.MessageBuilder
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildLimitOrder
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMultiLimitOrderCancelWrapper
-import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMultiLimitOrderWrapper
import com.lykke.matching.engine.utils.NumberUtils
import com.lykke.matching.engine.utils.assertEquals
import com.lykke.matching.engine.utils.balance.ReservedVolumesRecalculator
@@ -28,7 +27,6 @@ import org.junit.runner.RunWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.TestConfiguration
-import org.springframework.context.ApplicationEventPublisher
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Primary
import org.springframework.test.annotation.DirtiesContext
@@ -43,7 +41,6 @@ import com.lykke.matching.engine.outgoing.messages.v2.enums.OrderStatus as Outgo
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class MultiLimitOrderServiceTest: AbstractTest() {
-
@TestConfiguration
open class Config {
@Bean
@@ -105,7 +102,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
initServices()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1",
orders = listOf(
IncomingLimitOrder(0.1, 2.0),
IncomingLimitOrder(0.1, 1.5),
@@ -137,7 +134,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
@Test
fun testAddLimitOrder() {
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
listOf(IncomingLimitOrder(100.0, 1.2), IncomingLimitOrder(100.0, 1.3))))
assertEquals(BigDecimal.valueOf(1000.0), testWalletDatabaseAccessor.getBalance("Client1", "USD"))
@@ -164,7 +161,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
@Test
fun testAdd2LimitOrder() {
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
listOf(IncomingLimitOrder(100.0, 1.2), IncomingLimitOrder(100.0, 1.3))))
assertEquals(BigDecimal.valueOf(1000.0), testWalletDatabaseAccessor.getBalance("Client1", "USD"))
@@ -183,7 +180,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
assertEquals("1.3", event.orders[1].price)
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
listOf(IncomingLimitOrder(100.0, 1.4), IncomingLimitOrder(100.0, 1.5)),
cancel = false))
@@ -202,7 +199,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
@Test
fun testAddAndCancelLimitOrder() {
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
listOf(IncomingLimitOrder(100.0, 1.2), IncomingLimitOrder(100.0, 1.3))))
assertEquals(BigDecimal.valueOf(1000.0), testWalletDatabaseAccessor.getBalance("Client1", "USD"))
@@ -221,7 +218,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
assertEquals("1.2", event.orders[0].price)
assertEquals("1.3", event.orders[1].price)
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
listOf(IncomingLimitOrder(100.0, 1.4), IncomingLimitOrder(100.0, 1.5)),
cancel = false))
@@ -238,7 +235,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
assertEquals("1.4", event.orders[0].price)
assertEquals("1.5", event.orders[1].price)
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
listOf(IncomingLimitOrder(100.0, 2.0), IncomingLimitOrder(100.0, 2.1)), cancel = true))
assertEquals(1, testTrustedClientsLimitOrderListener.getCount())
@@ -265,7 +262,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
@Test
fun testAddAndMatchLimitOrder() {
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
listOf(IncomingLimitOrder(100.0, 1.3), IncomingLimitOrder(100.0, 1.2))))
assertEquals(1, testTrustedClientsLimitOrderListener.getCount())
@@ -296,7 +293,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
assertEquals(BigDecimal.valueOf(50.0), testWalletDatabaseAccessor.getReservedBalance("Client2", "EUR"))
assertOrderBookSize("EURUSD", true, 1)
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
listOf(IncomingLimitOrder(10.0, 1.3), IncomingLimitOrder(100.0, 1.26),
IncomingLimitOrder(100.0, 1.2)), cancel = true))
@@ -338,7 +335,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
@Test
fun testAddAndMatchLimitOrder2() {
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
listOf(IncomingLimitOrder(-100.0, 1.2), IncomingLimitOrder(-100.0, 1.3))))
assertEquals(1, testTrustedClientsLimitOrderListener.getCount())
@@ -369,7 +366,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
assertEquals(BigDecimal.valueOf(1100.0), testWalletDatabaseAccessor.getBalance("Client2", "EUR"))
assertEquals(BigDecimal.valueOf(62.5), testWalletDatabaseAccessor.getReservedBalance("Client2", "USD"))
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
listOf(IncomingLimitOrder(-10.0, 1.2),
IncomingLimitOrder(-10.0, 1.24),
IncomingLimitOrder(-10.0, 1.29),
@@ -421,9 +418,9 @@ class MultiLimitOrderServiceTest: AbstractTest() {
initServices()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "TIMEUSD", clientId = "Client5", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "TIMEUSD", clientId = "Client5", orders =
listOf(IncomingLimitOrder(-100.0, 26.955076))))
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "TIMEUSD", clientId = "Client5", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "TIMEUSD", clientId = "Client5", orders =
listOf(IncomingLimitOrder(0.69031943, 26.915076))))
assertEquals(2, testTrustedClientsLimitOrderListener.getCount())
@@ -468,7 +465,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
assertEquals(BigDecimal.valueOf(999.30968057), testWalletDatabaseAccessor.getBalance("Client2", "TIME"))
assertEquals(BigDecimal.valueOf(25.30968057), testWalletDatabaseAccessor.getReservedBalance("Client2", "TIME"))
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "TIMEUSD", clientId = "Client5", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "TIMEUSD", clientId = "Client5", orders =
listOf(IncomingLimitOrder(10.0, 26.915076), IncomingLimitOrder(10.0, 26.875076)), cancel = true))
assertEquals(0, testClientLimitOrderListener.getCount())
@@ -506,7 +503,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
assertEquals(OutgoingOrderStatus.PLACED, event.orders[0].status)
assertEquals("0.19259621", event.orders[0].remainingVolume)
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5", orders =
listOf(IncomingLimitOrder(-0.00574996, 3628.707)), cancel = true))
result = testClientLimitOrderListener.getQueue().poll() as LimitOrdersReport
assertEquals(OrderStatus.Matched.name, result.orders[0].order.status)
@@ -520,7 +517,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
assertEquals(OutgoingOrderStatus.PARTIALLY_MATCHED, event.orders[1].status)
assertEquals("0.18684625", event.orders[1].remainingVolume)
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5", orders =
listOf(IncomingLimitOrder(-0.01431186, 3624.794),
IncomingLimitOrder(-0.02956591, 3626.591)), cancel = true))
result = testClientLimitOrderListener.getQueue().poll() as LimitOrdersReport
@@ -537,7 +534,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
assertEquals("0.14296848", event.orders[1].remainingVolume)
assertEquals(OutgoingOrderStatus.MATCHED, event.orders[2].status)
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5", orders =
listOf(IncomingLimitOrder(-0.04996673, 3625.855)), cancel = true))
result = testClientLimitOrderListener.getQueue().poll() as LimitOrdersReport
assertEquals(OrderStatus.Matched.name, result.orders[0].order.status)
@@ -551,7 +548,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
assertEquals(OutgoingOrderStatus.PARTIALLY_MATCHED, event.orders[1].status)
assertEquals("0.09300175", event.orders[1].remainingVolume)
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5", orders =
listOf(IncomingLimitOrder(-0.00628173, 3622.865),
IncomingLimitOrder(-0.01280207, 3625.489),
IncomingLimitOrder(-0.02201331, 3627.41),
@@ -574,7 +571,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
assertEquals(OutgoingOrderStatus.MATCHED, event.orders[3].status)
assertEquals(OutgoingOrderStatus.MATCHED, event.orders[4].status)
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5", orders =
listOf(IncomingLimitOrder(-0.01708411, 3626.11)), cancel = true))
result = testClientLimitOrderListener.getQueue().poll() as LimitOrdersReport
assertEquals(OrderStatus.Matched.name, result.orders[0].order.status)
@@ -588,7 +585,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
assertEquals(OutgoingOrderStatus.PARTIALLY_MATCHED, event.orders[1].status)
assertEquals("0.00853152", event.orders[1].remainingVolume)
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = "Client5", orders =
listOf(IncomingLimitOrder(-0.00959341, 3625.302)), cancel = true))
result = testClientLimitOrderListener.getQueue().poll() as LimitOrdersReport
assertEquals(OrderStatus.Processing.name, result.orders[0].order.status)
@@ -634,7 +631,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
var event = clientsEventsQueue.poll() as ExecutionEvent
assertEquals(OutgoingOrderStatus.PLACED, event.orders[0].status)
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "BTCCHF", clientId = "Client3", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "BTCCHF", clientId = "Client3", orders =
listOf(IncomingLimitOrder(0.00643271, 4390.84),
IncomingLimitOrder(0.01359005, 4387.87),
IncomingLimitOrder(0.02033985, 4384.811)), cancel = true))
@@ -654,7 +651,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
assertEquals(OutgoingOrderStatus.MATCHED, event.orders[2].status)
assertEquals(OutgoingOrderStatus.MATCHED, event.orders[3].status)
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "BTCCHF", clientId = "Client3", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "BTCCHF", clientId = "Client3", orders =
listOf(IncomingLimitOrder(0.01691068, 4387.21)), cancel = true))
result = testClientLimitOrderListener.getQueue().poll() as LimitOrdersReport
assertEquals(OrderStatus.Matched.name, result.orders[0].order.status)
@@ -692,7 +689,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
var event = clientsEventsQueue.poll() as ExecutionEvent
assertEquals(OutgoingOrderStatus.PLACED, event.orders[0].status)
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "BTCCHF", clientId = "Client3", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "BTCCHF", clientId = "Client3", orders =
listOf(IncomingLimitOrder(0.00643271, 4390.84),
IncomingLimitOrder(0.01359005, 4387.87),
IncomingLimitOrder(0.02033985, 4384.811)), cancel = true))
@@ -726,7 +723,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
testOrderBookWrapper.addLimitOrder(buildLimitOrder(clientId = client, assetId = "BTCEUR", price = 4722.0, volume = 0.14825226))
initServices()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = marketMaker, orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "BTCEUR", clientId = marketMaker, orders =
listOf(IncomingLimitOrder(-0.4435, 4721.403)), cancel = true))
assertEquals(1, testClientLimitOrderListener.getCount())
@@ -756,7 +753,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
singleLimitOrderService.processMessage(messageBuilder.buildLimitOrderWrapper(buildLimitOrder(clientId = client, assetId = "EURUSD", price = 1.2, volume = -50.0)))
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(
pair = "EURUSD",
clientId = marketMaker,
orders = listOf(
@@ -788,7 +785,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
initServices()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(
clientId = marketMaker, pair = "EURUSD",
orders = listOf(
IncomingLimitOrder(2.0, 1.20),
@@ -844,7 +841,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
initServices()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(clientId = marketMaker, pair = "EURUSD", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(clientId = marketMaker, pair = "EURUSD", orders =
listOf(IncomingLimitOrder(-2.0, 1.1)), cancel = false))
assertEquals(0, testOrderDatabaseAccessor.getOrders("EURUSD", true).size)
@@ -882,12 +879,12 @@ class MultiLimitOrderServiceTest: AbstractTest() {
@Test
fun testCancelPreviousOrderWithSameUid() {
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
listOf(IncomingLimitOrder(-9.0, 0.4875, uid = "orders")),
cancel = true))
clearMessageQueues()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(pair = "EURUSD", clientId = "Client1", orders =
listOf(IncomingLimitOrder(-10.0, 0.4880, uid = "order1")),
cancel = true))
@@ -925,7 +922,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
testBalanceHolderWrapper.updateBalance("Client1", "EUR", 3000.0)
initServices()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCEUR", "Client1", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCEUR", "Client1", listOf(
IncomingLimitOrder(-0.4, 9200.0),
IncomingLimitOrder(-0.3, 9100.0),
IncomingLimitOrder(-0.2, 9000.0),
@@ -939,7 +936,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
fun testEmptyOrderWithCancelPreviousBothSides() {
setOrder()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCEUR", "Client1", orders = emptyList(),
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCEUR", "Client1", orders = emptyList(),
cancel = true, cancelMode = OrderCancelMode.BOTH_SIDES))
assertOrderBookSize("BTCEUR", true, 0)
@@ -960,7 +957,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
fun testOneSideOrderWithCancelPreviousBothSides() {
setOrder()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCEUR", "Client1",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCEUR", "Client1",
listOf(IncomingLimitOrder(-0.4, 9100.0, "1"),
IncomingLimitOrder(-0.3, 9000.0, "2")),
cancel = true, cancelMode = OrderCancelMode.BOTH_SIDES))
@@ -980,7 +977,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
fun testBothSidesOrderWithCancelPreviousOneSide() {
setOrder()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCEUR", "Client1",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCEUR", "Client1",
listOf(IncomingLimitOrder(-0.01, 9100.0, "1"),
IncomingLimitOrder(-0.009, 9000.0, "2"),
IncomingLimitOrder(0.2, 7900.0, "3")),
@@ -1007,7 +1004,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
testOrderBookWrapper.addLimitOrder(buildLimitOrder(uid = "ClientOrder", clientId = "Client2", assetId = "BTCEUR", volume = -0.1, price = 8000.0))
initServices()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCEUR", "Client1", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCEUR", "Client1", listOf(
IncomingLimitOrder(-0.4, 9300.0, "Ask-ToReplace-2"),
IncomingLimitOrder(-0.3, 9200.0, "Ask-ToReplace-1"),
IncomingLimitOrder(-0.2, 9100.0, "Ask-ToCancel-2"),
@@ -1018,7 +1015,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
)))
clearMessageQueues()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCEUR", "Client1", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCEUR", "Client1", listOf(
IncomingLimitOrder(-0.2, 9400.0, "NotFoundPrevious-1", oldUid = "NotExist-1"),
IncomingLimitOrder(-0.2, 9300.0, "ask2", oldUid = "Ask-ToReplace-2"),
IncomingLimitOrder(-0.3, 9200.0, "ask3", oldUid = "Ask-ToReplace-1"),
@@ -1097,13 +1094,13 @@ class MultiLimitOrderServiceTest: AbstractTest() {
@Test
fun testReplaceOrderWithNotEnoughFunds() {
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("EURUSD", "Client1", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("EURUSD", "Client1", listOf(
IncomingLimitOrder(-100.0, 1.2, "0"),
IncomingLimitOrder(-400.0, 1.3, "1"),
IncomingLimitOrder(-400.0, 1.4, "2")
), cancel = false))
clearMessageQueues()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("EURUSD", "Client1", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("EURUSD", "Client1", listOf(
IncomingLimitOrder(-700.0, 1.3, "3", oldUid = "1"),
IncomingLimitOrder(-400.0, 1.5, "4", oldUid = "2")
), cancel = false))
@@ -1140,7 +1137,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
initServices()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("EURUSD",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("EURUSD",
"Client1",
listOf(IncomingLimitOrder(10.0, 1.3, "1"))))
@@ -1222,7 +1219,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
order10,
order9)
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("EURUSD",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("EURUSD",
"Client1",
orders))
}
@@ -1251,7 +1248,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
@Test
fun testRejectRoundingOrdersWithNotEnoughFunds() {
testBalanceHolderWrapper.updateBalance("Client1", "EUR", 50.02)
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCEUR",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCEUR",
"Client1",
listOf(IncomingLimitOrder(0.005, 5003.0, "1"),//25.015
IncomingLimitOrder(0.005, 5001.0, "2")))) //25.005
@@ -1278,7 +1275,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
singleLimitOrderService.processMessage(messageBuilder.buildLimitOrderWrapper(buildLimitOrder(assetId = "BTCUSD", price = 4999.0, volume = 0.01, clientId = "Client3")))
clearMessageQueues()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "Client1", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "Client1", listOf(
IncomingLimitOrder(-0.01000199, 4998.0, "order1"),
IncomingLimitOrder(-0.01, 4999.0, "order2")
)))
@@ -1322,7 +1319,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
maxValue = BigDecimal.valueOf(10000.0)))
assetPairsCache.update()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "Client1", listOf(IncomingLimitOrder(-1.1, 10000.0))))
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "Client1", listOf(IncomingLimitOrder(-1.1, 10000.0))))
assertOrderBookSize("BTCUSD", false, 0)
}
@@ -1334,7 +1331,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
maxVolume = BigDecimal.valueOf(1.0)))
assetPairsCache.update()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "Client1", listOf(IncomingLimitOrder(-1.1, 10000.0))))
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "Client1", listOf(IncomingLimitOrder(-1.1, 10000.0))))
assertOrderBookSize("BTCUSD", false, 0)
}
@@ -1374,7 +1371,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
volume = -10.0,
price = 10.0))
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(clientId = "Client1",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(clientId = "Client1",
pair = "EURUSD",
orders = listOf(IncomingLimitOrder(6.0, 11.0, uid = "Matched", timeInForce = OrderTimeInForce.IOC),
IncomingLimitOrder(6.0, 10.0, uid = "PartiallyMatched", timeInForce = OrderTimeInForce.IOC),
@@ -1408,7 +1405,7 @@ class MultiLimitOrderServiceTest: AbstractTest() {
volume = -10.0,
price = 10.0))
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(clientId = "Client1",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(clientId = "Client1",
pair = "EURUSD",
orders = listOf(IncomingLimitOrder(6.0, 11.0, uid = "Matched", timeInForce = OrderTimeInForce.FOK),
IncomingLimitOrder(6.0, 10.0, uid = "PartiallyMatched", timeInForce = OrderTimeInForce.FOK),
diff --git a/src/test/kotlin/com/lykke/matching/engine/services/NegativePriceTest.kt b/src/test/kotlin/com/lykke/matching/engine/services/NegativePriceTest.kt
index 40747e8a1..6b9b07b51 100644
--- a/src/test/kotlin/com/lykke/matching/engine/services/NegativePriceTest.kt
+++ b/src/test/kotlin/com/lykke/matching/engine/services/NegativePriceTest.kt
@@ -11,7 +11,6 @@ import com.lykke.matching.engine.order.OrderStatus
import com.lykke.matching.engine.outgoing.messages.LimitOrdersReport
import com.lykke.matching.engine.utils.MessageBuilder
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildLimitOrder
-import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMultiLimitOrderWrapper
import com.lykke.matching.engine.utils.getSetting
import org.junit.Before
import org.junit.Test
@@ -77,7 +76,7 @@ class NegativePriceTest : AbstractTest() {
initServices()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("EURUSD",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("EURUSD",
"Client",
listOf(
IncomingLimitOrder(1.0, 1.0, uid = "order1"),
diff --git a/src/test/kotlin/com/lykke/matching/engine/services/OrderBookMaxSizeTest.kt b/src/test/kotlin/com/lykke/matching/engine/services/OrderBookMaxSizeTest.kt
index a1da0af2b..e0de769ba 100644
--- a/src/test/kotlin/com/lykke/matching/engine/services/OrderBookMaxSizeTest.kt
+++ b/src/test/kotlin/com/lykke/matching/engine/services/OrderBookMaxSizeTest.kt
@@ -18,7 +18,6 @@ import com.lykke.matching.engine.utils.MessageBuilder
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildLimitOrder
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMarketOrder
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMarketOrderWrapper
-import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMultiLimitOrderWrapper
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -140,7 +139,7 @@ class OrderBookMaxSizeTest : AbstractTest() {
fun testMultiLimitOrder() {
setMaxSizeOrderBook()
- val messageWrapper = buildMultiLimitOrderWrapper(
+ val messageWrapper = messageBuilder.buildMultiLimitOrderWrapper(
"EURUSD", "Client1", listOf(IncomingLimitOrder(-200.0, 3.0, "order1"),
IncomingLimitOrder(-200.0, 3.1, uid = "order2")))
multiLimitOrderService.processMessage(messageWrapper)
diff --git a/src/test/kotlin/com/lykke/matching/engine/services/PersistenceErrorTest.kt b/src/test/kotlin/com/lykke/matching/engine/services/PersistenceErrorTest.kt
index de74331d8..24f3b4e35 100644
--- a/src/test/kotlin/com/lykke/matching/engine/services/PersistenceErrorTest.kt
+++ b/src/test/kotlin/com/lykke/matching/engine/services/PersistenceErrorTest.kt
@@ -14,7 +14,6 @@ import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildLimitOrder
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMarketOrder
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMarketOrderWrapper
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMultiLimitOrderCancelWrapper
-import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMultiLimitOrderWrapper
import com.lykke.matching.engine.utils.getSetting
import org.junit.After
import org.junit.Before
@@ -79,7 +78,7 @@ class PersistenceErrorTest : AbstractTest() {
clientId = "Client1", assetId = "EURUSD", volume = 1.0, price = 2.0, uid = "order1"
)))
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("EURUSD", "TrustedClient",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("EURUSD", "TrustedClient",
listOf(IncomingLimitOrder(-1.0, 3.0, "order2"),
IncomingLimitOrder(-2.0, 3.1, "order3"),
IncomingLimitOrder(-3.0, 3.2, "order4"),
@@ -272,7 +271,7 @@ class PersistenceErrorTest : AbstractTest() {
@Test
fun testTrustedClientMultiLimitOrder() {
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(
"EURUSD", "TrustedClient",
listOf(IncomingLimitOrder(-1.0, 3.1),
IncomingLimitOrder(-2.0, 3.19),
@@ -285,7 +284,7 @@ class PersistenceErrorTest : AbstractTest() {
@Test
fun testClientMultiLimitOrder() {
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(
"EURUSD", "Client3",
listOf(IncomingLimitOrder(-1.0, 3.1),
IncomingLimitOrder(-2.0, 3.19),
@@ -293,7 +292,7 @@ class PersistenceErrorTest : AbstractTest() {
assertMultiLimitOrderResult()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(
"EURUSD", "Client3",
listOf(IncomingLimitOrder(-0.04, 5.1),
IncomingLimitOrder(-2.0, 5.2),
diff --git a/src/test/kotlin/com/lykke/matching/engine/services/StopLimitOrderTest.kt b/src/test/kotlin/com/lykke/matching/engine/services/StopLimitOrderTest.kt
index ebaecfc79..f3d59deaa 100644
--- a/src/test/kotlin/com/lykke/matching/engine/services/StopLimitOrderTest.kt
+++ b/src/test/kotlin/com/lykke/matching/engine/services/StopLimitOrderTest.kt
@@ -22,7 +22,6 @@ import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildLimitOrder
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMarketOrder
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMarketOrderWrapper
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMultiLimitOrderCancelWrapper
-import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMultiLimitOrderWrapper
import com.lykke.matching.engine.utils.assertEquals
import com.lykke.matching.engine.utils.getSetting
import org.junit.Before
@@ -465,7 +464,7 @@ class StopLimitOrderTest : AbstractTest() {
singleLimitOrderService.processMessage(messageBuilder.buildLimitOrderWrapper(buildLimitOrder(clientId = "Client2", assetId = "BTCUSD", volume = -0.2, price = 10000.0)))
clearMessageQueues()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD",
"Client3",
listOf(IncomingLimitOrder(-0.1, 11000.0),
IncomingLimitOrder(-0.05, 8500.0))))
@@ -555,7 +554,7 @@ class StopLimitOrderTest : AbstractTest() {
type = LimitOrderType.STOP_LIMIT, upperLimitPrice = 10000.0, upperPrice = 10500.0
)))
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD",
"Client2",
listOf(IncomingLimitOrder(-0.1, 9000.0),
IncomingLimitOrder(-0.2, 10000.0))))
@@ -650,11 +649,11 @@ class StopLimitOrderTest : AbstractTest() {
testDictionariesDatabaseAccessor.addAssetPair(AssetPair("EURUSD", "EUR", "USD", 2))
initServices()
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD", "Client2", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD", "Client2", listOf(
IncomingLimitOrder(-0.00009, 10000.0),
IncomingLimitOrder(-0.09, 11000.0))))
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("EURUSD", "Client2", listOf(
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("EURUSD", "Client2", listOf(
IncomingLimitOrder(1.0, 1.1),
IncomingLimitOrder(6.0, 1.0))))
@@ -774,7 +773,7 @@ class StopLimitOrderTest : AbstractTest() {
assertEquals(BigDecimal.valueOf( 0.1), balancesHolder.getReservedBalance("Client1", "BTC"))
assertEquals(BigDecimal.valueOf(1050.0), balancesHolder.getReservedBalance("Client3", "USD"))
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCUSD",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCUSD",
"Client2",
listOf(IncomingLimitOrder(-0.1, 10000.0),
IncomingLimitOrder(0.1, 9000.0))))
diff --git a/src/test/kotlin/com/lykke/matching/engine/services/validator/OrderValidationUtilsTest.kt b/src/test/kotlin/com/lykke/matching/engine/services/validator/OrderValidationUtilsTest.kt
index 4890299b8..c15c5fb4f 100644
--- a/src/test/kotlin/com/lykke/matching/engine/services/validator/OrderValidationUtilsTest.kt
+++ b/src/test/kotlin/com/lykke/matching/engine/services/validator/OrderValidationUtilsTest.kt
@@ -1,82 +1,14 @@
package com.lykke.matching.engine.services.validator
-import com.lykke.matching.engine.daos.AssetPair
import com.lykke.matching.engine.order.OrderStatus
import com.lykke.matching.engine.services.validators.common.OrderValidationUtils
import com.lykke.matching.engine.services.validators.impl.OrderValidationException
-import com.lykke.matching.engine.utils.MessageBuilder
-import org.junit.Assert
import org.junit.Test
-import java.math.BigDecimal
-import kotlin.test.assertFalse
import kotlin.test.assertTrue
class OrderValidationUtilsTest {
- private companion object {
- val MIN_VOLUME_ASSET_PAIR = AssetPair("EURUSD", "EUR", "USD", 5,
- BigDecimal.valueOf(0.1), BigDecimal.valueOf(0.2))
- val BTC_USD_ASSET_PAIR = AssetPair("BTCUSD", "BTC", "USD", 8)
- }
-
- @Test
- fun testCheckVolume() {
- assertTrue { OrderValidationUtils.checkMinVolume(MessageBuilder.buildLimitOrder(assetId = "BTCUSD", volume = 1.0), BTC_USD_ASSET_PAIR) }
- assertTrue { OrderValidationUtils.checkMinVolume(MessageBuilder.buildLimitOrder(assetId = "BTCUSD", volume = 0.1), BTC_USD_ASSET_PAIR) }
- assertTrue { OrderValidationUtils.checkMinVolume(MessageBuilder.buildLimitOrder(assetId = "BTCUSD", volume = 0.00000001), BTC_USD_ASSET_PAIR) }
-
- assertTrue { OrderValidationUtils.checkMinVolume(MessageBuilder.buildLimitOrder(volume = 1.0), MIN_VOLUME_ASSET_PAIR) }
- assertTrue { OrderValidationUtils.checkMinVolume(MessageBuilder.buildLimitOrder(volume = 0.1), MIN_VOLUME_ASSET_PAIR) }
- assertFalse { OrderValidationUtils.checkMinVolume(MessageBuilder.buildLimitOrder(volume = 0.09), MIN_VOLUME_ASSET_PAIR) }
-
- assertTrue { OrderValidationUtils.checkMinVolume(MessageBuilder.buildLimitOrder(volume = -1.0), MIN_VOLUME_ASSET_PAIR) }
- assertTrue { OrderValidationUtils.checkMinVolume(MessageBuilder.buildLimitOrder(volume = -0.1), MIN_VOLUME_ASSET_PAIR) }
- assertFalse { OrderValidationUtils.checkMinVolume(MessageBuilder.buildLimitOrder(volume = -0.09), MIN_VOLUME_ASSET_PAIR) }
-
- assertTrue { OrderValidationUtils.checkMinVolume(MessageBuilder.buildLimitOrder(price = 1.0, volume = 1.0), MIN_VOLUME_ASSET_PAIR) }
- assertTrue { OrderValidationUtils.checkMinVolume(MessageBuilder.buildLimitOrder(price = 1.0, volume = 0.1), MIN_VOLUME_ASSET_PAIR) }
- assertFalse { OrderValidationUtils.checkMinVolume(MessageBuilder.buildLimitOrder(price = 1.0, volume = 0.09), MIN_VOLUME_ASSET_PAIR) }
-
- assertTrue { OrderValidationUtils.checkMinVolume(MessageBuilder.buildLimitOrder(price = 1.0, volume = -1.0), MIN_VOLUME_ASSET_PAIR) }
- assertTrue { OrderValidationUtils.checkMinVolume(MessageBuilder.buildLimitOrder(price = 1.0, volume = -0.1), MIN_VOLUME_ASSET_PAIR) }
- assertFalse { OrderValidationUtils.checkMinVolume(MessageBuilder.buildLimitOrder(price = 1.0, volume = -0.09), MIN_VOLUME_ASSET_PAIR) }
-
- assertTrue { OrderValidationUtils.checkMinVolume(MessageBuilder.buildMarketOrder(assetId = "BTCUSD", volume = 1.0), BTC_USD_ASSET_PAIR) }
- assertTrue { OrderValidationUtils.checkMinVolume(MessageBuilder.buildMarketOrder(assetId = "BTCUSD", volume = 0.1), BTC_USD_ASSET_PAIR) }
- assertTrue { OrderValidationUtils.checkMinVolume(MessageBuilder.buildMarketOrder(assetId = "BTCUSD", volume = 0.00000001), BTC_USD_ASSET_PAIR) }
-
- assertTrue { OrderValidationUtils.checkMinVolume(MessageBuilder.buildMarketOrder(volume = 1.0), MIN_VOLUME_ASSET_PAIR) }
- assertTrue { OrderValidationUtils.checkMinVolume(MessageBuilder.buildMarketOrder(volume = 0.1), MIN_VOLUME_ASSET_PAIR) }
- assertFalse { OrderValidationUtils.checkMinVolume(MessageBuilder.buildMarketOrder(volume = 0.09), MIN_VOLUME_ASSET_PAIR) }
-
- assertTrue { OrderValidationUtils.checkMinVolume(MessageBuilder.buildMarketOrder(volume = -1.0), MIN_VOLUME_ASSET_PAIR) }
- assertTrue { OrderValidationUtils.checkMinVolume(MessageBuilder.buildMarketOrder(volume = -0.1), MIN_VOLUME_ASSET_PAIR) }
- assertFalse { OrderValidationUtils.checkMinVolume(MessageBuilder.buildMarketOrder(volume = -0.09), MIN_VOLUME_ASSET_PAIR) }
-
- assertTrue { OrderValidationUtils.checkMinVolume(MessageBuilder.buildMarketOrder(volume = 1.0, straight = false), MIN_VOLUME_ASSET_PAIR) }
- assertFalse { OrderValidationUtils.checkMinVolume(MessageBuilder.buildMarketOrder(volume = 0.1, straight = false), MIN_VOLUME_ASSET_PAIR) }
- assertFalse { OrderValidationUtils.checkMinVolume(MessageBuilder.buildMarketOrder(volume = 0.09, straight = false), MIN_VOLUME_ASSET_PAIR) }
-
- assertTrue { OrderValidationUtils.checkMinVolume(MessageBuilder.buildMarketOrder(volume = -1.0, straight = false), MIN_VOLUME_ASSET_PAIR) }
- assertFalse { OrderValidationUtils.checkMinVolume(MessageBuilder.buildMarketOrder(volume = -0.1, straight = false), MIN_VOLUME_ASSET_PAIR) }
- assertFalse { OrderValidationUtils.checkMinVolume(MessageBuilder.buildMarketOrder(volume = -0.09, straight = false), MIN_VOLUME_ASSET_PAIR) }
- }
-
-
- @Test(expected = OrderValidationException::class)
- fun testInvalidBalance() {
- try {
- //when
- OrderValidationUtils.validateBalance(BigDecimal.valueOf(10.0), BigDecimal.valueOf(11.0))
- } catch (e: OrderValidationException) {
- //then
- Assert.assertEquals(OrderStatus.NotEnoughFunds, e.orderStatus)
- throw e
- }
- }
-
@Test
- fun testValidBalance() {
- //when
- OrderValidationUtils.validateBalance(BigDecimal.valueOf(10.0), BigDecimal.valueOf(9.0))
+ fun isFatalInvalid() {
+ assertTrue(OrderValidationUtils.isFatalInvalid(OrderValidationException(OrderStatus.UnknownAsset)))
}
}
\ No newline at end of file
diff --git a/src/test/kotlin/com/lykke/matching/engine/services/validator/business/LimitOrderBusinessValidatorTest.kt b/src/test/kotlin/com/lykke/matching/engine/services/validator/business/LimitOrderBusinessValidatorTest.kt
index 2c4f7d08a..264be42f6 100644
--- a/src/test/kotlin/com/lykke/matching/engine/services/validator/business/LimitOrderBusinessValidatorTest.kt
+++ b/src/test/kotlin/com/lykke/matching/engine/services/validator/business/LimitOrderBusinessValidatorTest.kt
@@ -8,7 +8,9 @@ import com.lykke.matching.engine.daos.v2.LimitOrderFeeInstruction
import com.lykke.matching.engine.holders.OrderBookMaxTotalSizeHolderImpl
import com.lykke.matching.engine.order.OrderStatus
import com.lykke.matching.engine.services.AssetOrderBook
+import com.lykke.matching.engine.services.validators.business.OrderBusinessValidator
import com.lykke.matching.engine.services.validators.business.impl.LimitOrderBusinessValidatorImpl
+import com.lykke.matching.engine.services.validators.business.impl.OrderBusinessValidatorImpl
import com.lykke.matching.engine.services.validators.impl.OrderValidationException
import org.junit.Assert.assertEquals
import org.junit.Test
@@ -24,7 +26,7 @@ class LimitOrderBusinessValidatorTest {
@Test(expected = OrderValidationException::class)
fun testPreviousOrderNotFount() {
//given
- val limitOrderBusinessValidatorImpl = LimitOrderBusinessValidatorImpl(OrderBookMaxTotalSizeHolderImpl(null))
+ val limitOrderBusinessValidatorImpl = LimitOrderBusinessValidatorImpl(OrderBusinessValidatorImpl(), OrderBookMaxTotalSizeHolderImpl(null))
try {
//when
@@ -45,7 +47,7 @@ class LimitOrderBusinessValidatorTest {
@Test(expected = OrderValidationException::class)
fun testNotEnoughFounds() {
//given
- val limitOrderBusinessValidatorImpl = LimitOrderBusinessValidatorImpl(OrderBookMaxTotalSizeHolderImpl(null))
+ val limitOrderBusinessValidatorImpl = LimitOrderBusinessValidatorImpl(OrderBusinessValidatorImpl(), OrderBookMaxTotalSizeHolderImpl(null))
try {
//when
@@ -66,7 +68,8 @@ class LimitOrderBusinessValidatorTest {
@Test(expected = OrderValidationException::class)
fun testOrderBookMaxTotalSize() {
//given
- val limitOrderBusinessValidatorImpl = LimitOrderBusinessValidatorImpl(OrderBookMaxTotalSizeHolderImpl(10))
+ val limitOrderBusinessValidatorImpl = LimitOrderBusinessValidatorImpl(OrderBusinessValidatorImpl(),
+ OrderBookMaxTotalSizeHolderImpl(10))
try {
//when
@@ -87,7 +90,7 @@ class LimitOrderBusinessValidatorTest {
@Test
fun testValidOrder() {
//given
- val limitOrderBusinessValidatorImpl = LimitOrderBusinessValidatorImpl(OrderBookMaxTotalSizeHolderImpl(null))
+ val limitOrderBusinessValidatorImpl = LimitOrderBusinessValidatorImpl(OrderBusinessValidatorImpl(), OrderBookMaxTotalSizeHolderImpl(null))
//when
limitOrderBusinessValidatorImpl.performValidation(true,
diff --git a/src/test/kotlin/com/lykke/matching/engine/services/validator/business/OrderBusinessValidatorTest.kt b/src/test/kotlin/com/lykke/matching/engine/services/validator/business/OrderBusinessValidatorTest.kt
new file mode 100644
index 000000000..d48d5794e
--- /dev/null
+++ b/src/test/kotlin/com/lykke/matching/engine/services/validator/business/OrderBusinessValidatorTest.kt
@@ -0,0 +1,41 @@
+package com.lykke.matching.engine.services.validator.business
+
+import com.lykke.matching.engine.config.TestApplicationContext
+import com.lykke.matching.engine.order.OrderStatus
+import com.lykke.matching.engine.services.validators.business.OrderBusinessValidator
+import com.lykke.matching.engine.services.validators.impl.OrderValidationException
+import org.junit.Assert
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.annotation.DirtiesContext
+import org.springframework.test.context.junit4.SpringRunner
+import java.math.BigDecimal
+
+@RunWith(SpringRunner::class)
+@SpringBootTest(classes = [(TestApplicationContext::class)])
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
+class OrderBusinessValidatorTest {
+
+ @Autowired
+ private lateinit var orderBusinessValidator: OrderBusinessValidator
+
+ @Test(expected = OrderValidationException::class)
+ fun testInvalidBalance() {
+ try {
+ //when
+ orderBusinessValidator.validateBalance(BigDecimal.valueOf(10.0), BigDecimal.valueOf(11.0))
+ } catch (e: OrderValidationException) {
+ //then
+ Assert.assertEquals(OrderStatus.NotEnoughFunds, e.orderStatus)
+ throw e
+ }
+ }
+
+ @Test
+ fun testValidBalance() {
+ //when
+ orderBusinessValidator.validateBalance(BigDecimal.valueOf(10.0), BigDecimal.valueOf(9.0))
+ }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/com/lykke/matching/engine/services/validator/input/LimitOrderInputValidatorTest.kt b/src/test/kotlin/com/lykke/matching/engine/services/validator/input/LimitOrderInputValidatorTest.kt
index 00ab48e06..103f8a31d 100644
--- a/src/test/kotlin/com/lykke/matching/engine/services/validator/input/LimitOrderInputValidatorTest.kt
+++ b/src/test/kotlin/com/lykke/matching/engine/services/validator/input/LimitOrderInputValidatorTest.kt
@@ -65,7 +65,6 @@ class LimitOrderInputValidatorTest {
}
}
-
@Before
fun init() {
testDictionariesDatabaseAccessor.addAssetPair(MIN_VOLUME_ASSET_PAIR)
diff --git a/src/test/kotlin/com/lykke/matching/engine/services/validator/input/OrderInputValidatorTest.kt b/src/test/kotlin/com/lykke/matching/engine/services/validator/input/OrderInputValidatorTest.kt
new file mode 100644
index 000000000..a8cae7d59
--- /dev/null
+++ b/src/test/kotlin/com/lykke/matching/engine/services/validator/input/OrderInputValidatorTest.kt
@@ -0,0 +1,121 @@
+package com.lykke.matching.engine.services.validator.input
+
+import com.lykke.matching.engine.AbstractTest
+import com.lykke.matching.engine.config.TestApplicationContext
+import com.lykke.matching.engine.daos.AssetPair
+import com.lykke.matching.engine.daos.setting.AvailableSettingGroup
+import com.lykke.matching.engine.database.TestSettingsDatabaseAccessor
+import com.lykke.matching.engine.holders.AssetsPairsHolder
+import com.lykke.matching.engine.order.OrderStatus
+import com.lykke.matching.engine.services.validators.impl.OrderValidationException
+import com.lykke.matching.engine.services.validators.input.OrderInputValidator
+import com.lykke.matching.engine.utils.MessageBuilder
+import com.lykke.matching.engine.utils.getSetting
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.boot.test.context.TestConfiguration
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Primary
+import org.springframework.test.annotation.DirtiesContext
+import org.springframework.test.context.junit4.SpringRunner
+import java.math.BigDecimal
+import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
+
+@RunWith(SpringRunner::class)
+@SpringBootTest(classes = [(TestApplicationContext::class), (OrderInputValidatorTest.Config::class)])
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
+class OrderInputValidatorTest: AbstractTest() {
+ private companion object {
+ val MIN_VOLUME_ASSET_PAIR = AssetPair("EURUSD", "EUR", "USD", 5,
+ BigDecimal.valueOf(0.1), BigDecimal.valueOf(0.2))
+ val BTC_USD_ASSET_PAIR = AssetPair("BTCUSD", "BTC", "USD", 8)
+ }
+
+ @TestConfiguration
+ open class Config {
+
+ @Bean
+ @Primary
+ open fun testSettingsDatabaseAccessor(): TestSettingsDatabaseAccessor {
+ val testConfigDatabaseAccessor = TestSettingsDatabaseAccessor()
+ testConfigDatabaseAccessor.createOrUpdateSetting(AvailableSettingGroup.DISABLED_ASSETS, getSetting("JPY"))
+ return testConfigDatabaseAccessor
+ }
+ }
+
+ @Autowired
+ private lateinit var orderInputValidator: OrderInputValidator
+
+ @Autowired
+ private lateinit var assetPairHolder: AssetsPairsHolder
+
+ @Before
+ fun init() {
+ testDictionariesDatabaseAccessor.addAssetPair(AssetPair("EURUSD", "EUR", "USD", 5))
+ initServices()
+ }
+
+ @Test
+ fun testCheckVolume() {
+ assertTrue { orderInputValidator.checkMinVolume(MessageBuilder.buildLimitOrder(assetId = "BTCUSD", volume = 1.0), BTC_USD_ASSET_PAIR) }
+ assertTrue { orderInputValidator.checkMinVolume(MessageBuilder.buildLimitOrder(assetId = "BTCUSD", volume = 0.1), BTC_USD_ASSET_PAIR) }
+ assertTrue { orderInputValidator.checkMinVolume(MessageBuilder.buildLimitOrder(assetId = "BTCUSD", volume = 0.00000001), BTC_USD_ASSET_PAIR) }
+
+ assertTrue { orderInputValidator.checkMinVolume(MessageBuilder.buildLimitOrder(volume = 1.0), MIN_VOLUME_ASSET_PAIR) }
+ assertTrue { orderInputValidator.checkMinVolume(MessageBuilder.buildLimitOrder(volume = 0.1), MIN_VOLUME_ASSET_PAIR) }
+ assertFalse { orderInputValidator.checkMinVolume(MessageBuilder.buildLimitOrder(volume = 0.09), MIN_VOLUME_ASSET_PAIR) }
+
+ assertTrue { orderInputValidator.checkMinVolume(MessageBuilder.buildLimitOrder(volume = -1.0), MIN_VOLUME_ASSET_PAIR) }
+ assertTrue { orderInputValidator.checkMinVolume(MessageBuilder.buildLimitOrder(volume = -0.1), MIN_VOLUME_ASSET_PAIR) }
+ assertFalse { orderInputValidator.checkMinVolume(MessageBuilder.buildLimitOrder(volume = -0.09), MIN_VOLUME_ASSET_PAIR) }
+
+ assertTrue { orderInputValidator.checkMinVolume(MessageBuilder.buildLimitOrder(price = 1.0, volume = 1.0), MIN_VOLUME_ASSET_PAIR) }
+ assertTrue { orderInputValidator.checkMinVolume(MessageBuilder.buildLimitOrder(price = 1.0, volume = 0.1), MIN_VOLUME_ASSET_PAIR) }
+ assertFalse { orderInputValidator.checkMinVolume(MessageBuilder.buildLimitOrder(price = 1.0, volume = 0.09), MIN_VOLUME_ASSET_PAIR) }
+
+ assertTrue { orderInputValidator.checkMinVolume(MessageBuilder.buildLimitOrder(price = 1.0, volume = -1.0), MIN_VOLUME_ASSET_PAIR) }
+ assertTrue { orderInputValidator.checkMinVolume(MessageBuilder.buildLimitOrder(price = 1.0, volume = -0.1), MIN_VOLUME_ASSET_PAIR) }
+ assertFalse { orderInputValidator.checkMinVolume(MessageBuilder.buildLimitOrder(price = 1.0, volume = -0.09), MIN_VOLUME_ASSET_PAIR) }
+
+ assertTrue { orderInputValidator.checkMinVolume(MessageBuilder.buildMarketOrder(assetId = "BTCUSD", volume = 1.0), BTC_USD_ASSET_PAIR) }
+ assertTrue { orderInputValidator.checkMinVolume(MessageBuilder.buildMarketOrder(assetId = "BTCUSD", volume = 0.1), BTC_USD_ASSET_PAIR) }
+ assertTrue { orderInputValidator.checkMinVolume(MessageBuilder.buildMarketOrder(assetId = "BTCUSD", volume = 0.00000001), BTC_USD_ASSET_PAIR) }
+
+ assertTrue { orderInputValidator.checkMinVolume(MessageBuilder.buildMarketOrder(volume = 1.0), MIN_VOLUME_ASSET_PAIR) }
+ assertTrue { orderInputValidator.checkMinVolume(MessageBuilder.buildMarketOrder(volume = 0.1), MIN_VOLUME_ASSET_PAIR) }
+ assertFalse { orderInputValidator.checkMinVolume(MessageBuilder.buildMarketOrder(volume = 0.09), MIN_VOLUME_ASSET_PAIR) }
+
+ assertTrue { orderInputValidator.checkMinVolume(MessageBuilder.buildMarketOrder(volume = -1.0), MIN_VOLUME_ASSET_PAIR) }
+ assertTrue { orderInputValidator.checkMinVolume(MessageBuilder.buildMarketOrder(volume = -0.1), MIN_VOLUME_ASSET_PAIR) }
+ assertFalse { orderInputValidator.checkMinVolume(MessageBuilder.buildMarketOrder(volume = -0.09), MIN_VOLUME_ASSET_PAIR) }
+
+ assertTrue { orderInputValidator.checkMinVolume(MessageBuilder.buildMarketOrder(volume = 1.0, straight = false), MIN_VOLUME_ASSET_PAIR) }
+ assertFalse { orderInputValidator.checkMinVolume(MessageBuilder.buildMarketOrder(volume = 0.1, straight = false), MIN_VOLUME_ASSET_PAIR) }
+ assertFalse { orderInputValidator.checkMinVolume(MessageBuilder.buildMarketOrder(volume = 0.09, straight = false), MIN_VOLUME_ASSET_PAIR) }
+
+ assertTrue { orderInputValidator.checkMinVolume(MessageBuilder.buildMarketOrder(volume = -1.0, straight = false), MIN_VOLUME_ASSET_PAIR) }
+ assertFalse { orderInputValidator.checkMinVolume(MessageBuilder.buildMarketOrder(volume = -0.1, straight = false), MIN_VOLUME_ASSET_PAIR) }
+ assertFalse { orderInputValidator.checkMinVolume(MessageBuilder.buildMarketOrder(volume = -0.09, straight = false), MIN_VOLUME_ASSET_PAIR) }
+ }
+
+ @Test(expected = Exception::class)
+ fun unknownAsset() {
+ try {
+ orderInputValidator.validateAsset(null, "Unknown")
+ } catch (e: OrderValidationException) {
+ assertEquals(OrderStatus.UnknownAsset, e.orderStatus)
+ }
+
+
+ try {
+ orderInputValidator.validateAsset(assetPairHolder.getAssetPair("JPYUSD"), "Unknown")
+ } catch (e: OrderValidationException) {
+ assertEquals(OrderStatus.DisabledAsset, e.orderStatus)
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/com/lykke/matching/engine/utils/MessageBuilder.kt b/src/test/kotlin/com/lykke/matching/engine/utils/MessageBuilder.kt
index 56eefa4ff..87ac754d0 100644
--- a/src/test/kotlin/com/lykke/matching/engine/utils/MessageBuilder.kt
+++ b/src/test/kotlin/com/lykke/matching/engine/utils/MessageBuilder.kt
@@ -13,22 +13,23 @@ import com.lykke.matching.engine.incoming.parsers.data.LimitOrderMassCancelOpera
import com.lykke.matching.engine.incoming.parsers.ContextParser
import com.lykke.matching.engine.incoming.parsers.impl.CashInOutContextParser
import com.lykke.matching.engine.incoming.parsers.impl.CashTransferContextParser
-import com.lykke.matching.engine.incoming.parsers.impl.SingleLimitOrderContextParser
+import com.lykke.matching.engine.incoming.preprocessor.impl.MultilimitOrderPreprocessor
+import com.lykke.matching.engine.incoming.preprocessor.impl.SingleLimitOrderPreprocessor
import com.lykke.matching.engine.messages.MessageType
import com.lykke.matching.engine.messages.MessageWrapper
import com.lykke.matching.engine.messages.ProtocolMessages
import com.lykke.matching.engine.order.OrderCancelMode
import com.lykke.matching.engine.order.OrderStatus
-import com.lykke.matching.engine.services.validators.impl.OrderValidationResult
import com.lykke.matching.engine.socket.TestClientHandler
import java.math.BigDecimal
import java.util.*
-class MessageBuilder(private var singleLimitOrderContextParser: SingleLimitOrderContextParser,
+class MessageBuilder(private var singleLimitOrderPreprocessor: SingleLimitOrderPreprocessor,
private val cashInOutContextParser: CashInOutContextParser,
private val cashTransferContextParser: CashTransferContextParser,
private val limitOrderCancelOperationContextParser: ContextParser,
- private val limitOrderMassCancelOperationContextParser: ContextParser) {
+ private val limitOrderMassCancelOperationContextParser: ContextParser,
+ private val multilimitOrderPreprocessor: MultilimitOrderPreprocessor) {
companion object {
fun buildLimitOrder(uid: String = UUID.randomUUID().toString(),
assetId: String = "EURUSD",
@@ -160,53 +161,6 @@ companion object {
reservedVolume?.toBigDecimal(),
fee = fee, fees = fees)
- fun buildMultiLimitOrderWrapper(pair: String,
- clientId: String,
- orders: List,
- cancel: Boolean = true,
- cancelMode: OrderCancelMode? = null
- ): MessageWrapper {
- return MessageWrapper("Test", MessageType.MULTI_LIMIT_ORDER.type, buildMultiLimitOrder(pair, clientId,
- orders,
- cancel,
- cancelMode).toByteArray(), TestClientHandler(), messageId = "test", id = "test")
- }
-
- private fun buildMultiLimitOrder(assetPairId: String,
- clientId: String,
- orders: List,
- cancel: Boolean,
- cancelMode: OrderCancelMode?): ProtocolMessages.MultiLimitOrder {
- val multiOrderBuilder = ProtocolMessages.MultiLimitOrder.newBuilder()
- .setUid(UUID.randomUUID().toString())
- .setTimestamp(Date().time)
- .setClientId(clientId)
- .setAssetPairId(assetPairId)
- .setCancelAllPreviousLimitOrders(cancel)
- cancelMode?.let { multiOrderBuilder.cancelMode = it.externalId }
- orders.forEach { order ->
- val orderBuilder = ProtocolMessages.MultiLimitOrder.Order.newBuilder()
- .setVolume(order.volume)
- order.price?.let { orderBuilder.price = it }
- order.feeInstruction?.let { orderBuilder.fee = buildLimitOrderFee(it) }
- order.feeInstructions.forEach { orderBuilder.addFees(buildNewLimitOrderFee(it)) }
- orderBuilder.uid = order.uid
- order.oldUid?.let { orderBuilder.oldUid = order.oldUid }
- order.timeInForce?.let { orderBuilder.timeInForce = it.externalId }
- order.expiryTime?.let { orderBuilder.expiryTime = it.time }
- order.type?.let { orderBuilder.type = it.externalId }
- order.lowerLimitPrice?.let { orderBuilder.lowerLimitPrice = it }
- order.lowerPrice?.let { orderBuilder.lowerPrice = it }
- order.upperLimitPrice?.let { orderBuilder.upperLimitPrice = it }
- order.upperPrice?.let { orderBuilder.upperPrice = it }
- multiOrderBuilder.addOrders(orderBuilder.build())
- }
- return multiOrderBuilder.build()
- }
-
-
-
-
fun buildMultiLimitOrderCancelWrapper(clientId: String, assetPairId: String, isBuy: Boolean): MessageWrapper = MessageWrapper("Test", MessageType.MULTI_LIMIT_ORDER_CANCEL.type, ProtocolMessages.MultiLimitOrderCancel.newBuilder()
.setUid(UUID.randomUUID().toString())
.setTimestamp(Date().time)
@@ -332,6 +286,74 @@ companion object {
return limitOrderMassCancelOperationContextParser.parse(messageWrapper).messageWrapper
}
+ private fun buildMultiLimitOrder(assetPairId: String,
+ clientId: String,
+ orders: List,
+ cancel: Boolean,
+ cancelMode: OrderCancelMode?): ProtocolMessages.MultiLimitOrder {
+ val multiOrderBuilder = ProtocolMessages.MultiLimitOrder.newBuilder()
+ .setUid(UUID.randomUUID().toString())
+ .setTimestamp(Date().time)
+ .setClientId(clientId)
+ .setAssetPairId(assetPairId)
+ .setCancelAllPreviousLimitOrders(cancel)
+ cancelMode?.let { multiOrderBuilder.cancelMode = it.externalId }
+ orders.forEach { order ->
+ val orderBuilder = ProtocolMessages.MultiLimitOrder.Order.newBuilder()
+ .setVolume(order.volume)
+ order.price?.let { orderBuilder.price = it }
+ order.feeInstruction?.let { orderBuilder.fee = buildLimitOrderFee(it) }
+ order.feeInstructions.forEach { orderBuilder.addFees(buildNewLimitOrderFee(it)) }
+ orderBuilder.uid = order.uid
+ order.oldUid?.let { orderBuilder.oldUid = order.oldUid }
+ order.type?.let { orderBuilder.type = it.externalId }
+ order.lowerLimitPrice?.let { orderBuilder.lowerLimitPrice = it }
+ order.lowerPrice?.let { orderBuilder.lowerPrice = it }
+ order.timeInForce?.let { orderBuilder.timeInForce = it.externalId }
+ order.expiryTime?.let { orderBuilder.expiryTime = it.time }
+ order.upperLimitPrice?.let { orderBuilder.upperLimitPrice = it }
+ order.upperPrice?.let { orderBuilder.upperPrice = it }
+ multiOrderBuilder.addOrders(orderBuilder.build())
+ }
+ return multiOrderBuilder.build()
+ }
+
+ @Deprecated("Use buildMultiLimitOrderWrapper(5)")
+ fun buildMultiLimitOrderWrapper(pair: String,
+ clientId: String,
+ volumes: List,
+ ordersFee: List = emptyList(),
+ ordersFees: List> = emptyList(),
+ ordersUid: List = emptyList(),
+ cancel: Boolean = false,
+ cancelMode: OrderCancelMode? = null
+ ): MessageWrapper {
+ val orders = volumes.mapIndexed { i, volume ->
+ IncomingLimitOrder(volume.volume.toDouble(),
+ volume.price.toDouble(),
+ if (i < ordersUid.size) ordersUid[i] else UUID.randomUUID().toString(),
+ if (i < ordersFee.size) ordersFee[i] else null,
+ if (i < ordersFees.size) ordersFees[i] else emptyList(),
+ null)
+ }
+ return buildMultiLimitOrderWrapper(pair, clientId, orders, cancel, cancelMode)
+ }
+
+ fun buildMultiLimitOrderWrapper(pair: String,
+ clientId: String,
+ orders: List,
+ cancel: Boolean = true,
+ cancelMode: OrderCancelMode? = null
+ ): MessageWrapper {
+ val messageWrapper = MessageWrapper("Test", MessageType.MULTI_LIMIT_ORDER.type, buildMultiLimitOrder(pair, clientId,
+ orders,
+ cancel,
+ cancelMode).toByteArray(), TestClientHandler(), messageId = "test", id = "test")
+ multilimitOrderPreprocessor.preProcess(messageWrapper)
+ return messageWrapper
+ }
+
+
fun buildLimitOrderWrapper(order: LimitOrder,
cancel: Boolean = false): MessageWrapper {
val builder = ProtocolMessages.LimitOrder.newBuilder()
@@ -357,12 +379,8 @@ companion object {
order.upperPrice?.let { builder.setUpperPrice(it.toDouble()) }
order.expiryTime?.let { builder.setExpiryTime(it.time) }
order.timeInForce?.let { builder.setTimeInForce(it.externalId) }
- val messageWrapper = singleLimitOrderContextParser
- .parse(MessageWrapper("Test", MessageType.LIMIT_ORDER.type, builder.build().toByteArray(), TestClientHandler(), messageId = "test", id = "test"))
- .messageWrapper
-
- val singleLimitContext = messageWrapper.context as SingleLimitOrderContext
- singleLimitContext.validationResult = OrderValidationResult(true)
+ val messageWrapper = MessageWrapper("Test", MessageType.LIMIT_ORDER.type, builder.build().toByteArray(), TestClientHandler(), messageId = "test", id = "test")
+ singleLimitOrderPreprocessor.preProcess(messageWrapper)
return messageWrapper
}
diff --git a/src/test/kotlin/com/lykke/matching/engine/utils/order/MinVolumeOrderCancellerTest.kt b/src/test/kotlin/com/lykke/matching/engine/utils/order/MinVolumeOrderCancellerTest.kt
index 7cae40287..6247fd99d 100644
--- a/src/test/kotlin/com/lykke/matching/engine/utils/order/MinVolumeOrderCancellerTest.kt
+++ b/src/test/kotlin/com/lykke/matching/engine/utils/order/MinVolumeOrderCancellerTest.kt
@@ -11,7 +11,6 @@ import com.lykke.matching.engine.database.TestSettingsDatabaseAccessor
import com.lykke.matching.engine.outgoing.messages.LimitOrdersReport
import com.lykke.matching.engine.utils.MessageBuilder
import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildLimitOrder
-import com.lykke.matching.engine.utils.MessageBuilder.Companion.buildMultiLimitOrderWrapper
import com.lykke.matching.engine.utils.balance.ReservedVolumesRecalculator
import org.junit.Before
import org.junit.Test
@@ -100,7 +99,7 @@ class MinVolumeOrderCancellerTest : AbstractTest() {
singleLimitOrderService.processMessage(messageBuilder.buildLimitOrderWrapper(buildLimitOrder(uid = "validVolume", clientId = "Client1", assetId = "BTCUSD", price = 10001.0, volume = 0.01)))
singleLimitOrderService.processMessage(messageBuilder.buildLimitOrderWrapper(buildLimitOrder(clientId = "Client2", assetId = "BTCUSD", price = 10001.0, volume = 0.001)))
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(clientId = "TrustedClient", pair = "BTCUSD",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(clientId = "TrustedClient", pair = "BTCUSD",
orders = listOf(IncomingLimitOrder(0.00102, 10002.0), IncomingLimitOrder(-0.00001, 11000.0))))
singleLimitOrderService.processMessage(messageBuilder.buildLimitOrderWrapper(buildLimitOrder(clientId = "ClientForPartiallyMatching", assetId = "BTCUSD", price = 10002.0, volume = -0.001)))
@@ -112,7 +111,7 @@ class MinVolumeOrderCancellerTest : AbstractTest() {
singleLimitOrderService.processMessage(messageBuilder.buildLimitOrderWrapper(buildLimitOrder(uid = "order1", clientId = "Client2", assetId = "EURUSD", price = 1.3, volume = -4.09)))
singleLimitOrderService.processMessage(messageBuilder.buildLimitOrderWrapper(buildLimitOrder(uid = "order2", clientId = "Client2", assetId = "EURUSD", price = 1.1, volume = 4.09)))
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper(clientId = "TrustedClient", pair = "EURUSD",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper(clientId = "TrustedClient", pair = "EURUSD",
orders = listOf(IncomingLimitOrder(30.0, 1.1), IncomingLimitOrder(-30.0, 1.4))))
singleLimitOrderService.processMessage(messageBuilder.buildLimitOrderWrapper(buildLimitOrder(clientId = "ClientForPartiallyMatching", assetId = "EURUSD", price = 1.2, volume = 6.0)))
@@ -194,7 +193,7 @@ class MinVolumeOrderCancellerTest : AbstractTest() {
@Test
fun testCancelOrdersWithRemovedAssetPair() {
singleLimitOrderService.processMessage(messageBuilder.buildLimitOrderWrapper(buildLimitOrder(uid = "order1", clientId = "Client1", assetId = "BTCEUR", price = 10000.0, volume = -1.0)))
- multiLimitOrderService.processMessage(buildMultiLimitOrderWrapper("BTCEUR", "TrustedClient",
+ multiLimitOrderService.processMessage(messageBuilder.buildMultiLimitOrderWrapper("BTCEUR", "TrustedClient",
listOf(IncomingLimitOrder(-1.0, price = 10000.0, uid = "order2"))))
assertEquals(BigDecimal.ZERO, balancesHolder.getReservedBalance("TrustedClient", "BTC"))