Пример #1
0
        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);
            }
        }
Пример #2
0
        /// <summary>
        /// Given two ExchangeBalanceInfo objects, subtracts the pre trade balance from the post trade balance and builds a of the results.
        /// </summary>
        /// <param name="exchangeBalanceInfoBeforeArbitrationTrade">Balances of the exchanges before the arbitration trade.</param>
        /// <param name="postArbitrationTradebalanceInfo">Balances of the exchanges after the arbitration trade.</param>
        /// <returns></returns>
        private string BuildDifferenceString(ExchangeBalanceInfo exchangeBalanceInfoBeforeArbitrationTrade, ExchangeBalanceInfo postArbitrationTradebalanceInfo)
        {
            string returnString = "";

            foreach (KeyValuePair <string, decimal[]> preExchangeBalanceDetailInfo in exchangeBalanceInfoBeforeArbitrationTrade.exchangeBalanceDictionary)
            {
                //Grab the balance info from the post balance object as well
                KeyValuePair <string, decimal[]> postExchangeBalanceDetailInfo = postArbitrationTradebalanceInfo.exchangeBalanceDictionary.First(x => x.Key == preExchangeBalanceDetailInfo.Key);

                if (returnString.Length > 0)
                {
                    returnString += Environment.NewLine;
                }

                returnString += "\t\t" + preExchangeBalanceDetailInfo.Key + Environment.NewLine;
                returnString += "\t\t\tFiat: " + (postExchangeBalanceDetailInfo.Value[0] - preExchangeBalanceDetailInfo.Value[0]) + Environment.NewLine;
                returnString += "\t\t\tBtc: " + (postExchangeBalanceDetailInfo.Value[1] - preExchangeBalanceDetailInfo.Value[1]);
            }

            return(returnString);
        }
Пример #3
0
        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);
        }
Пример #4
0
        private ExchangeBalanceInfo CalculateFiatAndBitcoinTotals()
        {
            decimal totalFiat     = 0.0m;
            decimal totalBitcoin  = 0.0m;
            string  balanceString = "";

            ExchangeBalanceInfo returnInfo = new ExchangeBalanceInfo();

            foreach (BaseExchange exchange in _exchangeList)
            {
                //Add to the running totals of the fiat and bitcoin balances
                totalFiat    += exchange.AvailableFiat;
                totalBitcoin += exchange.AvailableBtc;

                //Add to the dictionary so the balances and be compared later
                returnInfo.exchangeBalanceDictionary.Add(exchange.Name, new [] { exchange.AvailableFiat, exchange.AvailableBtc });
            }

            returnInfo.TotalBitcoinBalance = totalBitcoin;
            returnInfo.TotalFiatBalance    = totalFiat;

            return(returnInfo);
        }
Пример #5
0
 public void SetFiatAndBitcoinBalanceBeforeArbitrationTrade()
 {
     _exchangeBalanceInfoBeforeArbitrationTrade = CalculateFiatAndBitcoinTotals();
 }