Beispiel #1
0
        public async void BackTest()
        {
            logger.Trace("Starting BackTest");

            IList <Asset> BackTestAssets  = new List <Asset>();
            IList <Asset> CompletedTrades = new List <Asset>();

            // flags.
            bool         hasTrade = false;
            MarketCandle buyCandle = null, sellCandle = null;

            var tickers = await api.GetTickersAsync();

            tickers = tickers.Where(t => t.Value.Volume.QuoteCurrency == "USD" &&
                                    !coinsToRemove.Contains(t.Value.Volume.BaseCurrency)
                                    );

            foreach (var ticker in tickers)
            {
                BackTestAssets.Add(new Asset {
                    Ticker = ticker.Key, BaseCurrency = ticker.Value.Volume.BaseCurrency
                });
            }

            int numTickers = BackTestAssets.Count();

            for (int idx = 0; idx < numTickers; idx++)
            {
                try
                {
                    var asset = BackTestAssets[idx];

                    // get 4-hour candles
                    var candles = (await api.GetCandlesAsync(asset.Ticker, 8 * 60 * 60, null, null)).ToArray();

                    IList <Quote> history = new List <Quote>();
                    foreach (var candle in candles)
                    {
                        history.Add(new Quote
                        {
                            Date   = candle.Timestamp,
                            Open   = candle.OpenPrice,
                            High   = candle.HighPrice,
                            Low    = candle.LowPrice,
                            Close  = candle.ClosePrice,
                            Volume = (decimal)candle.QuoteCurrencyVolume
                        });
                    }

                    // calculate RSI(14)
                    IList <HeikinAshiResult> ha       = Indicator.GetHeikinAshi(history).ToArray();
                    IList <HeikinAshi>       ashiList = new List <HeikinAshi>();
                    foreach (var item in ha)
                    {
                        ashiList.Add(new HeikinAshi(item));
                    }

                    // remember to throw out the last candle because that is the active candle that is not completed yet.

                    hasTrade = false;
                    for (int j = 1; j < candles.Length - 2; j++)
                    {
                        // remember to throw out the last candle because that is the active candle that is not completed yet.
                        // var completedRSI = rsi[j];
                        // var previousRSI = rsi[j - 1];
                        var completedAshi = ashiList[j];
                        var previousAshi  = ashiList[j - 1];

                        var isBuy        = completedAshi.Signal == HeikinAshi.HeikinAshiSignal.STRONGBUY && previousAshi.Signal != HeikinAshi.HeikinAshiSignal.STRONGBUY;
                        var isSellProfit = completedAshi.Signal == HeikinAshi.HeikinAshiSignal.STRONGSELL || previousAshi.Signal == HeikinAshi.HeikinAshiSignal.SELL;

                        if (isBuy && !hasTrade)
                        {
                            hasTrade  = true;
                            buyCandle = candles[j + 1];
                            // Debug.WriteLine($"Buy, {buyCandle.OpenPrice}, {buyCandle.HighPrice}");
                        }

                        if (isSellProfit && hasTrade)
                        {
                            hasTrade   = false;
                            sellCandle = candles[j + 1];
                            var lowPL = (sellCandle.LowPrice - buyCandle.HighPrice) / buyCandle.HighPrice * 100;
                            var pl    = (sellCandle.OpenPrice - buyCandle.OpenPrice) / buyCandle.OpenPrice * 100;
                            Debug.WriteLine($"{asset.Ticker}, {buyCandle.Timestamp}, {sellCandle.Timestamp}, {sellCandle.LowPrice}, {sellCandle.HighPrice}, {lowPL:0.00}, {pl:0.00}");
                        }
                    }

                    // unclosed trades.
                    if (hasTrade)
                    {
                        sellCandle = candles[candles.Length - 1];
                        var lowPL = (sellCandle.LowPrice - buyCandle.HighPrice) / buyCandle.HighPrice * 100;
                        var pl    = (sellCandle.OpenPrice - buyCandle.OpenPrice) / buyCandle.OpenPrice * 100;
                        Debug.WriteLine($"{asset.Ticker}, {buyCandle.Timestamp}, {sellCandle.Timestamp}, {sellCandle.LowPrice}, {sellCandle.HighPrice}, {lowPL:0.00}, {pl:0.00}, Unclosed ");
                    }
                }
                catch (Exception ex)
                {
                }
            }

            Debug.WriteLine("========= end backtesting =========");
        }
        public async Task <IWebSocket> GetWebsocketKlines(IEnumerable <string> streamTickers, KlineInterval interval)
        {
            string combined = string.Join("/", streamTickers.Select(s => s.ToLower() + "@" + interval.ToString()));

            return(await api.ConnectWebSocketAsync($"/stream?streams={combined}", (_socket, msg) =>
            {
                string json = msg.ToStringFromUTF8();
                //logger.Trace($"Kline Data:{json}");

                var klinedata = JsonConvert.DeserializeObject <KlineStream>(json);
                DateTime dt = CryptoUtility.ParseTimestamp(klinedata.Data.EventTime, TimestampType.UnixMilliseconds);

                /*
                 * logger.Trace($"EventTime:" + dt);
                 * logger.Trace($"KLineData:{klinedata.Data.kline.kLineClosed}:{klinedata.Data.MarketSymbol}:{klinedata.Data.kline.OpenTimestamp}");
                 * logger.Trace($"KLineData:{klinedata.Data.kline.kLineClosed}:{klinedata.Data.MarketSymbol}:{klinedata.Data.kline.Open}:{klinedata.Data.kline.High}:{klinedata.Data.kline.Low}:{klinedata.Data.kline.Close}");
                 * logger.Trace($"KLineData:{klinedata.Data.kline.kLineClosed}:{klinedata.Data.MarketSymbol}:{klinedata.Data.kline.BaseVolume}:{klinedata.Data.kline.QuoteVolume}");
                 * logger.Trace($"KLineData:{klinedata.Data.kline.kLineClosed}:{klinedata.Data.MarketSymbol}:{klinedata.Data.kline.TakerBaseVolume}:{klinedata.Data.kline.TakerQuoteVolume}");
                 */

                if (klinedata.Data.kline.kLineClosed == true)
                {
                    /*
                     * logger.Trace($"EventTime:" + dt);
                     * logger.Trace($"KLineData:{klinedata.Data.kline.kLineClosed}:{klinedata.Data.MarketSymbol}:{klinedata.Data.kline.OpenTimestamp}");
                     * logger.Trace($"KLineData:{klinedata.Data.kline.kLineClosed}:{klinedata.Data.MarketSymbol}:{klinedata.Data.kline.Open}:{klinedata.Data.kline.High}:{klinedata.Data.kline.Low}:{klinedata.Data.kline.Close}");
                     * logger.Trace($"KLineData:{klinedata.Data.kline.kLineClosed}:{klinedata.Data.MarketSymbol}:{klinedata.Data.kline.BaseVolume}:{klinedata.Data.kline.QuoteVolume}");
                     * logger.Trace($"KLineData:{klinedata.Data.kline.kLineClosed}:{klinedata.Data.MarketSymbol}:{klinedata.Data.kline.TakerBaseVolume}:{klinedata.Data.kline.TakerQuoteVolume}");
                     */
                    MarketCandle candle = new MarketCandle();
                    candle.OpenPrice = klinedata.Data.kline.Open;
                    candle.HighPrice = klinedata.Data.kline.High;
                    candle.LowPrice = klinedata.Data.kline.Low;
                    candle.ClosePrice = klinedata.Data.kline.Close;
                    candle.PeriodSeconds = (int)interval;

                    candle.BaseCurrencyVolume = (double)klinedata.Data.kline.BaseVolume;
                    candle.QuoteCurrencyVolume = (double)klinedata.Data.kline.QuoteVolume;

                    /*
                     * candle.BaseCurrencyVolume = (double)klinedata.Data.kline.TakerBaseVolume;
                     * candle.QuoteCurrencyVolume = (double)klinedata.Data.kline.TakerQuoteVolume;
                     */
                    candle.Timestamp = klinedata.Data.kline.OpenTimestamp;
                    if (!TickerKLines.ContainsKey(klinedata.Data.MarketSymbol))
                    {
                        TickerKLines[klinedata.Data.MarketSymbol] = new List <MarketCandle>();
                    }
                    TickerKLines[klinedata.Data.MarketSymbol].Add(candle);
                }

                /*
                 * string marketSymbol = update.Data.MarketSymbol;
                 * ExchangeOrderBook book = new ExchangeOrderBook { SequenceId = update.Data.FinalUpdate, MarketSymbol = marketSymbol, LastUpdatedUtc = CryptoUtility.UnixTimeStampToDateTimeMilliseconds(update.Data.EventTime) };
                 * foreach (List<object> ask in update.Data.Asks)
                 * {
                 *  var depth = new ExchangeOrderPrice { Price = ask[0].ConvertInvariant<decimal>(), Amount = ask[1].ConvertInvariant<decimal>() };
                 *  book.Asks[depth.Price] = depth;
                 * }
                 * foreach (List<object> bid in update.Data.Bids)
                 * {
                 *  var depth = new ExchangeOrderPrice { Price = bid[0].ConvertInvariant<decimal>(), Amount = bid[1].ConvertInvariant<decimal>() };
                 *  book.Bids[depth.Price] = depth;
                 * }
                 * callback(book);
                 */
                return Task.CompletedTask;
            }, (_sock) =>
            {
                logger.Trace("KLine socket connected");
                return Task.CompletedTask;
            }));
        }
Beispiel #3
0
 public SymbolTrend(int timeframe)
 {
     TimeframeInHours = timeframe;
     TrendRaw         = 0M;
     Candle           = null;
 }
Beispiel #4
0
 public static XCandle ToXCandle(this MarketCandle candle)
 {
     return(new XCandle(candle.ExchangeName, candle.Name, candle.Timestamp, candle.PeriodSeconds, candle.OpenPrice, candle.HighPrice, candle.LowPrice, candle.ClosePrice, (decimal)candle.BaseVolume, (decimal)candle.ConvertedVolume, candle.WeightedAverage));
 }