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
/*
* 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();
}
}
}
Alexandre Catarino
Why do you not make a pull request to Lean?
First, create an issue, so that we can give you some guidance. Normally, we ask for an unit test that compares the indicator output with an external source.
We can take a look at the implementation and merge it in.
Erik Bengtson
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!