Hi,

I'm trying to create an indicator based on the paper of John Ehler, but something is wrong, since I'm getting values above 1 and below 0, but I would expect it to range between 0 and 1. If you have any tips to provide... Thanks

Paper

 

/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using QuantConnect.Data.Market; using System; using System.Linq; namespace QuantConnect.Indicators { /// <summary> /// The Fractal Adaptive Moving Average (FRAMA) by John Ehlers /// </summary> public class RFSTO : BarIndicator { int _n = 16; int bars = 48; RollingWindow<double> _HighPass; RollingWindow<double> _Close; RollingWindow<double> _Filt; RollingWindow<double> _Stoc; RollingWindow<double> _MyStochastic; /// <summary> /// Initializes a new instance of the average class /// </summary> /// <param name="name">The name of the indicator instance</param> /// <param name="n">The window period (must be even). Example value: 16</param> /// <param name="longPeriod">The average period. Example value: 198</param> public RFSTO(string name, int period) : base(name) { _n = period; _HighPass = new RollingWindow<double>(3); _Stoc = new RollingWindow<double>(3); _MyStochastic = new RollingWindow<double>(3); _Close = new RollingWindow<double>(3); _Filt = new RollingWindow<double>(period); } /// <summary> /// Initializes a new instance of the average class /// </summary> /// <param name="n">The window period (must be even). Example value: 16</param> public RFSTO(int n) : this("RFSTO" + n, n) { } /// <summary> /// Computes the average value /// </summary> /// <param name="input">The data for the calculation</param> /// <returns>The average value</returns> protected override decimal ComputeNextValue(IBaseDataBar input) { if (!_Close.IsReady) { _Close.Add((double)input.Close); _HighPass.Add((double)0); _Filt.Add((double)0); return 0; } double alpha1, HighPass, a1, b1, c1, c2, c3, Stoc, MyStochastic, Filt; //Higass filter cyclic components whose periods are shorter than 48 bars alpha1 = (Math.Cos(.707*360 / bars) + Math.Sin (.707*360 / bars) - 1) / Math.Cos(.707*360 / bars); HighPass = (1 - alpha1 / 2)*(1 - alpha1 / 2)*((double)input.Close - 2 *_Close[1] + _Close[2]) + 2*(1 - alpha1)*_HighPass[1] - (1 - alpha1)*(1 - alpha1)*_HighPass[2]; //Smooth with a Super Smoother Filter a1 = Math.Exp(-1.414*3.14159 / 10); b1 = 2*a1*Math.Cos(1.414*180 / 10); c2 = b1; c3 = -a1*a1; c1 = 1 - c2 - c3; Filt = c1*(HighPass + _HighPass[1]) / 2 + c2*_Filt[1] + c3*_Filt[2]; double HighestC = Math.Max(Filt,_Filt.Max()); double LowestC = Math.Min(Filt,_Filt.Min()); Stoc = (Filt - LowestC) / (HighestC - LowestC); _Filt.Add(Filt); _HighPass.Add(HighPass); _Close.Add((double)input.Close); _Stoc.Add(Stoc); if (!_MyStochastic.IsReady) { _MyStochastic.Add(Stoc); return (decimal)0; } MyStochastic = c1*(Stoc + _Stoc[1]) / 2 + c2*_MyStochastic[1] + c3*_MyStochastic[2]; _MyStochastic.Add(MyStochastic); return (decimal)MyStochastic; } /// <summary> /// Returns whether the indicator will return valid results /// </summary> public override bool IsReady { get { return _MyStochastic.IsReady; } } /// <summary> /// Resets the average to its initial state /// </summary> public override void Reset() { _HighPass.Reset(); _Close.Reset(); _Filt.Reset(); _Stoc.Reset(); _MyStochastic.Reset(); base.Reset(); } } }