/// <summary> /// Get the real monney amount that will be exchanged for a transaction /// </summary> /// <param name="pTransaction">Transaction</param> /// <returns>Amount of real monney</returns> public CAmount GetTransationAmount(CTransaction pTransaction) { switch (pTransaction.TransactionType) { case ETransactionType.BUYS: return new CAmount((decimal)((pTransaction.Quantity * GetQuote()) * (1 + GetCommissionRate(pTransaction.Quantity))), ECurrencies.REAL_MONNEY); default: //TODO : Why does the broker gives his commission here instead of taking it ? Here is corrected version of the formula //return new CAmount((decimal)((pTransaction.Quantity * GetQuote()) * (1 + GetCommissionRate(pTransaction.Quantity))), ECurrencies.REAL_MONNEY); return new CAmount((decimal)((pTransaction.Quantity * GetQuote()) * (1 - GetCommissionRate(pTransaction.Quantity))), ECurrencies.REAL_MONNEY); } }
/// <summary> /// Get the real monney amount that will be exchanged for a transaction /// </summary> /// <param name="pTransaction">Transaction</param> /// <returns>Amount of real monney</returns> public CAmount GetTransationAmount(CTransaction pTransaction) { switch (pTransaction.TransactionType) { case ETransactionType.BUYS: return(new CAmount((decimal)((pTransaction.Quantity * GetQuote()) * (1 + GetCommissionRate(pTransaction.Quantity))), ECurrencies.REAL_MONNEY)); default: //TODO : Why does the broker gives his commission here instead of taking it ? Here is corrected version of the formula //return new CAmount((decimal)((pTransaction.Quantity * GetQuote()) * (1 + GetCommissionRate(pTransaction.Quantity))), ECurrencies.REAL_MONNEY); return(new CAmount((decimal)((pTransaction.Quantity * GetQuote()) * (1 - GetCommissionRate(pTransaction.Quantity))), ECurrencies.REAL_MONNEY)); } }
/// <summary> /// Copy constructor /// </summary> /// <param name="pTransaction"></param> public CTransaction(CTransaction pTransaction) { Quantity = pTransaction.Quantity; Client = pTransaction.Client; TransactionType = pTransaction.TransactionType; }
/// <summary> /// Executes client order /// </summary> /// <param name="pTransaction">Transaction</param> /// <returns></returns> public static CTransactionsInvoice ExecuteTransaction(CTransaction pTransaction) { if (Brokers == null || !Brokers.Any()) { throw new Exception("No broker specified"); } List<CTransactionsInvoice> combinaisons = new List<CTransactionsInvoice>(); //Cases of one simple transaction if (pTransaction.Quantity <= MAX_AMOUNT_PER_TRANSACTION) { combinaisons.Add(new CTransactionsInvoice(new List<CTransactionExecution> { CheckSingleTransaction(pTransaction, Brokers[0]) })); combinaisons.Add(new CTransactionsInvoice(new List<CTransactionExecution> { CheckSingleTransaction(pTransaction, Brokers[1]) })); } //Cases of combination of transactions (transaction splitted between two brookers) for (int i = CTransaction.LOT_SIZE; i <= MAX_AMOUNT_PER_TRANSACTION; i += CTransaction.LOT_SIZE) { //If max quanttity is not reached if(pTransaction.Quantity - i <= MAX_AMOUNT_PER_TRANSACTION && (pTransaction.Quantity - i) > 0) { CTransaction transaction1 = new CTransaction(pTransaction); CTransaction transaction2 = new CTransaction(pTransaction); //Split into 2 transactions transaction1.Quantity = i; transaction2.Quantity = pTransaction.Quantity - i; List<CTransactionExecution> transactions = new List<CTransactionExecution> { CheckSingleTransaction(transaction1, Brokers[0]), CheckSingleTransaction(transaction2, Brokers[1]) }; combinaisons.Add(new CTransactionsInvoice(transactions)); } } //init best combinaison CTransactionsInvoice bestCombinaison = combinaisons[0]; combinaisons.RemoveAt(0); foreach (CTransactionsInvoice combinaison in combinaisons) { //TODO : Why does lower price is the most interesting when we sell Digicoint ? here is code that get best transaction for clien if ((combinaison.TotalRealMonneyExchanged < bestCombinaison.TotalRealMonneyExchanged && pTransaction.TransactionType == ETransactionType.BUYS) //smaller amount is better when buying || (combinaison.TotalRealMonneyExchanged > bestCombinaison.TotalRealMonneyExchanged && pTransaction.TransactionType == ETransactionType.SELLS)) //bigger amount is better when selling { //better combinaison than previous bestCombinaison = combinaison; } } //Executes order buy adding it in customer and broker histories foreach(CTransactionExecution transactionExecuted in bestCombinaison.TransactionsExecuted) { transactionExecuted.Broker.TransactionsExecuted.Add(transactionExecuted); pTransaction.Client.TransactionsExecuted.Add(transactionExecuted); } //returns the invoice return bestCombinaison; }
/// <summary> /// Chack price of a single transactions in a broker /// </summary> /// <param name="pTransaction">Transaction</param> /// <param name="pBroker">Broker</param> /// <returns></returns> private static CTransactionExecution CheckSingleTransaction(CTransaction pTransaction, CBroker pBroker) { CAmount transactionAmount = pBroker.GetTransationAmount(pTransaction); CAmount digicoinsExchanged = new CAmount(pTransaction.Quantity, ECurrencies.DIGICOINS); CTransactionExecution transactionExecuted = new CTransactionExecution(pTransaction, pBroker, transactionAmount, digicoinsExchanged); return transactionExecuted; }
public void TestMethod1() { CClient clientA = new CClient("Client A"); CClient clientB = new CClient("Client B"); CClient clientC = new CClient("Client C"); CBroker1 broker1 = new CBroker1(); CBroker2 broker2 = new CBroker2(); CServer.Brokers[0] = broker1; CServer.Brokers[1] = broker2; //1) CTransaction transac1 = new CTransaction { Quantity = 10, Client = clientA, TransactionType = ETransactionType.BUYS }; CTransactionsInvoice transacExec1 = CServer.ExecuteTransaction(transac1); Assert.AreEqual(15.645M, transacExec1.TotalRealMonneyExchanged.Amount); //2) CTransaction transac2 = new CTransaction { Quantity = 40, Client = clientB, TransactionType = ETransactionType.BUYS }; CTransactionsInvoice transacExec2 = CServer.ExecuteTransaction(transac2); Assert.AreEqual(62.58M, transacExec2.TotalRealMonneyExchanged.Amount); //3) CTransaction transac3 = new CTransaction { Quantity = 50, Client = clientA, TransactionType = ETransactionType.BUYS }; CTransactionsInvoice transacExec3 = CServer.ExecuteTransaction(transac3); Assert.AreEqual(77.9M, transacExec3.TotalRealMonneyExchanged.Amount); //4) CTransaction transac4 = new CTransaction { Quantity = 100, Client = clientB, TransactionType = ETransactionType.BUYS }; CTransactionsInvoice transacExec4 = CServer.ExecuteTransaction(transac4); Assert.AreEqual(155.04M, transacExec4.TotalRealMonneyExchanged.Amount); //5) CTransaction transac5 = new CTransaction { Quantity = 80, Client = clientB, TransactionType = ETransactionType.SELLS }; CTransactionsInvoice transacExec5 = CServer.ExecuteTransaction(transac5); //Assert.AreEqual(124.64M, transacExec5.TotalRealMonneyExchanged.Amount); //TODO : Change assertions if commission rule changed in the case where client sells Digicoins //Broker1 : 80 DIGICOINS * 1.49 = 119.20 'REAL_MONNEY', Removal of commission of 5% : 119.20 * 0.95 = 113.24 'REAL_MONNEY' //Broker2 : 80 DIGICOINS * 1.52 = 121.60 'REAL_MONNEY', Removal of commission of 2.5% : 121.60 * 0.975 = 118.56 'REAL_MONNEY' => best choice Assert.AreEqual(118.56M, transacExec5.TotalRealMonneyExchanged.Amount); //6) CTransaction transac6 = new CTransaction { Quantity = 70, Client = clientC, TransactionType = ETransactionType.SELLS }; CTransactionsInvoice transacExec6 = CServer.ExecuteTransaction(transac6); //Assert.AreEqual(109.06M, transacExec6.TotalRealMonneyExchanged.Amount); Assert.AreEqual(103.74M, transacExec6.TotalRealMonneyExchanged.Amount); //7) CTransaction transac7 = new CTransaction { Quantity = 130, Client = clientA, TransactionType = ETransactionType.BUYS }; CTransactionsInvoice transacExec7 = CServer.ExecuteTransaction(transac7); Assert.AreEqual(201.975M, transacExec7.TotalRealMonneyExchanged.Amount); //8) CTransaction transac8 = new CTransaction { Quantity = 60, Client = clientB, TransactionType = ETransactionType.SELLS }; CTransactionsInvoice transacExec8 = CServer.ExecuteTransaction(transac8); //Assert.AreEqual(93.48M, transacExec8.TotalRealMonneyExchanged.Amount); Assert.AreEqual(88.92M, transacExec8.TotalRealMonneyExchanged.Amount); //9) //TODO : Selling commission rule changes the net position of client //Assert.AreEqual(296.56M, clientA.NetPosition); //Assert.AreEqual(0M, clientB.NetPosition); //Assert.AreEqual(-109.06M, clientC.NetPosition); Assert.AreEqual(295.520M, clientA.NetPosition); Assert.AreEqual(10.14M, clientB.NetPosition); Assert.AreEqual(-103.74, clientC.NetPosition); //10) Assert.AreEqual(80M, broker1.DigicoinsProcessed.Amount); Assert.AreEqual(460M, broker2.DigicoinsProcessed.Amount); }