public void ValidateArbitrationTradeOrderExecution(ArbitrationOpportunity arbitrationTrade) { bool tradeFailed = false; StringBuilder errorMessage = new StringBuilder("Arbitration trade " + CommonFunctions.StringManipulation.NullIntString(arbitrationTrade.Id) + " did not execute. "); //Note, btce is special. If orders are fulfilled immediately, it just returns zero, not the actual order id. So if the exchange is btce, //and the order id is 0, no need to do a check. //Check to see if both the buy and sell orders were executed; check for btce order fulfillment first, to keep an error getting thrown on the order fulfillment check because of a non-existent '0' order id. if (!(arbitrationTrade.SellExchange.GetType() == typeof(Btce) && arbitrationTrade.SellOrderId == "0") && !arbitrationTrade.SellExchange.IsOrderFulfilled(arbitrationTrade.SellOrderId)) { errorMessage.Append("Sell order did not get filled. "); tradeFailed = true; } if (!(arbitrationTrade.BuyExchange.GetType() == typeof(Btce) && arbitrationTrade.BuyOrderId == "0") && !arbitrationTrade.BuyExchange.IsOrderFulfilled(arbitrationTrade.BuyOrderId)) { errorMessage.Append("Buy order did not get filled. "); tradeFailed = true; } if (tradeFailed) { ExchangeBalanceInfo postArbitrationTradebalanceInfo = CalculateFiatAndBitcoinTotals(); string balanceString = ""; balanceString += "Balances after trade:" + Environment.NewLine + postArbitrationTradebalanceInfo.ToString() + Environment.NewLine; balanceString += "Differences: " + Environment.NewLine + BuildDifferenceString(_exchangeBalanceInfoBeforeArbitrationTrade, postArbitrationTradebalanceInfo); throw new ArbitrationTradeValidationException(errorMessage.ToString(), balanceString); } }
public string ValidateExchangeBalancesAfterTrade(ArbitrationOpportunity arbitrationTrade) { ExchangeBalanceInfo postArbitrationTradebalanceInfo = CalculateFiatAndBitcoinTotals(); decimal realizedProfit = postArbitrationTradebalanceInfo.TotalFiatBalance - _exchangeBalanceInfoBeforeArbitrationTrade.TotalFiatBalance; string errorMessage = ""; string balanceString = ""; balanceString += "\tBalances after trade:" + Environment.NewLine + postArbitrationTradebalanceInfo.ToString() + Environment.NewLine; balanceString += "\tDifferences: " + Environment.NewLine + BuildDifferenceString(_exchangeBalanceInfoBeforeArbitrationTrade, postArbitrationTradebalanceInfo); if (realizedProfit <= arbitrationTrade.Profit * 0.98m) { errorMessage = "Realized profit for arbitration trade " + arbitrationTrade.Id + " was more than 2% less than the expected profit. Expected profit = " + arbitrationTrade.Profit + ", realized profit = " + realizedProfit + "."; } else if (realizedProfit >= arbitrationTrade.Profit * 1.02m) { errorMessage = "Realized profit for arbitration trade " + arbitrationTrade.Id + " was more than 2% greater than the expected profit. Expected profit = " + arbitrationTrade.Profit + ", realized profit = " + realizedProfit + "."; } if (postArbitrationTradebalanceInfo.TotalBitcoinBalance <= _exchangeBalanceInfoBeforeArbitrationTrade.TotalBitcoinBalance * 0.98m) { errorMessage += "Bitcoin balance after arbitration trade " + arbitrationTrade.Id + " decreased by more than 2%. Bitcoin balance before trade = " + _exchangeBalanceInfoBeforeArbitrationTrade.TotalBitcoinBalance + ", bitcoin balance after trade = " + postArbitrationTradebalanceInfo.TotalBitcoinBalance + "."; } else if (postArbitrationTradebalanceInfo.TotalBitcoinBalance >= _exchangeBalanceInfoBeforeArbitrationTrade.TotalBitcoinBalance * 1.02m) { errorMessage += "Bitcoin balance after arbitration trade " + arbitrationTrade.Id + " increased by more than 2%. Bitcoin balance before trade = " + _exchangeBalanceInfoBeforeArbitrationTrade.TotalBitcoinBalance + ", bitcoin balance after trade = " + postArbitrationTradebalanceInfo.TotalBitcoinBalance + "."; } //If there is text in erroMessage, the trade did not validate if (!String.IsNullOrWhiteSpace(errorMessage)) { throw new ArbitrationTradeValidationException(errorMessage, balanceString); } return(balanceString); }