예제 #1
0
 public void Replace(CandleSample sample)
 {
     TimeSpanMs = sample.TimeSpanMs;
     LowPrice   = sample.LowPrice;
     HighPrice  = sample.HighPrice;
     OpenPrice  = sample.OpenPrice;
     ClosePrice = sample.ClosePrice;
     BuyVolume  = sample.BuyVolume;
     SellVolume = sample.SellVolume;
     Count      = sample.Count;
 }
예제 #2
0
        public void AggregateSample(CandleSample sample)
        {
            if (sample == null)
            {
                return;
            }

            this.TimeSpanMs += sample.TimeSpanMs;

            if (sample.LowPrice < this.LowPrice)
            {
                this.LowPrice = sample.LowPrice;
            }
            if (sample.HighPrice > this.HighPrice)
            {
                this.HighPrice = sample.HighPrice;
            }

            this.BuyVolume  += sample.BuyVolume;
            this.SellVolume += sample.SellVolume;
            this.Count      += sample.Count;
            this.ClosePrice  = sample.ClosePrice;
        }
예제 #3
0
        /// <summary>
        /// Generates random market candle stream
        /// </summary>
        public static CandleSample[] GenerateRandom(int count,
                                                    DateTime startDate,
                                                    int msInterval,
                                                    int msIntervalDeviation,
                                                    int priceDirChangeEvery,
                                                    int priceChangeAccel,
                                                    float currentMidPrice)
        {
            if (count <= 0)
            {
                count = 1;
            }
            if (msInterval == 0)
            {
                msInterval = 1000;
            }
            if (priceDirChangeEvery <= 0)
            {
                priceDirChangeEvery = 11;
            }
            if (priceChangeAccel == 0)
            {
                priceChangeAccel = 8;
            }

            var result = new CandleSample[count];

            var dt     = startDate;
            var deltaT = msInterval;

            var priceVelocity = -1.0f + (2.0f * (float)rnd.NextRandomDouble);
            var priceSteps    = 0;

            var price = currentMidPrice;

            for (var i = 0; i < count; i++)
            {
                var sample = new CandleSample(dt);
                dt = dt.AddMilliseconds(deltaT);
                if (msIntervalDeviation != 0)
                {
                    deltaT += rnd.NextScaledRandomInteger(-msIntervalDeviation, msIntervalDeviation);
                    if (deltaT == 0)
                    {
                        deltaT = msInterval;
                    }
                    if (i % 8 == 0)
                    {
                        deltaT = msInterval;
                    }
                }


                priceSteps++;
                if (priceSteps >=
                    rnd.NextScaledRandomInteger(
                        priceDirChangeEvery - 4, priceDirChangeEvery + 4))
                {
                    var accel = (float)rnd.NextScaledRandomInteger(1, priceChangeAccel);
                    priceVelocity = -accel + (2.0f * accel * (float)rnd.NextRandomDouble);
                    priceSteps    = 0;
                }

                price += priceVelocity;

                var pSample = i > 0 ? result[i - 1] : null;

                sample.OpenPrice  = pSample != null ? pSample.ClosePrice : price;
                sample.ClosePrice = price
                                    + (float)rnd.NextScaledRandomDouble(-0.08f * currentMidPrice, +0.08f * currentMidPrice);

                sample.LowPrice = Math.Min(sample.OpenPrice, sample.ClosePrice)
                                  - (float)rnd.NextScaledRandomDouble(0, +0.05f * currentMidPrice);

                sample.HighPrice = Math.Max(sample.OpenPrice, sample.ClosePrice)
                                   + (float)rnd.NextScaledRandomDouble(0, +0.05f * currentMidPrice);

                sample.Count = 1;

                result[i] = sample;
            }

            return(result);
        }
예제 #4
0
        /// <summary>
        /// Synthesizes a stream of candle samples from Quote and Trade samples coming from the market (i.e SecDB file)
        /// </summary>
        /// <param name="source">Source of market data</param>
        /// <param name="secSamplingPeriod">The output sampling period</param>
        /// <param name="funcQuote">Aggregation func for Quote, if null default is used which aggregates best bid</param>
        /// <param name="funcTrade">Aggregation func for Quote, if null default is used which aggregates buy and sell volumes</param>
        /// <returns>Synthesized candle stream</returns>
        public static IEnumerable <CandleSample> SynthesizeCandles(this IEnumerable <ITimeSeriesSample> source,
                                                                   uint secSamplingPeriod,
                                                                   Action <CandleSample, SecDBFileReader.QuoteSample, int> funcQuote = null,
                                                                   Action <CandleSample, SecDBFileReader.TradeSample, int> funcTrade = null)
        {
            if (source == null)
            {
                yield break;
            }

            if (funcQuote == null)
            {
                funcQuote = (cs, qs, i) =>
                {
                    var bestBid = qs.Bids.LastOrDefault();
                    if (Math.Abs(bestBid.Price) < float.Epsilon)
                    {
                        return;
                    }

                    if (i == 0)
                    {
                        cs.OpenPrice = bestBid.Price;
                    }

                    cs.HighPrice  = Math.Max(cs.HighPrice, bestBid.Price);
                    cs.LowPrice   = Math.Abs(cs.LowPrice) > float.Epsilon ? Math.Min(cs.LowPrice, bestBid.Price) : bestBid.Price;
                    cs.ClosePrice = bestBid.Price;
                };
            }

            if (funcTrade == null)
            {
                funcTrade = (cs, ts, i) =>
                {
                    if (!ts.IsQty)
                    {
                        return;
                    }

                    if (ts.Side == SecDBFileReader.TradeSample.SideType.Buy)
                    {
                        cs.BuyVolume += ts.Qty;
                    }
                    else
                    {
                        cs.SellVolume += ts.Qty;
                    }
                };
            }

            CandleSample emit = null;

            var filteredSamples = source.Where(s => s is SecDBFileReader.QuoteSample ||
                                               s is SecDBFileReader.TradeSample);

            var aggregateCount = 0;

            foreach (var sample in filteredSamples)
            {
                if (emit != null && (sample.TimeStamp - emit.TimeStamp).TotalSeconds > secSamplingPeriod)
                {
                    emit.TimeSpanMs = (long)(sample.TimeStamp - emit.TimeStamp).TotalMilliseconds;

                    yield return(emit);

                    emit = null;
                }

                if (emit == null)
                {
                    emit           = new CandleSample(sample.TimeStamp);
                    aggregateCount = 0;
                }

                var qts = sample as SecDBFileReader.QuoteSample;
                if (qts != null)
                {
                    funcQuote(emit, qts, aggregateCount);
                }

                var tds = sample as SecDBFileReader.TradeSample;
                if (tds != null)
                {
                    funcTrade(emit, tds, aggregateCount);
                }

                aggregateCount++;
            }

            if (emit != null)
            {
                yield return(emit);
            }
        }