void _barlisttracker_GotNewBar(string sym, int interval) { //int idx = Array.IndexOf(_symbols, sym); int idx = _symbols.IndexOf(sym); if (_isactive && _issymbolactive[idx]) { BarList bl = _barlisttracker[sym, interval]; double[] closes = Calc.Decimal2Double(bl.Close()); // when NewBar is triggered, the latest bar only has one tick closes = closes.Take(closes.Length - 1).ToArray(); EMAResult result = AnalysisEngine.EMA(closes, _barslookback, false); if (result.Values.Count == 0) // Not enough bars { return; } // check if (!_waittobefilled[idx]) { double ema = result.Values.Last(); if (_positiontracker[sym].isFlat) { // if our current price is above EMA if (closes.Last() > ema) { SendDebug("Cross above EMA, buy"); _waittobefilled[idx] = true; SendOrder(new MarketOrder(sym, sym.Contains("STK")?_tradesize:2)); } // if our current price is below EMA else if (closes.Last() < ema) { SendDebug("Cross below EMA, sell"); _waittobefilled[idx] = true; SendOrder(new MarketOrder(sym, -(sym.Contains("STK") ? _tradesize : 2))); } } else if ((_positiontracker[sym].isLong && (closes.Last() < ema)) || (_positiontracker[sym].isShort && (closes.Last() > ema))) { SendDebug("Counter trend, exit."); _waittobefilled[idx] = true; SendOrder(new MarketOrderFlat(_positiontracker[sym])); } // this way we can debug our indicators during development // indicators are sent in the same order as they are named above if (_waittobefilled[idx]) { SendIndicators(new string[] { "Time: " + _currenttime.ToString(), " EMA:" + ema.ToString("F2", System.Globalization.CultureInfo.InvariantCulture) }); } } } }
//------------------------------------------------------------------------------------------------------------------------------- /// <summary> /// Calculates Exponential Moving Average (EMA) indicator /// </summary> /// <param name="input">Input signal</param> /// <param name="period">Number of periods</param> /// <returns>Object containing operation results</returns> public static EMAResult EMA(IEnumerable <double> input, int period) { var returnValues = new List <double>(); double multiplier = (2.0 / (period + 1)); //double initialSMA = input.Take(period).Average(); //returnValues.Add(initialSMA); var copyInputValues = input.ToList(); int j = 0; for (int i = copyInputValues.Count - period; i < copyInputValues.Count; i++) { if (j < 1) { var resultValue = copyInputValues[i]; returnValues.Add(resultValue); } else { var resultValue = (copyInputValues[i] * multiplier) + (1 - multiplier) * returnValues.Last(); returnValues.Add(resultValue); } j++; } var result = new EMAResult() { EmaR = returnValues.Last(), Values = returnValues, StartIndexOffset = period - 1 }; return(result); }