Hi everyone,
I'm totally new to QC and C#. My programming background is mostly in Python/R/Matlab (and some C to improve performance when necessary).
As an exercise, I tried to implement an indicator, namely the Vortex Indicator, which I believe could be useful to some of you. The Vortex Indicator is basically an "enhanced" DMI indicator (https://en.wikipedia.org/wiki/Vortex_indicator)).
Nevertheless, I am struggling a bit as I don't fully understand the Architecture of LEAN yet (and lack some C# experience). I took the ATR as a base and tried to build on that. The fact is that I am not very comfortable with the Functional indicators (is it necessary in this case?) and data structure which bothers me a bit to make the code work. Especially, I want to take the previous value of the indicator to sum it but can't help it. The Any help appreciated! Thanks in advance for your help.
Finally, one question/request does QC offer a way to call R functions (with the COM Interface)? It could could be quite useful for ML applications and other stat analysis.
Best,
L
/*
* 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 System;
using QuantConnect.Data.Market;
namespace QuantConnect.Indicators
{
///
/// SumTrueRange is defined as the maximum of the following:
/// High - Low
/// ABS(High - PreviousClose)
/// ABS(Low - PreviousClose)
/// Summed over a N peridos window
/// VMplus:
///
/// SUM(ABS(High - previous.Low), N periods)
/// VMminus:
///
/// SUM(ABS(High - previous.High), N periods)
/// Vortex Indicator:
/// VMplus / SumTrueRange - VMminus / SumTrueRange
///
///
///
public class Vortex : TradeBarIndicator
{
private Sum _Sum;
private int _period;
///
/// Gets the Sumtrue,VMplus and VMminus range which is the more volatile calculation to be smoothed by this indicator
///
public IndicatorBase
public IndicatorBase
public IndicatorBase
///
/// Gets a flag indicating when this indicator is ready and fully initialized
///
public override bool IsReady
{
get { return Samples > _period; }
}
///
/// Creates a new AverageTrueRange indicator using the specified period and moving average type
///
/// The name of this indicator
/// The smoothing period used to smooth the true range values
public Vortex(string name, int period)
: base(name)
{
_period = period;
TradeBar previous = null;
SumTrueRange = new FunctionalIndicator
{
// in our ComputeNextValue function we'll just call the ComputeTrueRange
var nextValue = ComputeSumTrueRange(previous, currentBar);
previous = currentBar;
return nextValue;
} // in our IsReady function we just need at least two sample
, trueRangeIndicator => trueRangeIndicator.Samples >= _period
);
VMplus = new FunctionalIndicator
{
// in our ComputeNextValue function we'll just call the ComputeTrueRange
var nextValue = ComputeVMplus(previous, currentBar);
previous = currentBar;
return nextValue;
} // in our IsReady function we just need at least two sample
, trueRangeIndicator => trueRangeIndicator.Samples >= _period
);
VMminus = new FunctionalIndicator
{
// in our ComputeNextValue function we'll just call the ComputeTrueRange
var nextValue = ComputeVMminus(previous, currentBar);
previous = currentBar;
return nextValue;
} // in our IsReady function we just need at least two sample
, trueRangeIndicator => trueRangeIndicator.Samples >= _period
);
}
///
/// Creates a new AverageTrueRange indicator using the specified period and moving average type
///
/// The smoothing period used to smooth the true range values
/// The type of smoothing used to smooth the true range values
public Vortex(int period)
: this("Vortex" + period, period)
{
}
public static decimal ComputeSumTrueRange(TradeBar previous, TradeBar current)
{
var range1 = current.High - current.Low;
if (previous == null)
{
return 0m;
}
var range2 = Math.Abs(current.High - previous.Close);
var range3 = Math.Abs(current.Low - previous.Close);
return SumTrueRange.Current + Math.Max(range1, Math.Max(range2, range3));
}
public static decimal ComputeVMplus(TradeBar previous, TradeBar current)
{
if (previous == null)
{
return;
}
var range = Math.Abs(current.High - previous.Low);
return Current + range;
}
public static decimal ComputeVMminus(TradeBar previous, TradeBar current)
{
if (previous == null)
{
return;
}
var range = Math.Abs(current.Low - previous.High);
return Current + range;
}
///
/// Computes the next value of this indicator from the given state
///
/// The input given to the indicator
///
protected override decimal ComputeNextValue(TradeBar input)
{
// compute the true range and then sum it
SumTrueRange.Update(input);
VMplus.Update(input);
VMminus.Update(input);
decimal VIplus= VMplus / SumTrueRange;
decimal VIminus= VMminus / SumTrueRange;
return VIplus - VIminus;
}
///
/// Resets this indicator to its initial state
///
public override void Reset()
{
TrueRange.Reset();
VMplus.Reset();
VMminus.Reset();
base.Reset();
}
}
}
Michael Handschuh
Laurent keller
Build Error: File: /Vortex.cs Line:135 Column:15 - An object reference is required for the non-static field, method, or property 'Vortex.SumTrueRange' Build Error: File: /Vortex.cs Line:150 Column:19 - An object reference is required for the non-static field, method, or property 'IndicatorBase.Current' Build Error: File: /Vortex.cs Line:163 Column:19 - An object reference is required for the non-static field, method, or property 'IndicatorBase.Current'
Jared Broad
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.
Laurent keller
Michael Handschuh
Laurent keller
AlMoJo
Hi everybody,
Â
I made a custom version of the vortex. The change compared to Mr Jared BROAD is that I smooth the Vortex line values, with the EMA length being a 2nd parameters after the Vortex length, plus I use a threshold that is either 1 + a certain value like 1.10 to be crossed by one of the 2 lines or as being the difference between the 2 line to go higher than a certain value like 0.2 (1.10 minus 0.90). The problem is that I am not a Python or C# ninja so I was only able to make the script for TV which is here and works quite well for the backtest, but is very limited for time range on M1 timeframe:Â
Anyone with an idea on how to implement the thresholding and ema smoothing? Â Thanks a lot
Â
Louis Szeto
Hi AlMoJo
We recommend using Indicator.Extension function. Please go through this doc for the usage of EMA smoothening on the Vortex indicator.
Best
Louis
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.
Laurent keller
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!