protected internal CandleBuySellElement(CandleBuySellView view, PlotPane host, CandleSample sample, int x, float minScale, float maxScale) : base(host) { m_View = view; m_Sample = sample; m_ScaleMin = minScale; m_ScaleMax = maxScale; computeCoords(); var h = Math.Max(m_Lay_BuyHeight, m_Lay_SellHeight); this.Region = new Rectangle(x, (int)(host.Height / host.Zoom) - h, CandleView.BAR_WIDTH, h); }
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; }
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.ClosePrice = sample.ClosePrice; }
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; }
protected override Elements.Element MakeSampleElement(TimeSeriesChart chart, PlotPane pane, CandleSample sample, int x, float minScale, float maxScale) { return new CandleBuySellElement(this, pane, sample, x, minScale, maxScale); }
/// <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)ExternalRandomGenerator.Instance.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 += ExternalRandomGenerator.Instance.NextScaledRandomInteger(-msIntervalDeviation, msIntervalDeviation); if (deltaT == 0) { deltaT = msInterval; } if (i % 8 == 0) { deltaT = msInterval; } } priceSteps++; if (priceSteps >= ExternalRandomGenerator.Instance.NextScaledRandomInteger( priceDirChangeEvery - 4, priceDirChangeEvery + 4)) { var accel = (float)ExternalRandomGenerator.Instance.NextScaledRandomInteger(1, priceChangeAccel); priceVelocity = -accel + (2.0f * accel * (float)ExternalRandomGenerator.Instance.NextRandomDouble); priceSteps = 0; } price += priceVelocity; var pSample = i > 0 ? result[i - 1] : null; sample.OpenPrice = pSample != null ? pSample.ClosePrice : price; sample.ClosePrice = price + (float)ExternalRandomGenerator.Instance.NextScaledRandomDouble(-0.08f * currentMidPrice, +0.08f * currentMidPrice); sample.LowPrice = Math.Min(sample.OpenPrice, sample.ClosePrice) - (float)ExternalRandomGenerator.Instance.NextScaledRandomDouble(0, +0.05f * currentMidPrice); sample.HighPrice = Math.Max(sample.OpenPrice, sample.ClosePrice) + (float)ExternalRandomGenerator.Instance.NextScaledRandomDouble(0, +0.05f * currentMidPrice); sample.Count = 1; result[i] = sample; } return(result); }
/// <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)ExternalRandomGenerator.Instance.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 += ExternalRandomGenerator.Instance.NextScaledRandomInteger(-msIntervalDeviation, msIntervalDeviation); if (deltaT == 0) deltaT = msInterval; if (i%8 == 0) deltaT = msInterval; } priceSteps++; if (priceSteps >= ExternalRandomGenerator.Instance.NextScaledRandomInteger( priceDirChangeEvery - 4, priceDirChangeEvery + 4)) { var accel = (float)ExternalRandomGenerator.Instance.NextScaledRandomInteger(1, priceChangeAccel); priceVelocity = -accel + (2.0f*accel*(float)ExternalRandomGenerator.Instance.NextRandomDouble); priceSteps = 0; } price += priceVelocity; var pSample = i > 0 ? result[i - 1] : null; sample.OpenPrice = pSample != null ? pSample.ClosePrice : price; sample.ClosePrice = price + (float)ExternalRandomGenerator.Instance.NextScaledRandomDouble(-0.08f*currentMidPrice, +0.08f*currentMidPrice); sample.LowPrice = Math.Min(sample.OpenPrice, sample.ClosePrice) - (float)ExternalRandomGenerator.Instance.NextScaledRandomDouble(0, +0.05f*currentMidPrice); sample.HighPrice = Math.Max(sample.OpenPrice, sample.ClosePrice) + (float)ExternalRandomGenerator.Instance.NextScaledRandomDouble(0, +0.05f*currentMidPrice); sample.Count = 1; result[i] = sample; } return result; }
/// <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); } }
protected override Elements.Element MakeSampleElement(TimeSeriesChart chart, PlotPane pane, CandleSample sample, int x, float minScale, float maxScale) { return null; }
/// <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 (bestBid.Price!=0) { if (i==0) cs.OpenPrice = bestBid.Price; cs.HighPrice = Math.Max(cs.HighPrice, bestBid.Price); cs.LowPrice = cs.LowPrice!=0f ? Math.Min( cs.LowPrice , bestBid.Price) : bestBid.Price; cs.ClosePrice = bestBid.Price; } }; if (funcTrade==null) funcTrade = (cs, ts, i) => { if (ts.IsQty) { 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; }
private void tmrUpdate_Tick(object sender, EventArgs e) { if (!chkRealtime.Checked) return; var series = chart.Series as CandleTimeSeries; if (series==null) return; if (m_OriginalDataFromFile==null) return; var sample = m_OriginalDataFromFile.Skip(timerX).FirstOrDefault(); if (sample==null) { timerX = 0; sample = m_OriginalDataFromFile.Skip(timerX).FirstOrDefault(); } else timerX++; if (sample==null) return; var last = series.DataReveresed.First(); var newSample = new CandleSample(last.TimeStamp.AddSeconds(m_SecResolution)) { OpenPrice = sample.OpenPrice, ClosePrice = sample.ClosePrice, HighPrice = sample.HighPrice, LowPrice = sample.LowPrice, BuyVolume = sample.BuyVolume, SellVolume = sample.SellVolume, TimeSpanMs = sample.TimeSpanMs }; series.Add( newSample ); updateLevels(series); chart.NotifySeriesChange(); }