diff --git a/example/basket/src/main/scala/org/finos/vuu/core/module/basket/BasketConstants.scala b/example/basket/src/main/scala/org/finos/vuu/core/module/basket/BasketConstants.scala
index 6de498283..8e8baf046 100644
--- a/example/basket/src/main/scala/org/finos/vuu/core/module/basket/BasketConstants.scala
+++ b/example/basket/src/main/scala/org/finos/vuu/core/module/basket/BasketConstants.scala
@@ -2,7 +2,7 @@ package org.finos.vuu.core.module.basket
object BasketConstants {
- object Side{
+ object Side {
final val Buy = "BUY"
final val Sell = "SELL"
}
diff --git a/example/basket/src/main/scala/org/finos/vuu/core/module/basket/BasketModule.scala b/example/basket/src/main/scala/org/finos/vuu/core/module/basket/BasketModule.scala
index 70a5683f9..8630bcb8e 100644
--- a/example/basket/src/main/scala/org/finos/vuu/core/module/basket/BasketModule.scala
+++ b/example/basket/src/main/scala/org/finos/vuu/core/module/basket/BasketModule.scala
@@ -202,9 +202,4 @@ object BasketModule extends DefaultModule {
final val OrderStatus = "orderStatus"
final val FilledQty = "filledQty"
}
-
- object Sides{
- final val Buy = "Buy"
- final val Sell = "Sell"
- }
}
diff --git a/example/basket/src/main/scala/org/finos/vuu/core/module/basket/provider/BasketConstituentProvider.scala b/example/basket/src/main/scala/org/finos/vuu/core/module/basket/provider/BasketConstituentProvider.scala
index 4b1ec3d06..a87c400ed 100644
--- a/example/basket/src/main/scala/org/finos/vuu/core/module/basket/provider/BasketConstituentProvider.scala
+++ b/example/basket/src/main/scala/org/finos/vuu/core/module/basket/provider/BasketConstituentProvider.scala
@@ -34,7 +34,7 @@ class BasketConstituentProvider(val table: DataTable)(implicit lifecycle: Lifecy
val weighting = row("Weighting")
val side = BasketConstants.Side.Buy
val ricBasketId = symbol + "." + basketId
- table.processUpdate(ricBasketId, RowWithData(symbol, Map(
+ table.processUpdate(ricBasketId, RowWithData(ricBasketId, Map(
Ric -> symbol,
BasketId -> basketId,
RicBasketId -> ricBasketId,
diff --git a/example/basket/src/main/scala/org/finos/vuu/core/module/basket/provider/BasketTradingConstituentProvider.scala b/example/basket/src/main/scala/org/finos/vuu/core/module/basket/provider/BasketTradingConstituentProvider.scala
index 2cc9d691d..74fb2dd71 100644
--- a/example/basket/src/main/scala/org/finos/vuu/core/module/basket/provider/BasketTradingConstituentProvider.scala
+++ b/example/basket/src/main/scala/org/finos/vuu/core/module/basket/provider/BasketTradingConstituentProvider.scala
@@ -19,14 +19,16 @@ class BasketTradingConstituentProvider(val table: DataTable, val omsApi: OmsApi)
table.processUpdate(ack.clientOrderId, RowWithData(ack.clientOrderId, Map[String, Any](BTC.InstanceIdRic -> ack.clientOrderId,
BTC.OrderStatus -> OrderStates.ACKED)),clock.now())
}
- override def onCancelAck(ack: CancelAck): Unit = ???
+ override def onCancelAck(ack: CancelAck): Unit = {
+ table.processUpdate(ack.clientOrderId, RowWithData(ack.clientOrderId, Map[String, Any](BTC.InstanceIdRic -> ack.clientOrderId,
+ BTC.OrderStatus -> OrderStates.CANCELLED)), clock.now())
+ }
override def onReplaceAck(ack: ReplaceAck): Unit = ???
override def onFill(fill: Fill): Unit = {
val state = if(fill.orderQty == fill.totalFilledQty) OrderStates.FILLED else OrderStates.ACKED
table.processUpdate(fill.clientOrderId,
RowWithData(fill.clientOrderId, Map[String, Any](BTC.InstanceIdRic -> fill.clientOrderId,
- BTC.FilledQty -> fill.totalFilledQty, BTC.OrderStatus -> state))
- ,clock.now())
+ BTC.FilledQty -> fill.totalFilledQty, BTC.OrderStatus -> state)),clock.now())
}
})
diff --git a/example/basket/src/main/scala/org/finos/vuu/core/module/basket/service/BasketService.scala b/example/basket/src/main/scala/org/finos/vuu/core/module/basket/service/BasketService.scala
index b720d80ad..991aa248d 100644
--- a/example/basket/src/main/scala/org/finos/vuu/core/module/basket/service/BasketService.scala
+++ b/example/basket/src/main/scala/org/finos/vuu/core/module/basket/service/BasketService.scala
@@ -2,8 +2,9 @@ package org.finos.vuu.core.module.basket.service
import com.typesafe.scalalogging.StrictLogging
import org.finos.toolbox.time.Clock
+import org.finos.vuu.core.module.basket.BasketConstants.Side
import org.finos.vuu.core.module.basket.BasketModule
-import org.finos.vuu.core.module.basket.BasketModule.{BasketConstituentTable, Sides}
+import org.finos.vuu.core.module.basket.BasketModule.{BasketConstituentTable}
import org.finos.vuu.core.table.{DataTable, RowData, RowWithData, TableContainer}
import org.finos.vuu.net.rpc.RpcHandler
import org.finos.vuu.net.{ClientSessionId, RequestContext}
@@ -57,7 +58,7 @@ class BasketService(val table: DataTable, val tableContainer: TableContainer, va
}
private def mkTradingBasketRow(sourceBasketId: String, basketTradeName: String, basketTradeInstanceId: String) = {
- RowWithData(basketTradeInstanceId, Map(BT.InstanceId -> basketTradeInstanceId, BT.Status -> "OFF-MARKET", BT.BasketId -> sourceBasketId, BT.BasketName -> basketTradeName, BT.Side -> Sides.Buy, BT.Units -> 1))
+ RowWithData(basketTradeInstanceId, Map(BT.InstanceId -> basketTradeInstanceId, BT.Status -> "OFF-MARKET", BT.BasketId -> sourceBasketId, BT.BasketName -> basketTradeName, BT.Side -> Side.Buy, BT.Units -> 1))
}
def createBasketFromRpc(basketId: String, name: String)(ctx: RequestContext): ViewPortAction = {
diff --git a/example/basket/src/main/scala/org/finos/vuu/core/module/basket/service/BasketTradingConstituentJoinService.scala b/example/basket/src/main/scala/org/finos/vuu/core/module/basket/service/BasketTradingConstituentJoinService.scala
index 66a33d5b3..41d113792 100644
--- a/example/basket/src/main/scala/org/finos/vuu/core/module/basket/service/BasketTradingConstituentJoinService.scala
+++ b/example/basket/src/main/scala/org/finos/vuu/core/module/basket/service/BasketTradingConstituentJoinService.scala
@@ -5,9 +5,9 @@ import org.finos.toolbox.time.Clock
import org.finos.vuu.api.JoinTableDef
import org.finos.vuu.core.module.basket.BasketConstants.Side
import org.finos.vuu.core.module.basket.BasketModule
-import org.finos.vuu.core.module.basket.BasketModule.{BasketTradingColumnNames => BTColumnName, BasketTradingConstituentColumnNames => ColumnName}
+import org.finos.vuu.core.module.basket.BasketModule.{BasketConstituentColumnNames => BCColumnName, BasketTradingColumnNames => BTColumnName, BasketTradingConstituentColumnNames => ColumnName}
import org.finos.vuu.core.module.basket.result.ErrorReason
-import org.finos.vuu.core.table.{DataTable, JoinTable, RowWithData, TableContainer}
+import org.finos.vuu.core.table.{DataTable, JoinTable, RowData, RowWithData, TableContainer}
import org.finos.vuu.net.rpc.{EditRpcHandler, RpcHandler}
import org.finos.vuu.net.{ClientSessionId, RequestContext}
import org.finos.vuu.viewport._
@@ -64,11 +64,18 @@ class BasketTradingConstituentJoinService(val table: DataTable, val tableContain
val basketId = tradeRow.get(BTColumnName.BasketId).asInstanceOf[String]
val tradeUnit = tradeRow.get(BTColumnName.Units).asInstanceOf[Int]
+ val basketConstituentRows = getConstituentsWith(ric) //todo what to do when multiple result?
+ val description =
+ if(basketConstituentRows.nonEmpty)
+ basketConstituentRows.head.get(BCColumnName.Description).asInstanceOf[String]
+ else ""
+
val newRow = mkTradingConstituentRow(
basketTradeInstanceId = tradeId,
sourceBasketId = basketId,
tradeUnit = tradeUnit,
- ric = ric)
+ ric = ric,
+ description = description)
//todo should we guard against adding row for ric that already exist?
updateJoinTable(Array(newRow)) match {
@@ -79,6 +86,12 @@ class BasketTradingConstituentJoinService(val table: DataTable, val tableContain
}
}
+ private def getConstituentsWith(ric: String): List[RowData] = {
+ val table = tableContainer.getTable(BasketModule.BasketConstituentTable)
+ val keys = table.primaryKeys.toList
+ keys.map(key => table.pullRow(key)).filter(_.get(BCColumnName.Ric).toString == ric)
+ }
+
private def onEditCell(key: String, columnName: String, data: Any, vp: ViewPort, session: ClientSessionId): ViewPortEditAction = {
try {
getBaseTable() match {
@@ -180,7 +193,7 @@ class BasketTradingConstituentJoinService(val table: DataTable, val tableContain
}
}
- private def mkTradingConstituentRow(basketTradeInstanceId: String, sourceBasketId: String, tradeUnit: Int, ric: String): RowWithData = {
+ private def mkTradingConstituentRow(basketTradeInstanceId: String, sourceBasketId: String, tradeUnit: Int, ric: String, description: String): RowWithData = {
val constituentKey = s"$basketTradeInstanceId.$ric"
val weighting: Double = 0.1
RowWithData(
@@ -191,7 +204,7 @@ class BasketTradingConstituentJoinService(val table: DataTable, val tableContain
ColumnName.InstanceId -> basketTradeInstanceId,
ColumnName.InstanceIdRic -> constituentKey,
ColumnName.Quantity -> (weighting * 100).asInstanceOf[Long],
- ColumnName.Description -> "", //todo look up description from instrument table
+ ColumnName.Description -> description,
ColumnName.Side -> Side.Buy,
ColumnName.Weighting -> weighting,
ColumnName.PriceStrategyId -> 2,
diff --git a/example/basket/src/main/scala/org/finos/vuu/core/module/basket/service/BasketTradingService.scala b/example/basket/src/main/scala/org/finos/vuu/core/module/basket/service/BasketTradingService.scala
index a738b2887..8a805e9bc 100644
--- a/example/basket/src/main/scala/org/finos/vuu/core/module/basket/service/BasketTradingService.scala
+++ b/example/basket/src/main/scala/org/finos/vuu/core/module/basket/service/BasketTradingService.scala
@@ -3,14 +3,18 @@ package org.finos.vuu.core.module.basket.service
import com.typesafe.scalalogging.StrictLogging
import org.finos.toolbox.time.Clock
import org.finos.vuu.core.module.basket.BasketModule
-import org.finos.vuu.core.module.basket.BasketModule.{BasketTradingConstituentTable, Sides}
-import org.finos.vuu.core.table.{DataTable, RowWithData, TableContainer, ViewPortColumnCreator}
+import org.finos.vuu.core.module.basket.BasketConstants.Side
+import org.finos.vuu.core.module.basket.BasketModule.{BasketTradingConstituentTable}
+import org.finos.vuu.core.table.{DataTable, RowData, RowWithData, TableContainer, ViewPortColumnCreator}
import org.finos.vuu.net.rpc.{EditRpcHandler, RpcHandler}
import org.finos.vuu.net.{ClientSessionId, RequestContext}
-import org.finos.vuu.order.oms.{NewOrder, OmsApi}
+import org.finos.vuu.order.oms.{CancelOrder, NewOrder, OmsApi}
import org.finos.vuu.viewport._
-trait BasketTradingServiceIF extends EditRpcHandler{
+
+trait BasketTradingServiceIF extends EditRpcHandler {
def sendToMarket(basketInstanceId: String)(ctx: RequestContext): ViewPortAction
+
+ def takeOffMarket(basketInstanceId: String)(ctx: RequestContext): ViewPortAction
}
@@ -20,18 +24,14 @@ class BasketTradingService(val table: DataTable, val tableContainer: TableContai
/**
- * Send basket to market
+ * Send basket to market rpc call
*/
- override def sendToMarket(name: String)(ctx: RequestContext): ViewPortAction = {
- val tableRow = table.asTable.pullRow(name)
-
- logger.info("Sending basket to market:" + name + " (row:" + tableRow + ")")
+ override def sendToMarket(basketInstanceId: String)(ctx: RequestContext): ViewPortAction = {
+ val tableRow = table.asTable.pullRow(basketInstanceId)
- val tradingConsTable = tableContainer.getTable(BasketModule.BasketTradingConstituentTable)
+ logger.info("Sending basket to market:" + basketInstanceId + " (row:" + tableRow + ")")
- val constituents = tradingConsTable.primaryKeys.toList
- .map(tradingConsTable.pullRow)
- .filter(_.get(BTC.InstanceId) == name)
+ val constituents = getConstituents(basketInstanceId)
constituents.foreach(constituentRow => {
@@ -48,12 +48,43 @@ class BasketTradingService(val table: DataTable, val tableContainer: TableContai
omsApi.createOrder(nos)
})
- table.processUpdate(name, RowWithData(name,
- Map(BT.InstanceId -> name, BT.Status -> BasketStates.ON_MARKET)), clock.now())
+ updateBasketTradeStatus(basketInstanceId, state = BasketStates.ON_MARKET)
ViewPortEditSuccess()
}
+ /**
+ * Take basket off market rpc call
+ */
+ override def takeOffMarket(basketInstanceId: String)(ctx: RequestContext): ViewPortAction = {
+ val tableRow = table.asTable.pullRow(basketInstanceId)
+
+ logger.info("Tasking basket off market:" + basketInstanceId + " (row:" + tableRow + ")")
+
+ updateBasketTradeStatus(basketInstanceId, BasketStates.OFF_MARKET)
+
+ getConstituents(basketInstanceId)
+ .flatMap(c => omsApi.getOrderId(clientOrderId = c.get(BTC.InstanceIdRic).toString))
+ .foreach(orderId => omsApi.cancelOrder(CancelOrder(orderId)))
+
+ ViewPortEditSuccess()
+ }
+
+ private def getConstituents(basketInstanceId: String): List[RowData] = {
+ val tradingConsTable = tableContainer.getTable(BasketModule.BasketTradingConstituentTable)
+
+ tradingConsTable.primaryKeys.toList
+ .map(tradingConsTable.pullRow)
+ .filter(_.get(BTC.InstanceId) == basketInstanceId)
+ }
+
+ private def updateBasketTradeStatus(basketInstanceId: String, state: String): Unit = {
+ table.processUpdate(
+ basketInstanceId,
+ RowWithData(basketInstanceId, Map(BT.InstanceId -> basketInstanceId, BT.Status -> state)),
+ clock.now())
+ }
+
private def onEditCell(key: String, columnName: String, data: Any, vp: ViewPort, session: ClientSessionId): ViewPortEditAction = {
logger.info("Change requested for cell value for key:" + key + "(" + columnName + ":" + data + ")")
@@ -80,8 +111,8 @@ class BasketTradingService(val table: DataTable, val tableContainer: TableContai
val constituents = constituentTable.primaryKeys.map(key => constituentTable.pullRow(key)).filter(_.get(BTC.InstanceId) == key)
constituents.foreach(row => {
val newSide = row.get(BTC.Side) match {
- case Sides.Buy => Sides.Sell
- case _ => Sides.Buy
+ case Side.Buy => Side.Sell
+ case _ => Side.Buy
}
constituentTable.processUpdate(row.key(), RowWithData(row.key(), Map(BTC.InstanceIdRic -> row.key(), BTC.Side -> newSide)), clock.now())
})
diff --git a/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketConstituentMutateTest.scala b/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketConstituentMutateTest.scala
index 6fe045421..e3493813b 100644
--- a/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketConstituentMutateTest.scala
+++ b/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketConstituentMutateTest.scala
@@ -33,9 +33,9 @@ class BasketConstituentMutateTest extends VuuServerTestCase {
vuuServer.login("testUser", "testToken")
val basketName = "test_basket1"
- val tradeId = GivenBasketTrade(vuuServer.tableContainer, basketName, "Buy")
+ val tradeId = GivenBasketTrade(vuuServer.tableContainer, basketName, "BUY")
GivenPrices(vuuServer.tableContainer, List(("VOD.L", 1.1, 1.4), ("BP.L", 2.1, 2.4)))
- GivenBasketTradeConstituentsJoin(vuuServer.tableContainer, tradeId, Map(("VOD.L" -> "Buy"), ("BP.L" -> "Sell")))
+ GivenBasketTradeConstituentsJoin(vuuServer.tableContainer, tradeId, Map(("VOD.L" -> "BUY"), ("BP.L" -> "SELL")))
val vpBasketTrading = vuuServer.createViewPort(BasketModule.NAME, BasketTradingTable)
val vpBasketTradingConsJoin = vuuServer.createViewPort(BasketModule.NAME, BasketTradingConstituentJoin)
@@ -60,9 +60,9 @@ class BasketConstituentMutateTest extends VuuServerTestCase {
assertVpEq(filterByVp(vpBasketTradingConsJoin, updates)) {
Table(
("quantity", "side", "instanceId", "instanceIdRic", "basketId", "ric", "description", "notionalUsd", "notionalLocal", "venue", "algo", "algoParams", "pctFilled", "weighting", "priceSpread", "limitPrice", "priceStrategyId", "bid", "ask", "filledQty", "orderStatus"),
- (10L, "Buy", "testUser-00001", "testUser-00001.BP.L", ".FTSE", "BP.L", "Beyond Petroleum", null, null, null, -1, null, null, 0.1, null, null, 2, 2.1, 2.4, 0, "PENDING"),
- (10L, "Sell", "testUser-00001", "testUser-00001.BT.L", ".FTSE", "BT.L", "British Telecom", null, null, null, -1, null, null, 0.1, null, null, 2, null, null, 0, "PENDING"),
- (10L, "Sell", "testUser-00001", "testUser-00001.VOD.L", ".FTSE", "VOD.L", "Vodafone", null, null, null, -1, null, null, 0.1, null, null, 2, 1.1, 1.4, 0, "PENDING")
+ (10L, "BUY", "testUser-00001", "testUser-00001.BP.L", ".FTSE", "BP.L", "Beyond Petroleum", null, null, null, -1, null, null, 0.1, null, null, 2, 2.1, 2.4, 0, "PENDING"),
+ (10L, "SELL", "testUser-00001", "testUser-00001.BT.L", ".FTSE", "BT.L", "British Telecom", null, null, null, -1, null, null, 0.1, null, null, 2, null, null, 0, "PENDING"),
+ (10L, "SELL", "testUser-00001", "testUser-00001.VOD.L", ".FTSE", "VOD.L", "Vodafone", null, null, null, -1, null, null, 0.1, null, null, 2, 1.1, 1.4, 0, "PENDING")
)
}
}
diff --git a/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketCreateTest.scala b/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketCreateTest.scala
index f847d55e6..9451fa78f 100644
--- a/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketCreateTest.scala
+++ b/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketCreateTest.scala
@@ -68,7 +68,7 @@ class BasketCreateTest extends VuuServerTestCase {
assertVpEq(combineQsForVp(viewportBasketTrading)) {
Table(
("basketId", "instanceId", "basketName", "units", "status", "filledPct", "totalNotionalUsd", "totalNotional", "fxRateToUsd", "side"),
- (".FTSE", BasketTradeId.current, "TestBasket", 100, "OFF-MARKET", null, null, null, null, "Buy")
+ (".FTSE", BasketTradeId.current, "TestBasket", 100, "OFF-MARKET", null, null, null, null, "BUY")
)
}
}
diff --git a/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketMutateOffMarketTest.scala b/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketMutateOffMarketTest.scala
index 6ede3b3ef..c60cb88d1 100644
--- a/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketMutateOffMarketTest.scala
+++ b/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketMutateOffMarketTest.scala
@@ -60,9 +60,9 @@ class BasketMutateOffMarketTest extends VuuServerTestCase {
assertVpEq(combineQsForVp(vpConstituent)) {
Table(
("ricBasketId", "ric", "basketId", "weighting", "lastTrade", "change", "volume", "description", "side"),
- ("BP.L.FTSE", "BP.L", ".FTSE", 0.1, null, null, null, "Beyond Petroleum", "Buy"),
- ("BT.L.FTSE", "BT.L", ".FTSE", 0.1, null, null, null, "British Telecom", "Sell"),
- ("VOD.L.FTSE", "VOD.L", ".FTSE", 0.1, null, null, null, "Vodafone", "Buy")
+ ("BP.L.FTSE", "BP.L", ".FTSE", 0.1, null, null, null, "Beyond Petroleum", "BUY"),
+ ("BT.L.FTSE", "BT.L", ".FTSE", 0.1, null, null, null, "British Telecom", "SELL"),
+ ("VOD.L.FTSE", "VOD.L", ".FTSE", 0.1, null, null, null, "Vodafone", "BUY")
)
}
@@ -80,7 +80,7 @@ class BasketMutateOffMarketTest extends VuuServerTestCase {
assertVpEq(combineQsForVp(vpBasketTrading)) {
Table(
("instanceId", "basketId", "basketName", "status", "units", "filledPct", "fxRateToUsd", "totalNotional", "totalNotionalUsd", "side"),
- (basketTradeInstanceId, ".FTSE", "MyCustomBasket", "OFF-MARKET", 1, null, null, null, null, "Buy")
+ (basketTradeInstanceId, ".FTSE", "MyCustomBasket", "OFF-MARKET", 1, null, null, null, null, "BUY")
)
}
@@ -91,16 +91,16 @@ class BasketMutateOffMarketTest extends VuuServerTestCase {
assertVpEq(combineQsForVp(vpBasketTradingCons)) {
Table(
("quantity", "side", "instanceId", "instanceIdRic", "basketId", "ric", "description", "notionalUsd", "notionalLocal", "venue", "algo", "algoParams", "pctFilled", "weighting", "priceSpread", "limitPrice", "priceStrategyId", "filledQty", "orderStatus"),
- (10L, "Buy", basketTradeInstanceId, s"$basketTradeInstanceId.BP.L", ".FTSE", "BP.L", "Beyond Petroleum", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
- (10L, "Sell", basketTradeInstanceId, s"$basketTradeInstanceId.BT.L", ".FTSE", "BT.L", "British Telecom", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
- (10L, "Buy", basketTradeInstanceId, s"$basketTradeInstanceId.VOD.L", ".FTSE", "VOD.L", "Vodafone", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING")
+ (10L, "BUY", basketTradeInstanceId, s"$basketTradeInstanceId.BP.L", ".FTSE", "BP.L", "Beyond Petroleum", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
+ (10L, "SELL", basketTradeInstanceId, s"$basketTradeInstanceId.BT.L", ".FTSE", "BT.L", "British Telecom", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
+ (10L, "BUY", basketTradeInstanceId, s"$basketTradeInstanceId.VOD.L", ".FTSE", "VOD.L", "Vodafone", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING")
)
}
val basketTradingService = vuuServer.getViewPortRpcServiceProxy[BasketTradingServiceIF](vpBasketTrading)
When("we edit the side of the parent basket")
- basketTradingService.editCellAction().func(basketTradeInstanceId, "side", "Sell", vpBasketTrading, vuuServer.session)
+ basketTradingService.editCellAction().func(basketTradeInstanceId, "side", "SELL", vpBasketTrading, vuuServer.session)
Then("get all the updates that have occurred for all view ports from the outbound queue")
val updates = combineQs(vpBasketTrading)
@@ -109,7 +109,7 @@ class BasketMutateOffMarketTest extends VuuServerTestCase {
assertVpEq(filterByVp(vpBasketTrading, updates)) {
Table(
("instanceId", "basketId", "basketName", "status", "units", "filledPct", "fxRateToUsd", "totalNotional", "totalNotionalUsd", "side"),
- (basketTradeInstanceId, ".FTSE", "MyCustomBasket", "OFF-MARKET", 1, null, null, null, null, "Sell")
+ (basketTradeInstanceId, ".FTSE", "MyCustomBasket", "OFF-MARKET", 1, null, null, null, null, "SELL")
)
}
@@ -118,9 +118,9 @@ class BasketMutateOffMarketTest extends VuuServerTestCase {
assertVpEq(filterByVp(vpBasketTradingCons, updates)) {
Table(
("quantity", "side", "instanceId", "instanceIdRic", "basketId", "ric", "description", "notionalUsd", "notionalLocal", "venue", "algo", "algoParams", "pctFilled", "weighting", "priceSpread", "limitPrice", "priceStrategyId", "filledQty", "orderStatus"),
- (10L, "Sell", basketTradeInstanceId, s"$basketTradeInstanceId.BP.L", ".FTSE", "BP.L", "Beyond Petroleum", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
- (10L, "Buy", basketTradeInstanceId, s"$basketTradeInstanceId.BT.L", ".FTSE", "BT.L", "British Telecom", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
- (10L, "Sell", basketTradeInstanceId, s"$basketTradeInstanceId.VOD.L", ".FTSE", "VOD.L", "Vodafone", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING")
+ (10L, "SELL", basketTradeInstanceId, s"$basketTradeInstanceId.BP.L", ".FTSE", "BP.L", "Beyond Petroleum", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
+ (10L, "BUY", basketTradeInstanceId, s"$basketTradeInstanceId.BT.L", ".FTSE", "BT.L", "British Telecom", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
+ (10L, "SELL", basketTradeInstanceId, s"$basketTradeInstanceId.VOD.L", ".FTSE", "VOD.L", "Vodafone", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING")
)
}
@@ -131,9 +131,9 @@ class BasketMutateOffMarketTest extends VuuServerTestCase {
assertVpEq(filterByVp(vpBasketTradingCons, combineQs(vpBasketTrading))) {
Table(
("quantity", "side", "instanceId", "instanceIdRic", "basketId", "ric", "description", "notionalUsd", "notionalLocal", "venue", "algo", "algoParams", "pctFilled", "weighting", "priceSpread", "limitPrice", "priceStrategyId", "filledQty", "orderStatus"),
- (100L, "Sell", basketTradeInstanceId, s"$basketTradeInstanceId.BP.L", ".FTSE", "BP.L", "Beyond Petroleum", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
- (100L, "Buy", basketTradeInstanceId, s"$basketTradeInstanceId.BT.L", ".FTSE", "BT.L", "British Telecom", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
- (100L, "Sell", basketTradeInstanceId, s"$basketTradeInstanceId.VOD.L", ".FTSE", "VOD.L", "Vodafone", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING")
+ (100L, "SELL", basketTradeInstanceId, s"$basketTradeInstanceId.BP.L", ".FTSE", "BP.L", "Beyond Petroleum", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
+ (100L, "BUY", basketTradeInstanceId, s"$basketTradeInstanceId.BT.L", ".FTSE", "BT.L", "British Telecom", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
+ (100L, "SELL", basketTradeInstanceId, s"$basketTradeInstanceId.VOD.L", ".FTSE", "VOD.L", "Vodafone", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING")
)
}
}
@@ -160,7 +160,7 @@ class BasketMutateOffMarketTest extends VuuServerTestCase {
val basketTradingService = vuuServer.getViewPortRpcServiceProxy[BasketTradingServiceIF](vpBasketTrading)
When("we edit the side of the parent basket to same side as current value")
- basketTradingService.editCellAction().func(basketTradeInstanceId, "side", "Buy", vpBasketTrading, vuuServer.session)
+ basketTradingService.editCellAction().func(basketTradeInstanceId, "side", "BUY", vpBasketTrading, vuuServer.session)
vuuServer.runOnce()
Then("get all the updates that have occurred for all view ports from the outbound queue")
@@ -170,7 +170,7 @@ class BasketMutateOffMarketTest extends VuuServerTestCase {
assertVpEq(filterByVp(vpBasketTrading, updates2)) {
Table(
("instanceId", "basketId", "basketName", "status", "units", "filledPct", "fxRateToUsd", "totalNotional", "totalNotionalUsd", "side"),
- (basketTradeInstanceId, ".FTSE", "MyCustomBasket", "OFF-MARKET", 1, null, null, null, null, "Buy")
+ (basketTradeInstanceId, ".FTSE", "MyCustomBasket", "OFF-MARKET", 1, null, null, null, null, "BUY")
)
}
@@ -178,15 +178,15 @@ class BasketMutateOffMarketTest extends VuuServerTestCase {
assertVpEq(filterByVp(vpBasketTradingCons, updates2)) {
Table(
("quantity", "side", "instanceId", "instanceIdRic", "basketId", "ric", "description", "notionalUsd", "notionalLocal", "venue", "algo", "algoParams", "pctFilled", "weighting", "priceSpread", "limitPrice", "priceStrategyId", "filledQty", "orderStatus"),
- (10L, "Buy", basketTradeInstanceId, s"$basketTradeInstanceId.BP.L", ".FTSE", "BP.L", "Beyond Petroleum", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
- (10L, "Sell", basketTradeInstanceId, s"$basketTradeInstanceId.BT.L", ".FTSE", "BT.L", "British Telecom", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
- (10L, "Buy", basketTradeInstanceId, s"$basketTradeInstanceId.VOD.L", ".FTSE", "VOD.L", "Vodafone", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING")
+ (10L, "BUY", basketTradeInstanceId, s"$basketTradeInstanceId.BP.L", ".FTSE", "BP.L", "Beyond Petroleum", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
+ (10L, "SELL", basketTradeInstanceId, s"$basketTradeInstanceId.BT.L", ".FTSE", "BT.L", "British Telecom", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
+ (10L, "BUY", basketTradeInstanceId, s"$basketTradeInstanceId.VOD.L", ".FTSE", "VOD.L", "Vodafone", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING")
)
}
}
}
- //TODO oin table cannot be tested currently as it doesnt get updated when underlying table gets updated
+ //TODO join table cannot be tested currently as it doesnt get updated when underlying table gets updated
// Scenario("Adding new constituents by ric should add it to basket trading") {
// import BasketModule._
// implicit val clock: Clock = new TestFriendlyClock(10001L)
@@ -217,18 +217,16 @@ class BasketMutateOffMarketTest extends VuuServerTestCase {
// Then("get all the updates that have occurred for all view ports from the outbound queue")
// val updates = combineQs(vpBasketTradingConsJoin)
//
+// //todo should basketid be where the stock was sourced from? in this case .HSI?
//
-// //todo map description
-// //todo should basketid be where the stock was sourced from? in this case .HSI?
-//
-// And("assert the basket trading constituent table has not changed sides")
+// And("assert the basket trading constituent table has added row")
// assertVpEq(filterByVp(vpBasketTradingCons, updates)) {
// Table(
// ("quantity", "side", "instanceId", "instanceIdRic", "basketId", "ric", "description", "notionalUsd", "notionalLocal", "venue", "algo", "algoParams", "pctFilled", "weighting", "priceSpread", "limitPrice", "priceStrategyId", "filledQty", "orderStatus"),
-// (10L, "Buy", basketTradeInstanceId, s"$basketTradeInstanceId.BP.L", ".FTSE", "BP.L", "Beyond Petroleum", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
-// (10L, "Sell", basketTradeInstanceId, s"$basketTradeInstanceId.BT.L", ".FTSE", "BT.L", "British Telecom", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
-// (10L, "Buy", basketTradeInstanceId, s"$basketTradeInstanceId.VOD.L", ".FTSE", "VOD.L", "Vodafone", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
-// (10L, "Buy", basketTradeInstanceId, s"$basketTradeInstanceId.0001.HK", ".FTSE", "0001.HK", "", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING")
+// (10L, "BUY", basketTradeInstanceId, s"$basketTradeInstanceId.BP.L", ".FTSE", "BP.L", "Beyond Petroleum", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
+// (10L, "SELL", basketTradeInstanceId, s"$basketTradeInstanceId.BT.L", ".FTSE", "BT.L", "British Telecom", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
+// (10L, "BUY", basketTradeInstanceId, s"$basketTradeInstanceId.VOD.L", ".FTSE", "VOD.L", "Vodafone", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
+// (10L, "BUY", basketTradeInstanceId, s"$basketTradeInstanceId.0001.HK", ".FTSE", "0001.HK", "", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING")
// )
// }
// }
@@ -240,9 +238,9 @@ class BasketMutateOffMarketTest extends VuuServerTestCase {
basketProvider.tick(".FTSE", Map(B.Id -> ".FTSE", B.Name -> ".FTSE 100", B.NotionalValue -> 1000001, B.NotionalValueUsd -> 1500001))
val constituentProvider = vuuServer.getProvider(BasketModule.NAME, BasketModule.BasketConstituentTable)
- constituentProvider.tick("VOD.L.FTSE", Map(BC.RicBasketId -> "VOD.L.FTSE", BC.Ric -> "VOD.L", BC.BasketId -> basketId, BC.Weighting -> 0.1, BC.Side -> "Buy", BC.Description -> "Vodafone"))
- constituentProvider.tick("BT.L.FTSE", Map(BC.RicBasketId -> "BT.L.FTSE", BC.Ric -> "BT.L", BC.BasketId -> basketId, BC.Weighting -> 0.1, BC.Side -> "Sell", BC.Description -> "British Telecom"))
- constituentProvider.tick("BP.L.FTSE", Map(BC.RicBasketId -> "BP.L.FTSE", BC.Ric -> "BP.L", BC.BasketId -> basketId, BC.Weighting -> 0.1, BC.Side -> "Buy", BC.Description -> "Beyond Petroleum"))
+ constituentProvider.tick("VOD.L.FTSE", Map(BC.RicBasketId -> "VOD.L.FTSE", BC.Ric -> "VOD.L", BC.BasketId -> basketId, BC.Weighting -> 0.1, BC.Side -> "BUY", BC.Description -> "Vodafone"))
+ constituentProvider.tick("BT.L.FTSE", Map(BC.RicBasketId -> "BT.L.FTSE", BC.Ric -> "BT.L", BC.BasketId -> basketId, BC.Weighting -> 0.1, BC.Side -> "SELL", BC.Description -> "British Telecom"))
+ constituentProvider.tick("BP.L.FTSE", Map(BC.RicBasketId -> "BP.L.FTSE", BC.Ric -> "BP.L", BC.BasketId -> basketId, BC.Weighting -> 0.1, BC.Side -> "BUY", BC.Description -> "Beyond Petroleum"))
val vpBasket = vuuServer.createViewPort(BasketModule.NAME, BasketModule.BasketTable)
val basketService = vuuServer.getViewPortRpcServiceProxy[BasketServiceIF](vpBasket)
diff --git a/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketSendToMarketTest.scala b/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketSendToMarketTest.scala
index 36fc23848..7bc7511ea 100644
--- a/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketSendToMarketTest.scala
+++ b/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketSendToMarketTest.scala
@@ -54,9 +54,20 @@ class BasketSendToMarketTest extends VuuServerTestCase {
val basketTradeInstanceId = BasketTradeId.current
val vpBasketTrading = vuuServer.createViewPort(BasketModule.NAME, BasketTradingTable)
+ val vpBasketTradingCons = vuuServer.createViewPort(BasketModule.NAME, BasketTradingConstituentTable)
vuuServer.runOnce()
+ And("Check the trading constituents are created")
+ assertVpEq(combineQsForVp(vpBasketTradingCons)) {
+ Table(
+ ("quantity", "side", "instanceId", "instanceIdRic", "basketId", "ric", "description", "notionalUsd", "notionalLocal", "venue", "algo", "algoParams", "pctFilled", "weighting", "priceSpread", "limitPrice", "priceStrategyId", "filledQty", "orderStatus"),
+ (10L, "BUY", basketTradeInstanceId, s"$basketTradeInstanceId.BP.L", ".FTSE", "BP.L", "Beyond Petroleum", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
+ (10L, "SELL", basketTradeInstanceId, s"$basketTradeInstanceId.BT.L", ".FTSE", "BT.L", "British Telecom", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"),
+ (10L, "BUY", basketTradeInstanceId, s"$basketTradeInstanceId.VOD.L", ".FTSE", "VOD.L", "Vodafone", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING")
+ )
+ }
+
val tradingService = vuuServer.getViewPortRpcServiceProxy[BasketTradingServiceIF](vpBasketTrading)
And("send the basket to market")
@@ -68,7 +79,20 @@ class BasketSendToMarketTest extends VuuServerTestCase {
assertVpEq(combineQsForVp(vpBasketTrading)) {
Table(
("instanceId", "basketId", "basketName", "status", "units", "filledPct", "fxRateToUsd", "totalNotional", "totalNotionalUsd", "side"),
- (basketTradeInstanceId, ".FTSE", "TestBasket", "ON_MARKET", 1, null, null, null, null, "Buy")
+ (basketTradeInstanceId, ".FTSE", "TestBasket", "ON_MARKET", 1, null, null, null, null, "BUY")
+ )
+ }
+
+ Then("Take the basket off the market")
+ tradingService.takeOffMarket(basketTradeInstanceId)(vuuServer.requestContext)
+
+ vuuServer.runOnce()
+
+ And("verify basket is on market")
+ assertVpEq(combineQsForVp(vpBasketTrading)) {
+ Table(
+ ("instanceId", "basketId", "basketName", "status", "units", "filledPct", "fxRateToUsd", "totalNotional", "totalNotionalUsd", "side"),
+ (basketTradeInstanceId, ".FTSE", "TestBasket", "OFF_MARKET", 1, null, null, null, null, "BUY")
)
}
}
diff --git a/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketTestCaseHelper.scala b/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketTestCaseHelper.scala
index 540cb1d2d..657af5767 100644
--- a/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketTestCaseHelper.scala
+++ b/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketTestCaseHelper.scala
@@ -20,8 +20,8 @@ object BasketTestCaseHelper {
//symbol + "." + basketId
//Columns.fromNames(BC.RicBasketId.string(), BC.Ric.string(), BC.BasketId.string(), BC.Weighting.double(), BC.LastTrade.string(), BC.Change.string(),
// BC.Volume.string(), BC.Side.string())
- provider.tick("VOD.L.FTSE", Map(BC.RicBasketId -> "VOD.L.FTSE", BC.Ric -> "VOD.L", BC.BasketId -> ".FTSE", BC.Weighting -> 0.1, BC.Side -> "Buy", BC.Description -> "Vodafone"))
- provider.tick("BT.L.FTSE", Map(BC.RicBasketId -> "BT.L.FTSE", BC.Ric -> "BT.L", BC.BasketId -> ".FTSE", BC.Weighting -> 0.1, BC.Side -> "Sell", BC.Description -> "British Telecom"))
- provider.tick("BP.L.FTSE", Map(BC.RicBasketId -> "BP.L.FTSE", BC.Ric -> "BP.L", BC.BasketId -> ".FTSE", BC.Weighting -> 0.1, BC.Side -> "Buy", BC.Description -> "Beyond Petroleum"))
+ provider.tick("VOD.L.FTSE", Map(BC.RicBasketId -> "VOD.L.FTSE", BC.Ric -> "VOD.L", BC.BasketId -> ".FTSE", BC.Weighting -> 0.1, BC.Side -> "BUY", BC.Description -> "Vodafone"))
+ provider.tick("BT.L.FTSE", Map(BC.RicBasketId -> "BT.L.FTSE", BC.Ric -> "BT.L", BC.BasketId -> ".FTSE", BC.Weighting -> 0.1, BC.Side -> "SELL", BC.Description -> "British Telecom"))
+ provider.tick("BP.L.FTSE", Map(BC.RicBasketId -> "BP.L.FTSE", BC.Ric -> "BP.L", BC.BasketId -> ".FTSE", BC.Weighting -> 0.1, BC.Side -> "BUY", BC.Description -> "Beyond Petroleum"))
}
}
diff --git a/example/basket/src/test/scala/org/finos/vuu/core/module/basket/TestHelper/TestDataFactory.scala b/example/basket/src/test/scala/org/finos/vuu/core/module/basket/TestHelper/TestDataFactory.scala
index a7ce889b1..526a13f93 100644
--- a/example/basket/src/test/scala/org/finos/vuu/core/module/basket/TestHelper/TestDataFactory.scala
+++ b/example/basket/src/test/scala/org/finos/vuu/core/module/basket/TestHelper/TestDataFactory.scala
@@ -1,7 +1,7 @@
package org.finos.vuu.core.module.basket.TestHelper
+import org.finos.vuu.core.module.basket.BasketModule.{BasketTradingColumnNames => BT, BasketTradingConstituentColumnNames => BTC}
import org.finos.vuu.core.table.RowWithData
-import org.finos.vuu.core.module.basket.BasketModule.{Sides, BasketColumnNames => B, BasketConstituentColumnNames => BC, BasketTradingColumnNames => BT, BasketTradingConstituentColumnNames => BTC}
object TestDataFactory {
def uuid = java.util.UUID.randomUUID.toString
diff --git a/example/main-java/pom.xml b/example/main-java/pom.xml
index 6f9014449..7e1e2f1b3 100644
--- a/example/main-java/pom.xml
+++ b/example/main-java/pom.xml
@@ -19,6 +19,15 @@
0.9.36-SNAPSHOT
+
+ org.finos.vuu
+ vuu
+ 0.9.36-SNAPSHOT
+ tests
+ test-jar
+ test
+
+
org.finos.vuu
basket
diff --git a/example/main-java/src/main/java/org/finos/vuu/module/MyExampleModule.java b/example/main-java/src/main/java/org/finos/vuu/module/MyExampleModule.java
index 188ac9ffa..2d3d441ff 100644
--- a/example/main-java/src/main/java/org/finos/vuu/module/MyExampleModule.java
+++ b/example/main-java/src/main/java/org/finos/vuu/module/MyExampleModule.java
@@ -14,7 +14,7 @@
public class MyExampleModule extends DefaultModule {
- private final String NAME = "MY_MOD";
+ public static final String NAME = "MY_MOD";
public ViewServerModule create(final TableDefContainer tableDefContainer){
return ModuleFactory.withNamespace(NAME, tableDefContainer)
diff --git a/example/main-java/src/test/java/org/finos/vuu/JavaTestExample.java b/example/main-java/src/test/java/org/finos/vuu/JavaTestExample.java
new file mode 100644
index 000000000..617a5e29d
--- /dev/null
+++ b/example/main-java/src/test/java/org/finos/vuu/JavaTestExample.java
@@ -0,0 +1,60 @@
+package org.finos.vuu;
+
+import org.finos.toolbox.jmx.MetricsProvider;
+import org.finos.toolbox.jmx.MetricsProviderImpl;
+import org.finos.toolbox.lifecycle.LifecycleContainer;
+import org.finos.toolbox.time.Clock;
+import org.finos.toolbox.time.TestFriendlyClock;
+import org.finos.vuu.core.module.TableDefContainer;
+import org.finos.vuu.core.module.ViewServerModule;
+import org.finos.vuu.module.MyExampleModule;
+import org.finos.vuu.provider.MockProvider;
+import org.finos.vuu.test.VuuServerTestCase;
+import org.finos.vuu.viewport.ViewPort;
+import org.scalatest.Ignore;
+import scala.collection.immutable.Seq;
+
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+import static scala.jdk.javaapi.CollectionConverters.asScala;
+
+public class JavaTestExample extends VuuServerTestCase {
+
+ public static Seq toScalaSeq(ViewServerModule... modules){
+ return new scala.collection.mutable.ListBuffer().addAll(asScala(Arrays.stream(modules).collect(Collectors.toList()))).toSeq();
+ }
+
+
+ @Ignore
+ public void testVuuServerFunctionality() throws Exception{
+
+ final MetricsProvider metrics = new MetricsProviderImpl();
+ final Clock clock = new TestFriendlyClock(1000000000000L);
+ final LifecycleContainer lifecycle = new LifecycleContainer(clock);
+ final TableDefContainer tableDefContainer = new TableDefContainer();
+
+ final ViewServerModule module = new MyExampleModule().create(tableDefContainer);
+
+ withVuuServer(toScalaSeq(module), (vuuServer) -> {
+
+ vuuServer.login("test", "test");
+
+ ViewPort viewport = vuuServer.createViewPort(MyExampleModule.NAME, "myTable");
+
+ MockProvider provider = vuuServer.getProvider(MyExampleModule.NAME, "myTable");
+
+// provider.tick("123", Map.of("id", "123", "foo", "bar", "myInt", 123));
+//
+// Seq updates = combineQs(viewport);
+//
+// assertVpEq(updates, () -> asList(
+// asList("id", "foo", "myInt"),
+// asList("123", "bar", 123)
+// ));
+
+ return null;
+ }, clock, lifecycle, metrics);
+ }
+
+}
diff --git a/example/order/src/main/scala/org/finos/vuu/core/module/simul/provider/ParentChildOrdersModel.scala b/example/order/src/main/scala/org/finos/vuu/core/module/simul/provider/ParentChildOrdersModel.scala
index 5d08aee37..9b0be7bbf 100644
--- a/example/order/src/main/scala/org/finos/vuu/core/module/simul/provider/ParentChildOrdersModel.scala
+++ b/example/order/src/main/scala/org/finos/vuu/core/module/simul/provider/ParentChildOrdersModel.scala
@@ -291,7 +291,7 @@ class ParentChildOrdersModel(implicit clock: Clock, lifecycleContainer: Lifecycl
val instIdx = randomNumbers.seededRand(0, instruments.length - 1)
val instrument = instruments(instIdx)
val quantity = randomNumbers.seededRand(0, 30) * 100 + randomNumbers.seededRand(0, 100)
- val side = if (randomNumbers.seededRand(0, 10) > 8) "Buy" else "Sell"
+ val side = if (randomNumbers.seededRand(0, 10) > 8) "BUY" else "SELL"
val account = accounts(randomNumbers.seededRand(0, accounts.length - 1))
val algo = algos(randomNumbers.seededRand(0, algos.length - 1))
val volLimit = randomNumbers.seededRand(0, 10) * 10
diff --git a/example/order/src/main/scala/org/finos/vuu/order/oms/OmsApi.scala b/example/order/src/main/scala/org/finos/vuu/order/oms/OmsApi.scala
index 12a15fdac..a780c854a 100644
--- a/example/order/src/main/scala/org/finos/vuu/order/oms/OmsApi.scala
+++ b/example/order/src/main/scala/org/finos/vuu/order/oms/OmsApi.scala
@@ -23,6 +23,7 @@ trait OmsApi {
def addListener(omsListener: OmsListener): Unit
def runOnce(): Unit
def containsOrder(clientOrderId: String): Boolean
+ def getOrderId(clientOrderId: String): Option[Int]
}
trait OmsListener{
diff --git a/example/order/src/main/scala/org/finos/vuu/order/oms/impl/InMemOmsApi.scala b/example/order/src/main/scala/org/finos/vuu/order/oms/impl/InMemOmsApi.scala
index 1805f5a9b..09b4ac4c2 100644
--- a/example/order/src/main/scala/org/finos/vuu/order/oms/impl/InMemOmsApi.scala
+++ b/example/order/src/main/scala/org/finos/vuu/order/oms/impl/InMemOmsApi.scala
@@ -42,7 +42,13 @@ class InMemOmsApi(implicit val clock: Clock) extends OmsApi {
override def replaceOrder(replaceOrder: ReplaceOrder): Unit = ???
- override def cancelOrder(cancelOrder: CancelOrder): Unit = ???
+ override def cancelOrder(cancelOrder: CancelOrder): Unit = {
+ orders = orders.map(orderState =>
+ if (orderState.orderId == cancelOrder.orderId)
+ orderState.copy(state = States.CANCELLED, nextEventTime = clock.now())
+ else orderState
+ )
+ }
override def addListener(omsListener: OmsListener): Unit = listeners = listeners ++ List(omsListener)
@@ -58,9 +64,14 @@ class InMemOmsApi(implicit val clock: Clock) extends OmsApi {
orderstate.copy(state = States.ACKED, nextEventTime = clock.now() + random.between(1000, MaxTimes.MAX_FILL_TIME_MS), orderId = orderId)
case 'A' =>
val remainingQty = orderstate.qty - orderstate.filledQty
- val fillQty = if(remainingQty > 1) random.between(1, orderstate.qty - orderstate.filledQty) else 1
- listeners.foreach(_.onFill(Fill(orderstate.orderId, fillQty, orderstate.price, orderstate.clientOrderId, orderstate.filledQty + fillQty, orderstate.qty)))
- orderstate.copy(filledQty = orderstate.filledQty + fillQty, nextEventTime = clock.now() + random.between(1000, 5000))
+ val fillQty = if(remainingQty > 1) random.between(1, remainingQty) else 1
+ val totalFilledQty = orderstate.filledQty + fillQty
+ val nextState = if( orderstate.qty == totalFilledQty) States.FILLED else States.ACKED
+ listeners.foreach(_.onFill(Fill(orderstate.orderId, fillQty, orderstate.price, orderstate.clientOrderId, totalFilledQty, orderstate.qty)))
+ orderstate.copy(state = nextState, filledQty = totalFilledQty, nextEventTime = clock.now() + random.between(1000, MaxTimes.MAX_FILL_TIME_MS))
+ case 'X' =>
+ listeners.foreach(_.onCancelAck(CancelAck(orderstate.orderId, orderstate.clientOrderId)))
+ orderstate
case _ =>
orderstate
}
@@ -70,8 +81,14 @@ class InMemOmsApi(implicit val clock: Clock) extends OmsApi {
}
})
- orders = orders.filter(os => os.filledQty != os.qty)
+ orders = orders.filter(os => os.state != States.FILLED && os.state != States.CANCELLED)
}
+ override def getOrderId(clientOrderId: String): Option[Int] = {
+ orders.find(os => os.clientOrderId == clientOrderId) match {
+ case Some(os) => Some(os.orderId)
+ case None => None
+ }
+ }
}
diff --git a/example/order/src/test/scala/org/finos/vuu/order/oms/OmsApiTest.scala b/example/order/src/test/scala/org/finos/vuu/order/oms/OmsApiTest.scala
index e3e2b54f5..eb2ed2454 100644
--- a/example/order/src/test/scala/org/finos/vuu/order/oms/OmsApiTest.scala
+++ b/example/order/src/test/scala/org/finos/vuu/order/oms/OmsApiTest.scala
@@ -62,7 +62,7 @@ class OmsApiTest extends AnyFeatureSpec with GivenWhenThen with Matchers {
omsApi.addListener(listener)
- omsApi.createOrder(NewOrder("Buy","VOD.L", 1000L, 100.01, "clOrdId1"))
+ omsApi.createOrder(NewOrder("BUY","VOD.L", 1000L, 100.01, "clOrdId1"))
clock.sleep(MAX_ACK_TIME_MS)
omsApi.runOnce()
@@ -74,7 +74,7 @@ class OmsApiTest extends AnyFeatureSpec with GivenWhenThen with Matchers {
omsApi.containsOrder("clOrdId1") should equal(true)
- listener.getOrderState("clOrdId1").get.filledQty should be > (0L)
+ listener.getOrderState("clOrdId1").get.filledQty should be > 0L
for (n <- 1 to 1000) {
clock.sleep(MAX_FILL_TIME_MS)
@@ -84,5 +84,34 @@ class OmsApiTest extends AnyFeatureSpec with GivenWhenThen with Matchers {
omsApi.containsOrder("clOrdId1") should equal(false)
}
+
+ Scenario("Check we can submit order and cancel") {
+
+ implicit val clock: Clock = new TestFriendlyClock(1000L)
+
+ val omsApi = OmsApi()
+
+ val listener = new TestListener()
+
+ omsApi.addListener(listener)
+
+ omsApi.createOrder(NewOrder("BUY", "VOD.L", 1000L, 100.01, "clOrdId1"))
+ omsApi.createOrder(NewOrder("BUY", "BP.L", 1000L, 150.01, "clOrdId2"))
+
+ clock.sleep(MAX_ACK_TIME_MS)
+ omsApi.runOnce()
+
+ listener.getOrderState("clOrdId1").get.state should equal("ACKED")
+
+ val orderId = omsApi.getOrderId("clOrdId1").get
+ omsApi.cancelOrder(CancelOrder(orderId))
+ omsApi.runOnce()
+
+ omsApi.containsOrder("clOrdId1") should equal(false)
+ listener.getOrderState("clOrdId1").get.state should equal("CANCELLED")
+
+ omsApi.containsOrder("clOrdId2") should equal(true)
+
+ }
}
}
diff --git a/vuu/src/main/scala/org/finos/vuu/viewport/ViewPortAction.scala b/vuu/src/main/scala/org/finos/vuu/viewport/ViewPortAction.scala
index a91273908..3575beab6 100644
--- a/vuu/src/main/scala/org/finos/vuu/viewport/ViewPortAction.scala
+++ b/vuu/src/main/scala/org/finos/vuu/viewport/ViewPortAction.scala
@@ -25,7 +25,7 @@ case class CloseDialogViewPortAction(vpId: String) extends ViewPortAction
new Type(value = classOf[NoAction], name = "NO_ACTION"),
new Type(value = classOf[ViewPortEditSuccess], name = "VP_EDIT_SUCCESS"),
new Type(value = classOf[ViewPortEditFailure], name = "VP_EDIT_FAILURE"),
- new Type(value = classOf[ViewPortRpcSuccess], name = "VP_RCP_SUCCESS"),
- new Type(value = classOf[ViewPortRpcFailure], name = "VP_RCP_FAILURE"),
+ new Type(value = classOf[ViewPortRpcSuccess], name = "VP_RPC_SUCCESS"),
+ new Type(value = classOf[ViewPortRpcFailure], name = "VP_RPC_FAILURE"),
))
trait ViewPortActionMixin {}
diff --git a/vuu/src/main/scala/org/finos/vuu/viewport/ViewPortColumns.scala b/vuu/src/main/scala/org/finos/vuu/viewport/ViewPortColumns.scala
index 02775ed7c..eca0bd55b 100644
--- a/vuu/src/main/scala/org/finos/vuu/viewport/ViewPortColumns.scala
+++ b/vuu/src/main/scala/org/finos/vuu/viewport/ViewPortColumns.scala
@@ -2,40 +2,55 @@ package org.finos.vuu.viewport
import org.finos.vuu.core.table.{CalculatedColumn, Column, RowData, RowWithData}
-class ViewPortColumns(sourceColumns: List[Column]){
+class ViewPortColumns(sourceColumns: List[Column]) {
- @volatile private var columns: List[Column] = sourceColumns
+ @volatile private var columns: List[Column] = sourceColumns
- def addColumn(column: Column): Unit = {
- columns = columns ++ List(column)
- }
+ def canEqual(a: Any): Boolean = a.isInstanceOf[ViewPortColumns]
- def columnExists(name: String): Boolean = {
- columns.exists(_.name == name)
+ override def equals(that: Any): Boolean =
+ that match {
+ case that: ViewPortColumns =>
+ that.canEqual(this) &&
+ this.columns.size == that.columns.size &&
+ 0 == this.columns.sortBy(c => c.name)
+ .zip(that.columns.sortBy(c => c.name))
+ .count(columnPair => columnPair._1.name != columnPair._2.name || columnPair._1.dataType != columnPair._2.dataType)
+ case _ => false
}
- def getColumns(): List[Column] = columns
+ override def hashCode(): Int = columns.sortBy(c => c.name).map(_.hashCode()).hashCode()
- def getColumnForName(name: String): Option[Column] = {
- columns.find(_.name == name)
- }
+ def addColumn(column: Column): Unit = {
+ columns = columns ++ List(column)
+ }
- def count(): Int = columns.size
+ def columnExists(name: String): Boolean = {
+ columns.exists(_.name == name)
+ }
- private lazy val hasCalculatedColumn = columns.exists(c => c.isInstanceOf[CalculatedColumn])
+ def getColumns(): List[Column] = columns
- def pullRow(key: String, row: RowData): RowData = {
+ def getColumnForName(name: String): Option[Column] = {
+ columns.find(_.name == name)
+ }
- if(!hasCalculatedColumn){
- row
- }else{
- val rowData = this.getColumns().map(c => c.name -> row.get(c)).toMap
- RowWithData(key, rowData)
- }
- }
+ def count(): Int = columns.size
- def pullRowAlwaysFilter(key: String, row: RowData): RowData = {
+ private lazy val hasCalculatedColumn = columns.exists(c => c.isInstanceOf[CalculatedColumn])
+
+ def pullRow(key: String, row: RowData): RowData = {
+
+ if (!hasCalculatedColumn) {
+ row
+ } else {
val rowData = this.getColumns().map(c => c.name -> row.get(c)).toMap
RowWithData(key, rowData)
+ }
+ }
+
+ def pullRowAlwaysFilter(key: String, row: RowData): RowData = {
+ val rowData = this.getColumns().map(c => c.name -> row.get(c)).toMap
+ RowWithData(key, rowData)
}
}
diff --git a/vuu/src/test/scala/org/finos/vuu/viewport/ViewPortColumnsTests.scala b/vuu/src/test/scala/org/finos/vuu/viewport/ViewPortColumnsTests.scala
new file mode 100644
index 000000000..ff678c1bf
--- /dev/null
+++ b/vuu/src/test/scala/org/finos/vuu/viewport/ViewPortColumnsTests.scala
@@ -0,0 +1,55 @@
+package org.finos.vuu.viewport
+
+import org.finos.vuu.core.table.Columns
+import org.scalatest.featurespec.AnyFeatureSpec
+
+class ViewPortColumnsTests extends AnyFeatureSpec {
+
+ Feature("compare two view port columns") {
+
+ Scenario("when all the columns names are same equality check should return true") {
+ val sourceColumn = Columns.fromNames("firstColumn:String", "secondColumn:String")
+ val oldVPColumns = new ViewPortColumns(sourceColumn.toList)
+ val sourceColumn2 = Columns.fromNames("firstColumn:String", "secondColumn:String")
+ val newVPColumns = new ViewPortColumns(sourceColumn2.toList)
+
+ assert(oldVPColumns == newVPColumns)
+ }
+
+ Scenario("when all the columns names are same in different order equality check should return true") {
+ val sourceColumn = Columns.fromNames("firstColumn:String", "secondColumn:String")
+ val oldVPColumns = new ViewPortColumns(sourceColumn.toList)
+ val sourceColumn2 = Columns.fromNames("secondColumn:String", "firstColumn:String")
+ val newVPColumns = new ViewPortColumns(sourceColumn2.toList)
+
+ assert(oldVPColumns == newVPColumns)
+ }
+
+ Scenario("when one if the column has different type equality check should return false") {
+ val sourceColumn = Columns.fromNames("firstColumn:String", "secondColumn:String")
+ val oldVPColumns = new ViewPortColumns(sourceColumn.toList)
+ val sourceColumn2 = Columns.fromNames("firstColumn:String", "secondColumn:Int")
+ val newVPColumns = new ViewPortColumns(sourceColumn2.toList)
+
+ assert(oldVPColumns != newVPColumns)
+ }
+
+ Scenario("when one if the column has different name equality check should return false") {
+ val sourceColumn = Columns.fromNames("firstColumn:String", "secondColumn:String")
+ val oldVPColumns = new ViewPortColumns(sourceColumn.toList)
+ val sourceColumn2 = Columns.fromNames("firstColumn:String", "someOtherColumn:String")
+ val newVPColumns = new ViewPortColumns(sourceColumn2.toList)
+
+ assert(oldVPColumns != newVPColumns)
+ }
+
+ Scenario("when all the columns not same equality check should return false") {
+ val sourceColumn = Columns.fromNames("firstColumn:String", "secondColumn:String")
+ val oldVPColumns = new ViewPortColumns(sourceColumn.toList)
+ val sourceColumn2 = Columns.fromNames("firstColumn:String")
+ val newVPColumns = new ViewPortColumns(sourceColumn2.toList)
+
+ assert(oldVPColumns != newVPColumns)
+ }
+ }
+}