コード例 #1
0
        private void BuildEratio()
        {
            if (signals.Count == 0)
            {
                return;
            }

            ReadConfig();

            var signalStats   = signals.OrderBy(s => s.Time).Select(s => new SignalStat(s, timeframe, timeframes)).ToList();
            var actualStats   = new List <SignalStat>();
            var resultedStats = new List <SignalStat>();

            using (var candleReader = new CandleStream(quoteFilePath))
            {
                foreach (var candle in candleReader)
                {
                    candle.time = candle.time.AddHours(quoteOffset);
                    for (var i = 0; i < signalStats.Count; i++)
                    {
                        if (signalStats[i].time > candle.time)
                        {
                            break;
                        }
                        actualStats.Add(signalStats[i]);
                        // выровнять цену входа
                        signalStats[i].enter = (candle.o + candle.c) / 2;
                        signalStats.RemoveAt(i--);
                    }

                    for (var i = 0; i < actualStats.Count; i++)
                    {
                        // обновить pros / cons
                        actualStats[i].UpdateProsCons(candle, candle.time);
                        if (actualStats[i].endTime > candle.time)
                        {
                            break;
                        }
                        resultedStats.Add(actualStats[i]);
                        actualStats.RemoveAt(i--);
                    }
                }
            }
            resultedStats.AddRange(actualStats);

            // свернуть статистику в график
            ReduceERatio(resultedStats);
        }
コード例 #2
0
        private void FindTimeframeOffest()
        {
            var sigByTime = signals.GroupBy(s => s.Time).ToDictionary(s => s.Key, s => s.First());

            var mistakeByOffset = new Dictionary <int, OffsetMistake>();

            for (var i = -MaxOffset; i <= MaxOffset; i++)
            {
                mistakeByOffset.Add(i, new OffsetMistake {
                    offset = i
                });
            }
            using (var candleReader = new CandleStream(quoteFilePath))
            {
                foreach (var candle in candleReader)
                {
                    for (var i = -MaxOffset; i <= MaxOffset; i++)
                    {
                        var time = candle.time.AddHours(i);
                        if (!sigByTime.TryGetValue(time, out var sig))
                        {
                            continue;
                        }
                        var delta = Math.Abs(100 * ((decimal)candle.o - sig.Enter) / sig.Enter);
                        var mis   = mistakeByOffset[i];
                        mis.mistakeSum += delta;
                        mis.count++;
                    }
                }
            }
            // выбрать смещение с наименьшей ошибкой
            var min    = 0M;
            var offset = 0;

            foreach (var mis in mistakeByOffset.Values)
            {
                var av = mis.count == 0 ? 0 : mis.mistakeSum / mis.count;
                if (mis.count > 0 && av < min)
                {
                    offset = mis.offset;
                    min    = av;
                }
                Console.WriteLine($"[Offset {mis.offset}]: avg. mistake is {av:f4}%, count {mis.count}");
            }
            Console.WriteLine($"Offset should be {offset}");
        }
コード例 #3
0
        /// <summary>Access the order book for the given pair</summary>
        public List <MarketChartData> this[CurrencyPair pair, EMarketPeriod period, UnixMSec time_beg, UnixMSec time_end, CancellationToken? cancel = null]        // Worker thread context
        {
            get
            {
                var key = new PairAndTF {
                    Pair = pair, TimeFrame = period
                };
                try
                {
                    var stream = (CandleStream)null;
                    lock (Streams)
                    {
                        // Look for the stream for 'pair'. Create if not found.
                        // Return a copy since any thread can call this function.
                        if (!Streams.TryGetValue(key, out stream) || stream.Socket == null)
                        {
                            stream = Streams[key] = new CandleStream(pair, period, this);
                        }
                    }
                    lock (stream.CandleData)
                    {
                        // If the range is outside the cached data range, fall back to the REST call
                        if (stream.CandleData.Count == 0 || time_beg < stream.CandleData[0].Time)
                        {
                            return(Api.GetChartData(pair, period, time_beg, time_end, cancel).Result);
                        }

                        // Return the requested range
                        var ibeg = stream.CandleData.BinarySearch(x => x.Time.CompareTo(time_beg), find_insert_position: true);
                        var iend = stream.CandleData.BinarySearch(x => x.Time.CompareTo(time_end), find_insert_position: true);
                        return(stream.CandleData.GetRange(ibeg, iend - ibeg));
                    }
                }
                catch (Exception ex)
                {
                    BinanceApi.Log.Write(ELogLevel.Error, ex, $"Subscribing to candle data for {pair.Id}/{period} failed.");
                    lock (Streams) Streams.Remove(key);
                    return(new List <MarketChartData>());
                }
            }
        }