Exemplo n.º 1
0
        public async Task <ExchangeOrderResult> SimulateOrder(string pair, OrderSide side, OrderType type, decimal price, decimal amount, double delaySeconds = 0)
        {
            await Task.Delay((int)(delaySeconds * 1000)); //Wait to simulate real order lag

            ExchangeOrderResult result = new ExchangeOrderResult();

            if (type == OrderType.Limit)
            {
                var ticker = _client.GetTicker(pair);

                if (side == OrderSide.Buy)
                {
                    var bestAsk = ticker.Ask;
                }
                else
                {
                    var bestBid = ticker.Bid;
                }

                //TODO: Figure out how to simulate limit orders (Just take best price? Wait for theoretical fill?)
                throw new NotSupportedException();
            }
            else if (type == OrderType.Market)
            {
                var orderbook = _client.GetOrderBook(pair); //1 request, just like a real order TODO: Pull this from memory once supported (arb services->bots and prices->trading service)

                if (side == OrderSide.Buy)
                {
                    price = PriceCalculator.GetPriceQuote(orderbook.asks.Select(ask => new OrderbookOrder()
                    {
                        Price = ask[0], Amount = ask[1]
                    }).ToList(), PriceCalculator.ConvertBaseToAlt(orderbook.asks.First()[0], amount));
                    amount /= price;
                }
                else
                {
                    price = PriceCalculator.GetPriceQuote(orderbook.bids.Select(bid => new OrderbookOrder()
                    {
                        Price = bid[0], Amount = bid[1]
                    }).ToList(), amount);
                    amount *= price;
                }
                result = new ExchangeOrderResult()
                {
                    MarketSymbol = pair,
                    Price        = price,
                    IsBuy        = side == OrderSide.Buy,
                    Amount       = amount,
                    AmountFilled = amount,
                    AveragePrice = price,
                    Fees         = amount * (this.Fee / 100),
                    FeesCurrency = "Alt",
                    FillDate     = DateTime.Now,
                    OrderDate    = DateTime.Now,
                    Result       = ExchangeAPIOrderResult.Filled,
                };
            }
            else
            {
                throw new NotSupportedException();
            }

            return(result);
        }
