/// <summary> /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized. /// </summary> /// <seealso cref="QCAlgorithm.SetStartDate(System.DateTime)"/> /// <seealso cref="QCAlgorithm.SetEndDate(System.DateTime)"/> /// <seealso cref="QCAlgorithm.SetCash(decimal)"/> public override void Initialize() { SetStartDate(2009, 01, 01); SetEndDate(2015, 01, 01); AddSecurity(SecurityType.Equity, Symbol, Resolution.Minute); int count = 6; int offset = 5; int period = 15; // define our sma as the base of the ribbon var sma = new SimpleMovingAverage(period); _ribbon = Enumerable.Range(0, count).Select(x => { // define our offset to the zero sma, these various offsets will create our 'displaced' ribbon var delay = new Delay(offset*(x+1)); // define an indicator that takes the output of the sma and pipes it into our delay indicator var delayedSma = delay.Of(sma); // register our new 'delayedSma' for automaic updates on a daily resolution RegisterIndicator(Symbol, delayedSma, Resolution.Daily, data => data.Value); return delayedSma; }).ToArray(); }
protected override void Initialize() { ema5 = Robot.Indicators.ExponentialMovingAverage(Robot.MarketSeries.Close, 5); sma8 = Robot.Indicators.SimpleMovingAverage(Robot.MarketSeries.Open, 8); ema21 = Robot.Indicators.ExponentialMovingAverage(Robot.MarketSeries.Close, 21); ema55 = Robot.Indicators.ExponentialMovingAverage(Robot.MarketSeries.Close, 55); }
protected override void Initialize() { _deMax = CreateDataSeries(); _deMin = CreateDataSeries(); _deMaxSma = Indicators.SimpleMovingAverage(_deMax, Period); _deMinSma = Indicators.SimpleMovingAverage(_deMin, Period); }
/// <summary> /// Создать <see cref="StochasticOscillator"/>. /// </summary> public StochasticOscillator() { InnerIndicators.Add(K = new StochasticK()); InnerIndicators.Add(D = new SimpleMovingAverage { Length = 3 }); Mode = ComplexIndicatorModes.Sequence; }
public void PipesDataUsingOfFromFirstToSecond() { var first = new SimpleMovingAverage(2); var second = new Delay(1); // this is a configuration step, but returns the reference to the second for method chaining second.Of(first); var data1 = new IndicatorDataPoint(DateTime.UtcNow, 1m); var data2 = new IndicatorDataPoint(DateTime.UtcNow, 2m); var data3 = new IndicatorDataPoint(DateTime.UtcNow, 3m); var data4 = new IndicatorDataPoint(DateTime.UtcNow, 4m); // sma has one item first.Update(data1); Assert.IsFalse(first.IsReady); Assert.AreEqual(0m, second.Current.Value); // sma is ready, delay will repeat this value first.Update(data2); Assert.IsTrue(first.IsReady); Assert.IsFalse(second.IsReady); Assert.AreEqual(1.5m, second.Current.Value); // delay is ready, and repeats its first input first.Update(data3); Assert.IsTrue(second.IsReady); Assert.AreEqual(1.5m, second.Current.Value); // now getting the delayed data first.Update(data4); Assert.AreEqual(2.5m, second.Current.Value); }
public void MultiChain() { var identity = new Identity("identity"); var sma = new SimpleMovingAverage(2); var delay = new Delay(2); // create the SMA of the delay of the identity sma.Of(delay.Of(identity)); identity.Update(DateTime.UtcNow, 1m); Assert.IsTrue(identity.IsReady); Assert.IsFalse(delay.IsReady); Assert.IsFalse(sma.IsReady); identity.Update(DateTime.UtcNow, 2m); Assert.IsTrue(identity.IsReady); Assert.IsFalse(delay.IsReady); Assert.IsFalse(sma.IsReady); identity.Update(DateTime.UtcNow, 3m); Assert.IsTrue(identity.IsReady); Assert.IsTrue(delay.IsReady); Assert.IsFalse(sma.IsReady); identity.Update(DateTime.UtcNow, 4m); Assert.IsTrue(identity.IsReady); Assert.IsTrue(delay.IsReady); Assert.IsTrue(sma.IsReady); Assert.AreEqual(1.5m, sma); }
protected override void OnStart() { i_Moving_Average_200MA = Indicators.SimpleMovingAverage(MarketSeries.Close, (int)_Slow_SMA); i_Relative_Strength_Index = Indicators.RelativeStrengthIndex(MarketSeries.Close, (int)_RSI_Period); i_Moving_Average_5MA = Indicators.SimpleMovingAverage(MarketSeries.Close, (int)_Fast_SMA); }
protected override void Initialize() { _StdDev = Indicators.StandardDeviation(MarketSeries.Close, Period, MovingAverageType.Simple); _LinReg = Indicators.LinearRegressionForecast(MarketSeries.Close, Period); _Range = CreateDataSeries(); _Baseline = Indicators.SimpleMovingAverage(_Range, Period); }
protected override void OnStart() { _SMA = Indicators.SimpleMovingAverage(Source_SMA, Periods_SMA); _SOC = Indicators.StochasticOscillator(KPeriods, K_Slowing, DPeriods, MaType); Positions.Closed += PositionsOnClosed; }
public SmaStrategy(CandleSeries series, SimpleMovingAverage longSma, SimpleMovingAverage shortSma) { _series = series; LongSma = longSma; ShortSma = shortSma; }
protected override void OnStart() { i_Relative_Strength_Index = Indicators.RelativeStrengthIndex(MarketSeries.Close, 2); i_Moving_Average_200MA = Indicators.SimpleMovingAverage(MarketSeries.Close, 200); i_Moving_Average_5MA = Indicators.SimpleMovingAverage(MarketSeries.Close, 5); }
public YangZhang(string name, int period) : base(name) { _period = period; MuClose = new SimpleMovingAverage("MuC", period); MuOpen = new SimpleMovingAverage("MuO", period); CloseVol = new Sum("CV", period); OpenVol = new Sum("OV", period); RSVol = new SimpleMovingAverage("OV", period); TradeBar previous = null; OcCp = new FunctionalIndicator<TradeBar>(name + "_e", currentBar => { var nextValue = ComputeOcCp(previous, currentBar); previous = currentBar; return nextValue; } // in our IsReady function we just need at least two sample , trueRangeIndicator => trueRangeIndicator.Samples >= _period ); CcOc = new FunctionalIndicator<TradeBar>(name + "_", currentBar => ComputeCcOc(currentBar) , trueRangeIndicator => trueRangeIndicator.Samples >= _period); OHL = new FunctionalIndicator<TradeBar>(name + "_", currentBar => ComputeOHL(currentBar) , trueRangeIndicator => trueRangeIndicator.Samples >= _period); }
protected override void Initialize() { iSeries1 = CreateDataSeries(); iSeries4 = CreateDataSeries(); _sma = Indicators.SimpleMovingAverage(MarketSeries.Close, Len1); _sma2 = Indicators.SimpleMovingAverage(_sma.Result, Len1); _sma3 = Indicators.SimpleMovingAverage(_sma2.Result, Len1); _sma4 = Indicators.SimpleMovingAverage(_sma3.Result, Len1); _sma5 = Indicators.SimpleMovingAverage(_sma4.Result, Len1); _sma6 = Indicators.SimpleMovingAverage(_sma5.Result, Len1); _sma7 = Indicators.SimpleMovingAverage(_sma6.Result, Len1); _sma8 = Indicators.SimpleMovingAverage(_sma7.Result, Len1); _sma9 = Indicators.SimpleMovingAverage(_sma8.Result, Len1); _sma10 = Indicators.SimpleMovingAverage(_sma9.Result, Len1); _ema1 = Indicators.ExponentialMovingAverage(iSeries1, Len3); _ema2 = Indicators.ExponentialMovingAverage(_ema1.Result, Len3); _ema3 = Indicators.ExponentialMovingAverage(ST2, Len3); _ema4 = Indicators.ExponentialMovingAverage(_ema3.Result, Len3); _ema5 = Indicators.ExponentialMovingAverage(iSeries1, Len4); _ema6 = Indicators.ExponentialMovingAverage(_ema3.Result, Len4); }
protected override void Initialize() { _movingAverage5 = Indicators.SimpleMovingAverage(Source, 5); _movingAverage34 = Indicators.SimpleMovingAverage(Source, 34); _awesomeOsc = CreateDataSeries(); _movingAverage = Indicators.SimpleMovingAverage(_awesomeOsc, 5); _extBuffer0 = CreateDataSeries(); }
public void PipesDataFromFirstToSecond() { var first = new SimpleMovingAverage(2); var second = new Delay(1); var sequential = new SequentialIndicator<IndicatorDataPoint>(first, second); TestPipesData(sequential); }
public SmaStrategy(ICandleManager candleManager, CandleSeries series, SimpleMovingAverage longSma, SimpleMovingAverage shortSma) { _candleManager = candleManager; _series = series; LongSma = longSma; ShortSma = shortSma; }
public void PipesDataUsingOfFromFirstToSecond() { var first = new SimpleMovingAverage(2); var second = new Delay(1); var sequential = second.Of(first); TestPipesData(sequential); }
public SmaStrategy() { _timeFrame = this.Param("TimeFrame", TimeSpan.FromMinutes(5)); _longSmaPeriod = this.Param("LongSmaPeriod", 20).Optimize(15, 30); _shortSmaPeriod = this.Param("ShortSmaPeriod", 5).Optimize(3, 10); _shortSma = new SimpleMovingAverage(); _longSma = new SimpleMovingAverage(); }
protected override void Initialize() { _highSeries = CreateDataSeries(); _lowSeries = CreateDataSeries(); _smaHigh = Indicators.SimpleMovingAverage(_highSeries, SmaPeriod); _smaLow = Indicators.SimpleMovingAverage(_lowSeries, SmaPeriod); _dms = Indicators.DirectionalMovementSystem(AdxPeriod); }
protected override void Initialize() { _fastSma = Indicators.SimpleMovingAverage(Source, FastPeriod); _slowSma = Indicators.SimpleMovingAverage(Source, SlowPeriod); _sma100 = Indicators.SimpleMovingAverage(Source, 100); _sma200 = Indicators.SimpleMovingAverage(Source, 200); _sma20 = Indicators.SimpleMovingAverage(Source, 20); _elliot = CreateDataSeries(); }
public void IsReadyAfterPeriodUpdates() { var sma = new SimpleMovingAverage(3); sma.Update(DateTime.UtcNow, 1m); sma.Update(DateTime.UtcNow, 1m); Assert.IsFalse(sma.IsReady); sma.Update(DateTime.UtcNow, 1m); Assert.IsTrue(sma.IsReady); }
protected override void OnStart() { i_MACD_main = Indicators.MacdHistogram(MarketSeries.Close, (int)_Period_SlowEMA, (int)_Period_FastEMA, (int)_Period_MACD_SMA); i_MCAD_signal = Indicators.MacdHistogram(MarketSeries.Close, (int)_Period_SlowEMA, (int)_Period_FastEMA, (int)_Period_MACD_SMA); i_MA_Close = Indicators.SimpleMovingAverage(MarketSeries.Close, 1); i_Parabolic_SAR = Indicators.ParabolicSAR(_Step_PrbSAR, 0.1); i_MA_Open = Indicators.SimpleMovingAverage(MarketSeries.Open, 1); i_EMAf = Indicators.ExponentialMovingAverage(MarketSeries.Close, (int)_Period_FastEMA); }
public void TestSimpleNotFullStaticAverage() { var sma = new SimpleMovingAverage(5); sma.Add(3); sma.Add(4); sma.Add(2); sma.Add(3); var average = sma.Average(); Assert.Equal(3, average); }
public SmaStrategy(CandleSeries series, SimpleMovingAverage longSma, SimpleMovingAverage shortSma) { _series = series; LongSma = longSma; ShortSma = shortSma; _longSmaPeriod = this.Param("LongSmaPeriod", longSma.Length); _shortSmaPeriod = this.Param("ShortSmaPeriod", shortSma.Length); }
/// <summary> /// Создать <see cref="Acceleration"/>. /// </summary> /// <param name="ao">Чудесный осцилятор.</param> /// <param name="sma">Cкользящая средняя.</param> public Acceleration(AwesomeOscillator ao, SimpleMovingAverage sma) { if (ao == null) throw new ArgumentNullException("ao"); if (sma == null) throw new ArgumentNullException("sma"); Ao = ao; Sma = sma; }
protected override void Initialize() { _stochastic5 = Indicators.StochasticOscillator(5, 3, 3, MaType); _stochastic14 = Indicators.StochasticOscillator(14, 3, 3, MaType); _stochastic45 = Indicators.StochasticOscillator(45, 3, 14, MaType); _stochastic75 = Indicators.StochasticOscillator(75, 3, 20, MaType); _stpmt = CreateDataSeries(); _stpmtMa = Indicators.SimpleMovingAverage(_stpmt, 9); }
public void TestSimpleMovingAverage() { var sma = new SimpleMovingAverage(5); sma.Add(10); sma.Add(55); sma.Add(33); sma.Add(56); sma.Add (88); sma.Add(23); var average = sma.Average(); Assert.Equal(51, average); }
/// <summary> /// Initializes a new instance of the <see cref="AwesomeOscillator"/>. /// </summary> /// <param name="longSma">Long moving average.</param> /// <param name="shortSma">Short moving average.</param> public AwesomeOscillator(SimpleMovingAverage longSma, SimpleMovingAverage shortSma) { if (longSma == null) throw new ArgumentNullException(nameof(longSma)); if (shortSma == null) throw new ArgumentNullException(nameof(shortSma)); ShortMa = shortSma; LongMa = longSma; MedianPrice = new MedianPrice(); }
protected override void Initialize() { sma1 = Indicators.SimpleMovingAverage(MarketSeries.Close, Period1); sma2 = Indicators.SimpleMovingAverage(MarketSeries.Close, Period2); sma3 = Indicators.SimpleMovingAverage(MarketSeries.Close, Period3); sma4 = Indicators.SimpleMovingAverage(MarketSeries.Close, Period4); sma5 = Indicators.SimpleMovingAverage(MarketSeries.Close, Period5); sma6 = Indicators.SimpleMovingAverage(MarketSeries.Close, Period6); sma7 = Indicators.SimpleMovingAverage(MarketSeries.Close, Period7); sma8 = Indicators.SimpleMovingAverage(MarketSeries.Close, Period8); sma9 = Indicators.SimpleMovingAverage(MarketSeries.Close, Period9); sma10 = Indicators.SimpleMovingAverage(MarketSeries.Close, Period10); }
public TripleMovingAverageStrategy(Symbol sym, Indicator priceIdentity, MeanReversionAlgorithm algorithm, decimal minBarSize, decimal barDifferenceTolerance) { Algorithm = algorithm; symbol = sym; trend = new InstantaneousTrend(10).Of(_price); ema10 = new ExponentialMovingAverage(10).Of(_price); sma10 = new SimpleMovingAverage(10).Of(_price); Position = StockState.noInvested; EntryPrice = null; ActualSignal = OrderSignal.doNothing; }
/// <summary> /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized. /// </summary> public override void Initialize() { SetStartDate(2013, 10, 08); SetEndDate(2013, 10, 09); var SP500 = QuantConnect.Symbol.Create(Futures.Indices.SP500EMini, SecurityType.Future, Market.CME); _symbol = FutureChainProvider.GetFutureContractList(SP500, StartDate).First(); AddFutureContract(_symbol); // this collection will hold all indicators and at the end of the algorithm we will assert that all of them are ready _indicators = new List <IIndicator>(); // Test the different APIs for IndicatorBase<QuoteBar> works correctly. // Should be able to determine the correct consolidator and not throw an exception var indicator = new CustomIndicator(); RegisterIndicator(_symbol, indicator, Resolution.Minute); _indicators.Add(indicator); // specifying a selector and using resolution var indicator2 = new CustomIndicator(); RegisterIndicator(_symbol, indicator2, Resolution.Minute, data => (QuoteBar)data); _indicators.Add(indicator2); // specifying a selector and using timeSpan var indicator3 = new CustomIndicator(); RegisterIndicator(_symbol, indicator3, TimeSpan.FromMinutes(1), data => (QuoteBar)data); _indicators.Add(indicator3); // directly sending in the desired consolidator var indicator4 = new SimpleMovingAverage(10); var consolidator = ResolveConsolidator(_symbol, Resolution.Minute, typeof(QuoteBar)); RegisterIndicator(_symbol, indicator4, consolidator); _indicators.Add(indicator4); // directly sending in the desired consolidator and specifying a selector var indicator5 = new SimpleMovingAverage(10); var consolidator2 = ResolveConsolidator(_symbol, Resolution.Minute, typeof(QuoteBar)); RegisterIndicator(_symbol, indicator5, consolidator2, data => { var quoteBar = data as QuoteBar; return(quoteBar.High - quoteBar.Low); }); _indicators.Add(indicator5); // Now make sure default data type TradeBar works correctly and does not throw an exception // Specifying resolution and selector var movingAverage = new SimpleMovingAverage(10); RegisterIndicator(_symbol, movingAverage, Resolution.Minute, data => data.Value); _indicators.Add(movingAverage); // Specifying resolution var movingAverage2 = new SimpleMovingAverage(10); RegisterIndicator(_symbol, movingAverage2, Resolution.Minute); _indicators.Add(movingAverage2); // Specifying TimeSpan var movingAverage3 = new SimpleMovingAverage(10); RegisterIndicator(_symbol, movingAverage3, TimeSpan.FromMinutes(1)); _indicators.Add(movingAverage3); // Specifying TimeSpan and selector var movingAverage4 = new SimpleMovingAverage(10); RegisterIndicator(_symbol, movingAverage4, TimeSpan.FromMinutes(1), data => data.Value); _indicators.Add(movingAverage4); // Test custom data is able to register correctly and indicators updated var smaCustomData = new SimpleMovingAverage(1); var symbol = AddData <CustomDataRegressionAlgorithm.Bitcoin>("BTC", Resolution.Minute).Symbol; RegisterIndicator(symbol, smaCustomData, TimeSpan.FromMinutes(1), data => data.Value); _indicators.Add(smaCustomData); var smaCustomData2 = new SimpleMovingAverage(1); RegisterIndicator(symbol, smaCustomData2, Resolution.Minute); _indicators.Add(smaCustomData2); }
protected override void Initialize() { _smaHigh = Indicators.SimpleMovingAverage(MarketSeries.High, Period); _smaLow = Indicators.SimpleMovingAverage(MarketSeries.Low, Period); }
public SmaStrategy(ICandleManager candleManager, CandleSeries series, SimpleMovingAverage longSma, SimpleMovingAverage shortSma) { _candleManager = candleManager; _series = series; LongSma = longSma; ShortSma = shortSma; _longSmaPeriod = this.Param("LongSmaPeriod", longSma.Length); _shortSmaPeriod = this.Param("ShortSmaPeriod", shortSma.Length); }
//-------------------------------------- protected override void OnStart() { Today = Server.Time.Day; sma = Indicators.SimpleMovingAverage(MarketData.GetSeries(TimeFrame.Minute5).Close, 30); }
public static async Task <TimelineResponse> GetDuration(sc2dsstatsContext context, DsRequest request) { var replays = ReplayFilter.Filter(context, request); replays = replays.Where(x => x.Gametime >= request.StartTime); if (request.EndTime != DateTime.Today) { replays = replays.Where(x => x.Gametime <= request.EndTime); } var results = request.Player switch { true => from r in replays from p in r.Dsplayers where p.Race == (byte)DSData.GetCommander(request.Interest) && p.isPlayer select new { r.Id, r.Duration, p.Win }, false => from r in replays from p in r.Dsplayers where p.Race == (byte)DSData.GetCommander(request.Interest) select new { r.Id, r.Duration, p.Win } }; var lresults = await results.ToListAsync(); TimelineResponse response = new TimelineResponse() { Interest = request.Interest, Count = lresults.Select(s => s.Id).Distinct().Count(), AvgDuration = lresults.Count == 0 ? 0 : (int)(lresults.Sum(s => s.Duration) / lresults.Count), Items = new List <DsResponseItem>() }; if (lresults.Any()) { for (int i = 0; i < DSData.durations.Length; i++) { int startd = 0; if (i > 0) { Match m = d_rx.Match(DSData.durations[i]); if (m.Success) { startd = int.Parse(m.Value); } } int endd = startd + 3; if (i == 0) { endd = 8; } if (i == DSData.durations.Length - 1) { endd = 200; } var ilresults = lresults.Where(x => x.Duration > startd * 60 && x.Duration < endd * 60).ToList(); response.Items.Add(new DsResponseItem() { Label = $"{DSData.durations[i]} min ({ilresults.Count})", Count = ilresults.Count, Wins = ilresults.Where(x => x.Win == true).Count() }); } } var sma = new SimpleMovingAverage(4); response.SmaData = new List <double>(); response.SmaData = TimelineService.GetNiceLineData(response.Items.Select(s => s.Count == 0 ? 0 : ((double)s.Wins * 100.0 / (double)s.Count)), 4); return(response); } }
public IsAboveSimpleMovingAverage(IList <decimal> closes, int periodCount) : base(closes) { _sma = new SimpleMovingAverage(closes, periodCount); }
private void StartBtnClick(object sender, RoutedEventArgs e) { InitChart(); if (HistoryPath.Text.IsEmpty() || !Directory.Exists(HistoryPath.Text)) { MessageBox.Show(this, LocalizedStrings.Str3014); return; } if (_connectors.Any(t => t.State != EmulationStates.Stopped)) { MessageBox.Show(this, LocalizedStrings.Str3015); return; } var secIdParts = SecId.Text.Split('@'); if (secIdParts.Length != 2) { MessageBox.Show(this, LocalizedStrings.Str3016); return; } var timeFrame = TimeSpan.FromMinutes(5); // create backtesting modes var settings = new[] { Tuple.Create( TicksCheckBox, TicksTestingProcess, TicksParameterGrid, // ticks new EmulationInfo { UseTicks = true, CurveColor = Colors.DarkGreen, StrategyName = LocalizedStrings.Ticks }), Tuple.Create( TicksAndDepthsCheckBox, TicksAndDepthsTestingProcess, TicksAndDepthsParameterGrid, // ticks + order book new EmulationInfo { UseTicks = true, UseMarketDepth = true, CurveColor = Colors.Red, StrategyName = LocalizedStrings.XamlStr757 }), Tuple.Create( DepthsCheckBox, DepthsTestingProcess, DepthsParameterGrid, // order book new EmulationInfo { UseMarketDepth = true, CurveColor = Colors.OrangeRed, StrategyName = LocalizedStrings.MarketDepths }), Tuple.Create( CandlesCheckBox, CandlesTestingProcess, CandlesParameterGrid, // candles new EmulationInfo { UseCandleTimeFrame = timeFrame, CurveColor = Colors.DarkBlue, StrategyName = LocalizedStrings.Candles }), Tuple.Create( CandlesAndDepthsCheckBox, CandlesAndDepthsTestingProcess, CandlesAndDepthsParameterGrid, // candles + orderbook new EmulationInfo { UseMarketDepth = true, UseCandleTimeFrame = timeFrame, CurveColor = Colors.Cyan, StrategyName = LocalizedStrings.XamlStr635 }), Tuple.Create( OrderLogCheckBox, OrderLogTestingProcess, OrderLogParameterGrid, // order log new EmulationInfo { UseOrderLog = true, CurveColor = Colors.CornflowerBlue, StrategyName = LocalizedStrings.OrderLog }) }; // storage to historical data var storageRegistry = new StorageRegistry { // set historical path DefaultDrive = new LocalMarketDataDrive(HistoryPath.Text) }; var startTime = ((DateTime)From.Value).ChangeKind(DateTimeKind.Utc); var stopTime = ((DateTime)To.Value).ChangeKind(DateTimeKind.Utc); // ОЛ необходимо загружать с 18.45 пред дня, чтобы стаканы строились правильно if (OrderLogCheckBox.IsChecked == true) { startTime = startTime.Subtract(TimeSpan.FromDays(1)).AddHours(18).AddMinutes(45).AddTicks(1); } // ProgressBar refresh step var progressStep = ((stopTime - startTime).Ticks / 100).To <TimeSpan>(); // set ProgressBar bounds _progressBars.ForEach(p => { p.Value = 0; p.Maximum = 100; }); var logManager = new LogManager(); var fileLogListener = new FileLogListener("sample.log"); logManager.Listeners.Add(fileLogListener); //logManager.Listeners.Add(new DebugLogListener()); // for track logs in output window in Vusial Studio (poor performance). var generateDepths = GenDepthsCheckBox.IsChecked == true; var maxDepth = MaxDepth.Text.To <int>(); var maxVolume = MaxVolume.Text.To <int>(); var secCode = secIdParts[0]; var board = ExchangeBoard.GetOrCreateBoard(secIdParts[1]); foreach (var set in settings) { if (set.Item1.IsChecked == false) { continue; } var progressBar = set.Item2; var statistic = set.Item3; var emulationInfo = set.Item4; // create test security var security = new Security { Id = SecId.Text, // sec id has the same name as folder with historical data Code = secCode, Board = board, }; var level1Info = new Level1ChangeMessage { SecurityId = security.ToSecurityId(), ServerTime = startTime, } .TryAdd(Level1Fields.PriceStep, 10m) .TryAdd(Level1Fields.StepPrice, 6m) .TryAdd(Level1Fields.MinPrice, 10m) .TryAdd(Level1Fields.MaxPrice, 1000000m) .TryAdd(Level1Fields.MarginBuy, 10000m) .TryAdd(Level1Fields.MarginSell, 10000m); // test portfolio var portfolio = new Portfolio { Name = "test account", BeginValue = 1000000, }; // create backtesting connector var connector = new HistoryEmulationConnector( new[] { security }, new[] { portfolio }) { MarketEmulator = { Settings = { // match order if historical price touched our limit order price. // It is terned off, and price should go through limit order price level // (more "severe" test mode) MatchOnTouch = false, } }, UseExternalCandleSource = emulationInfo.UseCandleTimeFrame != null, CreateDepthFromOrdersLog = emulationInfo.UseOrderLog, CreateTradesFromOrdersLog = emulationInfo.UseOrderLog, HistoryMessageAdapter = { StorageRegistry = storageRegistry, // set history range StartDate = startTime, StopDate = stopTime, }, // set market time freq as time frame MarketTimeChangedInterval = timeFrame, }; ((ILogSource)connector).LogLevel = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info; logManager.Sources.Add(connector); var candleManager = emulationInfo.UseCandleTimeFrame == null ? new CandleManager(new TradeCandleBuilderSourceEx(connector)) : new CandleManager(connector); var series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame); _shortMa = new SimpleMovingAverage { Length = 10 }; _shortElem = new ChartIndicatorElement { Color = Colors.Coral, ShowAxisMarker = false, FullTitle = _shortMa.ToString() }; _bufferedChart.AddElement(_area, _shortElem); _longMa = new SimpleMovingAverage { Length = 80 }; _longElem = new ChartIndicatorElement { ShowAxisMarker = false, FullTitle = _longMa.ToString() }; _bufferedChart.AddElement(_area, _longElem); // create strategy based on 80 5-min и 10 5-min var strategy = new SmaStrategy(_bufferedChart, _candlesElem, _tradesElem, _shortMa, _shortElem, _longMa, _longElem, series) { Volume = 1, Portfolio = portfolio, Security = security, Connector = connector, LogLevel = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info, // by default interval is 1 min, // it is excessively for time range with several months UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To <TimeSpan>() }; logManager.Sources.Add(strategy); connector.NewSecurities += securities => { if (securities.All(s => s != security)) { return; } // fill level1 values connector.SendInMessage(level1Info); if (emulationInfo.UseMarketDepth) { connector.RegisterMarketDepth(security); if ( // if order book will be generated generateDepths || // of backtesting will be on candles emulationInfo.UseCandleTimeFrame != TimeSpan.Zero ) { // if no have order book historical data, but strategy is required, // use generator based on last prices connector.RegisterMarketDepth(new TrendMarketDepthGenerator(connector.GetSecurityId(security)) { Interval = TimeSpan.FromSeconds(1), // order book freq refresh is 1 sec MaxAsksDepth = maxDepth, MaxBidsDepth = maxDepth, UseTradeVolume = true, MaxVolume = maxVolume, MinSpreadStepCount = 2, // min spread generation is 2 pips MaxSpreadStepCount = 5, // max spread generation size (prevent extremely size) MaxPriceStepCount = 3 // pips size, }); } } if (emulationInfo.UseOrderLog) { connector.RegisterOrderLog(security); } if (emulationInfo.UseTicks) { connector.RegisterTrades(security); } // start strategy before emulation started strategy.Start(); candleManager.Start(series); // start historical data loading when connection established successfully and all data subscribed connector.Start(); }; // fill parameters panel statistic.Parameters.Clear(); statistic.Parameters.AddRange(strategy.StatisticManager.Parameters); var pnlCurve = Curve.CreateCurve("P&L " + emulationInfo.StrategyName, emulationInfo.CurveColor, EquityCurveChartStyles.Area); var unrealizedPnLCurve = Curve.CreateCurve(LocalizedStrings.PnLUnreal + emulationInfo.StrategyName, Colors.Black); var commissionCurve = Curve.CreateCurve(LocalizedStrings.Str159 + " " + emulationInfo.StrategyName, Colors.Red, EquityCurveChartStyles.DashedLine); var posItems = PositionCurve.CreateCurve(emulationInfo.StrategyName, emulationInfo.CurveColor); strategy.PnLChanged += () => { var pnl = new EquityData { Time = strategy.CurrentTime, Value = strategy.PnL - strategy.Commission ?? 0 }; var unrealizedPnL = new EquityData { Time = strategy.CurrentTime, Value = strategy.PnLManager.UnrealizedPnL }; var commission = new EquityData { Time = strategy.CurrentTime, Value = strategy.Commission ?? 0 }; pnlCurve.Add(pnl); unrealizedPnLCurve.Add(unrealizedPnL); commissionCurve.Add(commission); }; strategy.PositionChanged += () => posItems.Add(new EquityData { Time = strategy.CurrentTime, Value = strategy.Position }); var nextTime = startTime + progressStep; // handle historical time for update ProgressBar connector.MarketTimeChanged += d => { if (connector.CurrentTime < nextTime && connector.CurrentTime < stopTime) { return; } var steps = (connector.CurrentTime - startTime).Ticks / progressStep.Ticks + 1; nextTime = startTime + (steps * progressStep.Ticks).To <TimeSpan>(); this.GuiAsync(() => progressBar.Value = steps); }; connector.StateChanged += () => { if (connector.State == EmulationStates.Stopped) { candleManager.Stop(series); strategy.Stop(); logManager.Dispose(); _connectors.Clear(); SetIsEnabled(false); this.GuiAsync(() => { if (connector.IsFinished) { progressBar.Value = progressBar.Maximum; MessageBox.Show(this, LocalizedStrings.Str3024.Put(DateTime.Now - _startEmulationTime)); } else { MessageBox.Show(this, LocalizedStrings.cancelled); } }); } else if (connector.State == EmulationStates.Started) { SetIsEnabled(true); } }; if (ShowDepth.IsChecked == true) { MarketDepth.UpdateFormat(security); connector.NewMessage += message => { var quoteMsg = message as QuoteChangeMessage; if (quoteMsg != null) { MarketDepth.UpdateDepth(quoteMsg); } }; } _connectors.Add(connector); progressBar.Value = 0; } _startEmulationTime = DateTime.Now; // start emulation foreach (var connector in _connectors) { // raise NewSecurities and NewPortfolio for full fill strategy properties connector.Connect(); // 1 cent commission for trade connector.SendInMessage(new CommissionRuleMessage { Rule = new CommissionPerTradeRule { Value = 0.01m } }); } TabControl.Items.Cast <TabItem>().First(i => i.Visibility == Visibility.Visible).IsSelected = true; }
public static void AddIndicators(ref DataSet ds, List <Indicator> listofIndicators, string timeStampforRenko = "") { bool macdInd = false; bool superTrend = false; bool rsi = false; bool sma20 = false; bool sma50 = false; bool sma200 = false; bool sma10 = false; bool sma30 = false; bool sma100 = false; bool renko = false; bool alligator = false; bool adx = false; //add columns foreach (Indicator ind in listofIndicators) { if (ind.IndicatorName == "SuperTrend") { superTrend = true; ds.Tables[0].Columns.Add("ATR7", typeof(double)); ds.Tables[0].Columns.Add("FinalUpperBand", typeof(double)); ds.Tables[0].Columns.Add("FinalLowerBand", typeof(double)); ds.Tables[0].Columns.Add("Trend", typeof(double)); ds.Tables[0].Columns.Add("SuperTrend", typeof(double)); ds.Tables[0].Columns.Add("ATR14", typeof(string)); } if (ind.IndicatorName == "MACD") { macdInd = true; ds.Tables[0].Columns.Add("macd", typeof(double)); ds.Tables[0].Columns.Add("macd9", typeof(double)); ds.Tables[0].Columns.Add("Histogram", typeof(double)); } if (ind.IndicatorName == "RSI") { rsi = true; ds.Tables[0].Columns.Add("RSI14", typeof(double)); } if (ind.IndicatorName == "SMA20") { sma20 = true; ds.Tables[0].Columns.Add("20", typeof(double)); } if (ind.IndicatorName == "SMA50") { sma50 = true; ds.Tables[0].Columns.Add("50", typeof(double)); } if (ind.IndicatorName == "SMA200") { sma200 = true; ds.Tables[0].Columns.Add("200", typeof(double)); } if (ind.IndicatorName == "SMA30") { sma30 = true; ds.Tables[0].Columns.Add("30", typeof(double)); } if (ind.IndicatorName == "SMA100") { sma100 = true; ds.Tables[0].Columns.Add("100", typeof(double)); } if (ind.IndicatorName == "SMA10") { sma10 = true; ds.Tables[0].Columns.Add("10", typeof(double)); } if (ind.IndicatorName == "RENKO") { renko = true; ds.Tables[0].Columns.Add("ATR", typeof(double)); ds.Tables[0].Columns.Add("RENKO", typeof(string)); } if (ind.IndicatorName == "ALLIGATOR") { alligator = true; ds.Tables[0].Columns.Add("L", typeof(double)); ds.Tables[0].Columns.Add("LOffset", typeof(double)); ds.Tables[0].Columns.Add("M", typeof(double)); ds.Tables[0].Columns.Add("MOffset", typeof(double)); ds.Tables[0].Columns.Add("S", typeof(double)); ds.Tables[0].Columns.Add("SOffset", typeof(double)); ds.Tables[0].Columns.Add("AC", typeof(double)); } if (ind.IndicatorName == "ADX") { adx = true; ds.Tables[0].Columns.Add("pDi", typeof(double)); ds.Tables[0].Columns.Add("mDi", typeof(double)); ds.Tables[0].Columns.Add("ADX", typeof(double)); } } //general int ii = 0; //super trend double avgTR = 0; double avgTRenko = 0; double basicUpperBand = 0; double basicLowerBand = 0; double smma = 0, sma = 0; double smma8 = 0, sma8 = 0; double smma5 = 0, sma5 = 0; //macd double pEMA9 = 0, pEMA12 = 0, pEMA26 = 0, macd = 0; IMovingAverage avg20 = new SimpleMovingAverage(20); IMovingAverage avg50 = new SimpleMovingAverage(50); IMovingAverage avg200 = new SimpleMovingAverage(200); IMovingAverage avg10 = new SimpleMovingAverage(10); IMovingAverage avg30 = new SimpleMovingAverage(30); IMovingAverage avg100 = new SimpleMovingAverage(100); IMovingAverage avg9 = new SimpleMovingAverage(9); IMovingAverage avg12 = new SimpleMovingAverage(12); IMovingAverage avg26 = new SimpleMovingAverage(26); IMovingAverage rsiGain14 = new SimpleMovingAverage(14); IMovingAverage rsiLoss14 = new SimpleMovingAverage(14); IMovingAverage avg5 = new SimpleMovingAverage(5); IMovingAverage avg34 = new SimpleMovingAverage(34); IMovingAverage avgAO5 = new SimpleMovingAverage(5); //alligator IMovingAverage avg13 = new SimpleMovingAverage(13); IMovingAverage avg8 = new SimpleMovingAverage(8); double[] close = new double[ds.Tables[0].Rows.Count]; double[] pDI = new double[ds.Tables[0].Rows.Count]; double[] mDI = new double[ds.Tables[0].Rows.Count]; double[] adxV = new double[ds.Tables[0].Rows.Count]; //calculate values foreach (DataRow dr in ds.Tables[0].Rows) { if (alligator) { avg5.AddSample((float)(Convert.ToDouble(dr["f3"]) + Convert.ToDouble(dr["f4"])) / 2); avg34.AddSample((float)(Convert.ToDouble(dr["f3"]) + Convert.ToDouble(dr["f4"])) / 2); avgAO5.AddSample(avg5.Average - avg34.Average); avg13.AddSample((float)(Convert.ToDouble(dr["f3"]) + Convert.ToDouble(dr["f4"])) / 2); avg8.AddSample((float)(Convert.ToDouble(dr["f3"]) + Convert.ToDouble(dr["f4"])) / 2); if (ii == 14) { sma = avg13.Average; dr["L"] = sma; } else if (ii > 14) { smma = (sma * 12 + ((Convert.ToDouble(dr["f3"]) + Convert.ToDouble(dr["f4"])) / 2)) / 13; dr["L"] = smma; sma = smma; } if (ii == 9) { sma8 = avg8.Average; dr["M"] = sma8; } else if (ii > 9) { smma8 = (sma8 * 7 + ((Convert.ToDouble(dr["f3"]) + Convert.ToDouble(dr["f4"])) / 2)) / 8; dr["M"] = smma8; sma8 = smma8; } if (ii == 6) { sma5 = avg5.Average; dr["S"] = sma5; } else if (ii > 6) { smma5 = (sma5 * 4 + ((Convert.ToDouble(dr["f3"]) + Convert.ToDouble(dr["f4"])) / 2)) / 5; dr["S"] = smma5; sma5 = smma5; } if (ii >= 9) { dr["LOffset"] = ds.Tables[0].Rows[ii - 9]["L"]; } if (ii >= 6) { dr["MOffset"] = ds.Tables[0].Rows[ii - 6]["M"]; } if (ii >= 4) { dr["SOffset"] = ds.Tables[0].Rows[ii - 4]["S"]; } dr["AC"] = (avg5.Average - avg34.Average) - avgAO5.Average; } if (renko) { if (ii == 13) { avgTRenko = Math.Max(Math.Max(Convert.ToDouble(ds.Tables[0].Rows[ii]["f3"]) - Convert.ToDouble(ds.Tables[0].Rows[ii]["f4"]), Math.Abs(Convert.ToDouble(ds.Tables[0].Rows[ii]["f3"]) - Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]))), Math.Abs(Convert.ToDouble(ds.Tables[0].Rows[ii]["f4"]) - Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]))); dr["ATR"] = avgTRenko / 14; } else if (ii > 13) { dr["ATR"] = (Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["ATR"]) * 13 + avgTRenko) / 14; avgTRenko = Math.Max(Math.Max(Convert.ToDouble(ds.Tables[0].Rows[ii]["f3"]) - Convert.ToDouble(ds.Tables[0].Rows[ii]["f4"]), Math.Abs(Convert.ToDouble(ds.Tables[0].Rows[ii]["f3"]) - Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]))), Math.Abs(Convert.ToDouble(ds.Tables[0].Rows[ii]["f4"]) - Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]))); } else if (ii > 0) { avgTR = avgTR + Math.Max(Math.Max(Convert.ToDouble(ds.Tables[0].Rows[ii]["f3"]) - Convert.ToDouble(ds.Tables[0].Rows[ii]["f4"]), Math.Abs(Convert.ToDouble(ds.Tables[0].Rows[ii]["f3"]) - Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]))), Math.Abs(Convert.ToDouble(ds.Tables[0].Rows[ii]["f4"]) - Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]))); } else { avgTR = 0; } } if (true) { if (ii == 13) { avgTR = Math.Max(Math.Max(Convert.ToDouble(ds.Tables[0].Rows[ii]["f3"]) - Convert.ToDouble(ds.Tables[0].Rows[ii]["f4"]), Math.Abs(Convert.ToDouble(ds.Tables[0].Rows[ii]["f3"]) - Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]))), Math.Abs(Convert.ToDouble(ds.Tables[0].Rows[ii]["f4"]) - Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]))); dr["ATR14"] = avgTR / 14; } else if (ii > 13) { avgTR = Math.Max(Math.Max(Convert.ToDouble(ds.Tables[0].Rows[ii]["f3"]) - Convert.ToDouble(ds.Tables[0].Rows[ii]["f4"]), Math.Abs(Convert.ToDouble(ds.Tables[0].Rows[ii]["f3"]) - Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]))), Math.Abs(Convert.ToDouble(ds.Tables[0].Rows[ii]["f4"]) - Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]))); dr["ATR14"] = (Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["ATR7"]) * 13 + avgTR) / 14; } else { dr["ATR14"] = 0; if (ii > 0) { avgTR = avgTR + Math.Max(Math.Max(Convert.ToDouble(ds.Tables[0].Rows[ii]["f3"]) - Convert.ToDouble(ds.Tables[0].Rows[ii]["f4"]), Math.Abs(Convert.ToDouble(ds.Tables[0].Rows[ii]["f3"]) - Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]))), Math.Abs(Convert.ToDouble(ds.Tables[0].Rows[ii]["f4"]) - Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]))); } else { avgTR = 0; } } } if (superTrend) { if (ii == 6) { avgTR = Math.Max(Math.Max(Convert.ToDouble(ds.Tables[0].Rows[ii]["f3"]) - Convert.ToDouble(ds.Tables[0].Rows[ii]["f4"]), Math.Abs(Convert.ToDouble(ds.Tables[0].Rows[ii]["f3"]) - Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]))), Math.Abs(Convert.ToDouble(ds.Tables[0].Rows[ii]["f4"]) - Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]))); dr["ATR7"] = avgTR / 7; basicUpperBand = ((Convert.ToDouble(dr["f3"]) + Convert.ToDouble(dr["f4"])) / 2) - (Convert.ToDouble(dr["ATR7"]) * 3); basicLowerBand = ((Convert.ToDouble(dr["f3"]) + Convert.ToDouble(dr["f4"])) / 2) + (Convert.ToDouble(dr["ATR7"]) * 3); //basicUpperBand < Convert.ToDouble(ds.Tables[0].Rows[xI - 1]["FinalUpperBand"]) || if (Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]) > Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["FinalUpperBand"])) { dr["FinalUpperBand"] = Math.Max(basicUpperBand, Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["FinalUpperBand"])); } else { dr["FinalUpperBand"] = basicUpperBand; } //basicLowerBand > Convert.ToDouble(ds.Tables[0].Rows[xI - 1]["FinalLowerBand"]) || if (Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]) < Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["FinalLowerBand"])) { dr["FinalLowerBand"] = Math.Min(basicLowerBand, Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["FinalLowerBand"]));; } else { dr["FinalLowerBand"] = basicLowerBand; } double trend = Convert.ToDouble(ds.Tables[0].Rows[ii]["f2"]) > Convert.ToDouble(dr["FinalLowerBand"]) ? 1 : (Convert.ToDouble(ds.Tables[0].Rows[ii]["f2"]) < Convert.ToDouble(dr["FinalUpperBand"]) ? -1 : Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["Trend"])); if (trend == 1) { dr["SuperTrend"] = dr["FinalUpperBand"]; } else { dr["SuperTrend"] = dr["FinalLowerBand"]; } dr["trend"] = trend; } else if (ii > 6) { avgTR = Math.Max(Math.Max(Convert.ToDouble(ds.Tables[0].Rows[ii]["f3"]) - Convert.ToDouble(ds.Tables[0].Rows[ii]["f4"]), Math.Abs(Convert.ToDouble(ds.Tables[0].Rows[ii]["f3"]) - Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]))), Math.Abs(Convert.ToDouble(ds.Tables[0].Rows[ii]["f4"]) - Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]))); dr["ATR7"] = (Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["ATR7"]) * 6 + avgTR) / 7; basicUpperBand = ((Convert.ToDouble(dr["f3"]) + Convert.ToDouble(dr["f4"])) / 2) - (Convert.ToDouble(dr["ATR7"]) * 3); basicLowerBand = ((Convert.ToDouble(dr["f3"]) + Convert.ToDouble(dr["f4"])) / 2) + (Convert.ToDouble(dr["ATR7"]) * 3); //basicUpperBand < Convert.ToDouble(ds.Tables[0].Rows[xI - 1]["FinalUpperBand"]) || if (Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]) > Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["FinalUpperBand"])) { dr["FinalUpperBand"] = Math.Max(basicUpperBand, Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["FinalUpperBand"])); } else { dr["FinalUpperBand"] = basicUpperBand; } //basicLowerBand > Convert.ToDouble(ds.Tables[0].Rows[xI - 1]["FinalLowerBand"]) || if (Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]) < Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["FinalLowerBand"])) { dr["FinalLowerBand"] = Math.Min(basicLowerBand, Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["FinalLowerBand"]));; } else { dr["FinalLowerBand"] = basicLowerBand; } double trend = Convert.ToDouble(ds.Tables[0].Rows[ii]["f2"]) > Convert.ToDouble(dr["FinalLowerBand"]) ? 1 : (Convert.ToDouble(ds.Tables[0].Rows[ii]["f2"]) < Convert.ToDouble(dr["FinalUpperBand"]) ? -1 : Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["Trend"])); if (trend == 1) { dr["SuperTrend"] = dr["FinalUpperBand"]; } else { dr["SuperTrend"] = dr["FinalLowerBand"]; } dr["trend"] = trend; } else { dr["ATR7"] = 0; dr["FinalUpperBand"] = 0; dr["FinalLowerBand"] = 0; dr["SuperTrend"] = 0; dr["Trend"] = 1; if (ii > 0) { avgTR = avgTR + Math.Max(Math.Max(Convert.ToDouble(ds.Tables[0].Rows[ii]["f3"]) - Convert.ToDouble(ds.Tables[0].Rows[ii]["f4"]), Math.Abs(Convert.ToDouble(ds.Tables[0].Rows[ii]["f3"]) - Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]))), Math.Abs(Convert.ToDouble(ds.Tables[0].Rows[ii]["f4"]) - Convert.ToDouble(ds.Tables[0].Rows[ii - 1]["f2"]))); } else { avgTR = 0; } } } ii++; if (macdInd) { if (ii == 13) { pEMA12 = avg12.Average; } else if (ii > 13) { double ema = 0.153 * (Convert.ToDouble(dr["f2"]) - pEMA12) + pEMA12; pEMA12 = ema; } if (ii == 27) { pEMA26 = avg26.Average; } else if (ii > 27) { double ema = 0.074 * (Convert.ToDouble(dr["f2"]) - pEMA26) + pEMA26; pEMA26 = ema; macd = pEMA12 - pEMA26; } if (ii == 37) { pEMA9 = avg9.Average; } else if (ii > 37) { double ema = 0.2 * (macd - pEMA9) + pEMA9; pEMA9 = ema; } if (ii > 27 && ii < 37) { avg9.AddSample((float)(macd)); } avg12.AddSample((float)Convert.ToDouble(dr["f2"])); avg26.AddSample((float)Convert.ToDouble(dr["f2"])); dr["macd"] = macd; dr["macd9"] = pEMA9; dr["Histogram"] = macd - pEMA9; } if (rsi) { dr["rsi14"] = 0; if (ii > 1) { if ((double)dr["f2"] > (double)ds.Tables[0].Rows[ii - 2]["f2"]) { rsiGain14.AddSample((float)((double)dr["f2"] - (double)ds.Tables[0].Rows[ii - 2]["f2"])); rsiLoss14.AddSample(0); } else if ((double)ds.Tables[0].Rows[ii - 2]["f2"] > (double)dr["f2"]) { rsiLoss14.AddSample((float)((double)ds.Tables[0].Rows[ii - 2]["f2"] - (double)dr["f2"])); rsiGain14.AddSample(0); } else { rsiGain14.AddSample(0); rsiLoss14.AddSample(0); } dr["rsi14"] = 100 - (100 / (1 + (rsiGain14.Average / rsiLoss14.Average))); } } if (sma10) { avg10.AddSample((float)Convert.ToDouble(dr["f2"])); dr["10"] = avg10.Average; } if (sma30) { avg30.AddSample((float)Convert.ToDouble(dr["f2"])); dr["30"] = avg30.Average; } if (sma100) { avg100.AddSample((float)Convert.ToDouble(dr["f2"])); dr["100"] = avg100.Average; } if (sma20) { avg20.AddSample((float)Convert.ToDouble(dr["f2"])); dr["20"] = avg20.Average; } if (sma50) { avg50.AddSample((float)Convert.ToDouble(dr["f2"])); dr["50"] = avg50.Average; } if (sma200) { avg200.AddSample((float)Convert.ToDouble(dr["f2"])); dr["200"] = avg200.Average; } } if (renko) { string Direction = string.Empty; double renkoStartPrice = 0; double negativeMovementValue = 0; double positiveMovementValue = 0; double boxSize = Convert.ToDouble(ds.Tables[0].Select("TimeStamp='" + timeStampforRenko + "'")[0]["ATR"]); foreach (DataRow dr in ds.Tables[0].Rows) { if (Direction == string.Empty && dr["Candle"].ToString() == "R") { Direction = "S"; renkoStartPrice = Convert.ToDouble(dr["f2"]); } if (Direction == string.Empty && dr["Candle"].ToString() == "G") { Direction = "B"; renkoStartPrice = Convert.ToDouble(dr["f2"]); } if (Direction == "S") { if (negativeMovementValue == 0) { negativeMovementValue = renkoStartPrice + 2 * boxSize; positiveMovementValue = renkoStartPrice - boxSize; } } else if (Direction == "B") { if (positiveMovementValue == 0) { negativeMovementValue = renkoStartPrice - 2 * boxSize; positiveMovementValue = renkoStartPrice + boxSize; } } if (Direction == "S") { if (Convert.ToDouble(dr["f2"]) <= positiveMovementValue) { dr["RENKO"] = "R"; negativeMovementValue = negativeMovementValue - boxSize; positiveMovementValue = positiveMovementValue - boxSize; } else if (Convert.ToDouble(dr["f2"]) >= negativeMovementValue) { if (Convert.ToDouble(dr["f2"]) >= negativeMovementValue + boxSize) { dr["RENKO"] = "MG"; } else { dr["RENKO"] = "G"; } Direction = "B"; negativeMovementValue = negativeMovementValue - boxSize - boxSize; positiveMovementValue = positiveMovementValue + boxSize + boxSize + boxSize + boxSize; } else { dr["RENKO"] = "R"; } } else if (Direction == "B") { if (Convert.ToDouble(dr["f2"]) >= positiveMovementValue) { dr["RENKO"] = "G"; negativeMovementValue = negativeMovementValue + boxSize; positiveMovementValue = positiveMovementValue + boxSize; } else if (Convert.ToDouble(dr["f2"]) <= negativeMovementValue) { if (Convert.ToDouble(dr["f2"]) <= negativeMovementValue - boxSize) { dr["RENKO"] = "MR"; } else { dr["RENKO"] = "R"; } Direction = "S"; dr["RENKO"] = "R"; negativeMovementValue = negativeMovementValue + boxSize + boxSize; positiveMovementValue = positiveMovementValue - boxSize - boxSize - boxSize - boxSize; } else { dr["RENKO"] = "G"; } } } } //accept changes ds.Tables[0].AcceptChanges(); //remove columns if (superTrend) { ds.Tables[0].Columns.Remove("ATR7"); ds.Tables[0].Columns.Remove("FinalUpperBand"); ds.Tables[0].Columns.Remove("FinalLowerBand"); } if (macdInd) { //ds.Tables[0].Columns.Remove("macd"); //ds.Tables[0].Columns.Remove("macd9"); } }
public override void Initialize() { UniverseSettings.DataNormalizationMode = DataNormalizationMode.Raw; EnableAutomaticIndicatorWarmUp = true; SetStartDate(2013, 10, 07); SetEndDate(2013, 10, 09); var SP500 = QuantConnect.Symbol.Create(Futures.Indices.SP500EMini, SecurityType.Future, Market.CME); _symbol = FutureChainProvider.GetFutureContractList(SP500, StartDate).First(); // Test case: custom IndicatorBase<QuoteBar> indicator using Future unsubscribed symbol var indicator1 = new CustomIndicator(); AssertIndicatorState(indicator1, isReady: false); WarmUpIndicator(_symbol, indicator1); AssertIndicatorState(indicator1, isReady: true); // Test case: SimpleMovingAverage<IndicatorDataPoint> using Future unsubscribed symbol (should use TradeBar) var sma1 = new SimpleMovingAverage(10); AssertIndicatorState(sma1, isReady: false); WarmUpIndicator(_symbol, sma1); AssertIndicatorState(sma1, isReady: true); // Test case: SimpleMovingAverage<IndicatorDataPoint> using Equity unsubscribed symbol var spy = QuantConnect.Symbol.Create("SPY", SecurityType.Equity, Market.USA); var sma = new SimpleMovingAverage(10); AssertIndicatorState(sma, isReady: false); WarmUpIndicator(spy, sma); AssertIndicatorState(sma, isReady: true); // We add the symbol AddFutureContract(_symbol); AddEquity("SPY"); // force spy for use Raw data mode so that it matches the used when unsubscribed which uses the universe settings SubscriptionManager.SubscriptionDataConfigService.GetSubscriptionDataConfigs(spy).SetDataNormalizationMode(DataNormalizationMode.Raw); // Test case: custom IndicatorBase<QuoteBar> indicator using Future subscribed symbol var indicator = new CustomIndicator(); var consolidator = CreateConsolidator(TimeSpan.FromMinutes(1), typeof(QuoteBar)); RegisterIndicator(_symbol, indicator, consolidator); AssertIndicatorState(indicator, isReady: false); WarmUpIndicator(_symbol, indicator); AssertIndicatorState(indicator, isReady: true); // Test case: SimpleMovingAverage<IndicatorDataPoint> using Future Subscribed symbol (should use TradeBar) var sma11 = new SimpleMovingAverage(10); AssertIndicatorState(sma11, isReady: false); WarmUpIndicator(_symbol, sma11); AssertIndicatorState(sma11, isReady: true); if (!sma11.Current.Equals(sma1.Current)) { throw new Exception("Expected SMAs warmed up before and after adding the Future to the algorithm to have the same current value. " + "The result of 'WarmUpIndicator' shouldn't change if the symbol is or isn't subscribed"); } // Test case: SimpleMovingAverage<IndicatorDataPoint> using Equity unsubscribed symbol var smaSpy = new SimpleMovingAverage(10); AssertIndicatorState(smaSpy, isReady: false); WarmUpIndicator(spy, smaSpy); AssertIndicatorState(smaSpy, isReady: true); if (!smaSpy.Current.Equals(sma.Current)) { throw new Exception("Expected SMAs warmed up before and after adding the Equity to the algorithm to have the same current value. " + "The result of 'WarmUpIndicator' shouldn't change if the symbol is or isn't subscribed"); } }
/// <summary> /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized. /// </summary> public override void Initialize() { SetStartDate(2013, 10, 08); //Set Start Date SetEndDate(2013, 10, 11); //Set End Date SetCash(100000); //Set Strategy Cash // Find more symbols here: http://quantconnect.com/data AddSecurity(SecurityType.Equity, "SPY", Resolution.Daily); AddData <QuandlFuture>("CHRIS/CME_SP1", Resolution.Daily); // specifying the exchange will allow the history methods that accept a number of bars to return to work properly Securities["CHRIS/CME_SP1"].Exchange = new EquityExchange(); // we can get history in initialize to set up indicators and such spyDailySma = new SimpleMovingAverage(14); // get the last calendar year's worth of SPY data at the configured resolution (daily) var tradeBarHistory = History <TradeBar>("SPY", TimeSpan.FromDays(365)); AssertHistoryCount("History<TradeBar>(\"SPY\", TimeSpan.FromDays(365))", tradeBarHistory, 250); // get the last calendar day's worth of SPY data at the specified resolution tradeBarHistory = History <TradeBar>("SPY", TimeSpan.FromDays(1), Resolution.Minute); AssertHistoryCount("History<TradeBar>(\"SPY\", TimeSpan.FromDays(1), Resolution.Minute)", tradeBarHistory, 390); // get the last 14 bars of SPY at the configured resolution (daily) tradeBarHistory = History <TradeBar>("SPY", 14).ToList(); AssertHistoryCount("History<TradeBar>(\"SPY\", 14)", tradeBarHistory, 14); // get the last 14 minute bars of SPY tradeBarHistory = History <TradeBar>("SPY", 14, Resolution.Minute); AssertHistoryCount("History<TradeBar>(\"SPY\", 14, Resolution.Minute)", tradeBarHistory, 14); // we can loop over the return value from these functions and we get TradeBars // we can use these TradeBars to initialize indicators or perform other math foreach (TradeBar tradeBar in tradeBarHistory) { spyDailySma.Update(tradeBar.EndTime, tradeBar.Close); } // get the last calendar year's worth of quandl data at the configured resolution (daily) var quandlHistory = History <QuandlFuture>("CHRIS/CME_SP1", TimeSpan.FromDays(365)); AssertHistoryCount("History<Quandl>(\"CHRIS/CME_SP1\", TimeSpan.FromDays(365))", quandlHistory, 250); // get the last 14 bars of SPY at the configured resolution (daily) quandlHistory = History <QuandlFuture>("CHRIS/CME_SP1", 14); AssertHistoryCount("History<Quandl>(\"CHRIS/CME_SP1\", 14)", quandlHistory, 14); // get the last 14 minute bars of SPY // we can loop over the return values from these functions and we'll get Quandl data // this can be used in much the same way as the tradeBarHistory above spyDailySma.Reset(); foreach (QuandlFuture quandl in quandlHistory) { spyDailySma.Update(quandl.EndTime, quandl.Value); } // get the last year's worth of all configured Quandl data at the configured resolution (daily) var allQuandlData = History <QuandlFuture>(TimeSpan.FromDays(365)); AssertHistoryCount("History<QuandlFuture>(TimeSpan.FromDays(365))", allQuandlData, 250); // get the last 14 bars worth of Quandl data for the specified symbols at the configured resolution (daily) allQuandlData = History <QuandlFuture>(Securities.Keys, 14); AssertHistoryCount("History<QuandlFuture>(Securities.Keys, 14)", allQuandlData, 14); // NOTE: using different resolutions require that they are properly implemented in your data type, since // Quandl doesn't support minute data, this won't actually work, but if your custom data source has // different resolutions, it would need to be implemented in the GetSource and Reader methods properly //quandlHistory = History<QuandlFuture>("CHRIS/CME_SP1", TimeSpan.FromDays(7), Resolution.Minute); //quandlHistory = History<QuandlFuture>("CHRIS/CME_SP1", 14, Resolution.Minute); //allQuandlData = History<QuandlFuture>(TimeSpan.FromDays(365), Resolution.Minute); //allQuandlData = History<QuandlFuture>(Securities.Keys, 14, Resolution.Minute); //allQuandlData = History<QuandlFuture>(Securities.Keys, TimeSpan.FromDays(1), Resolution.Minute); //allQuandlData = History<QuandlFuture>(Securities.Keys, 14, Resolution.Minute); // get the last calendar year's worth of all quandl data allQuandlData = History <QuandlFuture>(Securities.Keys, TimeSpan.FromDays(365)); AssertHistoryCount("History<QuandlFuture>(Securities.Keys, TimeSpan.FromDays(365))", allQuandlData, 250); // the return is a series of dictionaries containing all quandl data at each time // we can loop over it to get the individual dictionaries foreach (DataDictionary <QuandlFuture> quandlsDataDictionary in allQuandlData) { // we can access the dictionary to get the quandl data we want var quandl = quandlsDataDictionary["CHRIS/CME_SP1"]; } // we can also access the return value from the multiple symbol functions to request a single // symbol and then loop over it var singleSymbolQuandl = allQuandlData.Get("CHRIS/CME_SP1"); AssertHistoryCount("allQuandlData.Get(\"CHRIS/CME_SP1\")", singleSymbolQuandl, 250); foreach (QuandlFuture quandl in singleSymbolQuandl) { // do something with 'CHRIS/CME_SP1' quandl data } // we can also access individual properties on our data, this will // get the 'CHRIS/CME_SP1' quandls like above, but then only return the Low properties var quandlSpyLows = allQuandlData.Get("CHRIS/CME_SP1", "Low"); AssertHistoryCount("allQuandlData.Get(\"CHRIS/CME_SP1\", \"Low\")", quandlSpyLows, 250); foreach (decimal low in quandlSpyLows) { // do something we each low value } // sometimes it's necessary to get the history for many configured symbols // request the last year's worth of history for all configured symbols at their configured resolutions var allHistory = History(TimeSpan.FromDays(365)); AssertHistoryCount("History(TimeSpan.FromDays(365))", allHistory, 250); // request the last days's worth of history at the minute resolution allHistory = History(TimeSpan.FromDays(1), Resolution.Minute); AssertHistoryCount("History(TimeSpan.FromDays(1), Resolution.Minute)", allHistory, 391); // request the last 100 bars for the specified securities at the configured resolution allHistory = History(Securities.Keys, 100); AssertHistoryCount("History(Securities.Keys, 100)", allHistory, 100); // request the last 100 minute bars for the specified securities allHistory = History(Securities.Keys, 100, Resolution.Minute); AssertHistoryCount("History(Securities.Keys, 100, Resolution.Minute)", allHistory, 101); // request the last calendar years worth of history for the specified securities allHistory = History(Securities.Keys, TimeSpan.FromDays(365)); AssertHistoryCount("History(Securities.Keys, TimeSpan.FromDays(365))", allHistory, 250); // we can also specify the resolutin allHistory = History(Securities.Keys, TimeSpan.FromDays(1), Resolution.Minute); AssertHistoryCount("History(Securities.Keys, TimeSpan.FromDays(1), Resolution.Minute)", allHistory, 391); // if we loop over this allHistory, we get Slice objects foreach (Slice slice in allHistory) { // do something with each slice, these will come in time order // and will NOT have auxilliary data, just price data and your custom data // if those symbols were specified } // we can access the history for individual symbols from the all history by specifying the symbol // the type must be a trade bar! tradeBarHistory = allHistory.Get <TradeBar>("SPY"); AssertHistoryCount("allHistory.Get(\"SPY\")", tradeBarHistory, 390); // we can access all the closing prices in chronological order using this get function var closeHistory = allHistory.Get("SPY", Field.Close); AssertHistoryCount("allHistory.Get(\"SPY\", Field.Close)", closeHistory, 390); foreach (decimal close in closeHistory) { // do something with each closing value in order } // we can convert the close history into your normal double array (double[]) using the ToDoubleArray method double[] doubleArray = closeHistory.ToDoubleArray(); }
/// <summary> /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized. /// </summary> public override void Initialize() { SetStartDate(2013, 10, 08); SetEndDate(2013, 10, 09); var SP500 = QuantConnect.Symbol.Create(Futures.Indices.SP500EMini, SecurityType.Future, Market.USA); _symbol = FutureChainProvider.GetFutureContractList(SP500, StartDate).First(); AddFutureContract(_symbol); _consolidationCount = new List <int> { 0, 0, 0, 0, 0, 0, 0, 0 }; var sma = new SimpleMovingAverage(10); Consolidate <QuoteBar>(_symbol, time => new CalendarInfo(time.RoundDown(TimeSpan.FromDays(1)), TimeSpan.FromDays(1)), bar => UpdateQuoteBar(sma, bar, 0)); var sma2 = new SimpleMovingAverage(10); Consolidate <QuoteBar>(_symbol, TimeSpan.FromDays(1), bar => UpdateQuoteBar(sma2, bar, 1)); var sma3 = new SimpleMovingAverage(10); Consolidate(_symbol, Resolution.Daily, TickType.Quote, (Action <QuoteBar>)(bar => UpdateQuoteBar(sma3, bar, 2))); var sma4 = new SimpleMovingAverage(10); Consolidate(_symbol, TimeSpan.FromDays(1), bar => UpdateTradeBar(sma4, bar, 3)); var sma5 = new SimpleMovingAverage(10); Consolidate <TradeBar>(_symbol, TimeSpan.FromDays(1), bar => UpdateTradeBar(sma5, bar, 4)); // custom data var sma6 = new SimpleMovingAverage(10); var symbol = AddData <CustomDataRegressionAlgorithm.Bitcoin>("BTC", Resolution.Minute).Symbol; Consolidate <TradeBar>(symbol, TimeSpan.FromDays(1), bar => _customDataConsolidator++); try { Consolidate <QuoteBar>(symbol, TimeSpan.FromDays(1), bar => { UpdateQuoteBar(sma6, bar, -1); }); throw new Exception($"Expected {nameof(ArgumentException)} to be thrown"); } catch (ArgumentException) { // will try to use BaseDataConsolidator for which input is TradeBars not QuoteBars } // Test using abstract T types, through defining a 'BaseData' handler var sma7 = new SimpleMovingAverage(10); Consolidate(_symbol, Resolution.Daily, null, (Action <BaseData>)(bar => UpdateBar(sma7, bar, 5))); var sma8 = new SimpleMovingAverage(10); Consolidate(_symbol, TimeSpan.FromDays(1), null, (Action <BaseData>)(bar => UpdateBar(sma8, bar, 6))); var sma9 = new SimpleMovingAverage(10); Consolidate(_symbol, TimeSpan.FromDays(1), (Action <BaseData>)(bar => UpdateBar(sma9, bar, 7))); }
private void UpdateQuoteBar(SimpleMovingAverage sma, QuoteBar quoteBar, int position) { _consolidationCount[position]++; sma.Update(quoteBar.EndTime, quoteBar.High); }
protected override ISignal CreateIndicator(Symbol pair, int i, string entryOrExit) { var key = entryOrExit + "Indicator" + i + "Direction"; var intDirection = GetConfigValue(key); var direction = intDirection == 0 || intDirection == 1 ? Direction.LongOnly : Direction.ShortOnly; key = entryOrExit + "Indicator" + i; var indicator = (TechnicalIndicator)GetConfigValue(key); ISignal signal = null; switch (indicator) { case TechnicalIndicator.SimpleMovingAverage: var fast = _algorithm.SMA(pair, _ignorePeriod ? 50 : _period, _resolution); var slow = _algorithm.SMA(pair, _ignorePeriod ? 200 : _period, _resolution); signal = new CrossingMovingAverageSignal(fast, slow, direction); break; case TechnicalIndicator.MovingAverageConvergenceDivergence: var macd = _algorithm.MACD(pair, _ignorePeriod ? 12 : _fastPeriod, _ignorePeriod ? 26 : _slowPeriod, _ignorePeriod ? 9 : _signalPeriod, MovingAverageType.Simple, _resolution); signal = new CrossingMovingAverageSignal(macd, macd.Signal, direction); break; case TechnicalIndicator.Stochastic: var sto = _algorithm.STO(pair, _ignorePeriod ? 14 : _period, _resolution); signal = new OscillatorSignal(sto, direction, _enableSurvival ? 3 : 1); break; case TechnicalIndicator.RelativeStrengthIndex: var rsi = _algorithm.RSI(pair, _ignorePeriod ? 11 : _period); signal = new OscillatorSignal(rsi, new[] { 30, 70 }, direction); break; case TechnicalIndicator.CommodityChannelIndex: var cci = _algorithm.CCI(pair, _ignorePeriod ? 20 : _period, MovingAverageType.Simple, _resolution); signal = new OscillatorSignal(cci, new[] { -100, 100 }, direction); break; case TechnicalIndicator.MomentumPercent: var pm = _algorithm.MOMP(pair, _ignorePeriod ? 60 : _period, _resolution); signal = new OscillatorSignal(pm, new[] { -5, 5 }, direction); break; case TechnicalIndicator.WilliamsPercentR: var wr = _algorithm.WILR(pair, _ignorePeriod ? 14 : _period, _resolution); signal = new OscillatorSignal(wr, new[] { -20, -80 }, direction); break; case TechnicalIndicator.PercentagePriceOscillator: var ppo = _algorithm.MACD(pair, _ignorePeriod ? 12 : _fastPeriod, _ignorePeriod ? 26 : _slowPeriod, _ignorePeriod ? 9 : _signalPeriod, MovingAverageType.Simple, _resolution) .Over(_algorithm.EMA(pair, _ignorePeriod ? 120 : _period, resolution: _resolution)).Plus(constant: 100m); var compound = new SimpleMovingAverage(_ignorePeriod ? 120 : _period).Of(ppo); signal = new CrossingMovingAverageSignal(ppo, compound, direction); break; case TechnicalIndicator.None: signal = new EmptySignal(); break; case TechnicalIndicator.AverageDirectionalIndex: var adx = _algorithm.ADX(pair, _ignorePeriod ? 20 : _period, _resolution); signal = new OscillatorSignal(adx, new[] { 25, 25 }, direction); break; //todo: case TechnicalIndicator.NormalizedAverageTrueRange: var natr = _algorithm.NATR(pair, _ignorePeriod ? 20 : _period, _resolution); signal = new OscillatorSignal(natr, new[] { 1, 1 }, direction); break; case TechnicalIndicator.BollingerBands: var bb = _algorithm.BB(pair, _ignorePeriod ? 20 : _period, k: 2); signal = new BBOscillatorSignal(bb, direction, _enableSurvival ? 4 : 1); break; case TechnicalIndicator.ExponentialMovingAverage: var fastema = _algorithm.EMA(pair, _ignorePeriod ? 50 : _fastPeriod); var slowema = _algorithm.EMA(pair, _ignorePeriod ? 200 : _slowPeriod); signal = new CrossingMovingAverageSignal(fastema, slowema, direction); break; case TechnicalIndicator.ChannelBreakout: var delay = new Delay(5); var _max = delay.Of(_algorithm.MAX(pair, _ignorePeriod ? 20 : _period)); var _min = delay.Of(_algorithm.MIN(pair, _ignorePeriod ? 20 : _period)); var cur = _algorithm.MAX(pair, 1); //current value signal = new ChannelOscillatorSignal(cur, _max, _min, direction, _enableSurvival ? 4 : 1); break; case TechnicalIndicator.DonchianTrend: var donchian = _algorithm.DCH(pair, _ignorePeriod ? 20 : _period); var max = _algorithm.MAX(pair, _ignorePeriod ? 1 : _period); signal = new DonchianSignal(max, donchian, 2, direction); break; } signal.Name = indicator.ToString(); return(signal); }
public static TimelineResponse GetTimeline(TimelineRequest request, List <CmdrStats> cmdrstats) { if (request.Step < 3) { request.Step = 3; } if (request.smaK < 3) { request.smaK = 3; } var stats = GetTimeStats(request, cmdrstats); int tcount = stats.Sum(s => s.count); TimelineResponse response = new TimelineResponse() { Interest = request.Interest, Count = request.Player ? tcount : tcount / 6, Versus = request.Versus, AvgDuration = tcount == 0 ? 0 : (int)(stats.Sum(s => s.duration) / tcount), Items = new List <DsResponseItem>() }; DateTime requestTime = request.StartTime; while (requestTime < request.EndTime) { var timeResults = stats.Where(f => f.year == requestTime.Year && f.month == requestTime.Month && f.RACE == (byte)DSData.GetCommander(request.Interest)); if (!timeResults.Any()) { response.Items.Add(new TimelineResponseItem() { Label = $"{requestTime.ToString("yyyy-MM")} (0)", Count = 0, Wins = 0 }); } else { int ccount = timeResults.Sum(s => s.count); response.Items.Add(new TimelineResponseItem() { Label = $"{requestTime.ToString("yyyy-MM")} ({ccount})", Count = ccount, Wins = timeResults.Sum(s => s.wins) }); } requestTime = requestTime.AddMonths(1); } if (response.Items.Any() && response.Items.Last().Count < 10) { response.Items.RemoveAt(response.Items.Count - 1); } var sma = new SimpleMovingAverage(request.smaK); response.SmaData = new List <double>(); response.SmaData = GetNiceLineData(response.Items.Select(s => s.Count == 0 ? 0 : ((double)s.Wins * 100.0 / (double)s.Count)), request.smaK); return(response); }
/// <summary> /// Executes the Instant Trend strategy /// </summary> /// <param name="data">TradeBars - the current OnData</param> /// <param name="tradesize"></param> /// <param name="trendCurrent">IndicatorDataPoint - the current trend value trend</param> /// <param name="orderId">int - the orderId if one is placed, -1 if order has not filled and 0 if no order was placed</param> public string ExecuteStrategy(TradeBars data, int tradesize, IndicatorDataPoint max, IndicatorDataPoint min, RateOfChangePercent rocp, ref SimpleMovingAverage sma20, out int orderId) { maximum = max; minimum = min; Price.Add(idp(data[_symbol].EndTime, (data[_symbol].Close + data[_symbol].Open) / 2)); orderId = 0; comment = string.Empty; if (_algorithm.Portfolio[_symbol].IsLong) { nStatus = 1; } if (_algorithm.Portfolio[_symbol].IsShort) { nStatus = -1; } #region "Strategy Execution" bReverseTrade = false; try { if (!_algorithm.Portfolio.Invested) { if (PricePassedAValley() && rocp.Current.Value < 0) { ticket = GetLong(tradesize); orderId = ticket.OrderId; comment = "Bot new position ppMin && rocp < 0"; } if (PricePassedAPeak() && rocp.Current.Value > 0) { ticket = GetShort(tradesize); orderId = ticket.OrderId; comment = "Sld new position ppMin && rocp < 0"; } } else { if (PricePassedAValley() && _algorithm.Portfolio[_symbol].IsShort) { if (Price[0].Value > sma20.Current.Value && (Math.Abs(sma20.Current.Value - Price[0].Value) / Price[0].Value) > .001m) { ticket = ReverseToLong(); comment = "Rev2Long Passed a Valley"; } } if (PricePassedAPeak() && _algorithm.Portfolio[_symbol].IsLong) { if (Price[0].Value <sma20.Current.Value && (Math.Abs(sma20.Current.Value - Price[0].Value) / Price[0].Value)> .001m) { ticket = ReverseToShort(); comment = "Rev2Short Passed a Peak"; } } } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.StackTrace); } #endregion return(comment); }
public void Generate(AudioTrack track) { IAudioStream audioStream = new ResamplingStream( new MonoStream(AudioStreamFactory.FromFileInfoIeee32(track.FileInfo)), ResamplingQuality.Medium, profile.SamplingRate); STFT stft = new STFT(audioStream, profile.WindowSize, profile.HopSize, WindowType.Hann, STFT.OutputFormat.Decibel); int index = 0; int indices = stft.WindowCount; int processedFrames = 0; float[] spectrum = new float[profile.WindowSize / 2]; float[] smoothedSpectrum = new float[spectrum.Length - profile.SpectrumSmoothingLength + 1]; // the smooved frequency spectrum of the current frame var spectrumSmoother = new SimpleMovingAverage(profile.SpectrumSmoothingLength); float[] spectrumTemporalAverage = new float[spectrum.Length]; // a running average of each spectrum bin over time float[] spectrumResidual = new float[spectrum.Length]; // the difference between the current spectrum and the moving average spectrum var peakHistory = new PeakHistory(1 + profile.TargetZoneDistance + profile.TargetZoneLength, spectrum.Length / 2); var peakPairs = new List <PeakPair>(profile.PeaksPerFrame * profile.PeakFanout); // keep a single instance of the list to avoid instantiation overhead var subFingerprints = new List <SubFingerprint>(); while (stft.HasNext()) { // Get the FFT spectrum stft.ReadFrame(spectrum); // Skip frames whose average spectrum volume is below the threshold // This skips silent frames (zero samples) that only contain very low noise from the FFT // and that would screw up the temporal spectrum average below for the following frames. if (spectrum.Average() < spectrumMinThreshold) { index++; continue; } // Smooth the frequency spectrum to remove small peaks if (profile.SpectrumSmoothingLength > 0) { spectrumSmoother.Clear(); for (int i = 0; i < spectrum.Length; i++) { var avg = spectrumSmoother.Add(spectrum[i]); if (i >= profile.SpectrumSmoothingLength) { smoothedSpectrum[i - profile.SpectrumSmoothingLength] = avg; } } } // Update the temporal moving bin average if (processedFrames == 0) { // Init averages on first frame for (int i = 0; i < spectrum.Length; i++) { spectrumTemporalAverage[i] = spectrum[i]; } } else { // Update averages on all subsequent frames for (int i = 0; i < spectrum.Length; i++) { spectrumTemporalAverage[i] = ExponentialMovingAverage.UpdateMovingAverage( spectrumTemporalAverage[i], profile.SpectrumTemporalSmoothingCoefficient, spectrum[i]); } } // Calculate the residual // The residual is the difference of the current spectrum to the temporal average spectrum. The higher // a bin residual is, the steeper the increase in energy in that peak. for (int i = 0; i < spectrum.Length; i++) { spectrumResidual[i] = spectrum[i] - spectrumTemporalAverage[i] - 90f; } // Find local peaks in the residual // The advantage of finding peaks in the residual instead of the spectrum is that spectrum energy is usually // concentrated in the low frequencies, resulting in a clustering of the highest peaks in the lows. Getting // peaks from the residual distributes the peaks more evenly across the spectrum. var peaks = peakHistory.List; // take oldest list, peaks.Clear(); // clear it, and FindLocalMaxima(spectrumResidual, peaks); // refill with new peaks // Pick the largest n peaks int numMaxima = Math.Min(peaks.Count, profile.PeaksPerFrame); if (numMaxima > 0) { peaks.Sort((p1, p2) => p1.Value == p2.Value ? 0 : p1.Value < p2.Value ? 1 : -1); // order peaks by height if (peaks.Count > numMaxima) { peaks.RemoveRange(numMaxima, peaks.Count - numMaxima); // select the n tallest peaks by deleting the rest } peaks.Sort((p1, p2) => p1.Index == p2.Index ? 0 : p1.Index < p2.Index ? -1 : 1); // sort peaks by index (not really necessary) } peakHistory.Add(index, peaks); if (FrameProcessed != null) { // Mark peaks as 0dB for spectrogram display purposes foreach (var peak in peaks) { spectrum[peak.Index] = 0; spectrumResidual[peak.Index] = 0; } FrameProcessed(this, new FrameProcessedEventArgs { AudioTrack = track, Index = index, Indices = indices, Spectrum = spectrum, SpectrumResidual = spectrumResidual }); } processedFrames++; index++; if (processedFrames >= peakHistory.Length) { peakPairs.Clear(); FindPairsWithMaxEnergy(peakHistory, peakPairs); ConvertPairsToSubFingerprints(peakPairs, subFingerprints); } if (subFingerprints.Count > 512) { FireFingerprintHashesGenerated(track, indices, subFingerprints); subFingerprints.Clear(); } } // Flush the remaining peaks of the last frames from the history to get all remaining pairs for (int i = 0; i < profile.TargetZoneLength; i++) { var peaks = peakHistory.List; peaks.Clear(); peakHistory.Add(-1, peaks); peakPairs.Clear(); FindPairsWithMaxEnergy(peakHistory, peakPairs); ConvertPairsToSubFingerprints(peakPairs, subFingerprints); } FireFingerprintHashesGenerated(track, indices, subFingerprints); audioStream.Close(); }
/// <summary> /// Initialize test /// </summary> public TestIndicatorSimpleMovingAverage() { DataStream stream = new OHLCBarStream(new ForexSecurity("EURUSD"), BarInterval.FiveMin); _sut = new SimpleMovingAverage(Period, stream.DefaultInterval, stream); }
private void Download_OnClick(object sender, RoutedEventArgs e) { var year = SelectedYear; var from = From.Value ?? year.Days.First(); var to = (To.Value ?? year.Days.Last()).EndOfDay(); var trader = SelectedTrader; var security = SelectedSecurity; var tf = SelectedTimeFrame; var series = new CandleSeries(typeof(TimeFrameCandle), security, tf); BusyIndicator.BusyContent = "Подготовка данных..."; BusyIndicator.IsBusy = true; Dictionary <DateTimeOffset, Tuple <MyTrade[], MyTrade> > trades = null; var worker = new BackgroundWorker { WorkerReportsProgress = true }; worker.DoWork += (o, ea) => { var candleStorage = _dataRegistry.GetCandleStorage(series, format: StorageFormats.Csv); _candles = candleStorage.Load(from, to); var candlesDatesCache = _candlesDates.SafeAdd(Tuple.Create(security, tf), k => new DatesCache(Path.Combine(((LocalMarketDataDrive)candleStorage.Drive.Drive).GetSecurityPath(security.ToSecurityId()), "{0}min_date.bin".Put((int)tf.TotalMinutes)))); var minCandleDate = candlesDatesCache.MinValue; var maxCandleDate = candlesDatesCache.MaxValue; if (from < minCandleDate || to > maxCandleDate) { var finamFrom = from; var finamTo = to; if (maxCandleDate != default(DateTime) && finamFrom >= minCandleDate && finamFrom <= maxCandleDate) { finamFrom = maxCandleDate + TimeSpan.FromDays(1); } if (minCandleDate != default(DateTime) && finamTo >= minCandleDate && finamTo <= maxCandleDate) { finamTo = minCandleDate - TimeSpan.FromDays(1); } if (finamTo > finamFrom) { worker.ReportProgress(1); var newCandles = (tf.Ticks == 1 ? finamFrom.Range(finamTo, TimeSpan.FromDays(1)).SelectMany(day => _finamHistorySource.GetTrades(security, day, day)).ToEx().ToCandles <TimeFrameCandle>(tf) : _finamHistorySource.GetCandles(security, tf, finamFrom, finamTo) ).ToArray(); candleStorage.Save(newCandles); foreach (var date in newCandles.Select(c => c.OpenTime.Date).Distinct()) { candlesDatesCache.Add(date); } candlesDatesCache.Save(); _candles = _candles.Concat(newCandles); } } var traderDrive = new LocalMarketDataDrive(trader); var traderStorage = _traderStorages.SafeAdd(trader, key => new StorageRegistry { DefaultDrive = traderDrive }); var olStorage = traderStorage.GetOrderLogStorage(security, format: StorageFormats.Csv); var tradeDatesCache = _tradesDates.SafeAdd(trader, k => new DatesCache(Path.Combine(traderDrive.Path, "dates.bin"))); trades = from .Range(to, TimeSpan.FromDays(1)) .Intersect(year.Days) .SelectMany(date => { if (olStorage.Dates.Contains(date)) { return(olStorage.Load(date)); } if (tradeDatesCache.Contains(date)) { return(Enumerable.Empty <OrderLogItem>()); } worker.ReportProgress(2, date); var loadedTrades = year.GetTrades(_securityStorage, trader, date); var secTrades = Enumerable.Empty <OrderLogItem>(); foreach (var group in loadedTrades.GroupBy(t => t.Order.Security)) { var sec = group.Key; traderStorage .GetOrderLogStorage(sec, format: StorageFormats.Csv) .Save(group.OrderBy(i => i.Order.Time)); if (group.Key == security) { secTrades = group; } } tradeDatesCache.Add(date); tradeDatesCache.Save(); return(secTrades); }) .GroupBy(ol => { var time = ol.Order.Time; var period = security.Board.WorkingTime.GetPeriod(time.DateTime); if (period != null && period.Times.Length > 0) { var last = period.Times.Last().Max; if (time.TimeOfDay >= last) { time = time.AddTicks(-1); } } return(time.Truncate(tf)); }) .ToDictionary(g => g.Key, g => { var candleTrades = g .Select(order => new MyTrade { Order = order.Order, Trade = order.Trade }) .ToArray(); if (candleTrades.Length > 0) { var order = candleTrades[0].Order; var volume = candleTrades.Sum(t1 => t1.Trade.Volume * (t1.Order.Direction == Sides.Buy ? 1 : -1)); if (volume == 0) { return(Tuple.Create(candleTrades, (MyTrade)null)); } var side = volume > 0 ? Sides.Buy : Sides.Sell; volume = volume.Abs(); var availableVolume = volume; var avgPrice = 0m; foreach (var trade in candleTrades.Where(t1 => t1.Order.Direction == side)) { var tradeVol = trade.Trade.Volume.Min(availableVolume); avgPrice += trade.Trade.Price * tradeVol; availableVolume -= tradeVol; if (availableVolume <= 0) { break; } } avgPrice = avgPrice / volume; return(Tuple.Create(candleTrades, new MyTrade { Order = new Order { Security = order.Security, Direction = side, Time = g.Key, Portfolio = order.Portfolio, Price = avgPrice, Volume = volume, }, Trade = new Trade { Security = order.Security, Time = g.Key, Volume = volume, Price = avgPrice } })); } return(null); }); }; worker.ProgressChanged += (o, ea) => { switch (ea.ProgressPercentage) { case 1: BusyIndicator.BusyContent = "Скачивание свечей..."; break; default: BusyIndicator.BusyContent = "Скачивание сделок за {0:yyyy-MM-dd}...".Put(ea.UserState); break; } }; worker.RunWorkerCompleted += (o, ea) => { BusyIndicator.IsBusy = false; if (ea.Error == null) { Chart.ClearAreas(); _statisticManager.Reset(); var area = new ChartArea(); area.YAxises.Add(new ChartAxis { Id = "equity", AutoRange = true, AxisType = ChartAxisType.Numeric, AxisAlignment = ChartAxisAlignment.Left, }); Chart.AddArea(area); var candlesElem = new ChartCandleElement { ShowAxisMarker = false }; Chart.AddElement(area, candlesElem, series); var tradesElem = new ChartTradeElement { BuyStrokeColor = Colors.Black, SellStrokeColor = Colors.Black, FullTitle = "trades", }; Chart.AddElement(area, tradesElem); var equityElem = new ChartIndicatorElement { YAxisId = "equity", FullTitle = "equity", IndicatorPainter = new PnlPainter() }; var equityInd = new SimpleMovingAverage { Length = 1 }; Chart.AddElement(area, equityElem); var positionArea = new ChartArea { Height = 200 }; Chart.AddArea(positionArea); var positionElem = new ChartIndicatorElement { FullTitle = "position" }; var positionInd = new SimpleMovingAverage { Length = 1 }; Chart.AddElement(positionArea, positionElem); Chart.IsAutoRange = true; var pnlQueue = new PnLQueue(security.ToSecurityId()); //var level1Info = new Level1ChangeMessage //{ // SecurityId = pnlQueue.SecurityId, //} //.TryAdd(Level1Fields.PriceStep, security.PriceStep) //.TryAdd(Level1Fields.StepPrice, security.StepPrice); //pnlQueue.ProcessLevel1(level1Info); var pos = 0m; var chartValues = _candles .Select(c => { c.State = CandleStates.Finished; pnlQueue.ProcessLevel1(new Level1ChangeMessage { SecurityId = security.ToSecurityId(), }.TryAdd(Level1Fields.LastTradePrice, c.ClosePrice)); var values = new Dictionary <IChartElement, object> { { candlesElem, c }, }; var candleTrade = trades.TryGetValue(c.OpenTime); if (candleTrade != null) { if (candleTrade.Item2 != null) { values.Add(tradesElem, candleTrade.Item2); } foreach (var myTrade in candleTrade.Item1) { pos += myTrade.Order.Direction == Sides.Buy ? myTrade.Trade.Volume : -myTrade.Trade.Volume; var pnl = pnlQueue.Process(myTrade.ToMessage()); _statisticManager.AddMyTrade(pnl); } _statisticManager.AddPosition(c.OpenTime, pos); _statisticManager.AddPnL(c.OpenTime, pnlQueue.RealizedPnL + pnlQueue.UnrealizedPnL); } values.Add(equityElem, equityInd.Process(pnlQueue.RealizedPnL + pnlQueue.UnrealizedPnL)); values.Add(positionElem, positionInd.Process(pos)); return(new RefPair <DateTimeOffset, IDictionary <IChartElement, object> > { First = c.OpenTime, Second = values }); }) .ToArray(); Chart.Draw(chartValues); Chart.IsAutoRange = false; } else { new MessageBoxBuilder() .Error() .Owner(this) .Text(ea.Error.ToString()) .Show(); } }; worker.RunWorkerAsync(); }
private void StartBtnClick(object sender, RoutedEventArgs e) { if (_connectors.Count > 0) { foreach (var connector in _connectors) { connector.Start(); } return; } if (HistoryPath.Folder.IsEmpty() || !Directory.Exists(HistoryPath.Folder)) { MessageBox.Show(this, LocalizedStrings.Str3014); return; } if (_connectors.Any(t => t.State != EmulationStates.Stopped)) { MessageBox.Show(this, LocalizedStrings.Str3015); return; } var id = SecId.Text.ToSecurityId(); //if (secIdParts.Length != 2) //{ // MessageBox.Show(this, LocalizedStrings.Str3016); // return; //} var timeFrame = TimeSpan.FromMinutes(TimeFrame.SelectedIndex == 0 ? 1 : 5); var secCode = id.SecurityCode; var board = _exchangeInfoProvider.GetOrCreateBoard(id.BoardCode); // create test security var security = new Security { Id = SecId.Text, // sec id has the same name as folder with historical data Code = secCode, Board = board, }; if (FinamCandlesCheckBox.IsChecked == true) { _finamHistorySource.Refresh(new FinamSecurityStorage(security), security, s => {}, () => false); } // create backtesting modes var settings = new[] { Tuple.Create( TicksCheckBox, TicksProgress, TicksParameterGrid, // ticks new EmulationInfo { UseTicks = true, CurveColor = Colors.DarkGreen, StrategyName = LocalizedStrings.Ticks }, TicksChart, TicksEquity, TicksPosition), Tuple.Create( TicksAndDepthsCheckBox, TicksAndDepthsProgress, TicksAndDepthsParameterGrid, // ticks + order book new EmulationInfo { UseTicks = true, UseMarketDepth = true, CurveColor = Colors.Red, StrategyName = LocalizedStrings.XamlStr757 }, TicksAndDepthsChart, TicksAndDepthsEquity, TicksAndDepthsPosition), Tuple.Create( DepthsCheckBox, DepthsProgress, DepthsParameterGrid, // order book new EmulationInfo { UseMarketDepth = true, CurveColor = Colors.OrangeRed, StrategyName = LocalizedStrings.MarketDepths }, DepthsChart, DepthsEquity, DepthsPosition), Tuple.Create( CandlesCheckBox, CandlesProgress, CandlesParameterGrid, // candles new EmulationInfo { UseCandleTimeFrame = timeFrame, CurveColor = Colors.DarkBlue, StrategyName = LocalizedStrings.Candles }, CandlesChart, CandlesEquity, CandlesPosition), Tuple.Create( CandlesAndDepthsCheckBox, CandlesAndDepthsProgress, CandlesAndDepthsParameterGrid, // candles + orderbook new EmulationInfo { UseMarketDepth = true, UseCandleTimeFrame = timeFrame, CurveColor = Colors.Cyan, StrategyName = LocalizedStrings.XamlStr635 }, CandlesAndDepthsChart, CandlesAndDepthsEquity, CandlesAndDepthsPosition), Tuple.Create( OrderLogCheckBox, OrderLogProgress, OrderLogParameterGrid, // order log new EmulationInfo { UseOrderLog = true, CurveColor = Colors.CornflowerBlue, StrategyName = LocalizedStrings.OrderLog }, OrderLogChart, OrderLogEquity, OrderLogPosition), Tuple.Create( Level1CheckBox, Level1Progress, Level1ParameterGrid, // order log new EmulationInfo { UseLevel1 = true, CurveColor = Colors.Aquamarine, StrategyName = LocalizedStrings.Level1 }, Level1Chart, Level1Equity, Level1Position), Tuple.Create( FinamCandlesCheckBox, FinamCandlesProgress, FinamCandlesParameterGrid, // candles new EmulationInfo { UseCandleTimeFrame = timeFrame, HistorySource = d => _finamHistorySource.GetCandles(security, timeFrame, d.Date, d.Date), CurveColor = Colors.DarkBlue, StrategyName = LocalizedStrings.FinamCandles }, FinamCandlesChart, FinamCandlesEquity, FinamCandlesPosition), Tuple.Create( YahooCandlesCheckBox, YahooCandlesProgress, YahooCandlesParameterGrid, // candles new EmulationInfo { UseCandleTimeFrame = timeFrame, HistorySource = d => new YahooHistorySource(_nativeIdStorage, _exchangeInfoProvider).GetCandles(security, timeFrame, d.Date, d.Date), CurveColor = Colors.DarkBlue, StrategyName = LocalizedStrings.YahooCandles }, YahooCandlesChart, YahooCandlesEquity, YahooCandlesPosition), }; // storage to historical data var storageRegistry = new StorageRegistry { // set historical path DefaultDrive = new LocalMarketDataDrive(HistoryPath.Folder) }; var startTime = ((DateTime)From.EditValue).UtcKind(); var stopTime = ((DateTime)To.EditValue).UtcKind(); // (ru only) ОЛ необходимо загружать с 18.45 пред дня, чтобы стаканы строились правильно if (OrderLogCheckBox.IsChecked == true) { startTime = startTime.Subtract(TimeSpan.FromDays(1)).AddHours(18).AddMinutes(45).AddTicks(1).ApplyTimeZone(TimeHelper.Moscow).UtcDateTime; } // ProgressBar refresh step var progressStep = ((stopTime - startTime).Ticks / 100).To <TimeSpan>(); // set ProgressBar bounds _progressBars.ForEach(p => { p.Value = 0; p.Maximum = 100; }); var logManager = new LogManager(); var fileLogListener = new FileLogListener("sample.log"); logManager.Listeners.Add(fileLogListener); //logManager.Listeners.Add(new DebugLogListener()); // for track logs in output window in Vusial Studio (poor performance). var generateDepths = GenDepthsCheckBox.IsChecked == true; var maxDepth = MaxDepth.Text.To <int>(); var maxVolume = MaxVolume.Text.To <int>(); var secId = security.ToSecurityId(); SetIsEnabled(false, false, false); foreach (var set in settings) { if (set.Item1.IsChecked == false) { continue; } var title = (string)set.Item1.Content; InitChart(set.Item5, set.Item6, set.Item7); var progressBar = set.Item2; var statistic = set.Item3; var emulationInfo = set.Item4; var level1Info = new Level1ChangeMessage { SecurityId = secId, ServerTime = startTime, } .TryAdd(Level1Fields.PriceStep, secCode == "RIZ2" ? 10m : 1) .TryAdd(Level1Fields.StepPrice, 6m) .TryAdd(Level1Fields.MinPrice, 10m) .TryAdd(Level1Fields.MaxPrice, 1000000m) .TryAdd(Level1Fields.MarginBuy, 10000m) .TryAdd(Level1Fields.MarginSell, 10000m); // test portfolio var portfolio = Portfolio.CreateSimulator(); // create backtesting connector var connector = new HistoryEmulationConnector( new[] { security }, new[] { portfolio }) { EmulationAdapter = { Emulator = { Settings = { // match order if historical price touched our limit order price. // It is terned off, and price should go through limit order price level // (more "severe" test mode) MatchOnTouch = false, } } }, //UseExternalCandleSource = emulationInfo.UseCandleTimeFrame != null, //CreateDepthFromOrdersLog = emulationInfo.UseOrderLog, //CreateTradesFromOrdersLog = emulationInfo.UseOrderLog, HistoryMessageAdapter = { StorageRegistry = storageRegistry, // set history range StartDate = startTime, StopDate = stopTime, OrderLogMarketDepthBuilders = { { secId, new OrderLogMarketDepthBuilder(secId) } } }, // set market time freq as time frame MarketTimeChangedInterval = timeFrame, }; ((ILogSource)connector).LogLevel = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info; logManager.Sources.Add(connector); var series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame) { BuildCandlesMode = emulationInfo.UseCandleTimeFrame == null ? MarketDataBuildModes.Build : MarketDataBuildModes.Load, BuildCandlesFrom = emulationInfo.UseOrderLog ? (MarketDataTypes?)MarketDataTypes.OrderLog : null, }; _shortMa = new SimpleMovingAverage { Length = 10 }; _shortElem = new ChartIndicatorElement { Color = Colors.Coral, ShowAxisMarker = false, FullTitle = _shortMa.ToString() }; var chart = set.Item5; chart.AddElement(_area, _shortElem); _longMa = new SimpleMovingAverage { Length = 80 }; _longElem = new ChartIndicatorElement { ShowAxisMarker = false, FullTitle = _longMa.ToString() }; chart.AddElement(_area, _longElem); // create strategy based on 80 5-min и 10 5-min var strategy = new SmaStrategy(chart, _candlesElem, _tradesElem, _shortMa, _shortElem, _longMa, _longElem, series) { Volume = 1, Portfolio = portfolio, Security = security, Connector = connector, LogLevel = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info, // by default interval is 1 min, // it is excessively for time range with several months UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To <TimeSpan>() }; logManager.Sources.Add(strategy); connector.Connected += () => { if (emulationInfo.HistorySource != null) { // passing null value as security to register the source for all securities if (emulationInfo.UseCandleTimeFrame != null) { connector.RegisterHistorySource(null, MarketDataTypes.CandleTimeFrame, emulationInfo.UseCandleTimeFrame.Value, emulationInfo.HistorySource); } if (emulationInfo.UseTicks) { connector.RegisterHistorySource(null, MarketDataTypes.Trades, null, emulationInfo.HistorySource); } if (emulationInfo.UseLevel1) { connector.RegisterHistorySource(null, MarketDataTypes.Level1, null, emulationInfo.HistorySource); } if (emulationInfo.UseMarketDepth) { connector.RegisterHistorySource(null, MarketDataTypes.MarketDepth, null, emulationInfo.HistorySource); } } }; connector.NewSecurity += s => { if (s != security) { return; } // fill level1 values connector.HistoryMessageAdapter.SendOutMessage(level1Info); if (emulationInfo.HistorySource == null) { if (emulationInfo.UseMarketDepth) { connector.RegisterMarketDepth(security); if ( // if order book will be generated generateDepths || // of backtesting will be on candles emulationInfo.UseCandleTimeFrame != TimeSpan.Zero ) { // if no have order book historical data, but strategy is required, // use generator based on last prices connector.RegisterMarketDepth(new TrendMarketDepthGenerator(connector.GetSecurityId(security)) { Interval = TimeSpan.FromSeconds(1), // order book freq refresh is 1 sec MaxAsksDepth = maxDepth, MaxBidsDepth = maxDepth, UseTradeVolume = true, MaxVolume = maxVolume, MinSpreadStepCount = 2, // min spread generation is 2 pips MaxSpreadStepCount = 5, // max spread generation size (prevent extremely size) MaxPriceStepCount = 3 // pips size, }); } } if (emulationInfo.UseOrderLog) { connector.RegisterOrderLog(security); } if (emulationInfo.UseTicks) { connector.RegisterTrades(security); } if (emulationInfo.UseLevel1) { connector.RegisterSecurity(security); } } // start strategy before emulation started strategy.Start(); // start historical data loading when connection established successfully and all data subscribed connector.Start(); }; // fill parameters panel statistic.Parameters.Clear(); statistic.Parameters.AddRange(strategy.StatisticManager.Parameters); var equity = set.Item6; var pnlCurve = equity.CreateCurve(LocalizedStrings.PnL + " " + emulationInfo.StrategyName, Colors.Green, Colors.Red, ChartIndicatorDrawStyles.Area); var unrealizedPnLCurve = equity.CreateCurve(LocalizedStrings.PnLUnreal + " " + emulationInfo.StrategyName, Colors.Black, ChartIndicatorDrawStyles.Line); var commissionCurve = equity.CreateCurve(LocalizedStrings.Str159 + " " + emulationInfo.StrategyName, Colors.Red, ChartIndicatorDrawStyles.DashedLine); strategy.PnLChanged += () => { var data = new ChartDrawData(); data .Group(strategy.CurrentTime) .Add(pnlCurve, strategy.PnL - strategy.Commission ?? 0) .Add(unrealizedPnLCurve, strategy.PnLManager.UnrealizedPnL ?? 0) .Add(commissionCurve, strategy.Commission ?? 0); equity.Draw(data); }; var posItems = set.Item7.CreateCurve(emulationInfo.StrategyName, emulationInfo.CurveColor, ChartIndicatorDrawStyles.Line); strategy.PositionChanged += () => { var data = new ChartDrawData(); data .Group(strategy.CurrentTime) .Add(posItems, strategy.Position); set.Item7.Draw(data); }; var nextTime = startTime + progressStep; // handle historical time for update ProgressBar connector.MarketTimeChanged += d => { if (connector.CurrentTime < nextTime && connector.CurrentTime < stopTime) { return; } var steps = (connector.CurrentTime - startTime).Ticks / progressStep.Ticks + 1; nextTime = startTime + (steps * progressStep.Ticks).To <TimeSpan>(); this.GuiAsync(() => progressBar.Value = steps); }; connector.StateChanged += () => { if (connector.State == EmulationStates.Stopped) { strategy.Stop(); SetIsChartEnabled(chart, false); if (_connectors.All(c => c.State == EmulationStates.Stopped)) { logManager.Dispose(); _connectors.Clear(); SetIsEnabled(true, false, false); } this.GuiAsync(() => { if (connector.IsFinished) { progressBar.Value = progressBar.Maximum; MessageBox.Show(this, LocalizedStrings.Str3024.Put(DateTime.Now - _startEmulationTime), title); } else { MessageBox.Show(this, LocalizedStrings.cancelled, title); } }); } else if (connector.State == EmulationStates.Started) { if (_connectors.All(c => c.State == EmulationStates.Started)) { SetIsEnabled(false, true, true); } SetIsChartEnabled(chart, true); } else if (connector.State == EmulationStates.Suspended) { if (_connectors.All(c => c.State == EmulationStates.Suspended)) { SetIsEnabled(true, false, true); } } }; if (ShowDepth.IsChecked == true) { MarketDepth.UpdateFormat(security); connector.NewMessage += message => { if (message is QuoteChangeMessage quoteMsg) { MarketDepth.UpdateDepth(quoteMsg); } }; } _connectors.Add(connector); progressBar.Value = 0; } _startEmulationTime = DateTime.Now; // start emulation foreach (var connector in _connectors) { // raise NewSecurities and NewPortfolio for full fill strategy properties connector.Connect(); // 1 cent commission for trade connector.SendInMessage(new CommissionRuleMessage { Rule = new CommissionPerTradeRule { Value = 0.01m } }); } TabControl.Items.Cast <TabItem>().First(i => i.Visibility == Visibility.Visible).IsSelected = true; }
private void StartBtnClick(object sender, RoutedEventArgs e) { InitChart(); if (HistoryPath.Text.IsEmpty() || !Directory.Exists(HistoryPath.Text)) { MessageBox.Show(this, LocalizedStrings.Str3014); return; } var secGen = new SecurityIdGenerator(); var secIdParts = secGen.Split(SecId.Text); var storageRegistry = new StorageRegistry() { DefaultDrive = new LocalMarketDataDrive(HistoryPath.Text) }; var startTime = ((DateTime)From.Value).ChangeKind(DateTimeKind.Utc); var stopTime = ((DateTime)To.Value).ChangeKind(DateTimeKind.Utc); //var logManager = new LogManager(); //var fileLogListener = new FileLogListener("sample.log"); //logManager.Listeners.Add(fileLogListener); //logManager.Listeners.Add(new DebugLogListener()); // for track logs in output window in Vusial Studio (poor performance). var maxDepth = 5; var maxVolume = 5; var secCode = secIdParts.Item1; var board = ExchangeBoard.GetOrCreateBoard(secIdParts.Item2); var progressBar = TicksTestingProcess; var progressStep = ((stopTime - startTime).Ticks / 100).To <TimeSpan>(); progressBar.Value = 0; progressBar.Maximum = 100; var statistic = TicksParameterGrid; var security = new Security() { Id = SecId.Text, Code = secCode, Board = board, }; var portfolio = new Portfolio() { Name = "test account", BeginValue = 1000000, }; var connector = new HistoryEmulationConnector(new[] { security }, new[] { portfolio }) { EmulationAdapter = { Emulator = { Settings = { MatchOnTouch = true, PortfolioRecalcInterval = TimeSpan.FromMilliseconds(100), SpreadSize = 1, }, LogLevel = LogLevels.Debug, }, LogLevel = LogLevels.Debug, }, HistoryMessageAdapter = { StorageRegistry = storageRegistry, StartDate = startTime, StopDate = stopTime, MarketTimeChangedInterval = TimeSpan.FromMilliseconds(50), }, }; //logManager.Sources.Add(connector); var candleManager = new CandleManager(connector); var series = new CandleSeries(typeof(RangeCandle), security, new Unit(100)); shortMa = new SimpleMovingAverage { Length = 10 }; shortElem = new ChartIndicatorElement { Color = Colors.Coral, ShowAxisMarker = false, FullTitle = shortMa.ToString() }; bufferedChart.AddElement(area, shortElem); longMa = new SimpleMovingAverage { Length = 30 }; longElem = new ChartIndicatorElement { ShowAxisMarker = false, FullTitle = longMa.ToString() }; bufferedChart.AddElement(area, longElem); var strategy = new SmaStrategy(bufferedChart, candlesElem, tradesElem, shortMa, shortElem, longMa, longElem, series) { Volume = 1, Portfolio = portfolio, Security = security, Connector = connector, LogLevel = LogLevels.Debug, UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To <TimeSpan>() }; //logManager.Sources.Add(strategy); connector.NewSecurities += securities => { if (securities.All(s => s != security)) { return; } connector.RegisterMarketDepth(security); connector.RegisterMarketDepth(new TrendMarketDepthGenerator(connector.GetSecurityId(security)) { Interval = TimeSpan.FromMilliseconds(100), // order book freq refresh is 1 sec MaxAsksDepth = maxDepth, MaxBidsDepth = maxDepth, UseTradeVolume = true, MaxVolume = maxVolume, MinSpreadStepCount = 1, // min spread generation is 2 pips MaxSpreadStepCount = 1, // max spread generation size (prevent extremely size) MaxPriceStepCount = 3 // pips size, }); connector.RegisterTrades(security); connector.RegisterSecurity(security); strategy.Start(); candleManager.Start(series); connector.Start(); }; statistic.Parameters.Clear(); statistic.Parameters.AddRange(strategy.StatisticManager.Parameters); var pnlCurve = Curve.CreateCurve(LocalizedStrings.PnL + " " + StrategyName, Colors.Cyan, EquityCurveChartStyles.Area); var unrealizedPnLCurve = Curve.CreateCurve(LocalizedStrings.PnLUnreal + StrategyName, Colors.Black); var commissionCurve = Curve.CreateCurve(LocalizedStrings.Str159 + " " + StrategyName, Colors.Red, EquityCurveChartStyles.DashedLine); var posItems = PositionCurve.CreateCurve(StrategyName, Colors.Crimson); strategy.PnLChanged += () => { var pnl = new EquityData() { Time = strategy.CurrentTime, Value = strategy.PnL - strategy.Commission ?? 0 }; var unrealizedPnL = new EquityData() { Time = strategy.CurrentTime, Value = strategy.PnLManager.UnrealizedPnL }; var commission = new EquityData() { Time = strategy.CurrentTime, Value = strategy.Commission ?? 0 }; pnlCurve.Add(pnl); unrealizedPnLCurve.Add(unrealizedPnL); commissionCurve.Add(commission); }; strategy.PositionChanged += () => posItems.Add(new EquityData { Time = strategy.CurrentTime, Value = strategy.Position }); var nextTime = startTime + progressStep; connector.MarketTimeChanged += d => { if (connector.CurrentTime < nextTime && connector.CurrentTime < stopTime) { return; } var steps = (connector.CurrentTime - startTime).Ticks / progressStep.Ticks + 1; nextTime = startTime + (steps * progressStep.Ticks).To <TimeSpan>(); this.GuiAsync(() => progressBar.Value = steps); }; connector.StateChanged += () => { if (connector.State == EmulationStates.Stopped) { candleManager.Stop(series); strategy.Stop(); //logManager.Dispose(); SetIsEnabled(false); this.GuiAsync(() => { if (connector.IsFinished) { progressBar.Value = progressBar.Maximum; MessageBox.Show(this, LocalizedStrings.Str3024.Put(DateTime.Now - startEmulationTime)); } else { MessageBox.Show(this, LocalizedStrings.cancelled); } }); } else if (connector.State == EmulationStates.Started) { SetIsEnabled(true); } }; progressBar.Value = 0; startEmulationTime = DateTime.Now; connector.Connect(); connector.SendInMessage(new CommissionRuleMessage() { Rule = new CommissionPerTradeRule { Value = 0.01m } }); }
protected override void Initialize() { imafast = Indicators.SimpleMovingAverage(DataSource, FastSMA); imaslow = Indicators.SimpleMovingAverage(DataSource, SlowSMA); }
public void CompareAgainstExternalData() { var sma = new SimpleMovingAverage(14); TestHelper.TestIndicator(sma, "SMA14", 1e-2); // test file only has }
private void StartClick(object sender, RoutedEventArgs e) { // если были получены и инструмент, и портфель if (_strategy == null) { if (Portfolios.SelectedPortfolio == null) { MessageBox.Show(this, LocalizedStrings.Str3009); return; } // создаем скользящие средние, на 80 5-минуток и 10 5-минуток var longSma = new SimpleMovingAverage { Length = 80 }; var shortSma = new SimpleMovingAverage { Length = 10 }; // регистрируем наш тайм-фрейм var series = new CandleSeries(typeof(TimeFrameCandle), _lkoh, _timeFrame); // создаем торговую стратегию _strategy = new SmaStrategy(_candleManager, series, longSma, shortSma) { Volume = 1, Security = _lkoh, Portfolio = Portfolios.SelectedPortfolio, Connector = _trader, }; _logManager.Sources.Add(_strategy); //_strategy.Log += OnLog; _strategy.PropertyChanged += OnStrategyPropertyChanged; _candlesElem = new ChartCandleElement(); _area.Elements.Add(_candlesElem); _longMaElem = new ChartIndicatorElement { Title = LocalizedStrings.Long, Color = Colors.OrangeRed }; _area.Elements.Add(_longMaElem); _shortMaElem = new ChartIndicatorElement { Title = LocalizedStrings.Short, Color = Colors.RoyalBlue }; _area.Elements.Add(_shortMaElem); var marketTime = _trader.CurrentTime; // начинаем получать свечи за период в 5 дней _candleManager.Start(series, DateTime.Today - TimeSpan.FromDays(5), marketTime); _lastHistoryCandle = _timeFrame.GetCandleBounds(marketTime).Min; Report.IsEnabled = true; } if (_strategy.ProcessState == ProcessStates.Stopped) { // запускаем процесс получения стакана, необходимый для работы алгоритма котирования _trader.RegisterMarketDepth(_strategy.Security); _strategy.Start(); Start.Content = LocalizedStrings.Str242; } else { _trader.UnRegisterMarketDepth(_strategy.Security); _strategy.Stop(); Start.Content = LocalizedStrings.Str2421; } }
public VolatilityAdjustedMovingAverage(string name, int period) : base(name) { _sma = new SimpleMovingAverage(400); _rsi = new RelativeStrengthIndex(6, MovingAverageType.Simple); _sd = new StandardDeviation(100); }
public SimpleMovingAverageTrend(Equity equity, int periodCount) : base(equity, periodCount) { _smaIndicator = new SimpleMovingAverage(equity, periodCount); }
public static bool FillSimpleMovingAvg(ref Stock stk, int periodShort = 0, int periodLong = 0) { //get defaults if zero if (periodShort == 0) { periodShort = stk.indicators.SMAPeriodShort; } if (periodLong == 0) { periodLong = stk.indicators.SMAPeriodLong; } //int valuesAdded = 0; IIndicator SMAShort = new SimpleMovingAverage(periodShort); IIndicator SMALong = new SimpleMovingAverage(periodLong); stk.indicators.SMAShort = SMAShort.CalculateIndicator(stk.MarketHistory); stk.indicators.SMALong = SMALong.CalculateIndicator(stk.MarketHistory); return(true); //Dictionary<string, decimal> tempLong = new Dictionary<string, decimal>(); //Dictionary<string, decimal> tempShort = new Dictionary<string, decimal>(); //foreach (MarketData m in stk.MarketHistory) //{ // var lastClosesShort = stk.MarketHistory.GetLastNClosingPrices(periodShort, m.dateStr); // var lastMClosesLong = stk.MarketHistory.GetLastNClosingPrices(periodLong, m.dateStr); // decimal avgShort = lastClosesShort.Average(); // decimal avgLong = lastMClosesLong.Average(); // //short eval // if (lastClosesShort.Count() == periodShort) // { // try // { // stk.indicators.SMAShort.Add(m.dateStr, avgShort); // } // catch (Exception) // { // stk.indicators.SMAShort[m.dateStr] = avgShort; // } // } // else // { // try // { // stk.indicators.SMAShort.Add(m.dateStr, 0m); // } // catch // { // stk.indicators.SMAShort[m.dateStr] = 0m; // } // } // //long eval // if (lastMClosesLong.Count() == periodLong) // { // try // { // stk.indicators.SMALong.Add(m.dateStr, avgLong); // } // catch (Exception) // { // stk.indicators.SMALong[m.dateStr] = avgLong; // } // } // else // { // try // { // stk.indicators.SMALong.Add(m.dateStr, 0m); // } // catch // { // stk.indicators.SMALong[m.dateStr] = 0m; // } // } // tempLong.Add(m.dateStr, avgLong); // tempShort.Add(m.dateStr, avgShort); // valuesAdded += 2; //} //return valuesAdded > 0; }
private void StartBtnClick(object sender, RoutedEventArgs e) { InitChart(); if (HistoryPath.Text.IsEmpty() || !Directory.Exists(HistoryPath.Text)) { MessageBox.Show(this, LocalizedStrings.Str3014); return; } if (_connectors.Any(t => t.State != EmulationStates.Stopped)) { MessageBox.Show(this, LocalizedStrings.Str3015); return; } var secIdParts = SecId.Text.Split('@'); if (secIdParts.Length != 2) { MessageBox.Show(this, LocalizedStrings.Str3016); return; } var timeFrame = TimeSpan.FromMinutes(5); // создаем настройки для тестирования var settings = new[] { Tuple.Create( TicksCheckBox, TicksTestingProcess, TicksParameterGrid, // тест только на тиках new EmulationInfo { CurveColor = Colors.DarkGreen, StrategyName = LocalizedStrings.Str3017 }), Tuple.Create( TicksAndDepthsCheckBox, TicksAndDepthsTestingProcess, TicksAndDepthsParameterGrid, // тест на тиках + стаканы new EmulationInfo { UseMarketDepth = true, CurveColor = Colors.Red, StrategyName = LocalizedStrings.Str3018 }), Tuple.Create( CandlesCheckBox, CandlesTestingProcess, CandlesParameterGrid, // тест на свечах new EmulationInfo { UseCandleTimeFrame = timeFrame, CurveColor = Colors.DarkBlue, StrategyName = LocalizedStrings.Str3019 }), Tuple.Create( CandlesAndDepthsCheckBox, CandlesAndDepthsTestingProcess, CandlesAndDepthsParameterGrid, // тест на свечах + стаканы new EmulationInfo { UseMarketDepth = true, UseCandleTimeFrame = timeFrame, CurveColor = Colors.Cyan, StrategyName = LocalizedStrings.Str3020 }), Tuple.Create( OrderLogCheckBox, OrderLogTestingProcess, OrderLogParameterGrid, // тест на логе заявок new EmulationInfo { UseOrderLog = true, CurveColor = Colors.CornflowerBlue, StrategyName = LocalizedStrings.Str3021 }) }; // хранилище, через которое будет производиться доступ к тиковой и котировочной базе var storageRegistry = new StorageRegistry { // изменяем путь, используемый по умолчанию DefaultDrive = new LocalMarketDataDrive(HistoryPath.Text) }; var startTime = (DateTime)From.Value; var stopTime = (DateTime)To.Value; // ОЛ необходимо загружать с 18.45 пред дня, чтобы стаканы строились правильно if (OrderLogCheckBox.IsChecked == true) { startTime = startTime.Subtract(TimeSpan.FromDays(1)).AddHours(18).AddMinutes(45).AddTicks(1); } // задаем шаг ProgressBar var progressStep = ((stopTime - startTime).Ticks / 100).To <TimeSpan>(); // в реальности период может быть другим, и это зависит от объема данных, // хранящихся по пути HistoryPath, TicksTestingProcess.Maximum = TicksAndDepthsTestingProcess.Maximum = CandlesTestingProcess.Maximum = 100; TicksTestingProcess.Value = TicksAndDepthsTestingProcess.Value = CandlesTestingProcess.Value = 0; var logManager = new LogManager(); var fileLogListener = new FileLogListener("sample.log"); logManager.Listeners.Add(fileLogListener); //logManager.Listeners.Add(new DebugLogListener()); // чтобы смотреть логи в отладчике - работает медленно. var generateDepths = GenDepthsCheckBox.IsChecked == true; var maxDepth = MaxDepth.Text.To <int>(); var maxVolume = MaxVolume.Text.To <int>(); var secCode = secIdParts[0]; var board = ExchangeBoard.GetOrCreateBoard(secIdParts[1]); foreach (var set in settings) { if (set.Item1.IsChecked == false) { continue; } var progressBar = set.Item2; var statistic = set.Item3; var emulationInfo = set.Item4; // создаем тестовый инструмент, на котором будет производится тестирование var security = new Security { Id = SecId.Text, // по идентификатору инструмента будет искаться папка с историческими маркет данными Code = secCode, Board = board, }; var level1Info = new Level1ChangeMessage { SecurityId = security.ToSecurityId(), ServerTime = startTime, } .TryAdd(Level1Fields.PriceStep, 10m) .TryAdd(Level1Fields.StepPrice, 6m) .TryAdd(Level1Fields.MinPrice, 10m) .TryAdd(Level1Fields.MaxPrice, 1000000m) .TryAdd(Level1Fields.MarginBuy, 10000m) .TryAdd(Level1Fields.MarginSell, 10000m); // тестовый портфель var portfolio = new Portfolio { Name = "test account", BeginValue = 1000000, }; // создаем подключение для эмуляции // инициализируем настройки (инструмент в истории обновляется раз в секунду) var connector = new HistoryEmulationConnector( new[] { security }, new[] { portfolio }) { StorageRegistry = storageRegistry, MarketEmulator = { Settings = { // использовать свечи UseCandlesTimeFrame = emulationInfo.UseCandleTimeFrame, // сведение сделки в эмуляторе если цена коснулась нашей лимитной заявки. // Если выключено - требуется "прохождение цены сквозь уровень" // (более "суровый" режим тестирования.) MatchOnTouch = false, } }, //UseExternalCandleSource = true, CreateDepthFromOrdersLog = emulationInfo.UseOrderLog, CreateTradesFromOrdersLog = emulationInfo.UseOrderLog, }; connector.MarketDataAdapter.SessionHolder.MarketTimeChangedInterval = timeFrame; ((ILogSource)connector).LogLevel = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info; logManager.Sources.Add(connector); connector.NewSecurities += securities => { //подписываемся на получение данных после получения инструмента if (securities.All(s => s != security)) { return; } // отправляем данные Level1 для инструмента connector.MarketDataAdapter.SendOutMessage(level1Info); // тест подразумевает наличие стаканов if (emulationInfo.UseMarketDepth) { connector.RegisterMarketDepth(security); if ( // если выбрана генерация стаканов вместо реальных стаканов generateDepths || // для свечей генерируем стаканы всегда emulationInfo.UseCandleTimeFrame != TimeSpan.Zero ) { // если история по стаканам отсутствует, но стаканы необходимы для стратегии, // то их можно сгенерировать на основании цен последних сделок или свечек. connector.RegisterMarketDepth(new TrendMarketDepthGenerator(connector.GetSecurityId(security)) { Interval = TimeSpan.FromSeconds(1), // стакан для инструмента в истории обновляется раз в секунду MaxAsksDepth = maxDepth, MaxBidsDepth = maxDepth, UseTradeVolume = true, MaxVolume = maxVolume, MinSpreadStepCount = 2, // минимальный генерируемый спред - 2 минимальных шага цены MaxSpreadStepCount = 5, // не генерировать спрэд между лучшим бид и аск больше чем 5 минимальных шагов цены - нужно чтобы при генерации из свечей не получалось слишком широкого спреда. MaxPriceStepCount = 3 // максимальное количество шагов между ценами, }); } } else if (emulationInfo.UseOrderLog) { connector.RegisterOrderLog(security); } }; // соединяемся с трейдером и запускаем экспорт, // чтобы инициализировать переданными инструментами и портфелями необходимые свойства EmulationTrader connector.Connect(); connector.StartExport(); var candleManager = new CandleManager(connector); var series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame); _shortMa = new SimpleMovingAverage { Length = 10 }; _shortElem = new ChartIndicatorElement { Color = Colors.Coral, ShowAxisMarker = false, FullTitle = _shortMa.ToString() }; _bufferedChart.AddElement(_area, _shortElem); _longMa = new SimpleMovingAverage { Length = 80 }; _longElem = new ChartIndicatorElement { ShowAxisMarker = false, FullTitle = _longMa.ToString() }; _bufferedChart.AddElement(_area, _longElem); // создаем торговую стратегию, скользящие средние на 80 5-минуток и 10 5-минуток var strategy = new SmaStrategy(_bufferedChart, _candlesElem, _tradesElem, _shortMa, _shortElem, _longMa, _longElem, series) { Volume = 1, Portfolio = portfolio, Security = security, Connector = connector, LogLevel = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info, // по-умолчанию интервал равен 1 минут, // что для истории в диапазон от нескольких месяцев излишне UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To <TimeSpan>() }; // комиссия в 1 копейку за сделку connector.MarketEmulator.SendInMessage(new CommissionRuleMessage { Rule = new CommissionPerTradeRule { Value = 0.01m } }); logManager.Sources.Add(strategy); // копируем параметры на визуальную панель statistic.Parameters.Clear(); statistic.Parameters.AddRange(strategy.StatisticManager.Parameters); var pnlCurve = Curve.CreateCurve("P&L " + emulationInfo.StrategyName, emulationInfo.CurveColor, EquityCurveChartStyles.Area); var unrealizedPnLCurve = Curve.CreateCurve(LocalizedStrings.PnLUnreal + emulationInfo.StrategyName, Colors.Black); var commissionCurve = Curve.CreateCurve(LocalizedStrings.Str159 + " " + emulationInfo.StrategyName, Colors.Red, EquityCurveChartStyles.DashedLine); var posItems = PositionCurve.CreateCurve(emulationInfo.StrategyName, emulationInfo.CurveColor); strategy.PnLChanged += () => { var pnl = new EquityData { Time = strategy.CurrentTime, Value = strategy.PnL - strategy.Commission ?? 0 }; var unrealizedPnL = new EquityData { Time = strategy.CurrentTime, Value = strategy.PnLManager.UnrealizedPnL }; var commission = new EquityData { Time = strategy.CurrentTime, Value = strategy.Commission ?? 0 }; pnlCurve.Add(pnl); unrealizedPnLCurve.Add(unrealizedPnL); commissionCurve.Add(commission); }; strategy.PositionChanged += () => posItems.Add(new EquityData { Time = strategy.CurrentTime, Value = strategy.Position }); var nextTime = startTime + progressStep; // и подписываемся на событие изменения времени, чтобы обновить ProgressBar connector.MarketTimeChanged += d => { if (connector.CurrentTime < nextTime && connector.CurrentTime < stopTime) { return; } var steps = (connector.CurrentTime - startTime).Ticks / progressStep.Ticks + 1; nextTime = startTime + (steps * progressStep.Ticks).To <TimeSpan>(); this.GuiAsync(() => progressBar.Value = steps); }; connector.StateChanged += () => { if (connector.State == EmulationStates.Stopped) { candleManager.Stop(series); strategy.Stop(); logManager.Dispose(); _connectors.Clear(); SetIsEnabled(false); this.GuiAsync(() => { if (connector.IsFinished) { progressBar.Value = progressBar.Maximum; MessageBox.Show(LocalizedStrings.Str3024.Put(DateTime.Now - _startEmulationTime)); } else { MessageBox.Show(LocalizedStrings.cancelled); } }); } else if (connector.State == EmulationStates.Started) { SetIsEnabled(true); // запускаем стратегию когда эмулятор запустился strategy.Start(); candleManager.Start(series); } }; if (ShowDepth.IsChecked == true) { MarketDepth.UpdateFormat(security); connector.NewMessage += (message, dir) => { var quoteMsg = message as QuoteChangeMessage; if (quoteMsg != null) { MarketDepth.UpdateDepth(quoteMsg); } }; } _connectors.Add(connector); } _startEmulationTime = DateTime.Now; // запускаем эмуляцию foreach (var connector in _connectors) { // указываем даты начала и конца тестирования connector.Start(startTime, stopTime); } TabControl.Items.Cast <TabItem>().First(i => i.Visibility == Visibility.Visible).IsSelected = true; }
private void UpdateTradeBar(SimpleMovingAverage sma, TradeBar tradeBar, int position) { _consolidationCount[position]++; sma.Update(tradeBar.EndTime, tradeBar.High); }