private List <TradeSignal> Calculate(Dictionary <Selection, IEnumerable <Bar> > marketData) { var signals = new List <TradeSignal>(); if (State == SignalState.Backtesting) { foreach (var data in marketData) { if (_dataStorage.TryGetValue(data.Key, out var neededValue)) { _dataStorage[data.Key] = neededValue.Concat(data.Value); } else { _dataStorage.Add(data.Key, data.Value); } } } else { _dataStorage = marketData; } //calculate for each selection foreach (var data in _dataStorage) { if (data.Value.Count() < RequiredBarsCount) { continue; } //MQL Compatibility Methods decimal GetCurrentBid() => data.Value.Last()?.CloseBid ?? 0m; decimal GetCurrentAsk() => data.Value.Last()?.CloseAsk ?? 0m; DateTime GetCurrentDate() => data.Value.Last()?.Date ?? DateTime.Now; Bar RatesArray(int index) => data.Value.ElementAt(data.Value.Count() - ++index); /////////////////////////// var zigZag = new ZigZag(); zigZag.Init(null, DataProvider); zigZag.Calculate(data.Value); _zzBuffer = new List <decimal>(zigZag.Series[0].Values.Select(s => (decimal)s.Value)); _hl[0] = 666; if (_hl[0] == 666) { var zCount = 0; for (var i = 0; i <= _zzBuffer.Count && zCount <= 3; i++) { if (_zzBuffer[i] == 0) { continue; } _hl[zCount] = _zzBuffer[i]; _hlTime[zCount] = RatesArray(i).Date; zCount++; } _trendDirection = CheckTrend(_hl[0], _hl[1], _hl[2], _hl[3]); _fibo00 = _hl[0]; _fibo100 = _hl[1]; _fiboBase = Math.Abs(_fibo100 - _fibo00); } // high-low points mapping in concequence if (_zzBuffer[0] != 0 && _zzBuffer[0] != _hl[0]) { _hl[3] = _hl[2]; _hl[2] = _hl[1]; _hl[1] = _hl[0]; _hl[0] = _zzBuffer[0]; _hlTime[3] = _hlTime[2]; _hlTime[2] = _hlTime[1]; _hlTime[1] = _hlTime[0]; _hlTime[0] = RatesArray(0).Date; _trendDirection = CheckTrend(_hl[0], _hl[1], _hl[2], _hl[3]); } if (BrokerAccounts == null) { continue; } foreach (var brokerAccount in BrokerAccounts) { if (GetPositions(brokerAccount, data.Key.Symbol)?.Count != 0) { continue; } switch (_trendDirection) { case 1: _fiboBase = _fibo00 - _fibo100; _fibo23 = _fibo00 - 0.236m * _fiboBase; _fibo38 = _fibo00 - 0.382m * _fiboBase; _fibo61 = _fibo00 - 0.618m * _fiboBase; _fibo76 = _fibo00 - 0.764m * _fiboBase; if (_hl[0] > _fibo00) { _fibo00 = _hl[0]; if (_hl[0] - _hl[1] > _fiboBase) { _fibo100 = _hl[1]; } } if (_hl[0] < _fibo100) { _fibo00 = _hl[0]; _fibo100 = _hl[1]; _trendDirection = CheckTrend(_hl[0], _hl[1], _hl[2], _hl[3]); } if (RatesArray(0).MeanClose - _fibo76 > Point * _safetyBuffer && _fibo76 - RatesArray(1).MeanClose > Point * _safetyBuffer || RatesArray(0).MeanClose - _fibo61 > Point * _safetyBuffer && _fibo61 - RatesArray(1).MeanClose > Point * _safetyBuffer || RatesArray(0).MeanClose - _fibo38 > Point * _safetyBuffer && _fibo38 - RatesArray(1).MeanClose > Point * _safetyBuffer || RatesArray(0).MeanClose - _fibo23 > Point * _safetyBuffer && _fibo23 - RatesArray(1).MeanClose > Point * _safetyBuffer) { var signal = TradeCheck(1, data.Key, GetCurrentBid(), GetCurrentAsk(), GetCurrentDate()); if (signal != null) { signals.Add(signal); } } break; case -1: _fiboBase = _fibo100 - _fibo00; _fibo23 = _fibo00 + 0.236m * _fiboBase; _fibo38 = _fibo00 + 0.382m * _fiboBase; _fibo61 = _fibo00 + 0.618m * _fiboBase; _fibo76 = _fibo00 + 0.764m * _fiboBase; if (_hl[0] < _fibo00) { _fibo00 = _hl[0]; if (_hl[1] - _hl[0] > _fiboBase) { _fibo100 = _hl[1]; } } if (_hl[0] > _fibo100) { _fibo00 = _hl[0]; _fibo100 = _hl[1]; _trendDirection = CheckTrend(_hl[0], _hl[1], _hl[2], _hl[3]); } if (_fibo76 - RatesArray(0).MeanClose > Point * _safetyBuffer && _fibo76 - RatesArray(1).MeanClose < Point * _safetyBuffer || _fibo61 - RatesArray(0).MeanClose > Point * _safetyBuffer && _fibo61 - RatesArray(1).MeanClose < Point * _safetyBuffer || _fibo38 - RatesArray(0).MeanClose > Point * _safetyBuffer && _fibo38 - RatesArray(1).MeanClose < Point * _safetyBuffer || _fibo23 - RatesArray(0).MeanClose > Point * _safetyBuffer && _fibo23 - RatesArray(1).MeanClose < Point * _safetyBuffer) { var signal = TradeCheck(-1, data.Key, GetCurrentBid(), GetCurrentAsk(), GetCurrentDate()); if (signal != null) { signals.Add(signal); } } break; case 0: _fiboBase = 0; _fibo23 = 0; _fibo38 = 0; _fibo61 = 0; _fibo76 = 0; break; } } } return(signals); }