Exemplo n.º 2
0
        public void CheckExchangeForNormalArbitrage(IExchange startExchange)
        {
            var     orderbooks = startExchange.Orderbooks;
            decimal endAmountBought;
            decimal audInvested = 100;

            try
            {
                foreach (var startOrderbook in orderbooks.Values)
                {
                    foreach (var exchange in _exchanges.Where(x => x.Name != startExchange.Name))
                    {
                        //Base->Alt->Base
                        var baseAmount = ConvertAudToCrypto(orderbooks, startOrderbook.BaseCurrency, audInvested);
                        if (baseAmount == 0)
                        {
                            continue; //Asset prices not loaded yet
                        }

                        if (!exchange.Orderbooks.TryGetValue(startOrderbook.AltCurrency + "/" + startOrderbook.BaseCurrency, out Orderbook endOrderbook))
                        {
                            exchange.Orderbooks.TryGetValue(startOrderbook.BaseCurrency + "/" + startOrderbook.AltCurrency, out endOrderbook);
                        }
                        if (endOrderbook == null)
                        {
                            continue; //Other exchange doesn't have the pair
                        }

                        var asks = startOrderbook.Asks;
                        if (asks.Count() == 0)
                        {
                            continue;
                        }
                        var startAmountBought = baseAmount / PriceCalculator.GetPriceQuote(asks, PriceCalculator.ConvertBaseToAlt(asks.First().Price, baseAmount));

                        if (endOrderbook.BaseCurrency == startOrderbook.BaseCurrency)
                        {
                            var endBids = endOrderbook.Bids;
                            if (endBids.Count() == 0)
                            {
                                continue;
                            }
                            endAmountBought = startAmountBought * PriceCalculator.GetPriceQuote(endBids, startAmountBought);
                        }
                        else
                        {
                            var endAsks = endOrderbook.Asks;
                            if (endAsks.Count() == 0)
                            {
                                continue;
                            }
                            endAmountBought = startAmountBought / PriceCalculator.GetPriceQuote(endAsks, PriceCalculator.ConvertBaseToAlt(endAsks.First().Price, startAmountBought));
                        }

                        decimal percentProfit = (endAmountBought - baseAmount) / baseAmount * 100;

                        var result = new ArbitrageResult()
                        {
                            Exchanges = new List <string>()
                            {
                                startExchange.Name, exchange.Name
                            },
                            Pairs = new List <Pair>()
                            {
                                new Pair(startOrderbook.Pair, startOrderbook.BaseCurrency, startOrderbook.AltCurrency)
                            },
                            Profit           = percentProfit,
                            TransactionFee   = startExchange.Fee + exchange.Fee,
                            InitialCurrency  = startOrderbook.BaseCurrency,
                            InitialLiquidity = baseAmount,
                            Type             = ArbitrageType.Normal
                        };
                        StoreNormalResults(result);

                        //Alt->Base->Alt
                        baseAmount = ConvertAudToCrypto(orderbooks, startOrderbook.AltCurrency, audInvested);
                        if (baseAmount == 0)
                        {
                            continue; //Asset prices not loaded yet
                        }

                        var bids = startOrderbook.Bids;
                        if (bids.Count() == 0)
                        {
                            continue;
                        }
                        startAmountBought = baseAmount * PriceCalculator.GetPriceQuote(bids, baseAmount);

                        if (endOrderbook.BaseCurrency == startOrderbook.BaseCurrency)
                        {
                            var endAsks = endOrderbook.Asks;
                            if (endAsks.Count() == 0)
                            {
                                continue;
                            }
                            endAmountBought = startAmountBought / PriceCalculator.GetPriceQuote(endAsks, PriceCalculator.ConvertBaseToAlt(endAsks.First().Price, startAmountBought));
                        }
                        else
                        {
                            var endBids = endOrderbook.Bids;
                            if (endBids.Count() == 0)
                            {
                                continue;
                            }
                            endAmountBought = startAmountBought * PriceCalculator.GetPriceQuote(endBids, startAmountBought);
                        }

                        percentProfit = (endAmountBought - baseAmount) / baseAmount * 100;

                        result = new ArbitrageResult()
                        {
                            Exchanges = new List <string>()
                            {
                                startExchange.Name, exchange.Name
                            },
                            Pairs = new List <Pair>()
                            {
                                new Pair(startOrderbook.Pair, startOrderbook.AltCurrency, startOrderbook.BaseCurrency)
                            },
                            Profit           = percentProfit,
                            TransactionFee   = startExchange.Fee + exchange.Fee,
                            InitialCurrency  = startOrderbook.AltCurrency,
                            InitialLiquidity = baseAmount,
                            Type             = ArbitrageType.Normal
                        };
                        StoreNormalResults(result);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Error in CheckExchangeForNormalArbitrage (" + e.Message + ")");
            }
        }
Exemplo n.º 3
0
        public decimal Amount; //Amount to currency to be bought (needed to work down the orderbook)

        public bool IsValid(List <IExchange> exchanges)
        {
            decimal startPrice, endPrice;
            var     startExchange = exchanges.First(x => x.Name == StartExchange);
            var     endExchange   = exchanges.First(x => x.Name == EndExchange);

            //Calculate start price
            if (StartSide == OrderSide.Buy)
            {
                var asks = startExchange.Orderbooks[StartPair].Asks;
                if (Amount == 0)
                {
                    startPrice = asks.First().Price;
                }
                else
                {
                    startPrice = PriceCalculator.GetPriceQuote(asks, PriceCalculator.ConvertBaseToAlt(asks.First().Price, Amount));
                }
            }
            else
            {
                var bids = startExchange.Orderbooks[StartPair].Bids;
                if (Amount == 0)
                {
                    startPrice = bids.First().Price;
                }
                else
                {
                    startPrice = PriceCalculator.GetPriceQuote(bids, Amount);
                }
            }

            //Calculate end price
            if (EndSide == OrderSide.Buy)
            {
                var asks = endExchange.Orderbooks[EndPair].Asks;
                if (Amount == 0)
                {
                    endPrice = asks.First().Price;
                }
                else
                {
                    endPrice = PriceCalculator.GetPriceQuote(asks, PriceCalculator.ConvertBaseToAlt(asks.First().Price, Amount));
                }
            }
            else
            {
                var bids = endExchange.Orderbooks[EndPair].Bids;
                if (Amount == 0)
                {
                    endPrice = bids.First().Price;
                }
                else
                {
                    endPrice = PriceCalculator.GetPriceQuote(bids, Amount);
                }
            }

            if (ConditionType == PriceConditionType.Higher)
            {
                return(startPrice > endPrice);
            }
            else
            {
                return(startPrice < endPrice);
            }
        }
Exemplo n.º 4
0
        public void CheckExchangeForTriangleArbitrage(IExchange exchange)
        {
            try {
                decimal altAmount, alt2Amount, finalAmount, baseAmount;
                //Assuming we are testing BTC/ETH->ETH/XRP->XRP/BTC, startCurrency == BTC, middleCurrency == ETH, endCurrency == XRP
                string startCurrency, middleCurrency, endCurrency; //The currency that's bought/sold from in the first transaction
                var    audInvested = 100;
                var    orderbooks  = exchange.Orderbooks;

                foreach (var market in orderbooks.Values)
                {
                    //Loop every market with a matching currency except itself (this could start on the base or alt currency)
                    foreach (var market2 in orderbooks.Values.Where(x => x.Pair != market.Pair && (x.AltCurrency == market.AltCurrency || x.BaseCurrency == market.AltCurrency || x.AltCurrency == market.BaseCurrency || x.BaseCurrency == market.BaseCurrency)))
                    {
                        //If the base/alt currency for the next market is the base currency, we need to bid (i.e. Buy for first trade)
                        if (market.BaseCurrency == market2.BaseCurrency || market.BaseCurrency == market2.AltCurrency)
                        {
                            baseAmount = ConvertAudToCrypto(orderbooks, market.AltCurrency, audInvested);

                            if (baseAmount == 0)
                            {
                                continue; //Asset prices not loaded yet
                            }

                            try
                            {
                                var bids = orderbooks[market.AltCurrency + "/" + market.BaseCurrency].Bids;
                                if (bids.Count() == 0)
                                {
                                    continue;
                                }
                                altAmount = baseAmount * PriceCalculator.GetPriceQuote(bids, baseAmount);
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine(e.Message);
                                continue;
                            }
                            startCurrency  = market.AltCurrency;
                            middleCurrency = market.BaseCurrency;
                        }
                        else //Else we need to ask (i.e. Sell for first trade)
                        {
                            baseAmount = ConvertAudToCrypto(orderbooks, market.BaseCurrency, audInvested);
                            if (baseAmount == 0)
                            {
                                continue; //Asset prices not loaded yet
                            }

                            try
                            {
                                var asks = orderbooks[market.AltCurrency + "/" + market.BaseCurrency].Asks;
                                if (asks.Count() == 0)
                                {
                                    continue;                                                                                                                   //Prices not loaded yet
                                }
                                altAmount = baseAmount / PriceCalculator.GetPriceQuote(asks, PriceCalculator.ConvertBaseToAlt(asks.First().Price, baseAmount)); //~3000 ETH from 100 BTC
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine(e.Message);
                                continue;
                            }
                            startCurrency  = market.BaseCurrency;
                            middleCurrency = market.AltCurrency;
                        }

                        //If the alt bought in step 1 is now a base, use ask price
                        if (market2.BaseCurrency == middleCurrency)
                        {
                            endCurrency = market2.AltCurrency;
                            try
                            {
                                var asks = orderbooks[market2.AltCurrency + "/" + market2.BaseCurrency].Asks;
                                if (asks.Count() == 0)
                                {
                                    continue; //Prices not loaded yet
                                }
                                alt2Amount = altAmount / PriceCalculator.GetPriceQuote(asks, PriceCalculator.ConvertBaseToAlt(asks.First().Price, altAmount));
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine(e.Message);
                                continue;
                            }
                        }
                        else //Otherwise it's the alt currency (i.e. we're selling to the new coin)
                        {
                            endCurrency = market2.BaseCurrency;
                            try
                            {
                                var bids = orderbooks[market2.AltCurrency + "/" + market2.BaseCurrency].Bids;
                                if (bids.Count() == 0)
                                {
                                    continue; //Not loaded yet
                                }
                                alt2Amount = altAmount * PriceCalculator.GetPriceQuote(bids, altAmount);
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine(e.Message);
                                continue;
                            }
                        }
                        //Find the final market (i.e. the market that has the middle and end currencies)
                        if (!orderbooks.TryGetValue(startCurrency + "/" + endCurrency, out Orderbook finalMarket))
                        {
                            orderbooks.TryGetValue(endCurrency + "/" + startCurrency, out finalMarket);
                        }

                        //If null, there's no pairs to finish the arb
                        if (finalMarket == null)
                        {
                            continue;
                        }

                        //If the base currency is the first currency, we need to sell (i.e. use bid)
                        if (finalMarket.BaseCurrency == startCurrency)
                        {
                            try
                            {
                                var bids = orderbooks[finalMarket.AltCurrency + "/" + finalMarket.BaseCurrency].Bids;
                                if (bids.Count() == 0)
                                {
                                    continue; //Not loaded yet
                                }
                                finalAmount = alt2Amount * PriceCalculator.GetPriceQuote(bids, alt2Amount);
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine(e.Message);
                                continue;
                            }
                        }
                        else //Else we buy (i.e. use ask)
                        {
                            try
                            {
                                var asks = orderbooks[finalMarket.AltCurrency + "/" + finalMarket.BaseCurrency].Asks;
                                if (asks.Count() == 0)
                                {
                                    continue; //Prices not loaded yet
                                }
                                finalAmount = alt2Amount / PriceCalculator.GetPriceQuote(asks, PriceCalculator.ConvertBaseToAlt(asks.First().Price, alt2Amount));
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine(e.Message);
                                continue;
                            }
                        }

                        decimal percentProfit = (finalAmount - baseAmount) / baseAmount * 100;
                        var     result        = new ArbitrageResult()
                        {
                            Exchanges = new List <string>()
                            {
                                exchange.Name
                            },
                            Pairs = new List <Pair>()
                            {
                                new Pair(market.Pair, market.BaseCurrency, market.AltCurrency),
                                new Pair(market2.Pair, market2.BaseCurrency, market2.AltCurrency),
                                new Pair(finalMarket.Pair, finalMarket.BaseCurrency, finalMarket.AltCurrency)
                            },
                            Profit           = percentProfit,
                            TransactionFee   = exchange.Fee * 3,
                            InitialCurrency  = startCurrency,
                            InitialLiquidity = baseAmount,
                            Type             = ArbitrageType.Triangle
                        };
                        StoreTriangleResults(result);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }