public void PersistArbitrationOpportunityWithoutRunId() { ArbitrationOpportunity testArbitrationTrade = new ArbitrationOpportunity(new Bitstamp(), new Kraken()); //This should result in an error since testArbitrationTrade.ArbitrationRunId was not set. testArbitrationTrade.PersistToDb(); }
public void MostProfitableTrade_Rule_OpportunityList_Null_Or_Empty() { ArbitrationOpportunity result = ArbitrationFilter.MostProfitableTrade(null); Assert.IsTrue(result == null); result = ArbitrationFilter.MostProfitableTrade(new List <ArbitrationOpportunity>()); Assert.IsTrue(result == null); }
public void TradeForExchangeWithLowestBtc_Rule_Validate() { List <BaseExchange> exchangeList = CreateExchangeList(new Anx(), new Bitstamp(), new Btce(), new ItBit(), new Btce(), new Kraken(), new Anx()); List <ArbitrationOpportunity> opportunityList = new List <ArbitrationOpportunity>(); ArbitrationOpportunity result; exchangeList[0].AvailableBtc = 0.6524987m; exchangeList[1].AvailableBtc = 0.9654689m; exchangeList[2].AvailableBtc = 1.069509478320m; exchangeList[3].AvailableBtc = 8.657849810m; exchangeList[4].AvailableBtc = 98.14651m; exchangeList[5].AvailableBtc = 9.98163521m; exchangeList[6].AvailableBtc = 0.0m; ArbitrationOpportunity opportunity1 = new ArbitrationOpportunity(exchangeList[0], exchangeList[1]); opportunity1.Profit = 7.87m; opportunity1.SellExchange = exchangeList[1]; opportunityList.Add(opportunity1); //Test case: only 1 opportunity in list result = ArbitrationFilter.MostProfitableTrade(opportunityList); Assert.IsTrue(result == opportunity1); ArbitrationOpportunity opportunity2 = new ArbitrationOpportunity(exchangeList[3], exchangeList[2]); opportunity2.Profit = 7.48m; opportunityList.Add(opportunity2); ArbitrationOpportunity opportunity3 = new ArbitrationOpportunity(exchangeList[5], exchangeList[0]); opportunity3.Profit = 4.57m; opportunityList.Add(opportunity3); ArbitrationOpportunity opportunity4 = new ArbitrationOpportunity(exchangeList[1], exchangeList[4]); opportunity4.Profit = 87.00m; opportunityList.Add(opportunity4); //Test case: no exchanges in the exchangelist map to any sell exchanges for an opportunity List <BaseExchange> exchangeList2 = CreateExchangeList(new ItBit(), new Kraken(), new ItBit(), new Kraken()); result = ArbitrationFilter.TradeForExchangeWithLowestBtc(opportunityList, exchangeList2); Assert.IsTrue(result == null); //Test case: Correct opportunity is in the middle of the opportunity list result = ArbitrationFilter.TradeForExchangeWithLowestBtc(opportunityList, exchangeList); Assert.IsTrue(result == opportunity3); //Test case: All opportunities have the same profit, opportunity for UseCryptos is returned because it has the least balance ArbitrationOpportunity opportunity5 = new ArbitrationOpportunity(exchangeList[1], exchangeList[6]); opportunity4.Profit = 87.00m; opportunityList.Add(opportunity5); result = ArbitrationFilter.TradeForExchangeWithLowestBtc(opportunityList, exchangeList); Assert.IsTrue(result == opportunity5); }
public void TradeForExchangeWithLowestBtc_Rule_OpportunityList_Empty() { List <BaseExchange> exchangeList = CreateExchangeList(new Anx(), new Btce(), new Bitstamp()); //Pass in a non empty exchange list ArbitrationOpportunity result = ArbitrationFilter.TradeForExchangeWithLowestBtc(new List <ArbitrationOpportunity>(), exchangeList); Assert.IsTrue(result == null); }
public void TradeForExchangeWithLowestBtc_Rule_ExchangeList_Empty() { //Create a list of opportunities with at least 1 opportunity List <ArbitrationOpportunity> opportunityList = new List <ArbitrationOpportunity>(); ArbitrationOpportunity opportunity1 = new ArbitrationOpportunity(new Anx(), new Bitstamp()); opportunityList.Add(opportunity1); ArbitrationOpportunity result = ArbitrationFilter.TradeForExchangeWithLowestBtc(opportunityList, new List <BaseExchange>()); Assert.IsTrue(result == null); }
public static ArbitrationOpportunity CreateArbitrationOpportunity(BaseExchange BuyExchange, BaseExchange SellExchange, int ArbitrationRunId, decimal amount = 0.0m) { ArbitrationOpportunity returnOpportunity = new ArbitrationOpportunity(BuyExchange, SellExchange); returnOpportunity.ArbitrationRunId = ArbitrationRunId; returnOpportunity.BuyAmount = amount; returnOpportunity.PersistToDb(); //If there was a problem saving the opportunity to the db. if (returnOpportunity.Id == null) { throw new Exception(); } return(returnOpportunity); }
public void TransferInsertTest() { BaseExchange sellExchange = new Kraken(); BaseExchange buyExchange = new Bitstamp(); int MaxId = 0; sellExchange.AvailableBtc = 1.0234234234m; buyExchange.AvailableBtc = 2.4534534m; decimal transferAmount = 0.6319841998m; //First need to create an arbitration run and opportunity ArbitrationRun testRun = TestsHelper.CreateArbitrationRun(); ArbitrationOpportunity testOpportunity = TestsHelper.CreateArbitrationOpportunity(buyExchange, sellExchange, testRun.Id.Value); //Before the test can continue, ensure the arbitraiton opportunity was properly inserted Assert.IsTrue(testOpportunity.Id != null); Transfer testTransfer = new Transfer(buyExchange, sellExchange, transferAmount); //Get the max id from TRANSFER table Object result = DatabaseManager.ExecuteQuery("select MaxId = max(id) from TRANSFER").Rows[0]["MaxId"]; if (result != DBNull.Value) { MaxId = (int)result; } //Now save the TRANSFER to the db testTransfer.PersistToDb(); //Select the transfer from the db result = DatabaseManager.ExecuteQuery(string.Format("select id from TRANSFER where id = {0} AND ORIGIN_EXCHANGE = '{1}' and DESTINATION_EXCHANGE = '{2}' AND AMOUNT = {3}", testTransfer.Id, buyExchange.Name, sellExchange.Name, transferAmount)).Rows[0][0]; //Clean up before testing result if (result != DBNull.Value) { //Remove the test transfer DatabaseManager.ExecuteNonQuery(String.Format("delete from TRANSFER where id = {0}", testTransfer.Id)); } TestsHelper.DeleteArbitrationTrade(testOpportunity.Id.Value); TestsHelper.DeleteArbitrationRun(testRun.Id.Value); //The above query should return the transfer that was created. Assert.IsTrue(result != DBNull.Value); }
public void MostProfitableTrade_Rule_Validate() { List <BaseExchange> exchangeList = CreateExchangeList(new Anx(), new Bitstamp(), new Btce(), new ItBit(), new Kraken()); List <ArbitrationOpportunity> opportunityList = null; ArbitrationOpportunity result; result = ArbitrationFilter.MostProfitableTrade(opportunityList); Assert.IsTrue(result == null); opportunityList = new List <ArbitrationOpportunity>(); result = ArbitrationFilter.MostProfitableTrade(opportunityList); Assert.IsTrue(result == null); ArbitrationOpportunity opportunity1 = new ArbitrationOpportunity(exchangeList[0], exchangeList[1]); opportunity1.Profit = 7.87m; ArbitrationOpportunity opportunity2 = new ArbitrationOpportunity(exchangeList[3], exchangeList[2]); opportunity2.Profit = 7.48m; ArbitrationOpportunity opportunity3 = new ArbitrationOpportunity(exchangeList[4], exchangeList[3]); opportunity3.Profit = 4.57m; ArbitrationOpportunity opportunity4 = new ArbitrationOpportunity(exchangeList[1], exchangeList[4]); opportunity4.Profit = 87.00m; opportunityList.Add(opportunity1); opportunityList.Add(opportunity2); opportunityList.Add(opportunity3); opportunityList.Add(opportunity4); result = ArbitrationFilter.MostProfitableTrade(opportunityList); Assert.IsTrue(result == opportunity4); opportunity2.Profit = 87.01m; result = ArbitrationFilter.MostProfitableTrade(opportunityList); Assert.IsTrue(result == opportunity2); opportunity1.Profit = 1000.00m; result = ArbitrationFilter.MostProfitableTrade(opportunityList); Assert.IsTrue(result == opportunity1); }
public void BtceOrdersDoNotGetCheckedForFulfillment() { int requiredRoundsForValidarion = 3; Btce btce = new Btce(); Kraken kraken = new Kraken(); List <BaseExchange> exchangeList = new List <BaseExchange>(); exchangeList.Add(btce); exchangeList.Add(kraken); OpportunityValidator opportunityValidator = new OpportunityValidator(requiredRoundsForValidarion, exchangeList); ArbitrationOpportunity testOpportunity = new ArbitrationOpportunity(btce, btce, 0.1m, 10.22m, 1.022m, 20.00m, 2.00m, 78m, 1); //Set the buy and sell order id to 0 to mimic the behavior of immediately filled orders for Btce. testOpportunity.BuyOrderId = "0"; testOpportunity.SellOrderId = "0"; //This will throw an error if it is not correct. opportunityValidator.ValidateArbitrationTradeOrderExecution(testOpportunity); }
public void PersistArbitrationOpportunity() { //Arbitraty test values decimal buyAmount = 351.654316m; decimal sellAmount = 351.654316m; decimal buyPrice = 409.21m; decimal sellPrice = 410.87m; decimal totalBuyCost = 1201.14m; decimal totalSellCost = 1301.54m; decimal profit = totalSellCost - totalBuyCost; string buyOrderId = "Abc-123"; string sellOrderId = "123-Abc"; DateTime executionDateTime = DateTime.Now; Bitstamp buyExchange = new Bitstamp(); Btce sellExchange = new Btce(); ArbitrationRun testRun = null; ArbitrationRun updateTestRun = null; ArbitrationOpportunity testArbitrationTrade = null; try { testRun = TestsHelper.CreateArbitrationRun(); updateTestRun = TestsHelper.CreateArbitrationRun(); testArbitrationTrade = new ArbitrationOpportunity(buyExchange, sellExchange); testArbitrationTrade.BuyAmount = buyAmount; testArbitrationTrade.SellAmount = sellAmount; testArbitrationTrade.ArbitrationRunId = testRun.Id.Value; testArbitrationTrade.BuyPrice = buyPrice; testArbitrationTrade.ExecutionDateTime = executionDateTime; testArbitrationTrade.Profit = profit; testArbitrationTrade.SellPrice = sellPrice; testArbitrationTrade.TotalBuyCost = totalBuyCost; testArbitrationTrade.TotalSellCost = totalSellCost; testArbitrationTrade.BuyOrderId = buyOrderId; testArbitrationTrade.SellOrderId = sellOrderId; //Now that the arbitration trade has been set up, save it to the db. testArbitrationTrade.PersistToDb(); //Ensure an id was set after the initial insert Assert.IsTrue(testArbitrationTrade.Id != null); string insertFetchSql = string.Format("" + "select " + " ID, " + " CREATE_DATETIME, " + " LAST_MODIFIED_DATETIME " + "from " + " ARBITRATION_TRADE " + "where " + " ID = {0} AND " + " BUY_AMOUNT = {1} AND " + " BUY_PRICE = {2} AND " + " SELL_PRICE = {3} AND" + " TOTAL_BUY_COST = {4} AND " + " TOTAL_SELL_COST = {5} AND " + " PROFIT = {6} AND " + " EXECUTION_DATETIME = '{7}' AND " + " SELL_EXCHANGE = '{8}' AND " + " BUY_EXCHANGE = '{9}' AND " + " BUY_ORDER_ID = '{10}' AND " + " SELL_ORDER_ID = '{11}' AND " + " ARBITRATION_RUN_ID = {12} AND " + " SELL_AMOUNT = {13}", testArbitrationTrade.Id.Value, buyAmount, buyPrice, sellPrice, totalBuyCost, totalSellCost, profit, executionDateTime.ToString("yyy-MM-dd HH:mm:ss"), sellExchange.Name, buyExchange.Name, buyOrderId, sellOrderId, testRun.Id.Value, sellAmount); //Ensure all the values were properly inserted. DataTable result = DatabaseManager.ExecuteQuery(insertFetchSql); Assert.IsTrue(result != null && Convert.ToInt32(result.Rows[0]["ID"]) == testArbitrationTrade.Id.Value); //Create some bogus dates for CREATE_DATETIME and LAST_MODIFIED_DATETIME DateTime createDateTime = new DateTime(2014, 1, 1, 13, 25, 05); DateTime lastModifiedDateTime = new DateTime(2014, 1, 1, 13, 25, 05); //In order to test that CREATE_DATETIME and LAST_MODIFIED_DATETIME behave properly on updates, need to put some bogus data in there: DatabaseManager.ExecuteNonQuery(string.Format("update ARBITRATION_TRADE set CREATE_DATETIME = '{0}', LAST_MODIFIED_DATETIME = '{1}' where ID = {2}", createDateTime.ToString("yyy-MM-dd HH:mm:ss"), lastModifiedDateTime.ToString("yyy-MM-dd HH:mm:ss"), testArbitrationTrade.Id.Value)); //Update properties with arbitraty test values. buyAmount = 103264798.175785743216m; sellAmount = 103264798.175785743216m; buyPrice = 1.02m; sellPrice = 10.02m; totalBuyCost = 2.01m; totalSellCost = 18.01m; profit = totalSellCost - totalBuyCost; executionDateTime = DateTime.Now; buyOrderId = "Choctaw-47"; sellOrderId = "Apache-48"; //Update arbitration trade to have new values testArbitrationTrade.BuyAmount = buyAmount; testArbitrationTrade.SellAmount = sellAmount; testArbitrationTrade.ArbitrationRunId = updateTestRun.Id.Value; testArbitrationTrade.BuyPrice = buyPrice; testArbitrationTrade.ExecutionDateTime = executionDateTime; testArbitrationTrade.Profit = profit; testArbitrationTrade.SellPrice = sellPrice; testArbitrationTrade.TotalBuyCost = totalBuyCost; testArbitrationTrade.TotalSellCost = totalSellCost; testArbitrationTrade.BuyOrderId = buyOrderId; testArbitrationTrade.SellOrderId = sellOrderId; testArbitrationTrade.PersistToDb(); string updateFetchSql = string.Format("" + "select " + " ID, " + " CREATE_DATETIME, " + " LAST_MODIFIED_DATETIME " + "from " + " ARBITRATION_TRADE " + "where " + " ID = {0} AND " + " BUY_AMOUNT = {1} AND " + " BUY_PRICE = {2} AND " + " SELL_PRICE = {3} AND" + " TOTAL_BUY_COST = {4} AND " + " TOTAL_SELL_COST = {5} AND " + " PROFIT = {6} AND " + " EXECUTION_DATETIME = '{7}' AND " + " SELL_EXCHANGE = '{8}' AND " + " BUY_EXCHANGE = '{9}' AND " + " BUY_ORDER_ID = '{10}' AND " + " SELL_ORDER_ID = '{11}' AND " + " ARBITRATION_RUN_ID = {12} AND " + " SELL_AMOUNT = {13}", testArbitrationTrade.Id.Value, buyAmount, buyPrice, sellPrice, totalBuyCost, totalSellCost, profit, executionDateTime.ToString("yyy-MM-dd HH:mm:ss"), sellExchange.Name, buyExchange.Name, buyOrderId, sellOrderId, updateTestRun.Id.Value, sellAmount); result = DatabaseManager.ExecuteQuery(updateFetchSql); //Ensure a record was found with all the updated values Assert.IsTrue(result != null); //Ensure the CREATE_DATETIME is the same, but the LAST_MODIFIED_DATETIME is different Assert.IsTrue(createDateTime == (DateTime)result.Rows[0]["CREATE_DATETIME"]); Assert.IsTrue(lastModifiedDateTime != (DateTime)result.Rows[0]["LAST_MODIFIED_DATETIME"]); } finally { //Remove test data from the database if (testArbitrationTrade.Id != null) { TestsHelper.DeleteArbitrationTrade(testArbitrationTrade.Id.Value); } if (testRun.Id != null) { TestsHelper.DeleteArbitrationRun(testRun.Id.Value); } if (updateTestRun.Id != null) { TestsHelper.DeleteArbitrationRun(updateTestRun.Id.Value); } } }
public void NotEnoughtBtcExceptionAreSwallowedCorrectly() { ArbitrationRun testRun = null; ArbitrationOpportunity opportunity1 = null; ArbitrationOpportunity opportunity2 = null; ArbitrationOpportunity opportunity3 = null; try { //Set up a test run testRun = TestsHelper.CreateArbitrationRun(); //Set up the buy and sell exchanges. Bitstamp bitstamp = new Bitstamp(); Kraken kraken = new Kraken(); List <BaseExchange> exchangeList = new List <BaseExchange>(); exchangeList.Add(bitstamp); exchangeList.Add(kraken); bitstamp.AvailableBtc = 0.2m; bitstamp.AvailableFiat = 100m; kraken.AvailableBtc = 0.2m; kraken.AvailableFiat = 30m; //Initial trad; bitstamp will need to transfer 0.1 btc to kraken for this. It will be found in the rollup later. //Bitstamp now has 0.4 btc. opportunity1 = TestsHelper.CreateArbitrationOpportunity(bitstamp, kraken, testRun.Id.Value, 0.1m); //Made up numbers; they don't really matter for this test opportunity1.TotalBuyCost = 10m; opportunity1.TotalSellCost = 10m; bitstamp.SimulatedBuy(opportunity1.BuyAmount, opportunity1.TotalBuyCost); kraken.SimulatedSell(opportunity1.BuyAmount, opportunity1.TotalSellCost); Assert.IsTrue(bitstamp.AvailableBtc == 0.3m); //Now a couple a trade where btc is sold off at Bitstamp; enough to make the rollup transfer fail //Bitstamp now has 0.1 opportunity2 = TestsHelper.CreateArbitrationOpportunity(kraken, bitstamp, testRun.Id.Value, 0.3m); //Made up numbers; they don't really matter for this test opportunity2.TotalBuyCost = 30m; opportunity2.TotalSellCost = 30m; kraken.SimulatedBuy(opportunity2.BuyAmount, opportunity2.TotalBuyCost); bitstamp.SimulatedSell(opportunity2.BuyAmount, opportunity2.TotalSellCost); Assert.IsTrue(bitstamp.AvailableBtc == 0.0m); //Now assume this trigger a transfer, so lets say 0.5btc is in transfer to bitstamp from kraken bitstamp.BTCInTransfer = 0.5m; //Now another buy at bitstamp; this will trigger a transfer rollup from bitstamp to kraken opportunity3 = TestsHelper.CreateArbitrationOpportunity(bitstamp, kraken, testRun.Id.Value, 0.15m); //Made up numbers; they don't really matter for this test opportunity3.TotalBuyCost = 15m; opportunity3.TotalSellCost = 15m; bitstamp.SimulatedBuy(opportunity3.BuyAmount, opportunity3.TotalBuyCost); kraken.SimulatedSell(opportunity3.BuyAmount, opportunity3.TotalSellCost); Assert.IsTrue(bitstamp.AvailableBtc == 0.15m); //This should detect a transfer, but not actually create it List <Transfer> transferFound = TransferManager.DetectAndExecuteRollupTransfers_Simulate(3, testRun.Id.Value, exchangeList); Assert.IsTrue(transferFound == null); //Erase btc in transfer and look for transfers again, this time the TransferManager should throw an exception because //a bad transfer has been found (it's amount is > bitstamp total btc) bool errorFound = false; bitstamp.BTCInTransfer = 0m; try { TransferManager.DetectAndExecuteRollupTransfers_Simulate(2, testRun.Id.Value, exchangeList); } catch (NotEnoughBtcException e) { errorFound = true; } Assert.IsTrue(errorFound, "TransferManager did not throw NotEnoughBtcException."); } //Clean up test data finally { if (opportunity1 != null) { TestsHelper.DeleteArbitrationTrade(opportunity1.Id.Value); } if (opportunity2 != null) { TestsHelper.DeleteArbitrationTrade(opportunity2.Id.Value); } if (opportunity3 != null) { TestsHelper.DeleteArbitrationTrade(opportunity3.Id.Value); } if (testRun != null) { TestsHelper.DeleteArbitrationTrade(testRun.Id.Value); } } }
public void OpportunityProfitValidatesProperly() { int requiredRoundsForValidarion = 3; Anx anx = new Anx(); Bitstamp bitstamp = new Bitstamp(); Kraken kraken = new Kraken(); ItBit itBit = new ItBit(); List <BaseExchange> exchangeList = new List <BaseExchange>(); decimal amount = 0.2m; decimal buyPrice = 150m; decimal totalBuyCost = 30m; decimal sellPrice = 200m; decimal totalSellCost = 40m; decimal profit = 10m; exchangeList.Add(anx); exchangeList.Add(bitstamp); exchangeList.Add(kraken); exchangeList.Add(itBit); OpportunityValidator opportunityValidator = new OpportunityValidator(requiredRoundsForValidarion, exchangeList); //Note, can use a fake run id here because the trade is never persisted to the db. ArbitrationOpportunity testOpportunity = new ArbitrationOpportunity(anx, bitstamp, amount, buyPrice, totalBuyCost, sellPrice, totalSellCost, profit, 1); //First, set the balances for all the exchanges. anx.AvailableFiat = 100m; anx.AvailableBtc = 100m; bitstamp.AvailableFiat = 100m; bitstamp.AvailableBtc = 100m; kraken.AvailableFiat = 100m; kraken.AvailableBtc = 100m; itBit.AvailableFiat = 100m; itBit.AvailableBtc = 100m; //Scenario 1; happy path. Buy and selling works as expected. //Prep the validator opportunityValidator.SetFiatAndBitcoinBalanceBeforeArbitrationTrade(); //Simulate the trade going through anx.AvailableFiat -= totalBuyCost; anx.AvailableBtc += amount; bitstamp.AvailableFiat += totalSellCost; bitstamp.AvailableBtc -= amount; //If there was as error, this will throw it. opportunityValidator.ValidateExchangeBalancesAfterTrade(testOpportunity); //Scenario 2: Buy never happens. Validator should throw an error bool errorThrown = false; anx.AvailableFiat = 100m; anx.AvailableBtc = 100m; bitstamp.AvailableFiat = 100m; bitstamp.AvailableBtc = 100m; kraken.AvailableFiat = 100m; kraken.AvailableBtc = 100m; itBit.AvailableFiat = 100m; itBit.AvailableBtc = 100m; //Prep the validator opportunityValidator.SetFiatAndBitcoinBalanceBeforeArbitrationTrade(); //Simulate the trade going through, but buy never happens. This should cause the validator to throw an error. bitstamp.AvailableFiat += totalSellCost; bitstamp.AvailableBtc -= amount; try { opportunityValidator.ValidateExchangeBalancesAfterTrade(testOpportunity); } catch (Exception e) { errorThrown = true; } Assert.IsTrue(errorThrown); }
public void OpportunityListValidatesProperly() { int requiredRoundsForValidarion = 3; Anx anx = new Anx(); Bitstamp bitstamp = new Bitstamp(); Kraken kraken = new Kraken(); ItBit itBit = new ItBit(); List <ArbitrationOpportunity> opportunityList = new List <ArbitrationOpportunity>(); List <ArbitrationOpportunity> validatedList; List <BaseExchange> exchangeList = new List <BaseExchange>(); exchangeList.Add(anx); exchangeList.Add(bitstamp); exchangeList.Add(kraken); exchangeList.Add(itBit); OpportunityValidator opportunityValidator = new OpportunityValidator(requiredRoundsForValidarion, exchangeList); //Build of a list of opportunities: ArbitrationOpportunity krakenItBitopportunity = new ArbitrationOpportunity(kraken, itBit) { Profit = 2.23m }; ArbitrationOpportunity krakenBitstampopportunity = new ArbitrationOpportunity(kraken, bitstamp) { Profit = 0.50m }; ArbitrationOpportunity anxItBitopportunity = new ArbitrationOpportunity(anx, itBit) { Profit = 2.01m }; ArbitrationOpportunity anxItBitopportunity2 = new ArbitrationOpportunity(anx, itBit) { Profit = 1.98m }; ArbitrationOpportunity anxItBitopportunity3 = new ArbitrationOpportunity(anx, itBit) { Profit = 0.27m }; opportunityList.Add(krakenItBitopportunity); opportunityList.Add(krakenBitstampopportunity); opportunityList.Add(anxItBitopportunity); //Round one: validatedList = opportunityValidator.ValidateOpportunities(opportunityList); Assert.IsTrue(validatedList.Count == 0); //Round two: opportunityList.Remove(krakenBitstampopportunity); validatedList = opportunityValidator.ValidateOpportunities(opportunityList); Assert.IsTrue(validatedList.Count == 0); //Round three: An oppportunity between Anx and ItBit has survived until now (alebit with a different profit) //Add the Kraken - Bitstamp opportunity. //Remove Krakken - ItBit opportunity; it only lasts two rounds. opportunityList.Add(krakenBitstampopportunity); opportunityList.Remove(krakenItBitopportunity); //Remove the Anx - ItBit opportunity, than add another opportunity with those exchanges but a less profit opportunityList.Remove(anxItBitopportunity); opportunityList.Add(anxItBitopportunity2); validatedList = opportunityValidator.ValidateOpportunities(opportunityList); Assert.IsTrue(validatedList.Count == 1); Assert.IsTrue(validatedList[0].Profit == 1.98m); //Round 4: anxItBitopportunity should still be in the returned list //Remove the Anx - ItBit opportunity, than add another opportunity with those exchanges but a less profit opportunityList.Remove(anxItBitopportunity); opportunityList.Add(anxItBitopportunity3); validatedList = opportunityValidator.ValidateOpportunities(opportunityList); Assert.IsTrue(validatedList.Count == 1); Assert.IsTrue(validatedList[0].Profit == 0.27m); //Round 5: anxItBitopportunity should still be in the returned list, krakenBitstampopportunity should have been added validatedList = opportunityValidator.ValidateOpportunities(opportunityList); Assert.IsTrue(validatedList.Count == 2); Assert.IsTrue(validatedList[0].Profit == 0.50m); Assert.IsTrue(validatedList[1].Profit == 0.27m); }
public void TradeForExchangeWithLowestBtc_Rule_ExchangeList_Null() { ArbitrationOpportunity result = ArbitrationFilter.TradeForExchangeWithLowestBtc(new List <ArbitrationOpportunity>(), null); }
public void TradeForExchangeWithLowestBtc_Rule_OpportunityList_Null() { ArbitrationOpportunity result = ArbitrationFilter.TradeForExchangeWithLowestBtc(null, new List <BaseExchange>()); }
public void MostProfitableTradeWithPercentRestriction_Rule_Validate() { List <BaseExchange> exchangeList = CreateExchangeList(new Anx(), new Bitstamp(), new Btce(), new ItBit(), new Kraken(), new Anx()); List <ArbitrationOpportunity> opportunityList = new List <ArbitrationOpportunity>(); ArbitrationOpportunity result; //Ensure an exception is thrown when exchangeList is null try { ArbitrationFilter.MostProfitableTradeWithPercentRestriction(opportunityList, null, 0.20m); } catch (ArgumentNullException) {} //Ensure an exception is thrown when opportunityList is null try { ArbitrationFilter.MostProfitableTradeWithPercentRestriction(null, exchangeList, 0.20m); } catch (ArgumentNullException) { } //Ensure an exception is thrown when percentRestrictionAsDecimal is not valid try { ArbitrationFilter.MostProfitableTradeWithPercentRestriction(opportunityList, exchangeList, -0.0000001m); } catch (ArgumentException) { } try { ArbitrationFilter.MostProfitableTradeWithPercentRestriction(opportunityList, exchangeList, 1.00000001m); } catch (ArgumentException) { } //Ensure an empty excchange list returns null List <ArbitrationOpportunity> throwAwayOpportunityList = new List <ArbitrationOpportunity>(); throwAwayOpportunityList.Add(new ArbitrationOpportunity(exchangeList[0], exchangeList[1])); result = ArbitrationFilter.MostProfitableTradeWithPercentRestriction(throwAwayOpportunityList, new List <BaseExchange>(), 0.45m); Assert.IsTrue(result == null); //Give all the test exchanges some money //Have a total of = $500.00 exchangeList[0].AvailableFiat = 50.0m; //10% exchangeList[1].AvailableFiat = 125.0m; //25% exchangeList[2].AvailableFiat = 225.0m; //45% exchangeList[3].AvailableFiat = 25.0m; //5% exchangeList[4].AvailableFiat = 40.0m; //8% exchangeList[5].AvailableFiat = 35.0m; //7% //Ensure an empty opportunity list returns null result = ArbitrationFilter.MostProfitableTradeWithPercentRestriction(opportunityList, exchangeList, 0.45m); Assert.IsTrue(result == null); //Buy @ Anx, sell @ Bitstamp. Would give Bitstamp 30.2% of the total money ArbitrationOpportunity opportunity1 = new ArbitrationOpportunity(exchangeList[0], exchangeList[1]); opportunity1.TotalSellCost = 26.0m; opportunity1.Profit = 0.81m; opportunityList.Add(opportunity1); //Ensure in a list of 1, where the opportunity is valid, that opportunity is returned. result = ArbitrationFilter.MostProfitableTradeWithPercentRestriction(opportunityList, exchangeList, 0.45m); Assert.IsTrue(result == opportunity1); //Ensure in a list of 1, where the opportunity is not valid, null is returned result = ArbitrationFilter.MostProfitableTradeWithPercentRestriction(opportunityList, exchangeList, 0.25m); Assert.IsTrue(result == null); //Buy @ Bitstamp, sell @ btce. Would give Btce %53 ArbitrationOpportunity opportunity2 = new ArbitrationOpportunity(exchangeList[1], exchangeList[2]); opportunity2.TotalSellCost = 40.00m; opportunity2.Profit = 1.07m; opportunityList.Add(opportunity2); //In an out-of-order list of 2, the most profitable is still returned result = ArbitrationFilter.MostProfitableTradeWithPercentRestriction(opportunityList, exchangeList, 0.53m); Assert.IsTrue(result == opportunity2); //Buy @ JustCoin, sell @ Kraken. Would give Kraken 8.4% ArbitrationOpportunity opportunity3 = new ArbitrationOpportunity(exchangeList[3], exchangeList[4]); opportunity3.TotalSellCost = 2.0m; opportunity3.Profit = 0.01m; opportunityList.Add(opportunity3); //List of three, least profitable is the only valid result = ArbitrationFilter.MostProfitableTradeWithPercentRestriction(opportunityList, exchangeList, 0.3019m); Assert.IsTrue(result == opportunity3); //List of two, second most profitable is valid result = ArbitrationFilter.MostProfitableTradeWithPercentRestriction(opportunityList, exchangeList, 0.47982m); Assert.IsTrue(result == opportunity1); }