Esempio n. 1
0
        public static void FindCrossesOnMarket(ref List <ExchangePair> crossRatesByMarket,
                                               Dictionary <string, int> curStartChain, BasicCryptoMarket market, bool needToSaveInTimeService = true)
        {
            double[,] currenciesMatrixPurchaseMin = new double[market.Currencies.Count, market.Currencies.Count];
            double[,] currenciesMatrixSellMax     = new double[market.Currencies.Count, market.Currencies.Count];

            int[, ,] visitedPurchaseMin = new int[market.Currencies.Count, market.Currencies.Count, market.Currencies.Count];
            int[, ,] visitedSellMax     = new int[market.Currencies.Count, market.Currencies.Count, market.Currencies.Count];

            int[,] nextPurchase = new int[market.Currencies.Count, market.Currencies.Count];
            int[,] nextSell     = new int[market.Currencies.Count, market.Currencies.Count];

            for (int i = 0; i < market.Currencies.Count; i++)
            {
                foreach (string cur in curStartChain.Keys.ToArray())
                {
                    if (market.Currencies[i] == cur)
                    {
                        curStartChain[cur] = i;
                    }
                }

                for (int j = 0; j < market.Currencies.Count; j++)
                {
                    nextPurchase[i, j] = i;
                    nextSell[i, j]     = i;

                    visitedPurchaseMin[i, j, i] = 1;
                    visitedPurchaseMin[i, j, j] = 1;
                    visitedSellMax[i, j, i]     = 1;
                    visitedSellMax[i, j, j]     = 1;

                    if (i == j)
                    {
                        currenciesMatrixPurchaseMin[i, j] = 1;
                        currenciesMatrixSellMax[i, j]     = 1;
                        continue;
                    }
                    currenciesMatrixPurchaseMin[i, j] = int.MaxValue;
                    currenciesMatrixSellMax[i, j]     = 0;
                }
            }

            foreach (KeyValuePair <string, ExchangePair> pair in market.Pairs)
            {
                string[] currencies = pair.Key.Split('-');
                int      index1     = market.Currencies.IndexOf(currencies[0]);
                int      index2     = market.Currencies.IndexOf(currencies[1]);

                currenciesMatrixPurchaseMin[index1, index2] = (double)pair.Value.PurchasePrice;
                currenciesMatrixPurchaseMin[index2, index1] = (double)(Math.Round(1 / pair.Value.SellPrice, 20));

                currenciesMatrixSellMax[index1, index2] = (double)pair.Value.SellPrice;
                currenciesMatrixSellMax[index2, index1] = (double)(Math.Round(1 / pair.Value.PurchasePrice, 20));
            }

            //Алгоритм Флойда-Уоршелла нахождения кратчайших путей между всеми парами вершин

            for (int k = 0; k < market.Currencies.Count; k++)
            {
                for (int i = 0; i < market.Currencies.Count; i++)
                {
                    foreach (int curIndex in curStartChain.Values)
                    {
                        if (i != curIndex && visitedPurchaseMin[curIndex, i, nextPurchase[k, i]] != 1 &&
                            currenciesMatrixPurchaseMin[curIndex, i] - currenciesMatrixPurchaseMin[curIndex, k] *
                            currenciesMatrixPurchaseMin[k, i] > 0.00000001)
                        {
                            currenciesMatrixPurchaseMin[curIndex, i]            = currenciesMatrixPurchaseMin[curIndex, k] * currenciesMatrixPurchaseMin[k, i];
                            visitedPurchaseMin[curIndex, i, nextPurchase[k, i]] = 1;
                            nextPurchase[curIndex, i] = nextPurchase[k, i];
                        }
                    }
                }
            }

            for (int k = 0; k < market.Currencies.Count; k++)
            {
                for (int i = 0; i < market.Currencies.Count; i++)
                {
                    foreach (int curIndex in curStartChain.Values)
                    {
                        if (i != curIndex && visitedSellMax[curIndex, i, nextSell[k, i]] != 1 && currenciesMatrixSellMax[curIndex, i] - currenciesMatrixSellMax[curIndex, k] * currenciesMatrixSellMax[k, i] < -0.00000001)
                        {
                            currenciesMatrixSellMax[curIndex, i]        = currenciesMatrixSellMax[curIndex, k] * currenciesMatrixSellMax[k, i];
                            visitedSellMax[curIndex, i, nextSell[k, i]] = 1;
                            nextSell[curIndex, i] = nextSell[k, i];
                        }
                    }
                }
            }

            for (int i = 0; i < market.Currencies.Count; i++)
            {
                for (int j = 0; j < market.Currencies.Count; j++)
                {
                    if (i != j && currenciesMatrixPurchaseMin[i, j] < currenciesMatrixSellMax[i, j] && curStartChain.Values.Contains(i))
                    {
                        ExchangePair crossRatePair = new ExchangePair();
                        try {
                            crossRatePair.PurchasePath = GetPath(i, j, new List <int>(), nextPurchase, market.Currencies, market.Currencies[j]);
                            crossRatePair.SellPath     = GetPath(i, j, new List <int>(), nextSell, market.Currencies, market.Currencies[j]);
                        } catch (Exception e) {
                            //Console.WriteLine($"Exception: {e.Message}");
                            continue;
                        }
                        crossRatePair.Market = market.MarketName;
                        try {
                            crossRatePair.PurchasePrice = (decimal)currenciesMatrixPurchaseMin[i, j];
                            crossRatePair.SellPrice     = (decimal)currenciesMatrixSellMax[i, j];
                            if (crossRatePair.PurchasePrice > 0 && crossRatePair.SellPrice > 0)
                            {
                                crossRatePair.IsCross = true;
                                crossRatePair.Spread  = Math.Round((crossRatePair.SellPrice - crossRatePair.PurchasePrice) / crossRatePair.PurchasePrice * 100, 4);
                                if (crossRatePair.Market == "Bittrex" && crossRatePair.PurchasePath.Split('-')[0] == "BTC" && needToSaveInTimeService)
                                {
                                    ShowRates(crossRatePair.PurchasePath.Split('-'), true, market);
                                    ShowRates(crossRatePair.SellPath.Split('-'), false, market);

                                    TimeService.AddCrossRateByMarketBittrex(crossRatePair);
                                }
                                crossRatesByMarket.Add(crossRatePair);
                            }
                        } catch (Exception e) {
                            //Console.WriteLine($"Exception! {e.Message}");
                        }
                    }
                }
            }
        }