chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// This indicator computes the Absolute Price Oscillator (APO)
|
||||
/// The Absolute Price Oscillator is calculated using the following formula:
|
||||
/// APO[i] = FastMA[i] - SlowMA[i]
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The Absolute Price Oscillator is the same as a MACD with the signal period equal to the slow period.
|
||||
/// </remarks>
|
||||
public class AbsolutePriceOscillator : MovingAverageConvergenceDivergence
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AbsolutePriceOscillator"/> class using the specified name and parameters.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="fastPeriod">The fast moving average period</param>
|
||||
/// <param name="slowPeriod">The slow moving average period</param>
|
||||
/// <param name="movingAverageType">The type of moving average to use</param>
|
||||
public AbsolutePriceOscillator(string name, int fastPeriod, int slowPeriod, MovingAverageType movingAverageType = MovingAverageType.Simple)
|
||||
: base(name, fastPeriod, slowPeriod, slowPeriod, movingAverageType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AbsolutePriceOscillator"/> class using the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="fastPeriod">The fast moving average period</param>
|
||||
/// <param name="slowPeriod">The slow moving average period</param>
|
||||
/// <param name="movingAverageType">The type of moving average to use</param>
|
||||
public AbsolutePriceOscillator(int fastPeriod, int slowPeriod, MovingAverageType movingAverageType = MovingAverageType.Simple)
|
||||
: this($"APO({fastPeriod},{slowPeriod})", fastPeriod, slowPeriod, movingAverageType)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// The Acceleration Bands created by Price Headley plots upper and lower envelope bands around a moving average.
|
||||
/// </summary>
|
||||
/// <seealso cref="Indicators.IndicatorBase{IBaseDataBar}" />
|
||||
public class AccelerationBands : IndicatorBase<IBaseDataBar>, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
private readonly decimal _width;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of moving average
|
||||
/// </summary>
|
||||
public MovingAverageType MovingAverageType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the middle acceleration band (moving average)
|
||||
/// </summary>
|
||||
public IndicatorBase<IndicatorDataPoint> MiddleBand { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the upper acceleration band (High * ( 1 + Width * (High - Low) / (High + Low)))
|
||||
/// </summary>
|
||||
public IndicatorBase<IndicatorDataPoint> UpperBand { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the lower acceleration band (Low * (1 - Width * (High - Low)/ (High + Low)))
|
||||
/// </summary>
|
||||
public IndicatorBase<IndicatorDataPoint> LowerBand { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AccelerationBands" /> class.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator.</param>
|
||||
/// <param name="period">The period of the three moving average (middle, upper and lower band).</param>
|
||||
/// <param name="width">A coefficient specifying the distance between the middle band and upper or lower bands.</param>
|
||||
/// <param name="movingAverageType">Type of the moving average.</param>
|
||||
public AccelerationBands(string name, int period, decimal width,
|
||||
MovingAverageType movingAverageType = MovingAverageType.Simple)
|
||||
: base(name)
|
||||
{
|
||||
WarmUpPeriod = period;
|
||||
_width = width;
|
||||
MovingAverageType = movingAverageType;
|
||||
MiddleBand = movingAverageType.AsIndicator(name + "_MiddleBand", period);
|
||||
LowerBand = movingAverageType.AsIndicator(name + "_LowerBand", period);
|
||||
UpperBand = movingAverageType.AsIndicator(name + "_UpperBand", period);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AccelerationBands" /> class.
|
||||
/// </summary>
|
||||
/// <param name="period">The period of the three moving average (middle, upper and lower band).</param>
|
||||
/// <param name="width">A coefficient specifying the distance between the middle band and upper or lower bands.</param>
|
||||
/// <param name="movingAverageType">Type of the moving average.</param>
|
||||
public AccelerationBands(int period, decimal width,
|
||||
MovingAverageType movingAverageType = MovingAverageType.Simple)
|
||||
: this($"ABANDS({period},{width},{movingAverageType})", period, width, movingAverageType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AccelerationBands" /> class.
|
||||
/// </summary>
|
||||
/// <param name="period">The period of the three moving average (middle, upper and lower band).</param>
|
||||
public AccelerationBands(int period)
|
||||
: this(period, 4)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => MiddleBand.IsReady && LowerBand.IsReady && UpperBand.IsReady;
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
MiddleBand.Reset();
|
||||
LowerBand.Reset();
|
||||
UpperBand.Reset();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>
|
||||
/// A new value for this indicator
|
||||
/// </returns>
|
||||
protected override decimal ComputeNextValue(IBaseDataBar input)
|
||||
{
|
||||
var coefficient = _width * (input.High - input.Low).SafeDivision(input.High + input.Low);
|
||||
|
||||
LowerBand.Update(input.EndTime, input.Low * (1 - coefficient));
|
||||
UpperBand.Update(input.EndTime, input.High * (1 + coefficient));
|
||||
MiddleBand.Update(input.EndTime, input.Close);
|
||||
|
||||
return MiddleBand.Current.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// This indicator computes the Accumulation/Distribution (AD)
|
||||
/// The Accumulation/Distribution is calculated using the following formula:
|
||||
/// AD = AD + ((Close - Low) - (High - Close)) / (High - Low) * Volume
|
||||
/// </summary>
|
||||
public class AccumulationDistribution : TradeBarIndicator, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AccumulationDistribution"/> class using the specified name.
|
||||
/// </summary>
|
||||
public AccumulationDistribution()
|
||||
: this("AD")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AccumulationDistribution"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public AccumulationDistribution(string name)
|
||||
: base(name)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => Samples > 0;
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod => 1;
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(TradeBar input)
|
||||
{
|
||||
var range = input.High - input.Low;
|
||||
return Current.Value + (range > 0 ? ((input.Close - input.Low) - (input.High - input.Close)) / range * input.Volume : 0m);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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
|
||||
{
|
||||
/// <summary>
|
||||
/// This indicator computes the Accumulation/Distribution Oscillator (ADOSC)
|
||||
/// The Accumulation/Distribution Oscillator is calculated using the following formula:
|
||||
/// ADOSC = EMA(fast,AD) - EMA(slow,AD)
|
||||
/// </summary>
|
||||
public class AccumulationDistributionOscillator : TradeBarIndicator, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
private readonly int _period;
|
||||
private readonly AccumulationDistribution _ad;
|
||||
private readonly ExponentialMovingAverage _emaFast;
|
||||
private readonly ExponentialMovingAverage _emaSlow;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AccumulationDistributionOscillator"/> class using the specified parameters
|
||||
/// </summary>
|
||||
/// <param name="fastPeriod">The fast moving average period</param>
|
||||
/// <param name="slowPeriod">The slow moving average period</param>
|
||||
public AccumulationDistributionOscillator(int fastPeriod, int slowPeriod)
|
||||
: this($"ADOSC({fastPeriod},{slowPeriod})", fastPeriod, slowPeriod)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AccumulationDistributionOscillator"/> class using the specified parameters
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="fastPeriod">The fast moving average period</param>
|
||||
/// <param name="slowPeriod">The slow moving average period</param>
|
||||
public AccumulationDistributionOscillator(string name, int fastPeriod, int slowPeriod)
|
||||
: base(name)
|
||||
{
|
||||
_period = Math.Max(fastPeriod, slowPeriod);
|
||||
_ad = new AccumulationDistribution(name + "_AD");
|
||||
_emaFast = new ExponentialMovingAverage(name + "_Fast", fastPeriod);
|
||||
_emaSlow = new ExponentialMovingAverage(name + "_Slow", slowPeriod);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => Samples >= _period;
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod => _period;
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(TradeBar input)
|
||||
{
|
||||
_ad.Update(input);
|
||||
_emaFast.Update(_ad.Current);
|
||||
_emaSlow.Update(_ad.Current);
|
||||
|
||||
return IsReady ? _emaFast.Current.Value - _emaSlow.Current.Value : 0m;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_ad.Reset();
|
||||
_emaFast.Reset();
|
||||
_emaSlow.Reset();
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.Linq;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// The Advance Decline Difference compute the difference between the number of stocks
|
||||
/// that closed higher and the number of stocks that closed lower than their previous day's closing prices.
|
||||
/// </summary>
|
||||
public class AdvanceDeclineDifference : AdvanceDeclineIndicator
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AdvanceDeclineDifference"/> class
|
||||
/// </summary>
|
||||
public AdvanceDeclineDifference(string name = "A/D Difference")
|
||||
: base(name, (entries) => entries.Count(), (advance, decline) => advance - decline) { }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// The advance-decline indicator compares the number of stocks
|
||||
/// that closed higher against the number of stocks
|
||||
/// that closed lower than their previous day's closing prices.
|
||||
/// </summary>
|
||||
public abstract class AdvanceDeclineIndicator : TradeBarIndicator, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
private IDictionary<SecurityIdentifier, TradeBar> _previousPeriod = new Dictionary<SecurityIdentifier, TradeBar>();
|
||||
private IDictionary<SecurityIdentifier, TradeBar> _currentPeriod = new Dictionary<SecurityIdentifier, TradeBar>();
|
||||
private readonly Func<IEnumerable<TradeBar>, decimal> _computeSubValue;
|
||||
private readonly Func<decimal, decimal, decimal> _computeMainValue;
|
||||
private DateTime? _currentPeriodTime = null;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AdvanceDeclineRatio"/> class
|
||||
/// </summary>
|
||||
public AdvanceDeclineIndicator(string name, Func<IEnumerable<TradeBar>, decimal> computeSub, Func<decimal, decimal, decimal> computeMain)
|
||||
: base(name)
|
||||
{
|
||||
_computeSubValue = computeSub;
|
||||
_computeMainValue = computeMain;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add tracking asset issue
|
||||
/// </summary>
|
||||
/// <param name="asset">tracking asset issue</param>
|
||||
public virtual void Add(Symbol asset)
|
||||
{
|
||||
if (!_currentPeriod.ContainsKey(asset.ID))
|
||||
{
|
||||
_currentPeriod.Add(asset.ID, null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deprecated
|
||||
/// </summary>
|
||||
[Obsolete("Please use Add(asset)")]
|
||||
public void AddStock(Symbol asset)
|
||||
{
|
||||
Add(asset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove tracking asset issue
|
||||
/// </summary>
|
||||
/// <param name="asset">tracking asset issue</param>
|
||||
public virtual void Remove(Symbol asset)
|
||||
{
|
||||
_currentPeriod.Remove(asset.ID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deprecated
|
||||
/// </summary>
|
||||
[Obsolete("Please use Remove(asset)")]
|
||||
public void RemoveStock(Symbol asset)
|
||||
{
|
||||
Remove(asset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => _previousPeriod.Keys.Any();
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod => 2;
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(TradeBar input)
|
||||
{
|
||||
var advStocks = new List<TradeBar>();
|
||||
var dclStocks = new List<TradeBar>();
|
||||
|
||||
TradeBar tradeBar;
|
||||
foreach (var stock in _currentPeriod)
|
||||
{
|
||||
if (!_previousPeriod.TryGetValue(stock.Key, out tradeBar) || tradeBar == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (stock.Value.Close < tradeBar.Close)
|
||||
{
|
||||
dclStocks.Add(stock.Value);
|
||||
}
|
||||
else if (stock.Value.Close > tradeBar.Close)
|
||||
{
|
||||
advStocks.Add(stock.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return _computeMainValue(_computeSubValue(advStocks), _computeSubValue(dclStocks));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override IndicatorResult ValidateAndComputeNextValue(TradeBar input)
|
||||
{
|
||||
Enqueue(input);
|
||||
|
||||
if (!_previousPeriod.Keys.Any() || _currentPeriod.Any(p => p.Value == null))
|
||||
{
|
||||
return new IndicatorResult(0, IndicatorStatus.ValueNotReady);
|
||||
}
|
||||
|
||||
var vNext = ComputeNextValue(input);
|
||||
return new IndicatorResult(vNext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_previousPeriod.Clear();
|
||||
foreach (var key in _currentPeriod.Keys.ToList())
|
||||
{
|
||||
_currentPeriod[key] = null;
|
||||
}
|
||||
|
||||
base.Reset();
|
||||
}
|
||||
|
||||
private void Enqueue(TradeBar input)
|
||||
{
|
||||
if (input.EndTime == _currentPeriodTime)
|
||||
{
|
||||
_previousPeriod[input.Symbol.ID] = input;
|
||||
return;
|
||||
}
|
||||
|
||||
if (input.Time > _currentPeriodTime)
|
||||
{
|
||||
_previousPeriod.Clear();
|
||||
foreach (var key in _currentPeriod.Keys.ToList())
|
||||
{
|
||||
_previousPeriod[key] = _currentPeriod[key];
|
||||
_currentPeriod[key] = null;
|
||||
}
|
||||
_currentPeriodTime = input.Time;
|
||||
}
|
||||
|
||||
if (_currentPeriod.ContainsKey(input.Symbol.ID) && (!_currentPeriodTime.HasValue || input.Time == _currentPeriodTime))
|
||||
{
|
||||
_currentPeriod[input.Symbol.ID] = input;
|
||||
if (!_currentPeriodTime.HasValue)
|
||||
{
|
||||
_currentPeriodTime = input.Time;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.Linq;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// The advance-decline ratio (ADR) compares the number of stocks
|
||||
/// that closed higher against the number of stocks
|
||||
/// that closed lower than their previous day's closing prices.
|
||||
/// </summary>
|
||||
public class AdvanceDeclineRatio : AdvanceDeclineIndicator
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AdvanceDeclineRatio"/> class
|
||||
/// </summary>
|
||||
public AdvanceDeclineRatio(string name = "A/D Ratio")
|
||||
: base(name, (entries) => entries.Count(), (advance, decline) => decline == 0m ? advance : advance / decline) { }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.Linq;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// The Advance Decline Volume Ratio is a Breadth indicator calculated as ratio of
|
||||
/// summary volume of advancing stocks to summary volume of declining stocks.
|
||||
/// AD Volume Ratio is used in technical analysis to see where the main trading activity is focused.
|
||||
/// </summary>
|
||||
public class AdvanceDeclineVolumeRatio : AdvanceDeclineIndicator
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AdvanceDeclineVolumeRatio"/> class
|
||||
/// </summary>
|
||||
public AdvanceDeclineVolumeRatio(string name = "A/D Volume Rate")
|
||||
: base(name, (entries) => entries.Sum(x => x.Volume), (advance, decline) => decline == 0m ? advance : advance / decline) { }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,341 @@
|
||||
/*
|
||||
* 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 Python.Runtime;
|
||||
using QuantConnect.Data;
|
||||
using QuantConnect.Data.Market;
|
||||
using QuantConnect.Python;
|
||||
using System;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// In financial analysis, the Alpha indicator is used to measure the performance of an investment (such as a stock or ETF)
|
||||
/// relative to a benchmark index, often representing the broader market. Alpha indicates the excess return of the investment
|
||||
/// compared to the return of the benchmark index.
|
||||
///
|
||||
/// The S P 500 index is frequently used as a benchmark in Alpha calculations to represent the overall market performance.
|
||||
/// Alpha is an essential tool for investors to understand the idiosyncratic returns of their investment that aren't caused
|
||||
/// by movement in the underlying benchmark.
|
||||
/// </summary>
|
||||
|
||||
public class Alpha : BarIndicator, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Symbol of the reference used
|
||||
/// </summary>
|
||||
private readonly Symbol _referenceSymbol;
|
||||
|
||||
/// <summary>
|
||||
/// Symbol of the target used
|
||||
/// </summary>
|
||||
private readonly Symbol _targetSymbol;
|
||||
|
||||
/// <summary>
|
||||
/// Period of the indicator - alpha
|
||||
/// </summary>
|
||||
private readonly decimal _alphaPeriod;
|
||||
|
||||
/// <summary>
|
||||
/// Rate of change of the target symbol
|
||||
/// </summary>
|
||||
private readonly RateOfChange _targetROC;
|
||||
|
||||
/// <summary>
|
||||
/// Rate of change of the reference symbol
|
||||
/// </summary>
|
||||
private readonly RateOfChange _referenceROC;
|
||||
|
||||
/// <summary>
|
||||
/// Alpha of the target used in relation with the reference
|
||||
/// </summary>
|
||||
private decimal _alpha;
|
||||
|
||||
/// <summary>
|
||||
/// Beta of the target used in relation with the reference
|
||||
/// </summary>
|
||||
private readonly Beta _beta;
|
||||
|
||||
/// <summary>
|
||||
/// Interest rate model used to compute the risk free rate
|
||||
/// </summary>
|
||||
private readonly IRiskFreeInterestRateModel _riskFreeInterestRateModel;
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when the indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => _targetROC.IsReady && _beta.IsReady && _referenceROC.IsReady;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Alpha indicator with the specified name, target, reference, and period values
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="targetSymbol">The target symbol of this indicator</param>
|
||||
/// <param name="referenceSymbol">The reference symbol of this indicator</param>
|
||||
/// <param name="alphaPeriod">Period of the indicator - alpha</param>
|
||||
/// <param name="betaPeriod">Period of the indicator - beta</param>
|
||||
/// <param name="riskFreeRateModel">The risk free rate model of this indicator</param>
|
||||
public Alpha(string name, Symbol targetSymbol, Symbol referenceSymbol, int alphaPeriod, int betaPeriod, IRiskFreeInterestRateModel riskFreeRateModel)
|
||||
: base(name)
|
||||
{
|
||||
// Assert that the target and reference symbols are not the same
|
||||
if (targetSymbol == referenceSymbol)
|
||||
{
|
||||
throw new ArgumentException("The target and reference symbols cannot be the same.");
|
||||
}
|
||||
|
||||
// Assert that the period is greater than 2, otherwise the alpha can not be computed
|
||||
if (alphaPeriod < 1)
|
||||
{
|
||||
throw new ArgumentException("The period must be equal or greater than 1.");
|
||||
}
|
||||
|
||||
// Assert that the beta period is greater than 2, otherwise the beta can not be computed
|
||||
if (betaPeriod < 2)
|
||||
{
|
||||
throw new ArgumentException("The beta period must be equal or greater than 2.");
|
||||
}
|
||||
|
||||
_targetSymbol = targetSymbol;
|
||||
_referenceSymbol = referenceSymbol;
|
||||
_alphaPeriod = alphaPeriod;
|
||||
_riskFreeInterestRateModel = riskFreeRateModel;
|
||||
|
||||
_targetROC = new RateOfChange($"{name}_TargetROC", alphaPeriod);
|
||||
_referenceROC = new RateOfChange($"{name}_ReferenceROC", alphaPeriod);
|
||||
|
||||
_beta = new Beta($"{name}_Beta", _targetSymbol, _referenceSymbol, betaPeriod);
|
||||
|
||||
WarmUpPeriod = alphaPeriod >= betaPeriod ? alphaPeriod + 1 : betaPeriod + 1;
|
||||
|
||||
_alpha = 0m;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Alpha indicator with the specified name, target, reference, and period values
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="targetSymbol">The target symbol of this indicator</param>
|
||||
/// <param name="referenceSymbol">The reference symbol of this indicator</param>
|
||||
/// <param name="alphaPeriod">Period of the indicator - alpha</param>
|
||||
/// <param name="betaPeriod">Period of the indicator - beta</param>
|
||||
/// <param name="riskFreeRate">The risk free rate of this indicator for given period</param>
|
||||
public Alpha(string name, Symbol targetSymbol, Symbol referenceSymbol, int alphaPeriod, int betaPeriod, decimal? riskFreeRate = null)
|
||||
: this(name, targetSymbol, referenceSymbol, alphaPeriod, betaPeriod, new ConstantRiskFreeRateInterestRateModel(riskFreeRate ?? 0m))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Alpha indicator with the specified target, reference, and period values
|
||||
/// </summary>
|
||||
/// <param name="targetSymbol"></param>
|
||||
/// <param name="referenceSymbol"></param>
|
||||
/// <param name="alphaPeriod">Period of the indicator - alpha</param>
|
||||
/// <param name="betaPeriod">Period of the indicator - beta</param>
|
||||
/// <param name="riskFreeRate">The risk free rate of this indicator for given period</param>
|
||||
public Alpha(Symbol targetSymbol, Symbol referenceSymbol, int alphaPeriod, int betaPeriod, decimal? riskFreeRate = null)
|
||||
: this($"ALPHA({targetSymbol},{referenceSymbol},{alphaPeriod},{betaPeriod},{riskFreeRate})", targetSymbol, referenceSymbol, alphaPeriod, betaPeriod, new ConstantRiskFreeRateInterestRateModel(riskFreeRate ?? 0m))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Alpha indicator with the specified target, reference, and period value
|
||||
/// </summary>
|
||||
/// <param name="targetSymbol">The target symbol of this indicator</param>
|
||||
/// <param name="referenceSymbol">The reference symbol of this indicator</param>
|
||||
/// <param name="period">Period of the indicator - alpha and beta</param>
|
||||
/// <param name="riskFreeRate">The risk free rate of this indicator for given period</param>
|
||||
public Alpha(Symbol targetSymbol, Symbol referenceSymbol, int period, decimal? riskFreeRate = null)
|
||||
: this($"ALPHA({targetSymbol},{referenceSymbol},{period},{riskFreeRate})", targetSymbol, referenceSymbol, period, period, new ConstantRiskFreeRateInterestRateModel(riskFreeRate ?? 0m))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Alpha indicator with the specified name, target, reference, and period value
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="targetSymbol"></param>
|
||||
/// <param name="referenceSymbol"></param>
|
||||
/// <param name="period">Period of the indicator - alpha and beta</param>
|
||||
/// <param name="riskFreeRate">The risk free rate of this indicator for given period</param>
|
||||
public Alpha(string name, Symbol targetSymbol, Symbol referenceSymbol, int period, decimal? riskFreeRate = null)
|
||||
: this(name, targetSymbol, referenceSymbol, period, period, new ConstantRiskFreeRateInterestRateModel(riskFreeRate ?? 0m))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Alpha indicator with the specified target, reference, and period values
|
||||
/// </summary>
|
||||
/// <param name="targetSymbol"></param>
|
||||
/// <param name="referenceSymbol"></param>
|
||||
/// <param name="alphaPeriod">Period of the indicator - alpha</param>
|
||||
/// <param name="betaPeriod">Period of the indicator - beta</param>
|
||||
/// <param name="riskFreeRateModel">The risk free rate model of this indicator</param>
|
||||
public Alpha(Symbol targetSymbol, Symbol referenceSymbol, int alphaPeriod, int betaPeriod, IRiskFreeInterestRateModel riskFreeRateModel)
|
||||
: this($"ALPHA({targetSymbol},{referenceSymbol},{alphaPeriod},{betaPeriod})", targetSymbol, referenceSymbol, alphaPeriod, betaPeriod, riskFreeRateModel)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Alpha indicator with the specified target, reference, and period value
|
||||
/// </summary>
|
||||
/// <param name="targetSymbol">The target symbol of this indicator</param>
|
||||
/// <param name="referenceSymbol">The reference symbol of this indicator</param>
|
||||
/// <param name="period">Period of the indicator - alpha and beta</param>
|
||||
/// <param name="riskFreeRateModel">The risk free rate model of this indicator</param>
|
||||
public Alpha(Symbol targetSymbol, Symbol referenceSymbol, int period, IRiskFreeInterestRateModel riskFreeRateModel)
|
||||
: this($"ALPHA({targetSymbol},{referenceSymbol},{period})", targetSymbol, referenceSymbol, period, period, riskFreeRateModel)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Alpha indicator with the specified name, target, reference, and period value
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="targetSymbol"></param>
|
||||
/// <param name="referenceSymbol"></param>
|
||||
/// <param name="period">Period of the indicator - alpha and beta</param>
|
||||
/// <param name="riskFreeRateModel">The risk free rate model of this indicator</param>
|
||||
public Alpha(string name, Symbol targetSymbol, Symbol referenceSymbol, int period, IRiskFreeInterestRateModel riskFreeRateModel)
|
||||
: this(name, targetSymbol, referenceSymbol, period, period, riskFreeRateModel)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Alpha indicator with the specified name, target, reference, and period values
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="targetSymbol">The target symbol of this indicator</param>
|
||||
/// <param name="referenceSymbol">The reference symbol of this indicator</param>
|
||||
/// <param name="alphaPeriod">Period of the indicator - alpha</param>
|
||||
/// <param name="betaPeriod">Period of the indicator - beta</param>
|
||||
/// <param name="riskFreeRateModel">The risk free rate model of this indicator</param>
|
||||
public Alpha(string name, Symbol targetSymbol, Symbol referenceSymbol, int alphaPeriod, int betaPeriod, PyObject riskFreeRateModel)
|
||||
: this(name, targetSymbol, referenceSymbol, alphaPeriod, betaPeriod, RiskFreeInterestRateModelPythonWrapper.FromPyObject(riskFreeRateModel))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Alpha indicator with the specified target, reference, and period values
|
||||
/// </summary>
|
||||
/// <param name="targetSymbol"></param>
|
||||
/// <param name="referenceSymbol"></param>
|
||||
/// <param name="alphaPeriod">Period of the indicator - alpha</param>
|
||||
/// <param name="betaPeriod">Period of the indicator - beta</param>
|
||||
/// <param name="riskFreeRateModel">The risk free rate model of this indicator</param>
|
||||
public Alpha(Symbol targetSymbol, Symbol referenceSymbol, int alphaPeriod, int betaPeriod, PyObject riskFreeRateModel)
|
||||
: this($"ALPHA({targetSymbol},{referenceSymbol},{alphaPeriod},{betaPeriod})", targetSymbol, referenceSymbol, alphaPeriod, betaPeriod, RiskFreeInterestRateModelPythonWrapper.FromPyObject(riskFreeRateModel))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Alpha indicator with the specified target, reference, and period value
|
||||
/// </summary>
|
||||
/// <param name="targetSymbol">The target symbol of this indicator</param>
|
||||
/// <param name="referenceSymbol">The reference symbol of this indicator</param>
|
||||
/// <param name="period">Period of the indicator - alpha and beta</param>
|
||||
/// <param name="riskFreeRateModel">The risk free rate model of this indicator</param>
|
||||
public Alpha(Symbol targetSymbol, Symbol referenceSymbol, int period, PyObject riskFreeRateModel)
|
||||
: this($"ALPHA({targetSymbol},{referenceSymbol},{period})", targetSymbol, referenceSymbol, period, period, RiskFreeInterestRateModelPythonWrapper.FromPyObject(riskFreeRateModel))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Alpha indicator with the specified name, target, reference, and period value
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="targetSymbol"></param>
|
||||
/// <param name="referenceSymbol"></param>
|
||||
/// <param name="period">Period of the indicator - alpha and beta</param>
|
||||
/// <param name="riskFreeRateModel">The risk free rate model of this indicator</param>
|
||||
public Alpha(string name, Symbol targetSymbol, Symbol referenceSymbol, int period, PyObject riskFreeRateModel)
|
||||
: this(name, targetSymbol, referenceSymbol, period, period, RiskFreeInterestRateModelPythonWrapper.FromPyObject(riskFreeRateModel))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value for this indicator from the given state.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
protected override decimal ComputeNextValue(IBaseDataBar input)
|
||||
{
|
||||
if (input is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(input));
|
||||
}
|
||||
var inputSymbol = input.Symbol;
|
||||
|
||||
if (inputSymbol == _targetSymbol)
|
||||
{
|
||||
_targetROC.Update(input.EndTime, input.Close);
|
||||
}
|
||||
else if (inputSymbol == _referenceSymbol)
|
||||
{
|
||||
_referenceROC.Update(input.EndTime, input.Close);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException($"The input symbol {inputSymbol} is not the target or reference symbol.");
|
||||
}
|
||||
|
||||
_beta.Update(input);
|
||||
|
||||
if (_targetROC.Samples == _referenceROC.Samples && _referenceROC.Samples > 0)
|
||||
{
|
||||
ComputeAlpha();
|
||||
}
|
||||
|
||||
return _alpha;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the alpha of the target used in relation with the reference and stores it in the _alpha field
|
||||
/// </summary>
|
||||
private void ComputeAlpha()
|
||||
{
|
||||
if (!_beta.IsReady || !_targetROC.IsReady || !_referenceROC.IsReady)
|
||||
{
|
||||
_alpha = 0m;
|
||||
return;
|
||||
}
|
||||
|
||||
var targetMean = _targetROC.Current.Value / _alphaPeriod;
|
||||
var referenceMean = _referenceROC.Current.Value / _alphaPeriod;
|
||||
|
||||
var riskFreeRate = _riskFreeInterestRateModel.GetInterestRate(_targetROC.Current.EndTime);
|
||||
|
||||
_alpha = targetMean - (riskFreeRate + _beta.Current.Value * (referenceMean - riskFreeRate));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_targetROC.Reset();
|
||||
_referenceROC.Reset();
|
||||
_beta.Reset();
|
||||
_alpha = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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
|
||||
{
|
||||
/// <summary>
|
||||
/// The Arms Index, also called the Short-Term Trading Index (TRIN)
|
||||
/// is a technical analysis indicator that compares the number of advancing
|
||||
/// and declining stocks (AD Ratio) to advancing and declining volume (AD volume).
|
||||
/// </summary>
|
||||
public class ArmsIndex : TradeBarIndicator, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
private readonly IndicatorBase<IndicatorDataPoint> _arms;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Advance/Decline Ratio (ADR) indicator
|
||||
/// </summary>
|
||||
public AdvanceDeclineRatio ADRatio { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Advance/Decline Volume Ratio (ADVR) indicator
|
||||
/// </summary>
|
||||
public AdvanceDeclineVolumeRatio ADVRatio { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ArmsIndex"/> class
|
||||
/// </summary>
|
||||
public ArmsIndex(string name = "TRIN") : base(name)
|
||||
{
|
||||
ADRatio = new AdvanceDeclineRatio(name + "_A/D Ratio");
|
||||
ADVRatio = new AdvanceDeclineVolumeRatio(name + "_A/D Volume Ratio");
|
||||
|
||||
_arms = ADRatio.Over(ADVRatio, name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => ADRatio.IsReady && ADVRatio.IsReady;
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod => System.Math.Max(ADRatio.WarmUpPeriod, ADVRatio.WarmUpPeriod);
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(TradeBar input)
|
||||
{
|
||||
ADRatio.Update(input);
|
||||
ADVRatio.Update(input);
|
||||
|
||||
if (ADVRatio == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _arms.Current.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
ADRatio.Reset();
|
||||
ADVRatio.Reset();
|
||||
_arms.Reset();
|
||||
|
||||
base.Reset();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add Tracking stock issue
|
||||
/// </summary>
|
||||
/// <param name="asset">the tracking stock issue</param>
|
||||
public void Add(Symbol asset)
|
||||
{
|
||||
ADRatio.Add(asset);
|
||||
ADVRatio.Add(asset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deprecated
|
||||
/// </summary>
|
||||
[Obsolete("Please use Add(asset)")]
|
||||
public void AddStock(Symbol asset)
|
||||
{
|
||||
Add(asset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove Tracking stock issue
|
||||
/// </summary>
|
||||
/// <param name="asset">the tracking stock issue</param>
|
||||
public void Remove(Symbol asset)
|
||||
{
|
||||
ADRatio.Remove(asset);
|
||||
ADVRatio.Remove(asset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deprecated
|
||||
/// </summary>
|
||||
[Obsolete("Please use Remove(asset)")]
|
||||
public void RemoveStock(Symbol asset)
|
||||
{
|
||||
Remove(asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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 System.Linq;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// Smooth and high sensitive moving Average. This moving average reduce lag of the information
|
||||
/// but still being smooth to reduce noises.
|
||||
/// Is a weighted moving average, which weights have a Normal shape;
|
||||
/// the parameters Sigma and Offset affect the kurtosis and skewness of the weights respectively.
|
||||
/// Source: https://www.cjournal.cz/files/308.pdf
|
||||
/// </summary>
|
||||
/// <seealso cref="IndicatorDataPoint" />
|
||||
public class ArnaudLegouxMovingAverage : WindowIndicator<IndicatorDataPoint>, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
private readonly decimal[] _weightVector;
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod => _weightVector.Length;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ArnaudLegouxMovingAverage" /> class.
|
||||
/// </summary>
|
||||
/// <param name="name">string - a name for the indicator</param>
|
||||
/// <param name="period">int - the number of periods to calculate the ALMA</param>
|
||||
/// <param name="sigma">
|
||||
/// int - this parameter is responsible for the shape of the curve coefficients. It affects the weight vector kurtosis.
|
||||
/// </param>
|
||||
/// <param name="offset">
|
||||
/// decimal - This parameter allows regulating the smoothness and high sensitivity of the
|
||||
/// Moving Average. The range for this parameter is [0, 1]. It affects the weight vector skewness.
|
||||
/// </param>
|
||||
public ArnaudLegouxMovingAverage(string name, int period, int sigma = 6, decimal offset = 0.85m)
|
||||
: base(name, period)
|
||||
{
|
||||
if (offset < 0 || offset > 1) throw new ArgumentException($"Offset parameter range is [0,1]. Value: {offset}", nameof(offset));
|
||||
|
||||
var m = Math.Floor(offset * (period - 1));
|
||||
var s = period * 1m / sigma;
|
||||
|
||||
var tmpVector = Enumerable.Range(0, period)
|
||||
.Select(i => Math.Exp((double) (-(i - m) * (i - m) / (2 * s * s))))
|
||||
.ToArray();
|
||||
|
||||
_weightVector = tmpVector
|
||||
.Select(i => (decimal) (i / tmpVector.Sum())).Reverse()
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ArnaudLegouxMovingAverage" /> class.
|
||||
/// </summary>
|
||||
/// <param name="name">string - a name for the indicator</param>
|
||||
/// <param name="period">int - the number of periods to calculate the ALMA.</param>
|
||||
public ArnaudLegouxMovingAverage(string name, int period)
|
||||
: this(name, period, 6)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ArnaudLegouxMovingAverage" /> class.
|
||||
/// </summary>
|
||||
/// <param name="period">int - the number of periods to calculate the ALMA</param>
|
||||
/// <param name="sigma">
|
||||
/// int - this parameter is responsible for the shape of the curve coefficients. It affects the weight
|
||||
/// vector kurtosis.
|
||||
/// </param>
|
||||
/// <param name="offset">
|
||||
/// decimal - This parameter allows regulating the smoothness and high sensitivity of the Moving
|
||||
/// Average. The range for this parameter is [0, 1]. It affects the weight vector skewness.
|
||||
/// </param>
|
||||
public ArnaudLegouxMovingAverage(int period, int sigma, decimal offset = 0.85m)
|
||||
: this($"ALMA({period},{sigma},{offset})", period, sigma, offset)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ArnaudLegouxMovingAverage" /> class.
|
||||
/// </summary>
|
||||
/// <param name="period">int - the number of periods to calculate the ALMA.</param>
|
||||
public ArnaudLegouxMovingAverage(int period)
|
||||
: this(period, 6)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value for this indicator from the given state.
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input value to this indicator on this time step</param>
|
||||
/// <returns>
|
||||
/// A new value for this indicator
|
||||
/// </returns>
|
||||
/// <exception cref="System.NotImplementedException"></exception>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IndicatorDataPoint> window,
|
||||
IndicatorDataPoint input)
|
||||
{
|
||||
return IsReady
|
||||
? window.Select((t, i) => t.Price * _weightVector[i]).Sum()
|
||||
: input.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// The Aroon Oscillator is the difference between AroonUp and AroonDown. The value of this
|
||||
/// indicator fluctuates between -100 and +100. An upward trend bias is present when the oscillator
|
||||
/// is positive, and a negative trend bias is present when the oscillator is negative. AroonUp/Down
|
||||
/// values over 75 identify strong trends in their respective direction.
|
||||
/// </summary>
|
||||
public class AroonOscillator : BarIndicator, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the AroonUp indicator
|
||||
/// </summary>
|
||||
public IndicatorBase<IndicatorDataPoint> AroonUp { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the AroonDown indicator
|
||||
/// </summary>
|
||||
public IndicatorBase<IndicatorDataPoint> AroonDown { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => AroonUp.IsReady && AroonDown.IsReady;
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new AroonOscillator from the specified up/down periods.
|
||||
/// </summary>
|
||||
/// <param name="upPeriod">The lookback period to determine the highest high for the AroonDown</param>
|
||||
/// <param name="downPeriod">The lookback period to determine the lowest low for the AroonUp</param>
|
||||
public AroonOscillator(int upPeriod, int downPeriod)
|
||||
: this($"AROON({upPeriod},{downPeriod})", upPeriod, downPeriod)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new AroonOscillator from the specified up/down periods.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="upPeriod">The lookback period to determine the highest high for the AroonDown</param>
|
||||
/// <param name="downPeriod">The lookback period to determine the lowest low for the AroonUp</param>
|
||||
public AroonOscillator(string name, int upPeriod, int downPeriod)
|
||||
: base(name)
|
||||
{
|
||||
var max = new Maximum(name + "_Max", upPeriod + 1);
|
||||
AroonUp = new FunctionalIndicator<IndicatorDataPoint>(name + "_AroonUp",
|
||||
input => ComputeAroonUp(upPeriod, max, input),
|
||||
aroonUp => max.IsReady,
|
||||
() => max.Reset()
|
||||
);
|
||||
|
||||
var min = new Minimum(name + "_Min", downPeriod + 1);
|
||||
AroonDown = new FunctionalIndicator<IndicatorDataPoint>(name + "_AroonDown",
|
||||
input => ComputeAroonDown(downPeriod, min, input),
|
||||
aroonDown => min.IsReady,
|
||||
() => min.Reset()
|
||||
);
|
||||
|
||||
WarmUpPeriod = 1 + Math.Max(upPeriod, downPeriod);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IBaseDataBar input)
|
||||
{
|
||||
AroonUp.Update(input.EndTime, input.High);
|
||||
AroonDown.Update(input.EndTime, input.Low);
|
||||
|
||||
return AroonUp.Current.Value - AroonDown.Current.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AroonUp = 100 * (period - {periods since max})/period
|
||||
/// </summary>
|
||||
/// <param name="upPeriod">The AroonUp period</param>
|
||||
/// <param name="max">A Maximum indicator used to compute periods since max</param>
|
||||
/// <param name="input">The next input data</param>
|
||||
/// <returns>The AroonUp value</returns>
|
||||
private static decimal ComputeAroonUp(int upPeriod, Maximum max, IndicatorDataPoint input)
|
||||
{
|
||||
max.Update(input);
|
||||
return 100m * (upPeriod - max.PeriodsSinceMaximum) / upPeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AroonDown = 100 * (period - {periods since min})/period
|
||||
/// </summary>
|
||||
/// <param name="downPeriod">The AroonDown period</param>
|
||||
/// <param name="min">A Minimum indicator used to compute periods since min</param>
|
||||
/// <param name="input">The next input data</param>
|
||||
/// <returns>The AroonDown value</returns>
|
||||
private static decimal ComputeAroonDown(int downPeriod, Minimum min, IndicatorDataPoint input)
|
||||
{
|
||||
min.Update(input);
|
||||
return 100m * (downPeriod - min.PeriodsSinceMinimum) / downPeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator and both sub-indicators (AroonUp and AroonDown)
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
AroonUp.Reset();
|
||||
AroonDown.Reset();
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// The Augen Price Spike indicator is an indicator that measures price
|
||||
/// changes in terms of standard deviations. In the book, The
|
||||
/// Volatility Edge in Options Trading, Jeff Augen describes a
|
||||
/// method for tracking absolute price changes in terms of recent
|
||||
/// volatility, using the standard deviation.
|
||||
///
|
||||
/// length = x
|
||||
/// closes = closeArray
|
||||
/// closes1 = closeArray shifted right by 1
|
||||
/// closes2 = closeArray shifted right by 2
|
||||
/// closeLog = np.log(np.divide(closes1, closes2))
|
||||
/// SDev = np.std(closeLog)
|
||||
/// m = SDev * closes1[-1]
|
||||
/// spike = (closes[-1]-closes1[-1])/m
|
||||
/// return spike
|
||||
///
|
||||
/// Augen Price Spike from TradingView
|
||||
/// https://www.tradingview.com/script/fC7Pn2X2-Price-Spike-Jeff-Augen/
|
||||
///
|
||||
/// </summary>
|
||||
public class AugenPriceSpike : Indicator, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
private readonly StandardDeviation _standardDeviation;
|
||||
private readonly RollingWindow<decimal> _rollingData;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the AugenPriceSpike class using the specified period
|
||||
/// </summary>
|
||||
/// <param name="period">The period over which to perform to computation</param>
|
||||
public AugenPriceSpike(int period = 3)
|
||||
: this($"APS({period})", period)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new AugenPriceSpike indicator with the specified period
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="period">The period of this indicator</param>
|
||||
public AugenPriceSpike(string name, int period)
|
||||
: base(name)
|
||||
{
|
||||
if (period < 3)
|
||||
{
|
||||
throw new ArgumentException("AugenPriceSpike Indicator must have a period of at least 3", nameof(period));
|
||||
}
|
||||
_standardDeviation = new StandardDeviation(period);
|
||||
_rollingData = new RollingWindow<decimal>(3);
|
||||
WarmUpPeriod = period + 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when the indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => _rollingData.IsReady && _standardDeviation.IsReady;
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value for this indicator from the given state.
|
||||
/// </summary>
|
||||
/// <param name="input">The input value to this indicator on this time step</param>
|
||||
/// <returns>A a value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IndicatorDataPoint input)
|
||||
{
|
||||
_rollingData.Add(input.Value);
|
||||
if (_rollingData.Count < 3) { return 0m; }
|
||||
|
||||
var previousPoint = _rollingData[1];
|
||||
var previousPoint2 = _rollingData[2];
|
||||
|
||||
var logPoint = 0.0;
|
||||
// Ensure the logarithm operation is valid, as log(0) is undefined, and avoid division by zero.
|
||||
if (previousPoint != 0 && previousPoint2 != 0)
|
||||
{
|
||||
logPoint = Math.Log((double)previousPoint / (double)previousPoint2);
|
||||
}
|
||||
|
||||
_standardDeviation.Update(input.EndTime, (decimal)logPoint);
|
||||
|
||||
if (!_rollingData.IsReady) { return 0m; }
|
||||
if (!_standardDeviation.IsReady) { return 0m; }
|
||||
|
||||
var m = _standardDeviation.Current.Value * previousPoint;
|
||||
if (m == 0) { return 0; }
|
||||
|
||||
var spikeValue = (input.Value - previousPoint) / m;
|
||||
return spikeValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_standardDeviation.Reset();
|
||||
_rollingData.Reset();
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,395 @@
|
||||
/*
|
||||
* 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 System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MathNet.Numerics;
|
||||
using MathNet.Numerics.LinearAlgebra.Double;
|
||||
using MathNet.Numerics.LinearRegression;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// An Autoregressive Intergrated Moving Average (ARIMA) is a time series model which can be used to describe a set of data.
|
||||
/// In particular,with Xₜ representing the series, the model assumes the data are of form
|
||||
/// (after differencing <see cref="_diffOrder" /> times):
|
||||
/// <para>
|
||||
/// Xₜ = c + εₜ + ΣᵢφᵢXₜ₋ᵢ + Σᵢθᵢεₜ₋ᵢ
|
||||
/// </para>
|
||||
/// where the first sum has an upper limit of <see cref="_arOrder" /> and the second <see cref="_maOrder" />.
|
||||
/// </summary>
|
||||
public class AutoRegressiveIntegratedMovingAverage : TimeSeriesIndicator
|
||||
{
|
||||
private List<double> _residuals;
|
||||
private readonly bool _intercept;
|
||||
private bool _loggedOnceInMovingAverageStep;
|
||||
private bool _loggedOnceInAutoRegressiveStep;
|
||||
private readonly RollingWindow<double> _rollingData;
|
||||
|
||||
/// <summary>
|
||||
/// Differencing coefficient (d). Determines how many times the series should be differenced before fitting the
|
||||
/// model.
|
||||
/// </summary>
|
||||
private readonly int _diffOrder;
|
||||
|
||||
/// <summary>
|
||||
/// AR coefficient -- p
|
||||
/// </summary>
|
||||
private readonly int _arOrder;
|
||||
|
||||
/// <summary>
|
||||
/// MA Coefficient -- q
|
||||
/// </summary>
|
||||
private readonly int _maOrder;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to handle potential exceptions, returning a zero value. I.e, the values
|
||||
/// provided as input are not valid by the Normal Equations direct regression method
|
||||
/// </summary>
|
||||
public bool HandleExceptions { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Fitted AR parameters (φ terms).
|
||||
/// </summary>
|
||||
public double[] ArParameters { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fitted MA parameters (θ terms).
|
||||
/// </summary>
|
||||
public double[] MaParameters { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fitted intercept (c term).
|
||||
/// </summary>
|
||||
public double Intercept { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => _rollingData.IsReady;
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public override int WarmUpPeriod { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The variance of the residuals (Var(ε)) from the first step of <see cref="TwoStepFit" />.
|
||||
/// </summary>
|
||||
public double ArResidualError { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The variance of the residuals (Var(ε)) from the second step of <see cref="TwoStepFit" />.
|
||||
/// </summary>
|
||||
public double MaResidualError { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fits an ARIMA(arOrder,diffOrder,maOrder) model of form (after differencing it <see cref="_diffOrder" /> times):
|
||||
/// <para>
|
||||
/// Xₜ = c + εₜ + ΣᵢφᵢXₜ₋ᵢ + Σᵢθᵢεₜ₋ᵢ
|
||||
/// </para>
|
||||
/// where the first sum has an upper limit of <see cref="_arOrder" /> and the second <see cref="_maOrder" />.
|
||||
/// This particular constructor fits the model by means of <see cref="TwoStepFit" /> for a specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the indicator</param>
|
||||
/// <param name="arOrder">AR order (p) -- defines the number of past values to consider in the AR component of the model.</param>
|
||||
/// <param name="diffOrder">Difference order (d) -- defines how many times to difference the model before fitting parameters.</param>
|
||||
/// <param name="maOrder">MA order -- defines the number of past values to consider in the MA component of the model.</param>
|
||||
/// <param name="period">Size of the rolling series to fit onto</param>
|
||||
/// <param name="intercept">Whether or not to include the intercept term</param>
|
||||
public AutoRegressiveIntegratedMovingAverage(
|
||||
string name,
|
||||
int arOrder,
|
||||
int diffOrder,
|
||||
int maOrder,
|
||||
int period,
|
||||
bool intercept = true
|
||||
)
|
||||
: base(name)
|
||||
{
|
||||
if (arOrder < 0 || maOrder < 0)
|
||||
{
|
||||
throw new ArgumentException("AR/MA orders cannot be negative.");
|
||||
}
|
||||
|
||||
if (arOrder == 0)
|
||||
{
|
||||
throw new ArgumentException("arOrder (p) must be greater than zero for all " +
|
||||
"currently available fitting methods.");
|
||||
}
|
||||
|
||||
if (period < Math.Max(arOrder, maOrder))
|
||||
{
|
||||
throw new ArgumentException("Period must exceed both arOrder and maOrder");
|
||||
}
|
||||
|
||||
_arOrder = arOrder;
|
||||
_maOrder = maOrder;
|
||||
_diffOrder = diffOrder;
|
||||
WarmUpPeriod = period;
|
||||
_rollingData = new RollingWindow<double>(period);
|
||||
_intercept = intercept;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fits an ARIMA(arOrder,diffOrder,maOrder) model of form (after differencing it <see cref="_diffOrder" /> times):
|
||||
/// <para>
|
||||
/// Xₜ = c + εₜ + ΣᵢφᵢXₜ₋ᵢ + Σᵢθᵢεₜ₋ᵢ
|
||||
/// </para>
|
||||
/// where the first sum has an upper limit of <see cref="_arOrder" /> and the second <see cref="_maOrder" />.
|
||||
/// This particular constructor fits the model by means of <see cref="TwoStepFit" /> using ordinary least squares.
|
||||
/// </summary>
|
||||
/// <param name="arOrder">AR order (p) -- defines the number of past values to consider in the AR component of the model.</param>
|
||||
/// <param name="diffOrder">Difference order (d) -- defines how many times to difference the model before fitting parameters.</param>
|
||||
/// <param name="maOrder">MA order (q) -- defines the number of past values to consider in the MA component of the model.</param>
|
||||
/// <param name="period">Size of the rolling series to fit onto</param>
|
||||
/// <param name="intercept">Whether to include an intercept term (c)</param>
|
||||
public AutoRegressiveIntegratedMovingAverage(
|
||||
int arOrder,
|
||||
int diffOrder,
|
||||
int maOrder,
|
||||
int period,
|
||||
bool intercept
|
||||
)
|
||||
: this($"ARIMA(({arOrder}, {diffOrder}, {maOrder}), {period}, {intercept})", arOrder, diffOrder, maOrder,
|
||||
period, intercept)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
_rollingData.Reset();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Forecasts the series of the fitted model one point ahead.
|
||||
/// </summary>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IndicatorDataPoint input)
|
||||
{
|
||||
_rollingData.Add((double)input.Value);
|
||||
if (_rollingData.IsReady)
|
||||
{
|
||||
var arrayData = _rollingData.ToArray();
|
||||
double[] diffHeads = default;
|
||||
arrayData = _diffOrder > 0 ? DifferenceSeries(_diffOrder, arrayData, out diffHeads) : arrayData;
|
||||
_diffHeads = diffHeads;
|
||||
TwoStepFit(arrayData);
|
||||
double summants = 0;
|
||||
if (_arOrder > 0)
|
||||
{
|
||||
for (var i = 0; i < _arOrder; i++) // AR Parameters
|
||||
{
|
||||
summants += ArParameters[i] * arrayData[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (_maOrder > 0)
|
||||
{
|
||||
for (var i = 0; i < _maOrder; i++) // MA Parameters
|
||||
{
|
||||
summants += MaParameters[i] * _residuals[_maOrder + i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
summants += Intercept; // By default equals 0
|
||||
|
||||
if (_diffOrder > 0)
|
||||
{
|
||||
var dataCast = arrayData.ToList();
|
||||
dataCast.Insert(0, summants); // Prepends
|
||||
summants = InverseDifferencedSeries(dataCast.ToArray(), _diffHeads).First(); // Returns disintegrated series
|
||||
}
|
||||
|
||||
return (decimal)summants;
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fits the model by means of implementing the following pseudo-code algorithm (in the form of "if{then}"):
|
||||
/// <code>
|
||||
/// if diffOrder > 0 {Difference data diffOrder times}
|
||||
/// if arOrder > 0 {Fit the AR model Xₜ = ΣᵢφᵢXₜ; ε's are set to residuals from fitting this.}
|
||||
/// if maOrder > 0 {Fit the MA parameters left over Xₜ = c + εₜ + ΣᵢφᵢXₜ₋ᵢ + Σᵢθᵢεₜ₋ᵢ}
|
||||
/// Return: φ and θ estimates.
|
||||
/// </code>
|
||||
/// http://mbhauser.com/informal-notes/two-step-arma-estimation.pdf
|
||||
/// </summary>
|
||||
private void TwoStepFit(double[] series) // Protected for any future inheritors (e.g., SARIMA)
|
||||
{
|
||||
_residuals = new List<double>();
|
||||
double errorAr = 0;
|
||||
double errorMa = 0;
|
||||
var lags = _arOrder > 0 ? LaggedSeries(_arOrder, series) : new[] {series};
|
||||
|
||||
AutoRegressiveStep(lags, series, errorAr);
|
||||
|
||||
if (_maOrder <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MovingAverageStep(lags, series, errorMa);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fits the moving average component in the <see cref="TwoStepFit"/> method.
|
||||
/// </summary>
|
||||
/// <param name="lags">An array of lagged data (<see cref="TimeSeriesIndicator.LaggedSeries"/>).</param>
|
||||
/// <param name="data">The input series, differenced <see cref="_diffOrder"/> times.</param>
|
||||
/// <param name="errorMa">The summed residuals (by default 0) associated with the MA component.</param>
|
||||
private void MovingAverageStep(double[][] lags, double[] data, double errorMa)
|
||||
{
|
||||
var appendedData = new List<double[]>();
|
||||
var laggedErrors = LaggedSeries(_maOrder, _residuals.ToArray());
|
||||
for (var i = 0; i < laggedErrors.Length; i++)
|
||||
{
|
||||
var doubles = lags[i].ToList();
|
||||
doubles.AddRange(laggedErrors[i]);
|
||||
appendedData.Add(doubles.ToArray());
|
||||
}
|
||||
|
||||
double[] maFits = default;
|
||||
if (HandleExceptions)
|
||||
{
|
||||
try
|
||||
{
|
||||
maFits = Fit.MultiDim(appendedData.ToArray(), data.Skip(_maOrder).ToArray(),
|
||||
method: DirectRegressionMethod.NormalEquations, intercept: _intercept);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!_loggedOnceInMovingAverageStep)
|
||||
{
|
||||
Logging.Log.Error($"AutoRegressiveIntegratedMovingAverage.MovingAverageStep(): {ex.Message}");
|
||||
_loggedOnceInMovingAverageStep = true;
|
||||
}
|
||||
|
||||
// The method Fit.MultiDim takes the appendedData array of mxn(m rows, n columns), computes its
|
||||
// transpose of size nxm, and then multiplies the tranpose with the original matrix, so the
|
||||
// resultant matrix is of size nxn. Then a linear system Ax=b is solved where A is the
|
||||
// aforementioned matrix and b is the data. Thus, the size of the response x is n
|
||||
//
|
||||
// It's worth saying that if intercept flag is set to true, the number of columns of the initial
|
||||
// matrix (appendedData) is increased in one. For more information, please see the implementation
|
||||
// of Fit.MultiDim() method (Ctrl + right click)
|
||||
var size = appendedData.ToArray()[0].Length + (_intercept ? 1 : 0);
|
||||
maFits = new double[size];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
maFits = Fit.MultiDim(appendedData.ToArray(), data.Skip(_maOrder).ToArray(),
|
||||
method: DirectRegressionMethod.NormalEquations, intercept: _intercept);
|
||||
}
|
||||
|
||||
for (var i = _maOrder; i < data.Length; i++) // Calculate the error assoc. with model.
|
||||
{
|
||||
var paramVector = _intercept
|
||||
? Vector.Build.Dense(maFits.Skip(1).ToArray())
|
||||
: Vector.Build.Dense(maFits);
|
||||
var residual = data[i] - Vector.Build.Dense(appendedData[i - _maOrder]).DotProduct(paramVector);
|
||||
errorMa += Math.Pow(residual, 2);
|
||||
}
|
||||
|
||||
switch (_intercept)
|
||||
{
|
||||
case true:
|
||||
MaResidualError = errorMa / (data.Length - Math.Max(_arOrder, _maOrder) - 1);
|
||||
MaParameters = maFits.Skip(1 + _arOrder).ToArray();
|
||||
ArParameters = maFits.Skip(1).Take(_arOrder).ToArray();
|
||||
Intercept = maFits[0];
|
||||
break;
|
||||
default:
|
||||
MaResidualError = errorMa / (data.Length - Math.Max(_arOrder, _maOrder) - 1);
|
||||
MaParameters = maFits.Skip(_arOrder).ToArray();
|
||||
ArParameters = maFits.Take(_arOrder).ToArray();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fits the autoregressive component in the <see cref="TwoStepFit"/> method.
|
||||
/// </summary>
|
||||
/// <param name="lags">An array of lagged data (<see cref="TimeSeriesIndicator.LaggedSeries"/>).</param>
|
||||
/// <param name="data">The input series, differenced <see cref="_diffOrder"/> times.</param>
|
||||
/// <param name="errorAr">The summed residuals (by default 0) associated with the AR component.</param>
|
||||
private void AutoRegressiveStep(double[][] lags, double[] data, double errorAr)
|
||||
{
|
||||
double[] arFits;
|
||||
if (HandleExceptions)
|
||||
{
|
||||
try
|
||||
{
|
||||
// The function (lags[time][lagged X]) |---> ΣᵢφᵢXₜ₋ᵢ
|
||||
arFits = Fit.MultiDim(lags, data.Skip(_arOrder).ToArray(),
|
||||
method: DirectRegressionMethod.NormalEquations);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!_loggedOnceInAutoRegressiveStep)
|
||||
{
|
||||
Logging.Log.Error($"AutoRegressiveIntegratedMovingAverage.AutoRegressiveStep(): {ex.Message}");
|
||||
_loggedOnceInAutoRegressiveStep = true;
|
||||
}
|
||||
|
||||
// The method Fit.MultiDim takes the lags array of mxn(m rows, n columns), computes its
|
||||
// transpose of size nxm, and then multiplies the tranpose with the original matrix, so the
|
||||
// resultant matrix is of size nxn. Then a linear system Ax=b is solved where A is the
|
||||
// aforementioned matrix and b is the data. Thus, the size of the response x is n
|
||||
//
|
||||
// For more information, please see the implementation of Fit.MultiDim() method (Ctrl + right click)
|
||||
var size = lags.ToArray()[0].Length;
|
||||
arFits = new double[size];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The function (lags[time][lagged X]) |---> ΣᵢφᵢXₜ₋ᵢ
|
||||
arFits = Fit.MultiDim(lags, data.Skip(_arOrder).ToArray(),
|
||||
method: DirectRegressionMethod.NormalEquations);
|
||||
}
|
||||
|
||||
var fittedVec = Vector.Build.Dense(arFits);
|
||||
|
||||
for (var i = 0; i < data.Length; i++) // Calculate the error assoc. with model.
|
||||
{
|
||||
if (i < _arOrder)
|
||||
{
|
||||
_residuals.Add(0); // 0-padding
|
||||
continue;
|
||||
}
|
||||
|
||||
var residual = data[i] - Vector.Build.Dense(lags[i - _arOrder]).DotProduct(fittedVec);
|
||||
errorAr += Math.Pow(residual, 2);
|
||||
_residuals.Add(residual);
|
||||
}
|
||||
|
||||
ArResidualError = errorAr / (data.Length - _arOrder - 1);
|
||||
if (_maOrder == 0)
|
||||
{
|
||||
ArParameters = arFits; // Will not be thrown out
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
* 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
|
||||
{
|
||||
/// <summary>
|
||||
/// This indicator computes Average Directional Index which measures trend strength without regard to trend direction.
|
||||
/// Firstly, it calculates the Directional Movement and the True Range value, and then the values are accumulated and smoothed
|
||||
/// using a custom smoothing method proposed by Wilder. For an n period smoothing, 1/n of each period's value is added to the total period.
|
||||
/// From these accumulated values we are therefore able to derived the 'Positive Directional Index' (+DI) and 'Negative Directional Index' (-DI)
|
||||
/// which is used to calculate the Average Directional Index.
|
||||
/// Computation source:
|
||||
/// https://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:average_directional_index_adx
|
||||
/// </summary>
|
||||
public class AverageDirectionalIndex : BarIndicator, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
private readonly int _period;
|
||||
private readonly IndicatorBase<IBaseDataBar> _trueRange;
|
||||
private readonly IndicatorBase<IBaseDataBar> _directionalMovementPlus;
|
||||
private readonly IndicatorBase<IBaseDataBar> _directionalMovementMinus;
|
||||
private readonly IndicatorBase<IndicatorDataPoint> _smoothedTrueRange;
|
||||
private readonly IndicatorBase<IndicatorDataPoint> _smoothedDirectionalMovementPlus;
|
||||
private readonly IndicatorBase<IndicatorDataPoint> _smoothedDirectionalMovementMinus;
|
||||
private readonly IndicatorBase<IndicatorDataPoint> _averageDirectionalIndex;
|
||||
private IBaseDataBar _previousInput;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => _averageDirectionalIndex.IsReady;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index of the Plus Directional Indicator
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The index of the Plus Directional Indicator.
|
||||
/// </value>
|
||||
public IndicatorBase<IndicatorDataPoint> PositiveDirectionalIndex { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index of the Minus Directional Indicator
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The index of the Minus Directional Indicator.
|
||||
/// </value>
|
||||
public IndicatorBase<IndicatorDataPoint> NegativeDirectionalIndex { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod => _period * 2;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AverageDirectionalIndex"/> class.
|
||||
/// </summary>
|
||||
/// <param name="period">The period.</param>
|
||||
public AverageDirectionalIndex(int period)
|
||||
: this($"ADX({period})", period)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AverageDirectionalIndex"/> class.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="period">The period.</param>
|
||||
public AverageDirectionalIndex(string name, int period)
|
||||
: base(name)
|
||||
{
|
||||
_period = period;
|
||||
|
||||
_trueRange = new FunctionalIndicator<IBaseDataBar>(name + "_TrueRange",
|
||||
ComputeTrueRange,
|
||||
isReady => _previousInput != null
|
||||
);
|
||||
|
||||
_directionalMovementPlus = new FunctionalIndicator<IBaseDataBar>(name + "_PositiveDirectionalMovement",
|
||||
ComputePositiveDirectionalMovement,
|
||||
isReady => _previousInput != null
|
||||
);
|
||||
|
||||
_directionalMovementMinus = new FunctionalIndicator<IBaseDataBar>(name + "_NegativeDirectionalMovement",
|
||||
ComputeNegativeDirectionalMovement,
|
||||
isReady => _previousInput != null
|
||||
);
|
||||
|
||||
PositiveDirectionalIndex = new FunctionalIndicator<IndicatorDataPoint>(name + "_PositiveDirectionalIndex",
|
||||
input =>
|
||||
{
|
||||
// Computes the Plus Directional Indicator(+DI period).
|
||||
if (_smoothedTrueRange != 0 && _smoothedDirectionalMovementPlus.IsReady)
|
||||
{
|
||||
return 100m * _smoothedDirectionalMovementPlus.Current.Value / _smoothedTrueRange.Current.Value;
|
||||
}
|
||||
return 0m;
|
||||
},
|
||||
positiveDirectionalIndex => _smoothedDirectionalMovementPlus.IsReady,
|
||||
() =>
|
||||
{
|
||||
_directionalMovementPlus.Reset();
|
||||
_trueRange.Reset();
|
||||
}
|
||||
);
|
||||
|
||||
NegativeDirectionalIndex = new FunctionalIndicator<IndicatorDataPoint>(name + "_NegativeDirectionalIndex",
|
||||
input =>
|
||||
{
|
||||
// Computes the Minus Directional Indicator(-DI period).
|
||||
if (_smoothedTrueRange != 0 && _smoothedDirectionalMovementMinus.IsReady)
|
||||
{
|
||||
return 100m * _smoothedDirectionalMovementMinus.Current.Value / _smoothedTrueRange.Current.Value;
|
||||
}
|
||||
return 0m;
|
||||
},
|
||||
negativeDirectionalIndex => _smoothedDirectionalMovementMinus.IsReady,
|
||||
() =>
|
||||
{
|
||||
_directionalMovementMinus.Reset();
|
||||
_trueRange.Reset();
|
||||
}
|
||||
);
|
||||
|
||||
_smoothedTrueRange = new FunctionalIndicator<IndicatorDataPoint>(name + "_SmoothedTrueRange",
|
||||
input =>
|
||||
{
|
||||
// Computes the Smoothed True Range value.
|
||||
var value = Samples > _period + 1 ? _smoothedTrueRange.Current.Value / _period : 0m;
|
||||
return _smoothedTrueRange.Current.Value + _trueRange.Current.Value - value;
|
||||
},
|
||||
isReady => Samples > period
|
||||
);
|
||||
|
||||
_smoothedDirectionalMovementPlus = new FunctionalIndicator<IndicatorDataPoint>(name + "_SmoothedDirectionalMovementPlus",
|
||||
input =>
|
||||
{
|
||||
// Computes the Smoothed Directional Movement Plus value.
|
||||
var value = Samples > _period + 1 ? _smoothedDirectionalMovementPlus.Current.Value / _period : 0m;
|
||||
return _smoothedDirectionalMovementPlus.Current.Value + _directionalMovementPlus.Current.Value - value;
|
||||
},
|
||||
isReady => Samples > period
|
||||
);
|
||||
|
||||
_smoothedDirectionalMovementMinus = new FunctionalIndicator<IndicatorDataPoint>(name + "_SmoothedDirectionalMovementMinus",
|
||||
input =>
|
||||
{
|
||||
// Computes the Smoothed Directional Movement Minus value.
|
||||
var value = Samples > _period + 1 ? _smoothedDirectionalMovementMinus.Current.Value / _period : 0m;
|
||||
return _smoothedDirectionalMovementMinus.Current.Value + _directionalMovementMinus.Current.Value - value;
|
||||
},
|
||||
isReady => Samples > period
|
||||
);
|
||||
|
||||
_averageDirectionalIndex = new WilderMovingAverage(period);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the True Range value.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <returns></returns>
|
||||
private decimal ComputeTrueRange(IBaseDataBar input)
|
||||
{
|
||||
if (_previousInput == null) return 0m;
|
||||
|
||||
var range1 = input.High - input.Low;
|
||||
var range2 = Math.Abs(input.High - _previousInput.Close);
|
||||
var range3 = Math.Abs(input.Low - _previousInput.Close);
|
||||
|
||||
return Math.Max(range1, Math.Max(range2, range3));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the positive directional movement.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <returns></returns>
|
||||
private decimal ComputePositiveDirectionalMovement(IBaseDataBar input)
|
||||
{
|
||||
if (_previousInput != null &&
|
||||
input.High > _previousInput.High &&
|
||||
input.High - _previousInput.High >= _previousInput.Low - input.Low)
|
||||
{
|
||||
return input.High - _previousInput.High;
|
||||
}
|
||||
return 0m;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the negative directional movement.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <returns></returns>
|
||||
private decimal ComputeNegativeDirectionalMovement(IBaseDataBar input)
|
||||
{
|
||||
if (_previousInput != null &&
|
||||
_previousInput.Low > input.Low &&
|
||||
_previousInput.Low - input.Low > input.High - _previousInput.High)
|
||||
{
|
||||
return _previousInput.Low - input.Low;
|
||||
}
|
||||
return 0m;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IBaseDataBar input)
|
||||
{
|
||||
_trueRange.Update(input);
|
||||
_directionalMovementPlus.Update(input);
|
||||
_directionalMovementMinus.Update(input);
|
||||
_smoothedTrueRange.Update(Current);
|
||||
_smoothedDirectionalMovementPlus.Update(Current);
|
||||
_smoothedDirectionalMovementMinus.Update(Current);
|
||||
_previousInput = input;
|
||||
|
||||
PositiveDirectionalIndex.Update(Current);
|
||||
NegativeDirectionalIndex.Update(Current);
|
||||
|
||||
var diff = Math.Abs(PositiveDirectionalIndex.Current.Value - NegativeDirectionalIndex.Current.Value);
|
||||
var sum = PositiveDirectionalIndex.Current.Value + NegativeDirectionalIndex.Current.Value;
|
||||
if (sum == 0) return 50m;
|
||||
|
||||
_averageDirectionalIndex.Update(input.EndTime, 100m * diff / sum);
|
||||
|
||||
return _averageDirectionalIndex.Current.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
_previousInput = null;
|
||||
_trueRange.Reset();
|
||||
_directionalMovementPlus.Reset();
|
||||
_directionalMovementMinus.Reset();
|
||||
_smoothedTrueRange.Reset();
|
||||
_smoothedDirectionalMovementPlus.Reset();
|
||||
_smoothedDirectionalMovementMinus.Reset();
|
||||
_averageDirectionalIndex.Reset();
|
||||
PositiveDirectionalIndex.Reset();
|
||||
NegativeDirectionalIndex.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// This indicator computes the Average Directional Movement Index Rating (ADXR).
|
||||
/// The Average Directional Movement Index Rating is calculated with the following formula:
|
||||
/// ADXR[i] = (ADX[i] + ADX[i - period + 1]) / 2
|
||||
/// </summary>
|
||||
public class AverageDirectionalMovementIndexRating : BarIndicator, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
private readonly int _period;
|
||||
private readonly RollingWindow<decimal> _adxHistory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AverageDirectionalMovementIndexRating"/> class using the specified name and period.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="period">The period of the ADXR</param>
|
||||
public AverageDirectionalMovementIndexRating(string name, int period)
|
||||
: base(name)
|
||||
{
|
||||
_period = period;
|
||||
ADX = new AverageDirectionalIndex(name + "_ADX", period);
|
||||
_adxHistory = new RollingWindow<decimal>(period);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AverageDirectionalMovementIndexRating"/> class using the specified period.
|
||||
/// </summary>
|
||||
/// <param name="period">The period of the ADXR</param>
|
||||
public AverageDirectionalMovementIndexRating(int period)
|
||||
: this($"ADXR({period})", period)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Average Directional Index indicator instance being used
|
||||
/// </summary>
|
||||
public AverageDirectionalIndex ADX { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => _adxHistory.IsReady;
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod => _period * 3 - 1;
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IBaseDataBar input)
|
||||
{
|
||||
ADX.Update(input);
|
||||
|
||||
if (ADX.IsReady)
|
||||
{
|
||||
_adxHistory.Add(ADX.Current.Value);
|
||||
}
|
||||
|
||||
return IsReady ? (ADX.Current.Value + _adxHistory[_period - 1]) / 2 : 50m;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
ADX.Reset();
|
||||
_adxHistory.Reset();
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the Average Range (AR) indicator, which calculates the average price range
|
||||
/// </summary>
|
||||
public class AverageRange : BarIndicator, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// The Simple Moving Average (SMA) used to calculate the average of the price ranges.
|
||||
/// </summary>
|
||||
private readonly SimpleMovingAverage _sma;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the AverageRange class with the specified name and period.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the AR indicator.</param>
|
||||
/// <param name="period">The number of periods over which to compute the average range.</param>
|
||||
public AverageRange(string name, int period) : base(name)
|
||||
{
|
||||
_sma = new SimpleMovingAverage(name + "_SMA", period);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the AR indicator with the default name format and period.
|
||||
/// </summary>
|
||||
public AverageRange(int period)
|
||||
: this($"AR({period})", period)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the indicator has enough data to start producing valid results.
|
||||
/// </summary>
|
||||
public override bool IsReady => _sma.IsReady;
|
||||
|
||||
/// <summary>
|
||||
/// The number of periods needed to fully initialize the AR indicator.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod => _sma.WarmUpPeriod;
|
||||
|
||||
/// <summary>
|
||||
/// Resets the indicator and clears the internal state, including the SMA.
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_sma.Reset();
|
||||
base.Reset();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of the Average Range (AR) by calculating the price range (high - low)
|
||||
/// and passing it to the SMA to get the smoothed value.
|
||||
/// </summary>
|
||||
/// <param name="input">The input data for the current bar, including open, high, low, close values.</param>
|
||||
/// <returns>The computed AR value, which is the smoothed average of price ranges.</returns>
|
||||
protected override decimal ComputeNextValue(IBaseDataBar input)
|
||||
{
|
||||
var priceRange = input.High - input.Low;
|
||||
// Update the SMA with the price range
|
||||
_sma.Update(new IndicatorDataPoint(input.EndTime, priceRange));
|
||||
return _sma.Current.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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
|
||||
{
|
||||
/// <summary>
|
||||
/// The AverageTrueRange indicator is a measure of volatility introduced by Welles Wilder in his
|
||||
/// book: New Concepts in Technical Trading Systems. This indicator computes the TrueRange and then
|
||||
/// smoothes the TrueRange over a given period.
|
||||
///
|
||||
/// TrueRange is defined as the maximum of the following:
|
||||
/// High - Low
|
||||
/// ABS(High - PreviousClose)
|
||||
/// ABS(Low - PreviousClose)
|
||||
/// </summary>
|
||||
public class AverageTrueRange : BarIndicator, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
/// <summary>This indicator is used to smooth the TrueRange computation</summary>
|
||||
/// <remarks>This is not exposed publicly since it is the same value as this indicator, meaning
|
||||
/// that this '_smoother' computers the ATR directly, so exposing it publicly would be duplication</remarks>
|
||||
private readonly IndicatorBase<IndicatorDataPoint> _smoother;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the true range which is the more volatile calculation to be smoothed by this indicator
|
||||
/// </summary>
|
||||
public IndicatorBase<IBaseDataBar> TrueRange { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => _smoother.IsReady;
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new AverageTrueRange indicator using the specified period and moving average type
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="period">The smoothing period used to smooth the true range values</param>
|
||||
/// <param name="movingAverageType">The type of smoothing used to smooth the true range values</param>
|
||||
public AverageTrueRange(string name, int period, MovingAverageType movingAverageType = MovingAverageType.Wilders)
|
||||
: base(name)
|
||||
{
|
||||
WarmUpPeriod = period;
|
||||
TrueRange = new TrueRange(name);
|
||||
_smoother = movingAverageType.AsIndicator($"{name}_{movingAverageType}", period).Of(TrueRange, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new AverageTrueRange indicator using the specified period and moving average type
|
||||
/// </summary>
|
||||
/// <param name="period">The smoothing period used to smooth the true range values</param>
|
||||
/// <param name="movingAverageType">The type of smoothing used to smooth the true range values</param>
|
||||
public AverageTrueRange(int period, MovingAverageType movingAverageType = MovingAverageType.Wilders)
|
||||
: this($"ATR({period})", period, movingAverageType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IBaseDataBar input)
|
||||
{
|
||||
// compute the true range and then send it to our smoother
|
||||
TrueRange.Update(input);
|
||||
|
||||
return _smoother.Current.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_smoother.Reset();
|
||||
TrueRange.Reset();
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// The Awesome Oscillator Indicator tracks the price midpoint-movement of a security. Specifically,
|
||||
/// <para>
|
||||
/// AO = MAfast[(H+L)/2] - MAslow[(H+L)/2]
|
||||
/// </para>
|
||||
/// where MAfast and MAslow denote simple moving averages wherein fast has a shorter period.
|
||||
/// https://www.barchart.com/education/technical-indicators/awesome_oscillator
|
||||
/// </summary>
|
||||
public class AwesomeOscillator : BarIndicator, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the indicators slow period moving average.
|
||||
/// </summary>
|
||||
public IndicatorBase<IndicatorDataPoint> SlowAo { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the indicators fast period moving average.
|
||||
/// </summary>
|
||||
public IndicatorBase<IndicatorDataPoint> FastAo { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => SlowAo.IsReady && FastAo.IsReady;
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Awesome Oscillator from the specified periods.
|
||||
/// </summary>
|
||||
/// <param name="fastPeriod">The period of the fast moving average associated with the AO</param>
|
||||
/// <param name="slowPeriod">The period of the slow moving average associated with the AO</param>
|
||||
/// <param name="type">The type of moving average used when computing the fast and slow term. Defaults to simple moving average.</param>
|
||||
public AwesomeOscillator(int fastPeriod, int slowPeriod, MovingAverageType type = MovingAverageType.Simple)
|
||||
: this($"AO({fastPeriod},{slowPeriod},{type})", fastPeriod, slowPeriod, type)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Awesome Oscillator from the specified periods.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="fastPeriod">The period of the fast moving average associated with the AO</param>
|
||||
/// <param name="slowPeriod">The period of the slow moving average associated with the AO</param>
|
||||
/// <param name="type">The type of moving average used when computing the fast and slow term. Defaults to simple moving average.</param>
|
||||
public AwesomeOscillator(string name, int fastPeriod, int slowPeriod, MovingAverageType type = MovingAverageType.Simple)
|
||||
: base(name)
|
||||
{
|
||||
SlowAo = type.AsIndicator(slowPeriod);
|
||||
FastAo = type.AsIndicator(fastPeriod);
|
||||
WarmUpPeriod = Math.Max(slowPeriod, fastPeriod);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state.
|
||||
/// </summary>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IBaseDataBar input)
|
||||
{
|
||||
var presentValue = (input.High + input.Low) / 2;
|
||||
SlowAo.Update(input.EndTime, presentValue);
|
||||
FastAo.Update(input.EndTime, presentValue);
|
||||
|
||||
return IsReady ? FastAo - SlowAo : 0m;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
FastAo.Reset();
|
||||
SlowAo.Reset();
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// This indicator computes the Balance Of Power (BOP).
|
||||
/// The Balance Of Power is calculated with the following formula:
|
||||
/// BOP = (Close - Open) / (High - Low)
|
||||
/// </summary>
|
||||
public class BalanceOfPower : BarIndicator, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BalanceOfPower"/> class using the specified name.
|
||||
/// </summary>
|
||||
public BalanceOfPower()
|
||||
: this("BOP")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BalanceOfPower"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public BalanceOfPower(string name)
|
||||
: base(name)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => Samples > 0;
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod => 1;
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IBaseDataBar input)
|
||||
{
|
||||
var range = input.High - input.Low;
|
||||
return range > 0 ? (input.Close - input.Open) / range : 0m;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// The BarIndicator is an indicator that accepts IBaseDataBar data as its input.
|
||||
///
|
||||
/// This type is more of a shim/typedef to reduce the need to refer to things as IndicatorBase<IBaseDataBar>
|
||||
/// </summary>
|
||||
public abstract class BarIndicator : IndicatorBase<IBaseDataBar>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new TradeBarIndicator with the specified name
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
protected BarIndicator(string name)
|
||||
: base(name)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* 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;
|
||||
using MathNet.Numerics.Statistics;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// In technical analysis Beta indicator is used to measure volatility or risk of a target (ETF) relative to the overall
|
||||
/// risk (volatility) of the reference (market indexes). The Beta indicators compares target's price movement to the
|
||||
/// movements of the indexes over the same period of time.
|
||||
///
|
||||
/// It is common practice to use the SPX index as a benchmark of the overall reference market when it comes to Beta
|
||||
/// calculations.
|
||||
///
|
||||
/// The indicator only updates when both assets have a price for a time step. When a bar is missing for one of the assets,
|
||||
/// the indicator value fills forward to improve the accuracy of the indicator.
|
||||
/// </summary>
|
||||
public class Beta : DualSymbolIndicator<IBaseDataBar>
|
||||
{
|
||||
/// <summary>
|
||||
/// RollingWindow of returns of the target symbol in the given period
|
||||
/// </summary>
|
||||
private readonly RollingWindow<double> _targetReturns;
|
||||
|
||||
/// <summary>
|
||||
/// RollingWindow of returns of the reference symbol in the given period
|
||||
/// </summary>
|
||||
private readonly RollingWindow<double> _referenceReturns;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when the indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => _targetReturns.IsReady && _referenceReturns.IsReady;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Beta indicator with the specified name, target, reference,
|
||||
/// and period values
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="targetSymbol">The target symbol of this indicator</param>
|
||||
/// <param name="period">The period of this indicator</param>
|
||||
/// <param name="referenceSymbol">The reference symbol of this indicator</param>
|
||||
public Beta(string name, Symbol targetSymbol, Symbol referenceSymbol, int period)
|
||||
: base(name, targetSymbol, referenceSymbol, 2)
|
||||
{
|
||||
// Assert the period is greater than two, otherwise the beta can not be computed
|
||||
if (period < 2)
|
||||
{
|
||||
throw new ArgumentException($"Period parameter for Beta indicator must be greater than 2 but was {period}.");
|
||||
}
|
||||
|
||||
_targetReturns = new RollingWindow<double>(period);
|
||||
_referenceReturns = new RollingWindow<double>(period);
|
||||
WarmUpPeriod += (period - 2) + 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Beta indicator with the specified target, reference,
|
||||
/// and period values
|
||||
/// </summary>
|
||||
/// <param name="targetSymbol">The target symbol of this indicator</param>
|
||||
/// <param name="period">The period of this indicator</param>
|
||||
/// <param name="referenceSymbol">The reference symbol of this indicator</param>
|
||||
public Beta(Symbol targetSymbol, Symbol referenceSymbol, int period)
|
||||
: this($"B({period})", targetSymbol, referenceSymbol, period)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Beta indicator with the specified name, period, target and
|
||||
/// reference values
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="period">The period of this indicator</param>
|
||||
/// <param name="targetSymbol">The target symbol of this indicator</param>
|
||||
/// <param name="referenceSymbol">The reference symbol of this indicator</param>
|
||||
/// <remarks>Constructor overload for backward compatibility.</remarks>
|
||||
public Beta(string name, int period, Symbol targetSymbol, Symbol referenceSymbol)
|
||||
: this(name, targetSymbol, referenceSymbol, period)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the returns with the new given data point and the last given data point
|
||||
/// </summary>
|
||||
/// <param name="rollingWindow">The collection of data points from which we want
|
||||
/// to compute the return</param>
|
||||
/// <returns>The returns with the new given data point</returns>
|
||||
private static double GetNewReturn(IReadOnlyWindow<IBaseDataBar> rollingWindow)
|
||||
{
|
||||
return (double)(rollingWindow[0].Close.SafeDivision(rollingWindow[1].Close) - 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the beta value of the target in relation with the reference
|
||||
/// using the target and reference returns
|
||||
/// </summary>
|
||||
protected override decimal ComputeIndicator()
|
||||
{
|
||||
if (TargetDataPoints.IsReady)
|
||||
{
|
||||
_targetReturns.Add(GetNewReturn(TargetDataPoints));
|
||||
}
|
||||
|
||||
if (ReferenceDataPoints.IsReady)
|
||||
{
|
||||
_referenceReturns.Add(GetNewReturn(ReferenceDataPoints));
|
||||
}
|
||||
|
||||
var varianceComputed = _referenceReturns.Variance();
|
||||
var covarianceComputed = _targetReturns.Covariance(_referenceReturns);
|
||||
|
||||
// Avoid division with NaN or by zero
|
||||
var variance = !varianceComputed.IsNaNOrZero() ? varianceComputed : 1;
|
||||
var covariance = !covarianceComputed.IsNaNOrZero() ? covarianceComputed : 0;
|
||||
return (decimal)(covariance / variance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_targetReturns.Reset();
|
||||
_referenceReturns.Reset();
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// This indicator creates a moving average (middle band) with an upper band and lower band
|
||||
/// fixed at k standard deviations above and below the moving average.
|
||||
/// </summary>
|
||||
public class BollingerBands : Indicator, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the type of moving average
|
||||
/// </summary>
|
||||
public MovingAverageType MovingAverageType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the standard deviation
|
||||
/// </summary>
|
||||
public IndicatorBase<IndicatorDataPoint> StandardDeviation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the middle Bollinger band (moving average)
|
||||
/// </summary>
|
||||
public IndicatorBase<IndicatorDataPoint> MiddleBand { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the upper Bollinger band (middleBand + k * stdDev)
|
||||
/// </summary>
|
||||
public IndicatorBase<IndicatorDataPoint> UpperBand { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the lower Bollinger band (middleBand - k * stdDev)
|
||||
/// </summary>
|
||||
public IndicatorBase<IndicatorDataPoint> LowerBand { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Bollinger BandWidth indicator
|
||||
/// BandWidth = ((Upper Band - Lower Band) / Middle Band) * 100
|
||||
/// </summary>
|
||||
public IndicatorBase<IndicatorDataPoint> BandWidth { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Bollinger %B
|
||||
/// %B = (Price - Lower Band)/(Upper Band - Lower Band)
|
||||
/// </summary>
|
||||
public IndicatorBase<IndicatorDataPoint> PercentB { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Price level
|
||||
/// </summary>
|
||||
public IndicatorBase<IndicatorDataPoint> Price { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the BollingerBands class
|
||||
/// </summary>
|
||||
/// <param name="period">The period of the standard deviation and moving average (middle band)</param>
|
||||
/// <param name="k">The number of standard deviations specifying the distance between the middle band and upper or lower bands</param>
|
||||
/// <param name="movingAverageType">The type of moving average to be used</param>
|
||||
public BollingerBands(int period, decimal k, MovingAverageType movingAverageType = MovingAverageType.Simple)
|
||||
: this($"BB({period},{k})", period, k, movingAverageType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the BollingerBands class
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="period">The period of the standard deviation and moving average (middle band)</param>
|
||||
/// <param name="k">The number of standard deviations specifying the distance between the middle band and upper or lower bands</param>
|
||||
/// <param name="movingAverageType">The type of moving average to be used</param>
|
||||
public BollingerBands(string name, int period, decimal k, MovingAverageType movingAverageType = MovingAverageType.Simple)
|
||||
: base(name)
|
||||
{
|
||||
WarmUpPeriod = period;
|
||||
MovingAverageType = movingAverageType;
|
||||
StandardDeviation = new StandardDeviation(name + "_StandardDeviation", period);
|
||||
MiddleBand = movingAverageType.AsIndicator(name + "_MiddleBand", period);
|
||||
LowerBand = MiddleBand.Minus(StandardDeviation.Times(k), name + "_LowerBand");
|
||||
UpperBand = MiddleBand.Plus(StandardDeviation.Times(k), name + "_UpperBand");
|
||||
|
||||
var UpperMinusLower = UpperBand.Minus(LowerBand);
|
||||
BandWidth = UpperMinusLower
|
||||
.Over(MiddleBand)
|
||||
.Times(new ConstantIndicator<IndicatorDataPoint>("ct", 100m), name + "_BandWidth");
|
||||
|
||||
Price = new Identity(name + "_Close");
|
||||
PercentB = IndicatorExtensions.Over(
|
||||
Price.Minus(LowerBand),
|
||||
UpperMinusLower,
|
||||
name + "_%B");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => MiddleBand.IsReady && UpperBand.IsReady && LowerBand.IsReady && BandWidth.IsReady && PercentB.IsReady;
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of the following sub-indicators from the given state:
|
||||
/// StandardDeviation, MiddleBand, UpperBand, LowerBand, BandWidth, %B
|
||||
/// </summary>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>The input is returned unmodified.</returns>
|
||||
protected override decimal ComputeNextValue(IndicatorDataPoint input)
|
||||
{
|
||||
StandardDeviation.Update(input);
|
||||
MiddleBand.Update(input);
|
||||
Price.Update(input);
|
||||
|
||||
return input.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate and Compute the next value for this indicator
|
||||
/// </summary>
|
||||
/// <param name="input">Input for this indicator</param>
|
||||
/// <returns><see cref="IndicatorResult"/> of this update</returns>
|
||||
/// <remarks>Override implemented to handle GH issue #4927</remarks>
|
||||
protected override IndicatorResult ValidateAndComputeNextValue(IndicatorDataPoint input)
|
||||
{
|
||||
// Update our Indicators
|
||||
var value = ComputeNextValue(input);
|
||||
|
||||
// If the STD = 0, we know that the our PercentB indicator will fail to update. This is
|
||||
// because the denominator will be 0. When this is the case after fully ready we do not
|
||||
// want the BollingerBands to emit an update because its PercentB property will be stale.
|
||||
return IsReady && StandardDeviation.Current.Value == 0
|
||||
? new IndicatorResult(value, IndicatorStatus.MathError)
|
||||
: new IndicatorResult(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator and all sub-indicators (StandardDeviation, LowerBand, MiddleBand, UpperBand, BandWidth, %B)
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
StandardDeviation.Reset();
|
||||
MiddleBand.Reset();
|
||||
UpperBand.Reset();
|
||||
LowerBand.Reset();
|
||||
BandWidth.Reset();
|
||||
PercentB.Reset();
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Abandoned Baby candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long white (black) real body
|
||||
/// - second candle: doji
|
||||
/// - third candle: black(white) real body that moves well within the first candle's real body
|
||||
/// - upside(downside) gap between the first candle and the doji(the shadows of the two candles don't touch)
|
||||
/// - downside (upside) gap between the doji and the third candle(the shadows of the two candles don't touch)
|
||||
/// The meaning of "doji" and "long" is specified with SetCandleSettings
|
||||
/// The meaning of "moves well within" is specified with penetration and "moves" should mean the real body should
|
||||
/// not be short ("short" is specified with SetCandleSettings) - Greg Morris wants it to be long, someone else want
|
||||
/// it to be relatively long
|
||||
/// The returned value is positive (+1) when it's an abandoned baby bottom or negative (-1) when it's
|
||||
/// an abandoned baby top; the user should consider that an abandoned baby is significant when it appears in
|
||||
/// an uptrend or downtrend, while this function does not consider the trend
|
||||
/// </remarks>
|
||||
public class AbandonedBaby : CandlestickPattern
|
||||
{
|
||||
private readonly decimal _penetration;
|
||||
|
||||
private readonly int _bodyDojiAveragePeriod;
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
|
||||
private decimal _bodyDojiPeriodTotal;
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
private decimal _bodyShortPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AbandonedBaby"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="penetration">Percentage of penetration of a candle within another candle</param>
|
||||
public AbandonedBaby(string name, decimal penetration = 0.3m)
|
||||
: base(name, Math.Max(Math.Max(CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod),
|
||||
CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod) + 2)
|
||||
{
|
||||
_penetration = penetration;
|
||||
|
||||
_bodyDojiAveragePeriod = CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod;
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AbandonedBaby"/> class.
|
||||
/// </summary>
|
||||
/// <param name="penetration">Percentage of penetration of a candle within another candle</param>
|
||||
public AbandonedBaby(decimal penetration)
|
||||
: this("ABANDONEDBABY", penetration)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AbandonedBaby"/> class.
|
||||
/// </summary>
|
||||
public AbandonedBaby()
|
||||
: this("ABANDONEDBABY")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples > Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples > Period - _bodyLongAveragePeriod)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]);
|
||||
}
|
||||
if (Samples > Period - _bodyDojiAveragePeriod)
|
||||
{
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, window[1]);
|
||||
}
|
||||
if (Samples > Period - _bodyShortAveragePeriod)
|
||||
{
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st: long
|
||||
GetRealBody(window[2]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[2]) &&
|
||||
// 2nd: doji
|
||||
GetRealBody(window[1]) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, window[1]) &&
|
||||
// 3rd: longer than short
|
||||
GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) &&
|
||||
((
|
||||
// 1st white
|
||||
GetCandleColor(window[2]) == CandleColor.White &&
|
||||
// 3rd black
|
||||
GetCandleColor(input) == CandleColor.Black &&
|
||||
// 3rd closes well within 1st rb
|
||||
input.Close < window[2].Close - GetRealBody(window[2]) * _penetration &&
|
||||
// upside gap between 1st and 2nd
|
||||
GetCandleGapUp(window[1], window[2]) &&
|
||||
// downside gap between 2nd and 3rd
|
||||
GetCandleGapDown(input, window[1])
|
||||
)
|
||||
||
|
||||
(
|
||||
// 1st black
|
||||
GetCandleColor(window[2]) == CandleColor.Black &&
|
||||
// 3rd white
|
||||
GetCandleColor(input) == CandleColor.White &&
|
||||
// 3rd closes well within 1st rb
|
||||
input.Close > window[2].Close + GetRealBody(window[2]) * _penetration &&
|
||||
// downside gap between 1st and 2nd
|
||||
GetCandleGapDown(window[1], window[2]) &&
|
||||
// upside gap between 2nd and 3rd
|
||||
GetCandleGapUp(input, window[1])
|
||||
)
|
||||
)
|
||||
)
|
||||
value = (int)GetCandleColor(input);
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod - 1]);
|
||||
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, window[1]) -
|
||||
GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod]);
|
||||
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod + 1]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = 0;
|
||||
_bodyDojiPeriodTotal = 0;
|
||||
_bodyShortPeriodTotal = 0;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Advance Block candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - three white candlesticks with consecutively higher closes
|
||||
/// - each candle opens within or near the previous white real body
|
||||
/// - first candle: long white with no or very short upper shadow(a short shadow is accepted too for more flexibility)
|
||||
/// - second and third candles, or only third candle, show signs of weakening: progressively smaller white real bodies
|
||||
/// and/or relatively long upper shadows; see below for specific conditions
|
||||
/// The meanings of "long body", "short shadow", "far" and "near" are specified with SetCandleSettings;
|
||||
/// The returned value is negative(-1): advance block is always bearish;
|
||||
/// The user should consider that advance block is significant when it appears in uptrend, while this function
|
||||
/// does not consider it
|
||||
/// </remarks>
|
||||
public class AdvanceBlock : CandlestickPattern
|
||||
{
|
||||
private readonly int _shadowShortAveragePeriod;
|
||||
private readonly int _shadowLongAveragePeriod;
|
||||
private readonly int _nearAveragePeriod;
|
||||
private readonly int _farAveragePeriod;
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
|
||||
private decimal[] _shadowShortPeriodTotal = new decimal[3];
|
||||
private decimal[] _shadowLongPeriodTotal = new decimal[2];
|
||||
private decimal[] _nearPeriodTotal = new decimal[3];
|
||||
private decimal[] _farPeriodTotal = new decimal[3];
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AdvanceBlock"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public AdvanceBlock(string name)
|
||||
: base(name, Math.Max(Math.Max(Math.Max(CandleSettings.Get(CandleSettingType.ShadowLong).AveragePeriod, CandleSettings.Get(CandleSettingType.ShadowShort).AveragePeriod),
|
||||
Math.Max(CandleSettings.Get(CandleSettingType.Far).AveragePeriod, CandleSettings.Get(CandleSettingType.Near).AveragePeriod)),
|
||||
CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod) + 2 + 1)
|
||||
{
|
||||
_shadowShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowShort).AveragePeriod;
|
||||
_shadowLongAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowLong).AveragePeriod;
|
||||
_nearAveragePeriod = CandleSettings.Get(CandleSettingType.Near).AveragePeriod;
|
||||
_farAveragePeriod = CandleSettings.Get(CandleSettingType.Far).AveragePeriod;
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AdvanceBlock"/> class.
|
||||
/// </summary>
|
||||
public AdvanceBlock()
|
||||
: this("ADVANCEBLOCK")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _shadowShortAveragePeriod)
|
||||
{
|
||||
_shadowShortPeriodTotal[2] += GetCandleRange(CandleSettingType.ShadowShort, window[2]);
|
||||
_shadowShortPeriodTotal[1] += GetCandleRange(CandleSettingType.ShadowShort, window[1]);
|
||||
_shadowShortPeriodTotal[0] += GetCandleRange(CandleSettingType.ShadowShort, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowLongAveragePeriod)
|
||||
{
|
||||
_shadowLongPeriodTotal[1] += GetCandleRange(CandleSettingType.ShadowLong, window[1]);
|
||||
_shadowLongPeriodTotal[0] += GetCandleRange(CandleSettingType.ShadowLong, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyLongAveragePeriod)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _nearAveragePeriod)
|
||||
{
|
||||
_nearPeriodTotal[2] += GetCandleRange(CandleSettingType.Near, window[2]);
|
||||
_nearPeriodTotal[1] += GetCandleRange(CandleSettingType.Near, window[1]);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _farAveragePeriod)
|
||||
{
|
||||
_farPeriodTotal[2] += GetCandleRange(CandleSettingType.Far, window[2]);
|
||||
_farPeriodTotal[1] += GetCandleRange(CandleSettingType.Far, window[1]);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st white
|
||||
GetCandleColor(window[2]) == CandleColor.White &&
|
||||
// 2nd white
|
||||
GetCandleColor(window[1]) == CandleColor.White &&
|
||||
// 3rd white
|
||||
GetCandleColor(input) == CandleColor.White &&
|
||||
// consecutive higher closes
|
||||
input.Close > window[1].Close && window[1].Close > window[2].Close &&
|
||||
// 2nd opens within/near 1st real body
|
||||
window[1].Open > window[2].Open &&
|
||||
window[1].Open <= window[2].Close + GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal[2], window[2]) &&
|
||||
// 3rd opens within/near 2nd real body
|
||||
input.Open > window[1].Open &&
|
||||
input.Open <= window[1].Close + GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal[1], window[1]) &&
|
||||
// 1st: long real body
|
||||
GetRealBody(window[2]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[2]) &&
|
||||
// 1st: short upper shadow
|
||||
GetUpperShadow(window[2]) < GetCandleAverage(CandleSettingType.ShadowShort, _shadowShortPeriodTotal[2], window[2]) &&
|
||||
(
|
||||
// ( 2 far smaller than 1 && 3 not longer than 2 )
|
||||
// advance blocked with the 2nd, 3rd must not carry on the advance
|
||||
(
|
||||
GetRealBody(window[1]) < GetRealBody(window[2]) - GetCandleAverage(CandleSettingType.Far, _farPeriodTotal[2], window[2]) &&
|
||||
GetRealBody(input) < GetRealBody(window[1]) + GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal[1], window[1])
|
||||
) ||
|
||||
// 3 far smaller than 2
|
||||
// advance blocked with the 3rd
|
||||
(
|
||||
GetRealBody(input) < GetRealBody(window[1]) - GetCandleAverage(CandleSettingType.Far, _farPeriodTotal[1], window[1])
|
||||
) ||
|
||||
// ( 3 smaller than 2 && 2 smaller than 1 && (3 or 2 not short upper shadow) )
|
||||
// advance blocked with progressively smaller real bodies and some upper shadows
|
||||
(
|
||||
GetRealBody(input) < GetRealBody(window[1]) &&
|
||||
GetRealBody(window[1]) < GetRealBody(window[2]) &&
|
||||
(
|
||||
GetUpperShadow(input) > GetCandleAverage(CandleSettingType.ShadowShort, _shadowShortPeriodTotal[0], input) ||
|
||||
GetUpperShadow(window[1]) > GetCandleAverage(CandleSettingType.ShadowShort, _shadowShortPeriodTotal[1], window[1])
|
||||
)
|
||||
) ||
|
||||
// ( 3 smaller than 2 && 3 long upper shadow )
|
||||
// advance blocked with 3rd candle's long upper shadow and smaller body
|
||||
(
|
||||
GetRealBody(input) < GetRealBody(window[1]) &&
|
||||
GetUpperShadow(input) > GetCandleAverage(CandleSettingType.ShadowLong, _shadowLongPeriodTotal[0], input)
|
||||
)
|
||||
)
|
||||
)
|
||||
value = -1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
for (var i = 2; i >= 0; i--)
|
||||
{
|
||||
_shadowShortPeriodTotal[i] += GetCandleRange(CandleSettingType.ShadowShort, window[i]) -
|
||||
GetCandleRange(CandleSettingType.ShadowShort, window[i + _shadowShortAveragePeriod]);
|
||||
}
|
||||
|
||||
for (var i = 1; i >= 0; i--)
|
||||
{
|
||||
_shadowLongPeriodTotal[i] += GetCandleRange(CandleSettingType.ShadowLong, window[i]) -
|
||||
GetCandleRange(CandleSettingType.ShadowLong, window[i + _shadowLongAveragePeriod]);
|
||||
}
|
||||
|
||||
for (var i = 2; i >= 1; i--)
|
||||
{
|
||||
_farPeriodTotal[i] += GetCandleRange(CandleSettingType.Far, window[i]) -
|
||||
GetCandleRange(CandleSettingType.Far, window[i + _farAveragePeriod]);
|
||||
_nearPeriodTotal[i] += GetCandleRange(CandleSettingType.Near, window[i]) -
|
||||
GetCandleRange(CandleSettingType.Near, window[i + _nearAveragePeriod]);
|
||||
}
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[2 + _bodyLongAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_shadowShortPeriodTotal = new decimal[3];
|
||||
_shadowLongPeriodTotal = new decimal[2];
|
||||
_nearPeriodTotal = new decimal[3];
|
||||
_farPeriodTotal = new decimal[3];
|
||||
_bodyLongPeriodTotal = 0;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Belt-hold candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - long white(black) real body
|
||||
/// - no or very short lower(upper) shadow
|
||||
/// The meaning of "long" and "very short" is specified with SetCandleSettings
|
||||
/// The returned value is positive(+1) when white(bullish), negative(-1) when black(bearish)
|
||||
/// </remarks>
|
||||
public class BeltHold : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
private readonly int _shadowVeryShortAveragePeriod;
|
||||
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
private decimal _shadowVeryShortPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BeltHold"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public BeltHold(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod, CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod) + 1)
|
||||
{
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_shadowVeryShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BeltHold"/> class.
|
||||
/// </summary>
|
||||
public BeltHold()
|
||||
: this("BELTHOLD")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyLongAveragePeriod)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowVeryShortAveragePeriod)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// long body
|
||||
GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, input) &&
|
||||
(
|
||||
(
|
||||
// white body and very short lower shadow
|
||||
GetCandleColor(input) == CandleColor.White &&
|
||||
GetLowerShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input)
|
||||
) ||
|
||||
(
|
||||
// black body and very short upper shadow
|
||||
GetCandleColor(input) == CandleColor.Black &&
|
||||
GetUpperShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input)
|
||||
)
|
||||
))
|
||||
value = (int)GetCandleColor(input);
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod]);
|
||||
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryShort, window[_shadowVeryShortAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = 0m;
|
||||
_shadowVeryShortPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Breakaway candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long black(white)
|
||||
/// - second candle: black(white) day whose body gaps down(up)
|
||||
/// - third candle: black or white day with lower(higher) high and lower(higher) low than prior candle's
|
||||
/// - fourth candle: black(white) day with lower(higher) high and lower(higher) low than prior candle's
|
||||
/// - fifth candle: white(black) day that closes inside the gap, erasing the prior 3 days
|
||||
/// The meaning of "long" is specified with SetCandleSettings
|
||||
/// The returned value is positive(+1) when bullish or negative(-1) when bearish;
|
||||
/// The user should consider that breakaway is significant in a trend opposite to the last candle, while this
|
||||
/// function does not consider it
|
||||
/// </remarks>
|
||||
public class Breakaway : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Breakaway"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public Breakaway(string name)
|
||||
: base(name, CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod + 4 + 1)
|
||||
{
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Breakaway"/> class.
|
||||
/// </summary>
|
||||
public Breakaway()
|
||||
: this("BREAKAWAY")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyLongAveragePeriod)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[4]);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st long
|
||||
GetRealBody(window[4]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[4]) &&
|
||||
// 1st, 2nd, 4th same color, 5th opposite
|
||||
GetCandleColor(window[4]) == GetCandleColor(window[3]) &&
|
||||
GetCandleColor(window[3]) == GetCandleColor(window[1]) &&
|
||||
(int)GetCandleColor(window[1]) == -(int)GetCandleColor(input) &&
|
||||
(
|
||||
(
|
||||
// when 1st is black:
|
||||
GetCandleColor(window[4]) == CandleColor.Black &&
|
||||
// 2nd gaps down
|
||||
GetRealBodyGapDown(window[3], window[4]) &&
|
||||
// 3rd has lower high and low than 2nd
|
||||
window[2].High < window[3].High && window[2].Low < window[3].Low &&
|
||||
// 4th has lower high and low than 3rd
|
||||
window[1].High < window[2].High && window[1].Low < window[2].Low &&
|
||||
// 5th closes inside the gap
|
||||
input.Close > window[3].Open && input.Close < window[4].Close
|
||||
)
|
||||
||
|
||||
(
|
||||
// when 1st is white:
|
||||
GetCandleColor(window[4]) == CandleColor.White &&
|
||||
// 2nd gaps up
|
||||
GetRealBodyGapUp(window[3], window[4]) &&
|
||||
// 3rd has higher high and low than 2nd
|
||||
window[2].High > window[3].High && window[2].Low > window[3].Low &&
|
||||
// 4th has higher high and low than 3rd
|
||||
window[1].High > window[2].High && window[1].Low > window[2].Low &&
|
||||
// 5th closes inside the gap
|
||||
input.Close < window[3].Open && input.Close > window[4].Close
|
||||
)
|
||||
)
|
||||
)
|
||||
value = (int)GetCandleColor(input);
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[4]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[4 + _bodyLongAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
namespace QuantConnect.Indicators.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Types of candlestick settings
|
||||
/// </summary>
|
||||
public enum CandleSettingType
|
||||
{
|
||||
/// <summary>
|
||||
/// Real body is long when it's longer than the average of the 10 previous candles' real body (0)
|
||||
/// </summary>
|
||||
BodyLong,
|
||||
|
||||
/// <summary>
|
||||
/// Real body is very long when it's longer than 3 times the average of the 10 previous candles' real body (1)
|
||||
/// </summary>
|
||||
BodyVeryLong,
|
||||
|
||||
/// <summary>
|
||||
/// Real body is short when it's shorter than the average of the 10 previous candles' real bodies (2)
|
||||
/// </summary>
|
||||
BodyShort,
|
||||
|
||||
/// <summary>
|
||||
/// Real body is like doji's body when it's shorter than 10% the average of the 10 previous candles' high-low range (3)
|
||||
/// </summary>
|
||||
BodyDoji,
|
||||
|
||||
/// <summary>
|
||||
/// Shadow is long when it's longer than the real body (4)
|
||||
/// </summary>
|
||||
ShadowLong,
|
||||
|
||||
/// <summary>
|
||||
/// Shadow is very long when it's longer than 2 times the real body (5)
|
||||
/// </summary>
|
||||
ShadowVeryLong,
|
||||
|
||||
/// <summary>
|
||||
/// Shadow is short when it's shorter than half the average of the 10 previous candles' sum of shadows (6)
|
||||
/// </summary>
|
||||
ShadowShort,
|
||||
|
||||
/// <summary>
|
||||
/// Shadow is very short when it's shorter than 10% the average of the 10 previous candles' high-low range (7)
|
||||
/// </summary>
|
||||
ShadowVeryShort,
|
||||
|
||||
/// <summary>
|
||||
/// When measuring distance between parts of candles or width of gaps
|
||||
/// "near" means "<= 20% of the average of the 5 previous candles' high-low range" (8)
|
||||
/// </summary>
|
||||
Near,
|
||||
|
||||
/// <summary>
|
||||
/// When measuring distance between parts of candles or width of gaps
|
||||
/// "far" means ">= 60% of the average of the 5 previous candles' high-low range" (9)
|
||||
/// </summary>
|
||||
Far,
|
||||
|
||||
/// <summary>
|
||||
/// When measuring distance between parts of candles or width of gaps
|
||||
/// "equal" means "<= 5% of the average of the 5 previous candles' high-low range" (10)
|
||||
/// </summary>
|
||||
Equal
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Types of candlestick ranges
|
||||
/// </summary>
|
||||
public enum CandleRangeType
|
||||
{
|
||||
/// <summary>
|
||||
/// The part of the candle between open and close (0)
|
||||
/// </summary>
|
||||
RealBody,
|
||||
|
||||
/// <summary>
|
||||
/// The complete range of the candle (1)
|
||||
/// </summary>
|
||||
HighLow,
|
||||
|
||||
/// <summary>
|
||||
/// The shadows (or tails) of the candle (2)
|
||||
/// </summary>
|
||||
Shadows
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Colors of a candle
|
||||
/// </summary>
|
||||
public enum CandleColor
|
||||
{
|
||||
/// <summary>
|
||||
/// White is an up candle (close higher or equal than open) (1)
|
||||
/// </summary>
|
||||
White = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Black is a down candle (close lower than open) (-1)
|
||||
/// </summary>
|
||||
Black = -1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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.Collections.Generic;
|
||||
|
||||
namespace QuantConnect.Indicators.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Candle settings for all candlestick patterns
|
||||
/// </summary>
|
||||
public static class CandleSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Default settings for all candle setting types
|
||||
/// </summary>
|
||||
private static readonly Dictionary<CandleSettingType, CandleSetting> DefaultSettings = new Dictionary<CandleSettingType, CandleSetting>
|
||||
{
|
||||
{ CandleSettingType.BodyLong, new CandleSetting(CandleRangeType.RealBody, 10, 1m) },
|
||||
{ CandleSettingType.BodyVeryLong, new CandleSetting(CandleRangeType.RealBody, 10, 3m) },
|
||||
{ CandleSettingType.BodyShort, new CandleSetting(CandleRangeType.RealBody, 10, 1m) },
|
||||
{ CandleSettingType.BodyDoji, new CandleSetting(CandleRangeType.HighLow, 10, 0.1m) },
|
||||
{ CandleSettingType.ShadowLong, new CandleSetting(CandleRangeType.RealBody, 0, 1m) },
|
||||
{ CandleSettingType.ShadowVeryLong, new CandleSetting(CandleRangeType.RealBody, 0, 2m) },
|
||||
{ CandleSettingType.ShadowShort, new CandleSetting(CandleRangeType.Shadows, 10, 1m) },
|
||||
{ CandleSettingType.ShadowVeryShort, new CandleSetting(CandleRangeType.HighLow, 10, 0.1m) },
|
||||
{ CandleSettingType.Near, new CandleSetting(CandleRangeType.HighLow, 5, 0.2m) },
|
||||
{ CandleSettingType.Far, new CandleSetting(CandleRangeType.HighLow, 5, 0.6m) },
|
||||
{ CandleSettingType.Equal, new CandleSetting(CandleRangeType.HighLow, 5, 0.05m) }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Returns the candle setting for the requested type
|
||||
/// </summary>
|
||||
/// <param name="type">The candle setting type</param>
|
||||
public static CandleSetting Get(CandleSettingType type)
|
||||
{
|
||||
CandleSetting setting;
|
||||
DefaultSettings.TryGetValue(type, out setting);
|
||||
return setting;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the default candle setting for the requested type
|
||||
/// </summary>
|
||||
/// <param name="type">The candle setting type</param>
|
||||
/// <param name="setting">The candle setting</param>
|
||||
public static void Set(CandleSettingType type, CandleSetting setting)
|
||||
{
|
||||
DefaultSettings[type] = setting;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a candle setting
|
||||
/// </summary>
|
||||
public class CandleSetting
|
||||
{
|
||||
/// <summary>
|
||||
/// The candle range type
|
||||
/// </summary>
|
||||
public CandleRangeType RangeType
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of previous candles to average
|
||||
/// </summary>
|
||||
public int AveragePeriod
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A multiplier to calculate candle ranges
|
||||
/// </summary>
|
||||
public decimal Factor
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="CandleSetting"/> class
|
||||
/// </summary>
|
||||
/// <param name="rangeType">The range type</param>
|
||||
/// <param name="averagePeriod">The average period</param>
|
||||
/// <param name="factor">The factor</param>
|
||||
public CandleSetting(CandleRangeType rangeType, int averagePeriod, decimal factor)
|
||||
{
|
||||
RangeType = rangeType;
|
||||
AveragePeriod = averagePeriod;
|
||||
Factor = factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstract base class for a candlestick pattern indicator
|
||||
/// </summary>
|
||||
public abstract class CandlestickPattern : WindowIndicator<IBaseDataBar>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="CandlestickPattern"/> with the specified name
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="period">The number of data points to hold in the window</param>
|
||||
protected CandlestickPattern(string name, int period)
|
||||
: base(name, period)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the candle color of a candle
|
||||
/// </summary>
|
||||
/// <param name="tradeBar">The input candle</param>
|
||||
protected static CandleColor GetCandleColor(IBaseDataBar tradeBar)
|
||||
{
|
||||
return tradeBar.Close >= tradeBar.Open ? CandleColor.White : CandleColor.Black;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the distance between the close and the open of a candle
|
||||
/// </summary>
|
||||
/// <param name="tradeBar">The input candle</param>
|
||||
protected static decimal GetRealBody(IBaseDataBar tradeBar)
|
||||
{
|
||||
return Math.Abs(tradeBar.Close - tradeBar.Open);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the full range of the candle
|
||||
/// </summary>
|
||||
/// <param name="tradeBar">The input candle</param>
|
||||
protected static decimal GetHighLowRange(IBaseDataBar tradeBar)
|
||||
{
|
||||
return tradeBar.High - tradeBar.Low;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the range of a candle
|
||||
/// </summary>
|
||||
/// <param name="type">The type of setting to use</param>
|
||||
/// <param name="tradeBar">The input candle</param>
|
||||
protected static decimal GetCandleRange(CandleSettingType type, IBaseDataBar tradeBar)
|
||||
{
|
||||
switch (CandleSettings.Get(type).RangeType)
|
||||
{
|
||||
case CandleRangeType.RealBody:
|
||||
return GetRealBody(tradeBar);
|
||||
|
||||
case CandleRangeType.HighLow:
|
||||
return GetHighLowRange(tradeBar);
|
||||
|
||||
case CandleRangeType.Shadows:
|
||||
return GetUpperShadow(tradeBar) + GetLowerShadow(tradeBar);
|
||||
|
||||
default:
|
||||
return 0m;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the candle is higher than the previous one
|
||||
/// </summary>
|
||||
protected static bool GetCandleGapUp(IBaseDataBar tradeBar, IBaseDataBar previousBar)
|
||||
{
|
||||
return tradeBar.Low > previousBar.High;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the candle is lower than the previous one
|
||||
/// </summary>
|
||||
protected static bool GetCandleGapDown(IBaseDataBar tradeBar, IBaseDataBar previousBar)
|
||||
{
|
||||
return tradeBar.High < previousBar.Low;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the candle is higher than the previous one (with no body overlap)
|
||||
/// </summary>
|
||||
protected static bool GetRealBodyGapUp(IBaseDataBar tradeBar, IBaseDataBar previousBar)
|
||||
{
|
||||
return Math.Min(tradeBar.Open, tradeBar.Close) > Math.Max(previousBar.Open, previousBar.Close);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the candle is lower than the previous one (with no body overlap)
|
||||
/// </summary>
|
||||
protected static bool GetRealBodyGapDown(IBaseDataBar tradeBar, IBaseDataBar previousBar)
|
||||
{
|
||||
return Math.Max(tradeBar.Open, tradeBar.Close) < Math.Min(previousBar.Open, previousBar.Close);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the range of the candle's lower shadow
|
||||
/// </summary>
|
||||
/// <param name="tradeBar">The input candle</param>
|
||||
protected static decimal GetLowerShadow(IBaseDataBar tradeBar)
|
||||
{
|
||||
return (tradeBar.Close >= tradeBar.Open ? tradeBar.Open : tradeBar.Close) - tradeBar.Low;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the range of the candle's upper shadow
|
||||
/// </summary>
|
||||
/// <param name="tradeBar">The input candle</param>
|
||||
protected static decimal GetUpperShadow(IBaseDataBar tradeBar)
|
||||
{
|
||||
return tradeBar.High - (tradeBar.Close >= tradeBar.Open ? tradeBar.Close : tradeBar.Open);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the average range of the previous candles
|
||||
/// </summary>
|
||||
/// <param name="type">The type of setting to use</param>
|
||||
/// <param name="sum">The sum of the previous candles ranges</param>
|
||||
/// <param name="tradeBar">The input candle</param>
|
||||
protected static decimal GetCandleAverage(CandleSettingType type, decimal sum, IBaseDataBar tradeBar)
|
||||
{
|
||||
var defaultSetting = CandleSettings.Get(type);
|
||||
|
||||
return defaultSetting.Factor *
|
||||
(defaultSetting.AveragePeriod != 0 ? sum / defaultSetting.AveragePeriod : GetCandleRange(type, tradeBar)) /
|
||||
(defaultSetting.RangeType == CandleRangeType.Shadows ? 2.0m : 1.0m);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Closing Marubozu candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - long white(black) real body
|
||||
/// - no or very short upper(lower) shadow
|
||||
/// The meaning of "long" and "very short" is specified with SetCandleSettings
|
||||
/// The returned value is positive(+1) when white(bullish), negative(-1) when black(bearish)
|
||||
/// </remarks>
|
||||
public class ClosingMarubozu : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
private readonly int _shadowVeryShortAveragePeriod;
|
||||
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
private decimal _shadowVeryShortPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ClosingMarubozu"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public ClosingMarubozu(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod, CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod) + 1)
|
||||
{
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_shadowVeryShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ClosingMarubozu"/> class.
|
||||
/// </summary>
|
||||
public ClosingMarubozu()
|
||||
: this("CLOSINGMARUBOZU")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyLongAveragePeriod)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowVeryShortAveragePeriod)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// long body
|
||||
GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, input) &&
|
||||
(
|
||||
(
|
||||
// white body and very short upper shadow
|
||||
GetCandleColor(input) == CandleColor.White &&
|
||||
GetUpperShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input)
|
||||
) ||
|
||||
(
|
||||
// black body and very short lower shadow
|
||||
GetCandleColor(input) == CandleColor.Black &&
|
||||
GetLowerShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input)
|
||||
)
|
||||
))
|
||||
value = (int)GetCandleColor(input);
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod]);
|
||||
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryShort, window[_shadowVeryShortAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = 0m;
|
||||
_shadowVeryShortPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Concealed Baby Swallow candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: black marubozu (very short shadows)
|
||||
/// - second candle: black marubozu(very short shadows)
|
||||
/// - third candle: black candle that opens gapping down but has an upper shadow that extends into the prior body
|
||||
/// - fourth candle: black candle that completely engulfs the third candle, including the shadows
|
||||
/// The meanings of "very short shadow" are specified with SetCandleSettings;
|
||||
/// The returned value is positive(+1): concealing baby swallow is always bullish;
|
||||
/// The user should consider that concealing baby swallow is significant when it appears in downtrend, while
|
||||
/// this function does not consider it
|
||||
/// </remarks>
|
||||
public class ConcealedBabySwallow : CandlestickPattern
|
||||
{
|
||||
private readonly int _shadowVeryShortAveragePeriod;
|
||||
|
||||
private decimal[] _shadowVeryShortPeriodTotal = new decimal[4];
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConcealedBabySwallow"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public ConcealedBabySwallow(string name)
|
||||
: base(name, CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod + 3 + 1)
|
||||
{
|
||||
_shadowVeryShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConcealedBabySwallow"/> class.
|
||||
/// </summary>
|
||||
public ConcealedBabySwallow()
|
||||
: this("CONCEALEDBABYSWALLOW")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _shadowVeryShortAveragePeriod)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal[3] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[3]);
|
||||
_shadowVeryShortPeriodTotal[2] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[2]);
|
||||
_shadowVeryShortPeriodTotal[1] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[1]);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st black
|
||||
GetCandleColor(window[3]) == CandleColor.Black &&
|
||||
// 2nd black
|
||||
GetCandleColor(window[2]) == CandleColor.Black &&
|
||||
// 3rd black
|
||||
GetCandleColor(window[1]) == CandleColor.Black &&
|
||||
// 4th black
|
||||
GetCandleColor(input) == CandleColor.Black &&
|
||||
// 1st: marubozu
|
||||
GetLowerShadow(window[3]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[3], window[3]) &&
|
||||
GetUpperShadow(window[3]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[3], window[3]) &&
|
||||
// 2nd: marubozu
|
||||
GetLowerShadow(window[2]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[2], window[2]) &&
|
||||
GetUpperShadow(window[2]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[2], window[2]) &&
|
||||
// 3rd: opens gapping down
|
||||
GetRealBodyGapDown(window[1], window[2]) &&
|
||||
// and has an upper shadow
|
||||
GetUpperShadow(window[1]) > GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[1], window[1]) &&
|
||||
// that extends into the prior body
|
||||
window[1].High > window[2].Close &&
|
||||
// 4th: engulfs the 3rd including the shadows
|
||||
input.High > window[1].High && input.Low < window[1].Low
|
||||
)
|
||||
value = 1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
for (var i = 3; i >= 1; i--)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal[i] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[i]) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryShort, window[i + _shadowVeryShortAveragePeriod]);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_shadowVeryShortPeriodTotal = new decimal[4];
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Counterattack candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long black (white)
|
||||
/// - second candle: long white(black) with close equal to the prior close
|
||||
/// The meaning of "equal" and "long" is specified with SetCandleSettings
|
||||
/// The returned value is positive(+1) when bullish or negative(-1) when bearish;
|
||||
/// The user should consider that counterattack is significant in a trend, while this function does not consider it
|
||||
/// </remarks>
|
||||
public class Counterattack : CandlestickPattern
|
||||
{
|
||||
private readonly int _equalAveragePeriod;
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
|
||||
private decimal _equalPeriodTotal;
|
||||
private decimal[] _bodyLongPeriodTotal = new decimal[2];
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Counterattack"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public Counterattack(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.Equal).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod) + 1 + 1)
|
||||
{
|
||||
_equalAveragePeriod = CandleSettings.Get(CandleSettingType.Equal).AveragePeriod;
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Counterattack"/> class.
|
||||
/// </summary>
|
||||
public Counterattack()
|
||||
: this("COUNTERATTACK")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _equalAveragePeriod)
|
||||
{
|
||||
_equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyLongAveragePeriod)
|
||||
{
|
||||
_bodyLongPeriodTotal[1] += GetCandleRange(CandleSettingType.BodyLong, window[1]);
|
||||
_bodyLongPeriodTotal[0] += GetCandleRange(CandleSettingType.BodyLong, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// opposite candles
|
||||
(int)GetCandleColor(window[1]) == -(int)GetCandleColor(input) &&
|
||||
// 1st long
|
||||
GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal[1], window[1]) &&
|
||||
// 2nd long
|
||||
GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal[0], input) &&
|
||||
// equal closes
|
||||
input.Close <= window[1].Close + GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[1]) &&
|
||||
input.Close >= window[1].Close - GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[1])
|
||||
)
|
||||
value = (int)GetCandleColor(input);
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, input) -
|
||||
GetCandleRange(CandleSettingType.Equal, window[_equalAveragePeriod + 1]);
|
||||
|
||||
for (var i = 1; i >= 0; i--)
|
||||
{
|
||||
_bodyLongPeriodTotal[i] += GetCandleRange(CandleSettingType.BodyLong, window[i]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[i + _bodyLongAveragePeriod]);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_equalPeriodTotal = 0;
|
||||
_bodyLongPeriodTotal = new decimal[2];
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Dark Cloud Cover candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long white candle
|
||||
/// - second candle: black candle that opens above previous day high and closes within previous day real body;
|
||||
/// Greg Morris wants the close to be below the midpoint of the previous real body
|
||||
/// The meaning of "long" is specified with SetCandleSettings, the penetration of the first real body is specified
|
||||
/// with optInPenetration
|
||||
/// The returned value is negative(-1): dark cloud cover is always bearish
|
||||
/// The user should consider that a dark cloud cover is significant when it appears in an uptrend, while
|
||||
/// this function does not consider it
|
||||
/// </remarks>
|
||||
public class DarkCloudCover : CandlestickPattern
|
||||
{
|
||||
private readonly decimal _penetration;
|
||||
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DarkCloudCover"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="penetration">Percentage of penetration of a candle within another candle</param>
|
||||
public DarkCloudCover(string name, decimal penetration = 0.5m)
|
||||
: base(name, CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod + 1 + 1)
|
||||
{
|
||||
_penetration = penetration;
|
||||
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DarkCloudCover"/> class.
|
||||
/// </summary>
|
||||
/// <param name="penetration">Percentage of penetration of a candle within another candle</param>
|
||||
public DarkCloudCover(decimal penetration)
|
||||
: this("DARKCLOUDCOVER", penetration)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DarkCloudCover"/> class.
|
||||
/// </summary>
|
||||
public DarkCloudCover()
|
||||
: this("DARKCLOUDCOVER")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyLongAveragePeriod)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st: white
|
||||
GetCandleColor(window[1]) == CandleColor.White &&
|
||||
// long
|
||||
GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[1]) &&
|
||||
// 2nd: black
|
||||
GetCandleColor(input) == CandleColor.Black &&
|
||||
// open above prior high
|
||||
input.Open > window[1].High &&
|
||||
// close within prior body
|
||||
input.Close > window[1].Open &&
|
||||
input.Close < window[1].Close - GetRealBody(window[1]) * _penetration
|
||||
)
|
||||
value = -1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 1]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = 0;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Doji candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - open quite equal to close
|
||||
/// How much can be the maximum distance between open and close is specified with SetCandleSettings
|
||||
/// The returned value is always positive(+1) but this does not mean it is bullish: doji shows uncertainty and it is
|
||||
/// neither bullish nor bearish when considered alone
|
||||
/// </remarks>
|
||||
public class Doji : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyDojiAveragePeriod;
|
||||
|
||||
private decimal _bodyDojiPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Doji"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public Doji(string name)
|
||||
: base(name, CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod + 1)
|
||||
{
|
||||
_bodyDojiAveragePeriod = CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Doji"/> class.
|
||||
/// </summary>
|
||||
public Doji()
|
||||
: this("DOJI")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyDojiAveragePeriod)
|
||||
{
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
var value = GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, input) ? 1m : 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input) -
|
||||
GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyDojiPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Doji Star candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long real body
|
||||
/// - second candle: star(open gapping up in an uptrend or down in a downtrend) with a doji
|
||||
/// The meaning of "doji" and "long" is specified with SetCandleSettings
|
||||
/// The returned value is positive(+1) when bullish or negative(-1) when bearish;
|
||||
/// it's defined bullish when the long candle is white and the star gaps up, bearish when the long candle
|
||||
/// is black and the star gaps down; the user should consider that a doji star is bullish when it appears
|
||||
/// in an uptrend and it's bearish when it appears in a downtrend, so to determine the bullishness or
|
||||
/// bearishness of the pattern the trend must be analyzed
|
||||
/// </remarks>
|
||||
public class DojiStar : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
private readonly int _bodyDojiAveragePeriod;
|
||||
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
private decimal _bodyDojiPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DojiStar"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public DojiStar(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod) + 1 + 1)
|
||||
{
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_bodyDojiAveragePeriod = CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DojiStar"/> class.
|
||||
/// </summary>
|
||||
public DojiStar()
|
||||
: this("DOJISTAR")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyLongAveragePeriod - 1 && Samples < Period - 1)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyDojiAveragePeriod)
|
||||
{
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st: long real body
|
||||
GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[1]) &&
|
||||
// 2nd: doji
|
||||
GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, input) &&
|
||||
// that gaps up if 1st is white
|
||||
((GetCandleColor(window[1]) == CandleColor.White && GetRealBodyGapUp(input, window[1]))
|
||||
||
|
||||
// or down if 1st is black
|
||||
(GetCandleColor(window[1]) == CandleColor.Black && GetRealBodyGapDown(input, window[1]))
|
||||
))
|
||||
value = -(int)GetCandleColor(window[1]);
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 1]);
|
||||
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input) -
|
||||
GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = 0m;
|
||||
_bodyDojiPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Dragonfly Doji candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - doji body
|
||||
/// - open and close at the high of the day = no or very short upper shadow
|
||||
/// - lower shadow(to distinguish from other dojis, here lower shadow should not be very short)
|
||||
/// The meaning of "doji" and "very short" is specified with SetCandleSettings
|
||||
/// The returned value is always positive(+1) but this does not mean it is bullish: dragonfly doji must be considered
|
||||
/// relatively to the trend
|
||||
/// </remarks>
|
||||
public class DragonflyDoji : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyDojiAveragePeriod;
|
||||
private readonly int _shadowVeryShortAveragePeriod;
|
||||
|
||||
private decimal _bodyDojiPeriodTotal;
|
||||
private decimal _shadowVeryShortPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DragonflyDoji"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public DragonflyDoji(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod, CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod) + 1)
|
||||
{
|
||||
_bodyDojiAveragePeriod = CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod;
|
||||
_shadowVeryShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DragonflyDoji"/> class.
|
||||
/// </summary>
|
||||
public DragonflyDoji()
|
||||
: this("DRAGONFLYDOJI")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyDojiAveragePeriod)
|
||||
{
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowVeryShortAveragePeriod)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, input) &&
|
||||
GetUpperShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input) &&
|
||||
GetLowerShadow(input) > GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input)
|
||||
)
|
||||
value = 1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input) -
|
||||
GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod]);
|
||||
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryShort, window[_shadowVeryShortAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyDojiPeriodTotal = 0m;
|
||||
_shadowVeryShortPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Engulfing candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first: black (white) real body
|
||||
/// - second: white(black) real body that engulfs the prior real body
|
||||
/// The returned value is positive(+1) when bullish or negative(-1) when bearish;
|
||||
/// The user should consider that an engulfing must appear in a downtrend if bullish or in an uptrend if bearish,
|
||||
/// while this function does not consider it
|
||||
/// </remarks>
|
||||
public class Engulfing : CandlestickPattern
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Engulfing"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public Engulfing(string name)
|
||||
: base(name, 3)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Engulfing"/> class.
|
||||
/// </summary>
|
||||
public Engulfing()
|
||||
: this("ENGULFING")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// white engulfs black
|
||||
(GetCandleColor(input) == CandleColor.White && GetCandleColor(window[1]) == CandleColor.Black &&
|
||||
input.Close > window[1].Open && input.Open < window[1].Close
|
||||
)
|
||||
||
|
||||
// black engulfs white
|
||||
(GetCandleColor(input) == CandleColor.Black && GetCandleColor(window[1]) == CandleColor.White &&
|
||||
input.Open > window[1].Close && input.Close < window[1].Open
|
||||
)
|
||||
)
|
||||
value = (int)GetCandleColor(input);
|
||||
else
|
||||
value = 0;
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Evening Doji Star candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long white real body
|
||||
/// - second candle: doji gapping up
|
||||
/// - third candle: black real body that moves well within the first candle's real body
|
||||
/// The meaning of "doji" and "long" is specified with SetCandleSettings
|
||||
/// The meaning of "moves well within" is specified with penetration and "moves" should mean the real body should
|
||||
/// not be short ("short" is specified with SetCandleSettings) - Greg Morris wants it to be long, someone else want
|
||||
/// it to be relatively long
|
||||
/// The returned value is negative(-1): evening star is always bearish;
|
||||
/// The user should consider that an evening star is significant when it appears in an uptrend,
|
||||
/// while this function does not consider the trend
|
||||
/// </remarks>
|
||||
public class EveningDojiStar : CandlestickPattern
|
||||
{
|
||||
private readonly decimal _penetration;
|
||||
|
||||
private readonly int _bodyDojiAveragePeriod;
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
|
||||
private decimal _bodyDojiPeriodTotal;
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
private decimal _bodyShortPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EveningDojiStar"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="penetration">Percentage of penetration of a candle within another candle</param>
|
||||
public EveningDojiStar(string name, decimal penetration = 0.3m)
|
||||
: base(name, Math.Max(Math.Max(CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod),
|
||||
CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod) + 2 + 1)
|
||||
{
|
||||
_penetration = penetration;
|
||||
|
||||
_bodyDojiAveragePeriod = CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod;
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EveningDojiStar"/> class.
|
||||
/// </summary>
|
||||
/// <param name="penetration">Percentage of penetration of a candle within another candle</param>
|
||||
public EveningDojiStar(decimal penetration)
|
||||
: this("EVENINGDOJISTAR", penetration)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EveningDojiStar"/> class.
|
||||
/// </summary>
|
||||
public EveningDojiStar()
|
||||
: this("EVENINGDOJISTAR")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyLongAveragePeriod - 2 && Samples < Period - 2)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyDojiAveragePeriod - 1 && Samples < Period - 1)
|
||||
{
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyShortAveragePeriod)
|
||||
{
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st: long
|
||||
GetRealBody(window[2]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[2]) &&
|
||||
// white
|
||||
GetCandleColor(window[2]) == CandleColor.White &&
|
||||
// 2nd: doji
|
||||
GetRealBody(window[1]) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, window[1]) &&
|
||||
// gapping up
|
||||
GetRealBodyGapUp(window[1], window[2]) &&
|
||||
// 3rd: longer than short
|
||||
GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) &&
|
||||
// black real body
|
||||
GetCandleColor(input) == CandleColor.Black &&
|
||||
// closing well within 1st rb
|
||||
input.Close < window[2].Close - GetRealBody(window[2]) * _penetration
|
||||
)
|
||||
value = -1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 2]);
|
||||
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, window[1]) -
|
||||
GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod + 1]);
|
||||
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = 0;
|
||||
_bodyDojiPeriodTotal = 0;
|
||||
_bodyShortPeriodTotal = 0;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Evening Star candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long white real body
|
||||
/// - second candle: star(short real body gapping up)
|
||||
/// - third candle: black real body that moves well within the first candle's real body
|
||||
/// The meaning of "short" and "long" is specified with SetCandleSettings
|
||||
/// The meaning of "moves well within" is specified with penetration and "moves" should mean the real body should
|
||||
/// not be short ("short" is specified with SetCandleSettings) - Greg Morris wants it to be long, someone else want
|
||||
/// it to be relatively long
|
||||
/// The returned value is negative(-1): evening star is always bearish;
|
||||
/// The user should consider that an evening star is significant when it appears in an uptrend,
|
||||
/// while this function does not consider the trend
|
||||
/// </remarks>
|
||||
public class EveningStar : CandlestickPattern
|
||||
{
|
||||
private readonly decimal _penetration;
|
||||
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
private decimal _bodyShortPeriodTotal;
|
||||
private decimal _bodyShortPeriodTotal2;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EveningStar"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="penetration">Percentage of penetration of a candle within another candle</param>
|
||||
public EveningStar(string name, decimal penetration = 0.3m)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod) + 2 + 1)
|
||||
{
|
||||
_penetration = penetration;
|
||||
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EveningStar"/> class.
|
||||
/// </summary>
|
||||
/// <param name="penetration">Percentage of penetration of a candle within another candle</param>
|
||||
public EveningStar(decimal penetration)
|
||||
: this("EVENINGSTAR", penetration)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EveningStar"/> class.
|
||||
/// </summary>
|
||||
public EveningStar()
|
||||
: this("EVENINGSTAR")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyLongAveragePeriod - 2 && Samples < Period - 2)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyShortAveragePeriod && Samples < Period)
|
||||
{
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, window[1]);
|
||||
_bodyShortPeriodTotal2 += GetCandleRange(CandleSettingType.BodyShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st: long
|
||||
GetRealBody(window[2]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[2]) &&
|
||||
// white
|
||||
GetCandleColor(window[2]) == CandleColor.White &&
|
||||
// 2nd: short
|
||||
GetRealBody(window[1]) <= GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, window[1]) &&
|
||||
// gapping up
|
||||
GetRealBodyGapUp(window[1], window[2]) &&
|
||||
// 3rd: longer than short
|
||||
GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal2, input) &&
|
||||
// black real body
|
||||
GetCandleColor(input) == CandleColor.Black &&
|
||||
// closing well within 1st rb
|
||||
input.Close < window[2].Close - GetRealBody(window[2]) * _penetration
|
||||
)
|
||||
value = -1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 2]);
|
||||
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, window[1]) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod + 1]);
|
||||
|
||||
_bodyShortPeriodTotal2 += GetCandleRange(CandleSettingType.BodyShort, input) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = 0;
|
||||
_bodyShortPeriodTotal = 0;
|
||||
_bodyShortPeriodTotal2 = 0;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Up/Down-gap side-by-side white lines candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - upside or downside gap (between the bodies)
|
||||
/// - first candle after the window: white candlestick
|
||||
/// - second candle after the window: white candlestick with similar size(near the same) and about the same
|
||||
/// open(equal) of the previous candle
|
||||
/// - the second candle does not close the window
|
||||
/// The meaning of "near" and "equal" is specified with SetCandleSettings
|
||||
/// The returned value is positive(+1) or negative(-1): the user should consider that upside
|
||||
/// or downside gap side-by-side white lines is significant when it appears in a trend, while this function
|
||||
/// does not consider the trend
|
||||
/// </remarks>
|
||||
public class GapSideBySideWhite : CandlestickPattern
|
||||
{
|
||||
private readonly int _nearAveragePeriod;
|
||||
private readonly int _equalAveragePeriod;
|
||||
|
||||
private decimal _nearPeriodTotal;
|
||||
private decimal _equalPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GapSideBySideWhite"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public GapSideBySideWhite(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.Near).AveragePeriod, CandleSettings.Get(CandleSettingType.Equal).AveragePeriod) + 2 + 1)
|
||||
{
|
||||
_nearAveragePeriod = CandleSettings.Get(CandleSettingType.Near).AveragePeriod;
|
||||
_equalAveragePeriod = CandleSettings.Get(CandleSettingType.Equal).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GapSideBySideWhite"/> class.
|
||||
/// </summary>
|
||||
public GapSideBySideWhite()
|
||||
: this("GAPSIDEBYSIDEWHITE")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _nearAveragePeriod)
|
||||
{
|
||||
_nearPeriodTotal += GetCandleRange(CandleSettingType.Near, window[1]);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _equalAveragePeriod)
|
||||
{
|
||||
_equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
( // upside or downside gap between the 1st candle and both the next 2 candles
|
||||
(GetRealBodyGapUp(window[1], window[2]) && GetRealBodyGapUp(input, window[2]))
|
||||
||
|
||||
(GetRealBodyGapDown(window[1], window[2]) && GetRealBodyGapDown(input, window[2]))
|
||||
) &&
|
||||
// 2nd: white
|
||||
GetCandleColor(window[1]) == CandleColor.White &&
|
||||
// 3rd: white
|
||||
GetCandleColor(input) == CandleColor.White &&
|
||||
// same size 2 and 3
|
||||
GetRealBody(input) >= GetRealBody(window[1]) - GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal, window[1]) &&
|
||||
GetRealBody(input) <= GetRealBody(window[1]) + GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal, window[1]) &&
|
||||
// same open 2 and 3
|
||||
input.Open >= window[1].Open - GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[1]) &&
|
||||
input.Open <= window[1].Open + GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[1])
|
||||
)
|
||||
value = GetRealBodyGapUp(window[1], window[2]) ? 1m : -1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_nearPeriodTotal += GetCandleRange(CandleSettingType.Near, window[1]) -
|
||||
GetCandleRange(CandleSettingType.Near, window[1 + _nearAveragePeriod]);
|
||||
|
||||
_equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]) -
|
||||
GetCandleRange(CandleSettingType.Equal, window[1 + _equalAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_nearPeriodTotal = 0;
|
||||
_equalPeriodTotal = 0;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Gravestone Doji candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - doji body
|
||||
/// - open and close at the low of the day = no or very short lower shadow
|
||||
/// - upper shadow(to distinguish from other dojis, here upper shadow should not be very short)
|
||||
/// The meaning of "doji" and "very short" is specified with SetCandleSettings
|
||||
/// The returned value is always positive(+1) but this does not mean it is bullish: gravestone doji must be considered
|
||||
/// relatively to the trend
|
||||
/// </remarks>
|
||||
public class GravestoneDoji : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyDojiAveragePeriod;
|
||||
private readonly int _shadowVeryShortAveragePeriod;
|
||||
|
||||
private decimal _bodyDojiPeriodTotal;
|
||||
private decimal _shadowVeryShortPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GravestoneDoji"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public GravestoneDoji(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod, CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod) + 1)
|
||||
{
|
||||
_bodyDojiAveragePeriod = CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod;
|
||||
_shadowVeryShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GravestoneDoji"/> class.
|
||||
/// </summary>
|
||||
public GravestoneDoji()
|
||||
: this("GRAVESTONEDOJI")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyDojiAveragePeriod)
|
||||
{
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowVeryShortAveragePeriod)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, input) &&
|
||||
GetLowerShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input) &&
|
||||
GetUpperShadow(input) > GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input)
|
||||
)
|
||||
value = 1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input) -
|
||||
GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod]);
|
||||
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryShort, window[_shadowVeryShortAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyDojiPeriodTotal = 0m;
|
||||
_shadowVeryShortPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Hammer candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - small real body
|
||||
/// - long lower shadow
|
||||
/// - no, or very short, upper shadow
|
||||
/// - body below or near the lows of the previous candle
|
||||
/// The meaning of "short", "long" and "near the lows" is specified with SetCandleSettings;
|
||||
/// The returned value is positive(+1): hammer is always bullish;
|
||||
/// The user should consider that a hammer must appear in a downtrend, while this function does not consider it
|
||||
/// </remarks>
|
||||
public class Hammer : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
private readonly int _shadowLongAveragePeriod;
|
||||
private readonly int _shadowVeryShortAveragePeriod;
|
||||
private readonly int _nearAveragePeriod;
|
||||
|
||||
private decimal _bodyShortPeriodTotal;
|
||||
private decimal _shadowLongPeriodTotal;
|
||||
private decimal _shadowVeryShortPeriodTotal;
|
||||
private decimal _nearPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Hammer"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public Hammer(string name)
|
||||
: base(name, Math.Max(Math.Max(Math.Max(CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod, CandleSettings.Get(CandleSettingType.ShadowLong).AveragePeriod),
|
||||
CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod), CandleSettings.Get(CandleSettingType.Near).AveragePeriod) + 1 + 1)
|
||||
{
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_shadowLongAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowLong).AveragePeriod;
|
||||
_shadowVeryShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod;
|
||||
_nearAveragePeriod = CandleSettings.Get(CandleSettingType.Near).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Hammer"/> class.
|
||||
/// </summary>
|
||||
public Hammer()
|
||||
: this("HAMMER")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyShortAveragePeriod)
|
||||
{
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowLongAveragePeriod)
|
||||
{
|
||||
_shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowVeryShortAveragePeriod)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _nearAveragePeriod - 1 && Samples < Period - 1)
|
||||
{
|
||||
_nearPeriodTotal += GetCandleRange(CandleSettingType.Near, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// small rb
|
||||
GetRealBody(input) < GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) &&
|
||||
// long lower shadow
|
||||
GetLowerShadow(input) > GetCandleAverage(CandleSettingType.ShadowLong, _shadowLongPeriodTotal, input) &&
|
||||
// very short upper shadow
|
||||
GetUpperShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input) &&
|
||||
// rb near the prior candle's lows
|
||||
Math.Min(input.Close, input.Open) <= window[1].Low + GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal, window[1])
|
||||
)
|
||||
value = 1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]);
|
||||
|
||||
_shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input) -
|
||||
GetCandleRange(CandleSettingType.ShadowLong, window[_shadowLongAveragePeriod]);
|
||||
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryShort, window[_shadowVeryShortAveragePeriod]);
|
||||
|
||||
_nearPeriodTotal += GetCandleRange(CandleSettingType.Near, window[1]) -
|
||||
GetCandleRange(CandleSettingType.Near, window[_nearAveragePeriod + 1]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyShortPeriodTotal = 0m;
|
||||
_shadowLongPeriodTotal = 0m;
|
||||
_shadowVeryShortPeriodTotal = 0m;
|
||||
_nearPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Hanging Man candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - small real body
|
||||
/// - long lower shadow
|
||||
/// - no, or very short, upper shadow
|
||||
/// - body above or near the highs of the previous candle
|
||||
/// The meaning of "short", "long" and "near the highs" is specified with SetCandleSettings;
|
||||
/// The returned value is negative (-1): hanging man is always bearish;
|
||||
/// The user should consider that a hanging man must appear in an uptrend, while this function does not consider it
|
||||
/// </remarks>
|
||||
public class HangingMan : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
private readonly int _shadowLongAveragePeriod;
|
||||
private readonly int _shadowVeryShortAveragePeriod;
|
||||
private readonly int _nearAveragePeriod;
|
||||
|
||||
private decimal _bodyShortPeriodTotal;
|
||||
private decimal _shadowLongPeriodTotal;
|
||||
private decimal _shadowVeryShortPeriodTotal;
|
||||
private decimal _nearPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HangingMan"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public HangingMan(string name)
|
||||
: base(name, Math.Max(Math.Max(Math.Max(CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod, CandleSettings.Get(CandleSettingType.ShadowLong).AveragePeriod),
|
||||
CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod), CandleSettings.Get(CandleSettingType.Near).AveragePeriod) + 1 + 1)
|
||||
{
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_shadowLongAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowLong).AveragePeriod;
|
||||
_shadowVeryShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod;
|
||||
_nearAveragePeriod = CandleSettings.Get(CandleSettingType.Near).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HangingMan"/> class.
|
||||
/// </summary>
|
||||
public HangingMan()
|
||||
: this("HANGINGMAN")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyShortAveragePeriod)
|
||||
{
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowLongAveragePeriod)
|
||||
{
|
||||
_shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowVeryShortAveragePeriod)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _nearAveragePeriod - 1 && Samples < Period - 1)
|
||||
{
|
||||
_nearPeriodTotal += GetCandleRange(CandleSettingType.Near, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// small rb
|
||||
GetRealBody(input) < GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) &&
|
||||
// long lower shadow
|
||||
GetLowerShadow(input) > GetCandleAverage(CandleSettingType.ShadowLong, _shadowLongPeriodTotal, input) &&
|
||||
// very short upper shadow
|
||||
GetUpperShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input) &&
|
||||
// rb near the prior candle's highs
|
||||
Math.Min(input.Close, input.Open) >= window[1].High - GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal, window[1])
|
||||
)
|
||||
value = -1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]);
|
||||
|
||||
_shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input) -
|
||||
GetCandleRange(CandleSettingType.ShadowLong, window[_shadowLongAveragePeriod]);
|
||||
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryShort, window[_shadowVeryShortAveragePeriod]);
|
||||
|
||||
_nearPeriodTotal += GetCandleRange(CandleSettingType.Near, window[1]) -
|
||||
GetCandleRange(CandleSettingType.Near, window[_nearAveragePeriod + 1]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyShortPeriodTotal = 0m;
|
||||
_shadowLongPeriodTotal = 0m;
|
||||
_shadowVeryShortPeriodTotal = 0m;
|
||||
_nearPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Harami candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long white (black) real body
|
||||
/// - second candle: short real body totally engulfed by the first
|
||||
/// The meaning of "short" and "long" is specified with SetCandleSettings
|
||||
/// The returned value is positive(+1) when bullish or negative(-1) when bearish;
|
||||
/// The user should consider that a harami is significant when it appears in a downtrend if bullish or
|
||||
/// in an uptrend when bearish, while this function does not consider the trend
|
||||
/// </remarks>
|
||||
public class Harami : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
private decimal _bodyShortPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Harami"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public Harami(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod) + 1 + 1)
|
||||
{
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Harami"/> class.
|
||||
/// </summary>
|
||||
public Harami()
|
||||
: this("HARAMI")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyLongAveragePeriod - 1 && Samples < Period - 1)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyShortAveragePeriod)
|
||||
{
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st: long
|
||||
GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[1]) &&
|
||||
// 2nd: short
|
||||
GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) &&
|
||||
// engulfed by 1st
|
||||
Math.Max(input.Close, input.Open) < Math.Max(window[1].Close, window[1].Open) &&
|
||||
Math.Min(input.Close, input.Open) > Math.Min(window[1].Close, window[1].Open)
|
||||
)
|
||||
value = -(int)GetCandleColor(window[1]);
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 1]);
|
||||
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = 0m;
|
||||
_bodyShortPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Harami Cross candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long white (black) real body
|
||||
/// - second candle: doji totally engulfed by the first
|
||||
/// The meaning of "doji" and "long" is specified with SetCandleSettings
|
||||
/// The returned value is positive(+1) when bullish or negative(-1) when bearish;
|
||||
/// The user should consider that a harami cross is significant when it appears in a downtrend if bullish or
|
||||
/// in an uptrend when bearish, while this function does not consider the trend
|
||||
/// </remarks>
|
||||
public class HaramiCross : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
private readonly int _bodyDojiAveragePeriod;
|
||||
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
private decimal _bodyDojiPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HaramiCross"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public HaramiCross(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod) + 1 + 1)
|
||||
{
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_bodyDojiAveragePeriod = CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HaramiCross"/> class.
|
||||
/// </summary>
|
||||
public HaramiCross()
|
||||
: this("HARAMICROSS")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyLongAveragePeriod - 1 && Samples < Period - 1)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyDojiAveragePeriod)
|
||||
{
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st: long
|
||||
GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[1]) &&
|
||||
// 2nd: doji
|
||||
GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, input) &&
|
||||
// engulfed by 1st
|
||||
Math.Max(input.Close, input.Open) < Math.Max(window[1].Close, window[1].Open) &&
|
||||
Math.Min(input.Close, input.Open) > Math.Min(window[1].Close, window[1].Open)
|
||||
)
|
||||
value = -(int)GetCandleColor(window[1]);
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 1]);
|
||||
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input) -
|
||||
GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = 0m;
|
||||
_bodyDojiPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// High-Wave Candle candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - short real body
|
||||
/// - very long upper and lower shadow
|
||||
/// The meaning of "short" and "very long" is specified with SetCandleSettings
|
||||
/// The returned value is positive(+1) when white or negative(-1) when black;
|
||||
/// it does not mean bullish or bearish
|
||||
/// </remarks>
|
||||
public class HighWaveCandle : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
private readonly int _shadowVeryLongAveragePeriod;
|
||||
|
||||
private decimal _bodyShortPeriodTotal;
|
||||
private decimal _shadowVeryLongPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HighWaveCandle"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public HighWaveCandle(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod, CandleSettings.Get(CandleSettingType.ShadowVeryLong).AveragePeriod) + 1)
|
||||
{
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod;
|
||||
_shadowVeryLongAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryLong).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HighWaveCandle"/> class.
|
||||
/// </summary>
|
||||
public HighWaveCandle()
|
||||
: this("HIGHWAVECANDLE")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyShortAveragePeriod)
|
||||
{
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowVeryLongAveragePeriod)
|
||||
{
|
||||
_shadowVeryLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryLong, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (GetRealBody(input) < GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) &&
|
||||
GetUpperShadow(input) > GetCandleAverage(CandleSettingType.ShadowVeryLong, _shadowVeryLongPeriodTotal, input) &&
|
||||
GetLowerShadow(input) > GetCandleAverage(CandleSettingType.ShadowVeryLong, _shadowVeryLongPeriodTotal, input)
|
||||
)
|
||||
value = (int)GetCandleColor(input);
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]);
|
||||
|
||||
_shadowVeryLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryLong, input) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryLong, window[_shadowVeryLongAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyShortPeriodTotal = 0m;
|
||||
_shadowVeryLongPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Hikkake candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first and second candle: inside bar (2nd has lower high and higher low than 1st)
|
||||
/// - third candle: lower high and lower low than 2nd(higher high and higher low than 2nd)
|
||||
/// The returned value for the hikkake bar is positive(+1) or negative(-1) meaning bullish or bearish hikkake
|
||||
/// Confirmation could come in the next 3 days with:
|
||||
/// - a day that closes higher than the high(lower than the low) of the 2nd candle
|
||||
/// The returned value for the confirmation bar is equal to 1 + the bullish hikkake result or -1 - the bearish hikkake result
|
||||
/// Note: if confirmation and a new hikkake come at the same bar, only the new hikkake is reported(the new hikkake
|
||||
/// overwrites the confirmation of the old hikkake)
|
||||
/// </remarks>
|
||||
public class Hikkake : CandlestickPattern
|
||||
{
|
||||
private int _patternIndex;
|
||||
private int _patternResult;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Hikkake"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public Hikkake(string name)
|
||||
: base(name, 5 + 1)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Hikkake"/> class.
|
||||
/// </summary>
|
||||
public Hikkake()
|
||||
: this("HIKKAKE")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= 3)
|
||||
{
|
||||
// copy here the pattern recognition code below
|
||||
// 1st + 2nd: lower high and higher low
|
||||
if (window[1].High < window[2].High && window[1].Low > window[2].Low &&
|
||||
// (bull) 3rd: lower high and lower low
|
||||
((input.High < window[1].High && input.Low < window[1].Low)
|
||||
||
|
||||
// (bear) 3rd: higher high and higher low
|
||||
(input.High > window[1].High && input.Low > window[1].Low)
|
||||
)
|
||||
)
|
||||
{
|
||||
_patternResult = (input.High < window[1].High ? 1 : -1);
|
||||
_patternIndex = (int)Samples - 1;
|
||||
}
|
||||
else
|
||||
// search for confirmation if hikkake was no more than 3 bars ago
|
||||
if (Samples <= _patternIndex + 4 &&
|
||||
// close higher than the high of 2nd
|
||||
((_patternResult > 0 && input.Close > window[(int)Samples - _patternIndex].High)
|
||||
||
|
||||
// close lower than the low of 2nd
|
||||
(_patternResult < 0 && input.Close < window[(int)Samples - _patternIndex].Low)
|
||||
)
|
||||
)
|
||||
_patternIndex = 0;
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
// 1st + 2nd: lower high and higher low
|
||||
if (window[1].High < window[2].High && window[1].Low > window[2].Low &&
|
||||
// (bull) 3rd: lower high and lower low
|
||||
((input.High < window[1].High && input.Low < window[1].Low)
|
||||
||
|
||||
// (bear) 3rd: higher high and higher low
|
||||
(input.High > window[1].High && input.Low > window[1].Low)
|
||||
)
|
||||
)
|
||||
{
|
||||
_patternResult = (input.High < window[1].High ? 1 : -1);
|
||||
_patternIndex = (int) Samples - 1;
|
||||
value = _patternResult;
|
||||
}
|
||||
else
|
||||
{
|
||||
// search for confirmation if hikkake was no more than 3 bars ago
|
||||
if (Samples <= _patternIndex + 4 &&
|
||||
// close higher than the high of 2nd
|
||||
((_patternResult > 0 && input.Close > window[(int) Samples - _patternIndex].High)
|
||||
||
|
||||
// close lower than the low of 2nd
|
||||
(_patternResult < 0 && input.Close < window[(int) Samples - _patternIndex].Low)
|
||||
)
|
||||
)
|
||||
{
|
||||
value = _patternResult + (_patternResult > 0 ? 1 : -1);
|
||||
_patternIndex = 0;
|
||||
}
|
||||
else
|
||||
value = 0;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_patternIndex = 0;
|
||||
_patternResult = 0;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Hikkake Modified candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle
|
||||
/// - second candle: candle with range less than first candle and close near the bottom(near the top)
|
||||
/// - third candle: lower high and higher low than 2nd
|
||||
/// - fourth candle: lower high and lower low(higher high and higher low) than 3rd
|
||||
/// The returned value for the hikkake bar is positive(+1) or negative(-1) meaning bullish or bearish hikkake
|
||||
/// Confirmation could come in the next 3 days with:
|
||||
/// - a day that closes higher than the high(lower than the low) of the 3rd candle
|
||||
/// The returned value for the confirmation bar is equal to 1 + the bullish hikkake result or -1 - the bearish hikkake result
|
||||
/// Note: if confirmation and a new hikkake come at the same bar, only the new hikkake is reported(the new hikkake
|
||||
/// overwrites the confirmation of the old hikkake);
|
||||
/// The user should consider that modified hikkake is a reversal pattern, while hikkake could be both a reversal
|
||||
/// or a continuation pattern, so bullish(bearish) modified hikkake is significant when appearing in a downtrend(uptrend)
|
||||
/// </remarks>
|
||||
public class HikkakeModified : CandlestickPattern
|
||||
{
|
||||
private readonly int _nearAveragePeriod;
|
||||
|
||||
private decimal _nearPeriodTotal;
|
||||
|
||||
private int _patternIndex;
|
||||
private int _patternResult;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HikkakeModified"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public HikkakeModified(string name)
|
||||
: base(name, Math.Max(1, CandleSettings.Get(CandleSettingType.Near).AveragePeriod) + 5 + 1)
|
||||
{
|
||||
_nearAveragePeriod = CandleSettings.Get(CandleSettingType.Near).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HikkakeModified"/> class.
|
||||
/// </summary>
|
||||
public HikkakeModified()
|
||||
: this("HIKKAKEMODIFIED")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _nearAveragePeriod - 3 && Samples < Period - 3)
|
||||
{
|
||||
_nearPeriodTotal += GetCandleRange(CandleSettingType.Near, window[2]);
|
||||
}
|
||||
|
||||
else if (Samples >= Period - 3)
|
||||
{
|
||||
// copy here the pattern recognition code below
|
||||
// 2nd: lower high and higher low than 1st
|
||||
if (window[2].High < window[3].High && window[2].Low > window[3].Low &&
|
||||
// 3rd: lower high and higher low than 2nd
|
||||
window[1].High < window[2].High && window[1].Low > window[2].Low &&
|
||||
// (bull) 4th: lower high and lower low
|
||||
((input.High < window[1].High && input.Low < window[1].Low &&
|
||||
// (bull) 2nd: close near the low
|
||||
window[2].Close <= window[2].Low + GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal, window[2])
|
||||
)
|
||||
||
|
||||
// (bear) 4th: higher high and higher low
|
||||
(input.High > window[1].High && input.Low > window[1].Low &&
|
||||
// (bull) 2nd: close near the top
|
||||
window[2].Close >= window[2].High - GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal, window[2])
|
||||
)
|
||||
)
|
||||
)
|
||||
{
|
||||
_patternResult = (input.High < window[1].High ? 1 : -1);
|
||||
_patternIndex = (int) Samples - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// search for confirmation if modified hikkake was no more than 3 bars ago
|
||||
if (Samples <= _patternIndex + 4 &&
|
||||
// close higher than the high of 3rd
|
||||
((_patternResult > 0 && input.Close > window[(int) Samples - _patternIndex].High)
|
||||
||
|
||||
// close lower than the low of 3rd
|
||||
(_patternResult < 0 && input.Close < window[(int) Samples - _patternIndex].Low))
|
||||
)
|
||||
_patternIndex = 0;
|
||||
}
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_nearPeriodTotal += GetCandleRange(CandleSettingType.Near, window[2]) -
|
||||
GetCandleRange(CandleSettingType.Near, window[(int)Samples - 1]);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
// 2nd: lower high and higher low than 1st
|
||||
if (window[2].High < window[3].High && window[2].Low > window[3].Low &&
|
||||
// 3rd: lower high and higher low than 2nd
|
||||
window[1].High < window[2].High && window[1].Low > window[2].Low &&
|
||||
// (bull) 4th: lower high and lower low
|
||||
((input.High < window[1].High && input.Low < window[1].Low &&
|
||||
// (bull) 2nd: close near the low
|
||||
window[2].Close <= window[2].Low + GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal, window[2])
|
||||
)
|
||||
||
|
||||
// (bear) 4th: higher high and higher low
|
||||
(input.High > window[1].High && input.Low > window[1].Low &&
|
||||
// (bull) 2nd: close near the top
|
||||
window[2].Close >= window[2].High - GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal, window[2])
|
||||
)
|
||||
)
|
||||
)
|
||||
{
|
||||
_patternResult = (input.High < window[1].High ? 1 : -1);
|
||||
_patternIndex = (int) Samples - 1;
|
||||
value = _patternResult;
|
||||
}
|
||||
else
|
||||
{
|
||||
// search for confirmation if modified hikkake was no more than 3 bars ago
|
||||
if (Samples <= _patternIndex + 4 &&
|
||||
// close higher than the high of 3rd
|
||||
((_patternResult > 0 && input.Close > window[(int)Samples - _patternIndex].High)
|
||||
||
|
||||
// close lower than the low of 3rd
|
||||
(_patternResult < 0 && input.Close < window[(int)Samples - _patternIndex].Low))
|
||||
)
|
||||
{
|
||||
value = _patternResult + (_patternResult > 0 ? 1 : -1);
|
||||
_patternIndex = 0;
|
||||
}
|
||||
else
|
||||
value = 0;
|
||||
}
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_nearPeriodTotal += GetCandleRange(CandleSettingType.Near, window[2]) -
|
||||
GetCandleRange(CandleSettingType.Near, window[_nearAveragePeriod + 5]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_nearPeriodTotal = 0;
|
||||
_patternIndex = 0;
|
||||
_patternResult = 0;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Homing Pigeon candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long black candle
|
||||
/// - second candle: short black real body completely inside the previous day's body
|
||||
/// The meaning of "short" and "long" is specified with SetCandleSettings
|
||||
/// The returned value is positive(+1): homing pigeon is always bullish;
|
||||
/// The user should consider that homing pigeon is significant when it appears in a downtrend,
|
||||
/// while this function does not consider the trend
|
||||
/// </remarks>
|
||||
public class HomingPigeon : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
private decimal _bodyShortPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HomingPigeon"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public HomingPigeon(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod) + 1 + 1)
|
||||
{
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HomingPigeon"/> class.
|
||||
/// </summary>
|
||||
public HomingPigeon()
|
||||
: this("HOMINGPIGEON")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyLongAveragePeriod)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyShortAveragePeriod)
|
||||
{
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st black
|
||||
GetCandleColor(window[1]) == CandleColor.Black &&
|
||||
// 2nd black
|
||||
GetCandleColor(input) == CandleColor.Black &&
|
||||
// 1st long
|
||||
GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[1]) &&
|
||||
// 2nd short
|
||||
GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) &&
|
||||
// 2nd engulfed by 1st
|
||||
input.Open < window[1].Open &&
|
||||
input.Close > window[1].Close
|
||||
)
|
||||
value = 1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 1]);
|
||||
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = 0m;
|
||||
_bodyShortPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Identical Three Crows candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - three consecutive and declining black candlesticks
|
||||
/// - each candle must have no or very short lower shadow
|
||||
/// - each candle after the first must open at or very close to the prior candle's close
|
||||
/// The meaning of "very short" is specified with SetCandleSettings;
|
||||
/// the meaning of "very close" is specified with SetCandleSettings(Equal);
|
||||
/// The returned value is negative(-1): identical three crows is always bearish;
|
||||
/// The user should consider that identical 3 crows is significant when it appears after a mature advance or at high levels,
|
||||
/// while this function does not consider it
|
||||
/// </remarks>
|
||||
public class IdenticalThreeCrows : CandlestickPattern
|
||||
{
|
||||
private readonly int _shadowVeryShortAveragePeriod;
|
||||
private readonly int _equalAveragePeriod;
|
||||
|
||||
private decimal[] _shadowVeryShortPeriodTotal = new decimal[3];
|
||||
private decimal[] _equalPeriodTotal = new decimal[3];
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IdenticalThreeCrows"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public IdenticalThreeCrows(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod, CandleSettings.Get(CandleSettingType.Equal).AveragePeriod) + 2 + 1)
|
||||
{
|
||||
_shadowVeryShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod;
|
||||
_equalAveragePeriod = CandleSettings.Get(CandleSettingType.Equal).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IdenticalThreeCrows"/> class.
|
||||
/// </summary>
|
||||
public IdenticalThreeCrows()
|
||||
: this("IDENTICALTHREECROWS")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _shadowVeryShortAveragePeriod)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal[2] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[2]);
|
||||
_shadowVeryShortPeriodTotal[1] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[1]);
|
||||
_shadowVeryShortPeriodTotal[0] += GetCandleRange(CandleSettingType.ShadowVeryShort, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _equalAveragePeriod)
|
||||
{
|
||||
_equalPeriodTotal[2] += GetCandleRange(CandleSettingType.Near, window[2]);
|
||||
_equalPeriodTotal[1] += GetCandleRange(CandleSettingType.Near, window[1]);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st black
|
||||
GetCandleColor(window[2]) == CandleColor.Black &&
|
||||
// very short lower shadow
|
||||
GetLowerShadow(window[2]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[2], window[2]) &&
|
||||
// 2nd black
|
||||
GetCandleColor(window[1]) == CandleColor.Black &&
|
||||
// very short lower shadow
|
||||
GetLowerShadow(window[1]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[1], window[1]) &&
|
||||
// 3rd black
|
||||
GetCandleColor(input) == CandleColor.Black &&
|
||||
// very short lower shadow
|
||||
GetLowerShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[0], input) &&
|
||||
// three declining
|
||||
window[2].Close > window[1].Close &&
|
||||
window[1].Close > input.Close &&
|
||||
// 2nd black opens very close to 1st close
|
||||
window[1].Open <= window[2].Close + GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal[2], window[2]) &&
|
||||
window[1].Open >= window[2].Close - GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal[2], window[2]) &&
|
||||
// 3rd black opens very close to 2nd close
|
||||
input.Open <= window[1].Close + GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal[1], window[1]) &&
|
||||
input.Open >= window[1].Close - GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal[1], window[1])
|
||||
)
|
||||
value = -1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
for (var i = 2; i >= 0; i--)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal[i] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[i]) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryShort, window[i + _shadowVeryShortAveragePeriod]);
|
||||
}
|
||||
|
||||
for (var i = 2; i >= 1; i--)
|
||||
{
|
||||
_equalPeriodTotal[i] += GetCandleRange(CandleSettingType.Equal, window[i]) -
|
||||
GetCandleRange(CandleSettingType.Equal, window[i + _equalAveragePeriod]);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_shadowVeryShortPeriodTotal = new decimal[3];
|
||||
_equalPeriodTotal = new decimal[3];
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// In-Neck candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long black candle
|
||||
/// - second candle: white candle with open below previous day low and close slightly into previous day body
|
||||
/// The meaning of "equal" is specified with SetCandleSettings
|
||||
/// The returned value is negative(-1): in-neck is always bearish
|
||||
/// The user should consider that in-neck is significant when it appears in a downtrend, while this function
|
||||
/// does not consider it
|
||||
/// </remarks>
|
||||
public class InNeck : CandlestickPattern
|
||||
{
|
||||
private readonly int _equalAveragePeriod;
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
|
||||
private decimal _equalPeriodTotal;
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="InNeck"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public InNeck(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.Equal).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod) + 1 + 1)
|
||||
{
|
||||
_equalAveragePeriod = CandleSettings.Get(CandleSettingType.Equal).AveragePeriod;
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="InNeck"/> class.
|
||||
/// </summary>
|
||||
public InNeck()
|
||||
: this("INNECK")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _equalAveragePeriod)
|
||||
{
|
||||
_equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyLongAveragePeriod)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st: black
|
||||
GetCandleColor(window[1]) == CandleColor.Black &&
|
||||
// long
|
||||
GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[1]) &&
|
||||
// 2nd: white
|
||||
GetCandleColor(input) == CandleColor.White &&
|
||||
// open below prior low
|
||||
input.Open < window[1].Low &&
|
||||
// close slightly into prior body
|
||||
input.Close <= window[1].Close + GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[1]) &&
|
||||
input.Close >= window[1].Close
|
||||
)
|
||||
value = -1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]) -
|
||||
GetCandleRange(CandleSettingType.Equal, window[_equalAveragePeriod + 1]);
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 1]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_equalPeriodTotal = 0m;
|
||||
_bodyLongPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Inverted Hammer candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - small real body
|
||||
/// - long upper shadow
|
||||
/// - no, or very short, lower shadow
|
||||
/// - gap down
|
||||
/// The meaning of "short", "very short" and "long" is specified with SetCandleSettings;
|
||||
/// The returned value is positive(+1): inverted hammer is always bullish;
|
||||
/// The user should consider that an inverted hammer must appear in a downtrend, while this function does not consider it
|
||||
/// </remarks>
|
||||
public class InvertedHammer : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
private readonly int _shadowLongAveragePeriod;
|
||||
private readonly int _shadowVeryShortAveragePeriod;
|
||||
|
||||
private decimal _bodyShortPeriodTotal;
|
||||
private decimal _shadowLongPeriodTotal;
|
||||
private decimal _shadowVeryShortPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="InvertedHammer"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public InvertedHammer(string name)
|
||||
: base(name, Math.Max(Math.Max(CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod, CandleSettings.Get(CandleSettingType.ShadowLong).AveragePeriod),
|
||||
CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod) + 1 + 1)
|
||||
{
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_shadowLongAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowLong).AveragePeriod;
|
||||
_shadowVeryShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="InvertedHammer"/> class.
|
||||
/// </summary>
|
||||
public InvertedHammer()
|
||||
: this("INVERTEDHAMMER")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyShortAveragePeriod)
|
||||
{
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowLongAveragePeriod)
|
||||
{
|
||||
_shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowVeryShortAveragePeriod)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// small rb
|
||||
GetRealBody(input) < GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) &&
|
||||
// long upper shadow
|
||||
GetUpperShadow(input) > GetCandleAverage(CandleSettingType.ShadowLong, _shadowLongPeriodTotal, input) &&
|
||||
// very short lower shadow
|
||||
GetLowerShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input) &&
|
||||
// gap down
|
||||
GetRealBodyGapDown(input, window[1])
|
||||
)
|
||||
value = 1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]);
|
||||
|
||||
_shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input) -
|
||||
GetCandleRange(CandleSettingType.ShadowLong, window[_shadowLongAveragePeriod]);
|
||||
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryShort, window[_shadowVeryShortAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyShortPeriodTotal = 0m;
|
||||
_shadowLongPeriodTotal = 0m;
|
||||
_shadowVeryShortPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Kicking candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: marubozu
|
||||
/// - second candle: opposite color marubozu
|
||||
/// - gap between the two candles: upside gap if black then white, downside gap if white then black
|
||||
/// The meaning of "long body" and "very short shadow" is specified with SetCandleSettings
|
||||
/// The returned value is positive(+1) when bullish or negative(-1) when bearish
|
||||
/// </remarks>
|
||||
public class Kicking : CandlestickPattern
|
||||
{
|
||||
private readonly int _shadowVeryShortAveragePeriod;
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
|
||||
private decimal[] _shadowVeryShortPeriodTotal = new decimal[2];
|
||||
private decimal[] _bodyLongPeriodTotal = new decimal[2];
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Kicking"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public Kicking(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod) + 1 + 1)
|
||||
{
|
||||
_shadowVeryShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod;
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Kicking"/> class.
|
||||
/// </summary>
|
||||
public Kicking()
|
||||
: this("KICKING")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _shadowVeryShortAveragePeriod)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal[1] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[1]);
|
||||
_shadowVeryShortPeriodTotal[0] += GetCandleRange(CandleSettingType.ShadowVeryShort, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyLongAveragePeriod)
|
||||
{
|
||||
_bodyLongPeriodTotal[1] += GetCandleRange(CandleSettingType.BodyLong, window[1]);
|
||||
_bodyLongPeriodTotal[0] += GetCandleRange(CandleSettingType.BodyLong, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// opposite candles
|
||||
(int)GetCandleColor(window[1]) == -(int)GetCandleColor(input) &&
|
||||
// 1st marubozu
|
||||
GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal[1], window[1]) &&
|
||||
GetUpperShadow(window[1]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[1], window[1]) &&
|
||||
GetLowerShadow(window[1]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[1], window[1]) &&
|
||||
// 2nd marubozu
|
||||
GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal[0], input) &&
|
||||
GetUpperShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[0], input) &&
|
||||
GetLowerShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[0], input) &&
|
||||
// gap
|
||||
(
|
||||
(GetCandleColor(window[1]) == CandleColor.Black && GetCandleGapUp(input, window[1]))
|
||||
||
|
||||
(GetCandleColor(window[1]) == CandleColor.White && GetCandleGapDown(input, window[1]))
|
||||
)
|
||||
)
|
||||
value = (int)GetCandleColor(input);
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
for (var i = 1; i >= 0; i--)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal[i] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[i]) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryShort, window[i + _shadowVeryShortAveragePeriod]);
|
||||
|
||||
_bodyLongPeriodTotal[i] += GetCandleRange(CandleSettingType.BodyLong, window[i]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[i + _bodyLongAveragePeriod]);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_shadowVeryShortPeriodTotal = new decimal[2];
|
||||
_bodyLongPeriodTotal = new decimal[2];
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Kicking (bull/bear determined by the longer marubozu) candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: marubozu
|
||||
/// - second candle: opposite color marubozu
|
||||
/// - gap between the two candles: upside gap if black then white, downside gap if white then black
|
||||
/// The meaning of "long body" and "very short shadow" is specified with SetCandleSettings
|
||||
/// The returned value is positive(+1) when bullish or negative(-1) when bearish; the longer of the two
|
||||
/// marubozu determines the bullishness or bearishness of this pattern
|
||||
/// </remarks>
|
||||
public class KickingByLength : CandlestickPattern
|
||||
{
|
||||
private readonly int _shadowVeryShortAveragePeriod;
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
|
||||
private decimal[] _shadowVeryShortPeriodTotal = new decimal[2];
|
||||
private decimal[] _bodyLongPeriodTotal = new decimal[2];
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="KickingByLength"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public KickingByLength(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod) + 1 + 1)
|
||||
{
|
||||
_shadowVeryShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod;
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="KickingByLength"/> class.
|
||||
/// </summary>
|
||||
public KickingByLength()
|
||||
: this("KICKINGBYLENGTH")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _shadowVeryShortAveragePeriod)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal[1] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[1]);
|
||||
_shadowVeryShortPeriodTotal[0] += GetCandleRange(CandleSettingType.ShadowVeryShort, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyLongAveragePeriod)
|
||||
{
|
||||
_bodyLongPeriodTotal[1] += GetCandleRange(CandleSettingType.BodyLong, window[1]);
|
||||
_bodyLongPeriodTotal[0] += GetCandleRange(CandleSettingType.BodyLong, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// opposite candles
|
||||
(int)GetCandleColor(window[1]) == -(int)GetCandleColor(input) &&
|
||||
// 1st marubozu
|
||||
GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal[1], window[1]) &&
|
||||
GetUpperShadow(window[1]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[1], window[1]) &&
|
||||
GetLowerShadow(window[1]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[1], window[1]) &&
|
||||
// 2nd marubozu
|
||||
GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal[0], input) &&
|
||||
GetUpperShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[0], input) &&
|
||||
GetLowerShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[0], input) &&
|
||||
// gap
|
||||
(
|
||||
(GetCandleColor(window[1]) == CandleColor.Black && GetCandleGapUp(input, window[1]))
|
||||
||
|
||||
(GetCandleColor(window[1]) == CandleColor.White && GetCandleGapDown(input, window[1]))
|
||||
)
|
||||
)
|
||||
value = (int)GetCandleColor(GetRealBody(input) > GetRealBody(window[1]) ? input : window[1]);
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
for (var i = 1; i >= 0; i--)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal[i] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[i]) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryShort, window[i + _shadowVeryShortAveragePeriod]);
|
||||
|
||||
_bodyLongPeriodTotal[i] += GetCandleRange(CandleSettingType.BodyLong, window[i]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[i + _bodyLongAveragePeriod]);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_shadowVeryShortPeriodTotal = new decimal[2];
|
||||
_bodyLongPeriodTotal = new decimal[2];
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Ladder Bottom candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - three black candlesticks with consecutively lower opens and closes
|
||||
/// - fourth candle: black candle with an upper shadow(it's supposed to be not very short)
|
||||
/// - fifth candle: white candle that opens above prior candle's body and closes above prior candle's high
|
||||
/// The meaning of "very short" is specified with SetCandleSettings
|
||||
/// The returned value is positive (+1): ladder bottom is always bullish;
|
||||
/// The user should consider that ladder bottom is significant when it appears in a downtrend,
|
||||
/// while this function does not consider it
|
||||
/// </remarks>
|
||||
public class LadderBottom : CandlestickPattern
|
||||
{
|
||||
private readonly int _shadowVeryShortAveragePeriod;
|
||||
|
||||
private decimal _shadowVeryShortPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LadderBottom"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public LadderBottom(string name)
|
||||
: base(name, CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod + 4 + 1)
|
||||
{
|
||||
_shadowVeryShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LadderBottom"/> class.
|
||||
/// </summary>
|
||||
public LadderBottom()
|
||||
: this("LADDERBOTTOM")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _shadowVeryShortAveragePeriod)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, window[1]);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 3 black candlesticks
|
||||
GetCandleColor(window[4]) == CandleColor.Black &&
|
||||
GetCandleColor(window[3]) == CandleColor.Black &&
|
||||
GetCandleColor(window[2]) == CandleColor.Black &&
|
||||
// with consecutively lower opens
|
||||
window[4].Open > window[3].Open && window[3].Open > window[2].Open &&
|
||||
// and closes
|
||||
window[4].Close > window[3].Close && window[3].Close > window[2].Close &&
|
||||
// 4th: black with an upper shadow
|
||||
GetCandleColor(window[1]) == CandleColor.Black &&
|
||||
GetUpperShadow(window[1]) > GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, window[1]) &&
|
||||
// 5th: white
|
||||
GetCandleColor(input) == CandleColor.White &&
|
||||
// that opens above prior candle's body
|
||||
input.Open > window[1].Open &&
|
||||
// and closes above prior candle's high
|
||||
input.Close > window[1].High
|
||||
)
|
||||
value = 1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, window[1]) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryShort, window[_shadowVeryShortAveragePeriod + 1]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_shadowVeryShortPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Long Legged Doji candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - doji body
|
||||
/// - one or two long shadows
|
||||
/// The meaning of "doji" is specified with SetCandleSettings
|
||||
/// The returned value is always positive(+1) but this does not mean it is bullish: long legged doji shows uncertainty
|
||||
/// </remarks>
|
||||
public class LongLeggedDoji : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyDojiAveragePeriod;
|
||||
private readonly int _shadowLongAveragePeriod;
|
||||
|
||||
private decimal _bodyDojiPeriodTotal;
|
||||
private decimal _shadowLongPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LongLeggedDoji"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public LongLeggedDoji(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod, CandleSettings.Get(CandleSettingType.ShadowLong).AveragePeriod) + 1)
|
||||
{
|
||||
_bodyDojiAveragePeriod = CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod;
|
||||
_shadowLongAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowLong).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LongLeggedDoji"/> class.
|
||||
/// </summary>
|
||||
public LongLeggedDoji()
|
||||
: this("LONGLEGGEDDOJI")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyDojiAveragePeriod)
|
||||
{
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowLongAveragePeriod)
|
||||
{
|
||||
_shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, input) &&
|
||||
(GetLowerShadow(input) > GetCandleAverage(CandleSettingType.ShadowLong, _shadowLongPeriodTotal, input)
|
||||
||
|
||||
GetUpperShadow(input) > GetCandleAverage(CandleSettingType.ShadowLong, _shadowLongPeriodTotal, input)
|
||||
)
|
||||
)
|
||||
value = 1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input) -
|
||||
GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod]);
|
||||
|
||||
_shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input) -
|
||||
GetCandleRange(CandleSettingType.ShadowLong, window[_shadowLongAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyDojiPeriodTotal = 0m;
|
||||
_shadowLongPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Long Line Candle candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - long real body
|
||||
/// - short upper and lower shadow
|
||||
/// The meaning of "long" and "short" is specified with SetCandleSettings
|
||||
/// The returned value is positive(+1) when white(bullish), negative(-1) when black(bearish)
|
||||
/// </remarks>
|
||||
public class LongLineCandle : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
private readonly int _shadowShortAveragePeriod;
|
||||
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
private decimal _shadowShortPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LongLineCandle"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public LongLineCandle(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod, CandleSettings.Get(CandleSettingType.ShadowShort).AveragePeriod) + 1)
|
||||
{
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_shadowShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LongLineCandle"/> class.
|
||||
/// </summary>
|
||||
public LongLineCandle()
|
||||
: this("LONGLINECANDLE")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyLongAveragePeriod)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowShortAveragePeriod)
|
||||
{
|
||||
_shadowShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, input) &&
|
||||
GetUpperShadow(input) < GetCandleAverage(CandleSettingType.ShadowShort, _shadowShortPeriodTotal, input) &&
|
||||
GetLowerShadow(input) < GetCandleAverage(CandleSettingType.ShadowShort, _shadowShortPeriodTotal, input)
|
||||
)
|
||||
value = (int)GetCandleColor(input);
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod]);
|
||||
|
||||
_shadowShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowShort, input) -
|
||||
GetCandleRange(CandleSettingType.ShadowShort, window[_shadowShortAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = 0m;
|
||||
_shadowShortPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Marubozu candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - long real body
|
||||
/// - no or very short upper and lower shadow
|
||||
/// The meaning of "long" and "very short" is specified with SetCandleSettings
|
||||
/// The returned value is positive(+1) when white(bullish), negative(-1) when black(bearish)
|
||||
/// </remarks>
|
||||
public class Marubozu : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
private readonly int _shadowVeryShortAveragePeriod;
|
||||
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
private decimal _shadowVeryShortPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Marubozu"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public Marubozu(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod, CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod) + 1)
|
||||
{
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_shadowVeryShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Marubozu"/> class.
|
||||
/// </summary>
|
||||
public Marubozu()
|
||||
: this("MARUBOZU")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyLongAveragePeriod)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowVeryShortAveragePeriod)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, input) &&
|
||||
GetUpperShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input) &&
|
||||
GetLowerShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input)
|
||||
)
|
||||
value = (int)GetCandleColor(input);
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod]);
|
||||
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryShort, window[_shadowVeryShortAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = 0m;
|
||||
_shadowVeryShortPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Mat Hold candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long white candle
|
||||
/// - upside gap between the first and the second bodies
|
||||
/// - second candle: small black candle
|
||||
/// - third and fourth candles: falling small real body candlesticks(commonly black) that hold within the long
|
||||
/// white candle's body and are higher than the reaction days of the rising three methods
|
||||
/// - fifth candle: white candle that opens above the previous small candle's close and closes higher than the
|
||||
/// high of the highest reaction day
|
||||
/// The meaning of "short" and "long" is specified with SetCandleSettings;
|
||||
/// "hold within" means "a part of the real body must be within";
|
||||
/// penetration is the maximum percentage of the first white body the reaction days can penetrate(it is
|
||||
/// to specify how much the reaction days should be "higher than the reaction days of the rising three methods")
|
||||
/// The returned value is positive(+1): mat hold is always bullish
|
||||
/// </remarks>
|
||||
public class MatHold : CandlestickPattern
|
||||
{
|
||||
private readonly decimal _penetration;
|
||||
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
|
||||
private decimal[] _bodyPeriodTotal = new decimal[5];
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MatHold"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="penetration">Percentage of penetration of a candle within another candle</param>
|
||||
public MatHold(string name, decimal penetration = 0.5m)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod) + 4 + 1)
|
||||
{
|
||||
_penetration = penetration;
|
||||
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod;
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MatHold"/> class.
|
||||
/// </summary>
|
||||
/// <param name="penetration">Percentage of penetration of a candle within another candle</param>
|
||||
public MatHold(decimal penetration)
|
||||
: this("MATHOLD", penetration)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MatHold"/> class.
|
||||
/// </summary>
|
||||
public MatHold()
|
||||
: this("MATHOLD")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples > Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples > Period - _bodyShortAveragePeriod)
|
||||
{
|
||||
_bodyPeriodTotal[3] += GetCandleRange(CandleSettingType.BodyShort, window[3]);
|
||||
_bodyPeriodTotal[2] += GetCandleRange(CandleSettingType.BodyShort, window[2]);
|
||||
_bodyPeriodTotal[1] += GetCandleRange(CandleSettingType.BodyShort, window[1]);
|
||||
}
|
||||
|
||||
if (Samples > Period - _bodyLongAveragePeriod)
|
||||
{
|
||||
_bodyPeriodTotal[4] += GetCandleRange(CandleSettingType.BodyLong, window[4]);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st long, then 3 small
|
||||
GetRealBody(window[4]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyPeriodTotal[4], window[4]) &&
|
||||
GetRealBody(window[3]) < GetCandleAverage(CandleSettingType.BodyShort, _bodyPeriodTotal[3], window[3]) &&
|
||||
GetRealBody(window[2]) < GetCandleAverage(CandleSettingType.BodyShort, _bodyPeriodTotal[2], window[2]) &&
|
||||
GetRealBody(window[1]) < GetCandleAverage(CandleSettingType.BodyShort, _bodyPeriodTotal[1], window[1]) &&
|
||||
// white, black, 2 black or white, white
|
||||
GetCandleColor(window[4]) == CandleColor.White &&
|
||||
GetCandleColor(window[3]) == CandleColor.Black &&
|
||||
GetCandleColor(input) == CandleColor.White &&
|
||||
// upside gap 1st to 2nd
|
||||
GetRealBodyGapUp(window[3], window[4]) &&
|
||||
// 3rd to 4th hold within 1st: a part of the real body must be within 1st real body
|
||||
Math.Min(window[2].Open, window[2].Close) < window[4].Close &&
|
||||
Math.Min(window[1].Open, window[1].Close) < window[4].Close &&
|
||||
// reaction days penetrate first body less than optInPenetration percent
|
||||
Math.Min(window[2].Open, window[2].Close) > window[4].Close - GetRealBody(window[4]) * _penetration &&
|
||||
Math.Min(window[1].Open, window[1].Close) > window[4].Close - GetRealBody(window[4]) * _penetration &&
|
||||
// 2nd to 4th are falling
|
||||
Math.Max(window[2].Close, window[2].Open) < window[3].Open &&
|
||||
Math.Max(window[1].Close, window[1].Open) < Math.Max(window[2].Close, window[2].Open) &&
|
||||
// 5th opens above the prior close
|
||||
input.Open > window[1].Close &&
|
||||
// 5th closes above the highest high of the reaction days
|
||||
input.Close > Math.Max(Math.Max(window[3].High, window[2].High), window[1].High)
|
||||
)
|
||||
value = 1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyPeriodTotal[4] += GetCandleRange(CandleSettingType.BodyLong, window[4]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 4]);
|
||||
|
||||
for (var i = 3; i >= 1; i--)
|
||||
{
|
||||
_bodyPeriodTotal[i] += GetCandleRange(CandleSettingType.BodyShort, window[i]) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[i + _bodyShortAveragePeriod]);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyPeriodTotal = new decimal[5];
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Matching Low candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: black candle
|
||||
/// - second candle: black candle with the close equal to the previous close
|
||||
/// The meaning of "equal" is specified with SetCandleSettings
|
||||
/// The returned value is always positive(+1): matching low is always bullish;
|
||||
/// </remarks>
|
||||
public class MatchingLow : CandlestickPattern
|
||||
{
|
||||
private readonly int _equalAveragePeriod;
|
||||
|
||||
private decimal _equalPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MatchingLow"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public MatchingLow(string name)
|
||||
: base(name, CandleSettings.Get(CandleSettingType.Equal).AveragePeriod + 1 + 1)
|
||||
{
|
||||
_equalAveragePeriod = CandleSettings.Get(CandleSettingType.Equal).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MatchingLow"/> class.
|
||||
/// </summary>
|
||||
public MatchingLow()
|
||||
: this("MATCHINGLOW")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _equalAveragePeriod)
|
||||
{
|
||||
_equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// first black
|
||||
GetCandleColor(window[1]) == CandleColor.Black &&
|
||||
// second black
|
||||
GetCandleColor(input) == CandleColor.Black &&
|
||||
// 1st and 2nd same close
|
||||
input.Close <= window[1].Close + GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[1]) &&
|
||||
input.Close >= window[1].Close - GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[1])
|
||||
)
|
||||
value = 1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]) -
|
||||
GetCandleRange(CandleSettingType.Equal, window[_equalAveragePeriod + 1]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_equalPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Morning Doji Star candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long black real body
|
||||
/// - second candle: doji gapping down
|
||||
/// - third candle: white real body that moves well within the first candle's real body
|
||||
/// The meaning of "doji" and "long" is specified with SetCandleSettings
|
||||
/// The meaning of "moves well within" is specified with penetration and "moves" should mean the real body should
|
||||
/// not be short ("short" is specified with SetCandleSettings) - Greg Morris wants it to be long, someone else want
|
||||
/// it to be relatively long
|
||||
/// The returned value is positive(+1): morning doji star is always bullish;
|
||||
/// the user should consider that a morning star is significant when it appears in a downtrend,
|
||||
/// while this function does not consider the trend
|
||||
/// </remarks>
|
||||
public class MorningDojiStar : CandlestickPattern
|
||||
{
|
||||
private readonly decimal _penetration;
|
||||
|
||||
private readonly int _bodyDojiAveragePeriod;
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
|
||||
private decimal _bodyDojiPeriodTotal;
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
private decimal _bodyShortPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MorningDojiStar"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="penetration">Percentage of penetration of a candle within another candle</param>
|
||||
public MorningDojiStar(string name, decimal penetration = 0.3m)
|
||||
: base(name, Math.Max(Math.Max(CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod),
|
||||
CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod) + 2 + 1)
|
||||
{
|
||||
_penetration = penetration;
|
||||
|
||||
_bodyDojiAveragePeriod = CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod;
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MorningDojiStar"/> class.
|
||||
/// </summary>
|
||||
/// <param name="penetration">Percentage of penetration of a candle within another candle</param>
|
||||
public MorningDojiStar(decimal penetration)
|
||||
: this("MORNINGDOJISTAR", penetration)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MorningDojiStar"/> class.
|
||||
/// </summary>
|
||||
public MorningDojiStar()
|
||||
: this("MORNINGDOJISTAR")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyLongAveragePeriod - 2 && Samples < Period - 2)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyDojiAveragePeriod - 1 && Samples < Period - 1)
|
||||
{
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyShortAveragePeriod)
|
||||
{
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st: long
|
||||
GetRealBody(window[2]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[2]) &&
|
||||
// black
|
||||
GetCandleColor(window[2]) == CandleColor.Black &&
|
||||
// 2nd: doji
|
||||
GetRealBody(window[1]) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, window[1]) &&
|
||||
// gapping down
|
||||
GetRealBodyGapDown(window[1], window[2]) &&
|
||||
// 3rd: longer than short
|
||||
GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) &&
|
||||
// white real body
|
||||
GetCandleColor(input) == CandleColor.White &&
|
||||
// closing well within 1st rb
|
||||
input.Close > window[2].Close + GetRealBody(window[2]) * _penetration
|
||||
)
|
||||
value = 1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 2]);
|
||||
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, window[1]) -
|
||||
GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod + 1]);
|
||||
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = 0;
|
||||
_bodyDojiPeriodTotal = 0;
|
||||
_bodyShortPeriodTotal = 0;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Morning Star candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long black real body
|
||||
/// - second candle: star(Short real body gapping down)
|
||||
/// - third candle: white real body that moves well within the first candle's real body
|
||||
/// The meaning of "short" and "long" is specified with SetCandleSettings
|
||||
/// The meaning of "moves well within" is specified with penetration and "moves" should mean the real body should
|
||||
/// not be short ("short" is specified with SetCandleSettings) - Greg Morris wants it to be long, someone else want
|
||||
/// it to be relatively long
|
||||
/// The returned value is positive(+1): morning star is always bullish;
|
||||
/// The user should consider that a morning star is significant when it appears in a downtrend,
|
||||
/// while this function does not consider the trend
|
||||
/// </remarks>
|
||||
public class MorningStar : CandlestickPattern
|
||||
{
|
||||
private readonly decimal _penetration;
|
||||
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
private decimal _bodyShortPeriodTotal;
|
||||
private decimal _bodyShortPeriodTotal2;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MorningStar"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="penetration">Percentage of penetration of a candle within another candle</param>
|
||||
public MorningStar(string name, decimal penetration = 0.3m)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod) + 2 + 1)
|
||||
{
|
||||
_penetration = penetration;
|
||||
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MorningStar"/> class.
|
||||
/// </summary>
|
||||
/// <param name="penetration">Percentage of penetration of a candle within another candle</param>
|
||||
public MorningStar(decimal penetration)
|
||||
: this("MORNINGSTAR", penetration)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MorningStar"/> class.
|
||||
/// </summary>
|
||||
public MorningStar()
|
||||
: this("MORNINGSTAR")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyLongAveragePeriod - 2 && Samples < Period - 2)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyShortAveragePeriod - 1 && Samples < Period - 1)
|
||||
{
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input);
|
||||
_bodyShortPeriodTotal2 += GetCandleRange(CandleSettingType.BodyShort, window[1]);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st: long
|
||||
GetRealBody(window[2]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[2]) &&
|
||||
// black
|
||||
GetCandleColor(window[2]) == CandleColor.Black &&
|
||||
// 2nd: short
|
||||
GetRealBody(window[1]) <= GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, window[1]) &&
|
||||
// gapping down
|
||||
GetRealBodyGapDown(window[1], window[2]) &&
|
||||
// 3rd: longer than short
|
||||
GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal2, input) &&
|
||||
// white real body
|
||||
GetCandleColor(input) == CandleColor.White &&
|
||||
// closing well within 1st rb
|
||||
input.Close > window[2].Close + GetRealBody(window[2]) * _penetration
|
||||
)
|
||||
value = 1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 2]);
|
||||
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, window[1]) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod + 1]);
|
||||
|
||||
_bodyShortPeriodTotal2 += GetCandleRange(CandleSettingType.BodyShort, input) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = 0;
|
||||
_bodyShortPeriodTotal = 0;
|
||||
_bodyShortPeriodTotal2 = 0;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// On-Neck candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long black candle
|
||||
/// - second candle: white candle with open below previous day low and close equal to previous day low
|
||||
/// The meaning of "equal" is specified with SetCandleSettings
|
||||
/// The returned value is negative(-1): on-neck is always bearish
|
||||
/// The user should consider that on-neck is significant when it appears in a downtrend, while this function
|
||||
/// does not consider it
|
||||
/// </remarks>
|
||||
public class OnNeck : CandlestickPattern
|
||||
{
|
||||
private readonly int _equalAveragePeriod;
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
|
||||
private decimal _equalPeriodTotal;
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OnNeck"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public OnNeck(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.Equal).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod) + 1 + 1)
|
||||
{
|
||||
_equalAveragePeriod = CandleSettings.Get(CandleSettingType.Equal).AveragePeriod;
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OnNeck"/> class.
|
||||
/// </summary>
|
||||
public OnNeck()
|
||||
: this("ONNECK")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _equalAveragePeriod)
|
||||
{
|
||||
_equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyLongAveragePeriod)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st: black
|
||||
GetCandleColor(window[1]) == CandleColor.Black &&
|
||||
// long
|
||||
GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[1]) &&
|
||||
// 2nd: white
|
||||
GetCandleColor(input) == CandleColor.White &&
|
||||
// open below prior low
|
||||
input.Open < window[1].Low &&
|
||||
// close equal to prior low
|
||||
input.Close <= window[1].Low + GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[1]) &&
|
||||
input.Close >= window[1].Low - GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[1])
|
||||
)
|
||||
value = -1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]) -
|
||||
GetCandleRange(CandleSettingType.Equal, window[_equalAveragePeriod + 1]);
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 1]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_equalPeriodTotal = 0m;
|
||||
_bodyLongPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Piercing candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long black candle
|
||||
/// - second candle: long white candle with open below previous day low and close at least at 50% of previous day
|
||||
/// real body
|
||||
/// The meaning of "long" is specified with SetCandleSettings
|
||||
/// The returned value is positive(+1): piercing pattern is always bullish
|
||||
/// The user should consider that a piercing pattern is significant when it appears in a downtrend, while
|
||||
/// this function does not consider it
|
||||
/// </remarks>
|
||||
public class Piercing : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
|
||||
private decimal[] _bodyLongPeriodTotal = new decimal[2];
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Piercing"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public Piercing(string name)
|
||||
: base(name, CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod + 1 + 1)
|
||||
{
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Piercing"/> class.
|
||||
/// </summary>
|
||||
public Piercing()
|
||||
: this("PIERCING")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyLongAveragePeriod)
|
||||
{
|
||||
_bodyLongPeriodTotal[1] += GetCandleRange(CandleSettingType.BodyLong, window[1]);
|
||||
_bodyLongPeriodTotal[0] += GetCandleRange(CandleSettingType.BodyLong, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st: black
|
||||
GetCandleColor(window[1]) == CandleColor.Black &&
|
||||
// long
|
||||
GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal[1], window[1]) &&
|
||||
// 2nd: white
|
||||
GetCandleColor(input) == CandleColor.White &&
|
||||
// long
|
||||
GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal[0], input) &&
|
||||
// open below prior low
|
||||
input.Open < window[1].Low &&
|
||||
// close within prior body
|
||||
input.Close < window[1].Open &&
|
||||
// above midpoint
|
||||
input.Close > window[1].Close + GetRealBody(window[1]) * 0.5m
|
||||
)
|
||||
value = 1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
for (var i = 1; i >= 0; i--)
|
||||
{
|
||||
_bodyLongPeriodTotal[i] += GetCandleRange(CandleSettingType.BodyLong, window[i]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[i + _bodyLongAveragePeriod]);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = new decimal[2];
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Rickshaw Man candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - doji body
|
||||
/// - two long shadows
|
||||
/// - body near the midpoint of the high-low range
|
||||
/// The meaning of "doji" and "near" is specified with SetCandleSettings
|
||||
/// The returned value is always positive(+1) but this does not mean it is bullish: rickshaw man shows uncertainty
|
||||
/// </remarks>
|
||||
public class RickshawMan : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyDojiAveragePeriod;
|
||||
private readonly int _shadowLongAveragePeriod;
|
||||
private readonly int _nearAveragePeriod;
|
||||
|
||||
private decimal _bodyDojiPeriodTotal;
|
||||
private decimal _shadowLongPeriodTotal;
|
||||
private decimal _nearPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RickshawMan"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public RickshawMan(string name)
|
||||
: base(name, Math.Max(Math.Max(CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod, CandleSettings.Get(CandleSettingType.ShadowLong).AveragePeriod),
|
||||
CandleSettings.Get(CandleSettingType.Near).AveragePeriod) + 1)
|
||||
{
|
||||
_bodyDojiAveragePeriod = CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod;
|
||||
_shadowLongAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowLong).AveragePeriod;
|
||||
_nearAveragePeriod = CandleSettings.Get(CandleSettingType.Near).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RickshawMan"/> class.
|
||||
/// </summary>
|
||||
public RickshawMan()
|
||||
: this("RICKSHAWMAN")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyDojiAveragePeriod)
|
||||
{
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowLongAveragePeriod)
|
||||
{
|
||||
_shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _nearAveragePeriod)
|
||||
{
|
||||
_nearPeriodTotal += GetCandleRange(CandleSettingType.Near, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// doji
|
||||
GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, input) &&
|
||||
// long shadow
|
||||
GetLowerShadow(input) > GetCandleAverage(CandleSettingType.ShadowLong, _shadowLongPeriodTotal, input) &&
|
||||
// long shadow
|
||||
GetUpperShadow(input) > GetCandleAverage(CandleSettingType.ShadowLong, _shadowLongPeriodTotal, input) &&
|
||||
// body near midpoint
|
||||
(
|
||||
Math.Min(input.Open, input.Close)
|
||||
<= input.Low + GetHighLowRange(input) / 2 + GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal, input)
|
||||
&&
|
||||
Math.Max(input.Open, input.Close)
|
||||
>= input.Low + GetHighLowRange(input) / 2 - GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal, input)
|
||||
)
|
||||
)
|
||||
value = 1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input) -
|
||||
GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod]);
|
||||
|
||||
_shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input) -
|
||||
GetCandleRange(CandleSettingType.ShadowLong, window[_shadowLongAveragePeriod]);
|
||||
|
||||
_nearPeriodTotal += GetCandleRange(CandleSettingType.Near, input) -
|
||||
GetCandleRange(CandleSettingType.Near, window[_nearAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyDojiPeriodTotal = 0;
|
||||
_shadowLongPeriodTotal = 0;
|
||||
_nearPeriodTotal = 0;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Rising/Falling Three Methods candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long white (black) candlestick
|
||||
/// - then: group of falling(rising) small real body candlesticks(commonly black (white)) that hold within
|
||||
/// the prior long candle's range: ideally they should be three but two or more than three are ok too
|
||||
/// - final candle: long white(black) candle that opens above(below) the previous small candle's close
|
||||
/// and closes above(below) the first long candle's close
|
||||
/// The meaning of "short" and "long" is specified with SetCandleSettings; here only patterns with 3 small candles
|
||||
/// are considered;
|
||||
/// The returned value is positive(+1) or negative(-1)
|
||||
/// </remarks>
|
||||
public class RiseFallThreeMethods : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
|
||||
private decimal[] _bodyPeriodTotal = new decimal[5];
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RiseFallThreeMethods"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public RiseFallThreeMethods(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod) + 4 + 1)
|
||||
{
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod;
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RiseFallThreeMethods"/> class.
|
||||
/// </summary>
|
||||
public RiseFallThreeMethods()
|
||||
: this("RISEFALLTHREEMETHODS")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples > Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples > Period - _bodyShortAveragePeriod)
|
||||
{
|
||||
_bodyPeriodTotal[3] += GetCandleRange(CandleSettingType.BodyShort, window[3]);
|
||||
_bodyPeriodTotal[2] += GetCandleRange(CandleSettingType.BodyShort, window[2]);
|
||||
_bodyPeriodTotal[1] += GetCandleRange(CandleSettingType.BodyShort, window[1]);
|
||||
}
|
||||
|
||||
if (Samples > Period - _bodyLongAveragePeriod)
|
||||
{
|
||||
_bodyPeriodTotal[4] += GetCandleRange(CandleSettingType.BodyLong, window[4]);
|
||||
_bodyPeriodTotal[0] += GetCandleRange(CandleSettingType.BodyLong, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st long, then 3 small, 5th long
|
||||
GetRealBody(window[4]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyPeriodTotal[4], window[4]) &&
|
||||
GetRealBody(window[3]) < GetCandleAverage(CandleSettingType.BodyShort, _bodyPeriodTotal[3], window[3]) &&
|
||||
GetRealBody(window[2]) < GetCandleAverage(CandleSettingType.BodyShort, _bodyPeriodTotal[2], window[2]) &&
|
||||
GetRealBody(window[1]) < GetCandleAverage(CandleSettingType.BodyShort, _bodyPeriodTotal[1], window[1]) &&
|
||||
GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyLong, _bodyPeriodTotal[0], input) &&
|
||||
// white, 3 black, white || black, 3 white, black
|
||||
(int)GetCandleColor(window[4]) == -(int)GetCandleColor(window[3]) &&
|
||||
GetCandleColor(window[3]) == GetCandleColor(window[2]) &&
|
||||
GetCandleColor(window[2]) == GetCandleColor(window[1]) &&
|
||||
(int)GetCandleColor(window[1]) == -(int)GetCandleColor(input) &&
|
||||
// 2nd to 4th hold within 1st: a part of the real body must be within 1st range
|
||||
Math.Min(window[3].Open, window[3].Close) < window[4].High && Math.Max(window[3].Open, window[3].Close) > window[4].Low &&
|
||||
Math.Min(window[2].Open, window[2].Close) < window[4].High && Math.Max(window[2].Open, window[2].Close) > window[4].Low &&
|
||||
Math.Min(window[1].Open, window[1].Close) < window[4].High && Math.Max(window[1].Open, window[1].Close) > window[4].Low &&
|
||||
// 2nd to 4th are falling (rising)
|
||||
window[2].Close * (int)GetCandleColor(window[4]) < window[3].Close * (int)GetCandleColor(window[4]) &&
|
||||
window[1].Close * (int)GetCandleColor(window[4]) < window[2].Close * (int)GetCandleColor(window[4]) &&
|
||||
// 5th opens above (below) the prior close
|
||||
input.Open * (int)GetCandleColor(window[4]) > window[1].Close * (int)GetCandleColor(window[4]) &&
|
||||
// 5th closes above (below) the 1st close
|
||||
input.Close * (int)GetCandleColor(window[4]) > window[4].Close * (int)GetCandleColor(window[4])
|
||||
)
|
||||
value = (int)GetCandleColor(window[4]);
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyPeriodTotal[4] += GetCandleRange(CandleSettingType.BodyLong, window[4]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 4]);
|
||||
|
||||
for (var i = 3; i >= 1; i--)
|
||||
{
|
||||
_bodyPeriodTotal[i] += GetCandleRange(CandleSettingType.BodyShort, window[i]) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[i + _bodyShortAveragePeriod]);
|
||||
}
|
||||
|
||||
_bodyPeriodTotal[0] += GetCandleRange(CandleSettingType.BodyLong, input) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyPeriodTotal = new decimal[5];
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Separating Lines candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: black (white) candle
|
||||
/// - second candle: bullish(bearish) belt hold with the same open as the prior candle
|
||||
/// The meaning of "long body" and "very short shadow" of the belt hold is specified with SetCandleSettings
|
||||
/// The returned value is positive(+1) when bullish or negative(-1) when bearish;
|
||||
/// The user should consider that separating lines is significant when coming in a trend and the belt hold has
|
||||
/// the same direction of the trend, while this function does not consider it
|
||||
/// </remarks>
|
||||
public class SeparatingLines : CandlestickPattern
|
||||
{
|
||||
private readonly int _shadowVeryShortAveragePeriod;
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
private readonly int _equalAveragePeriod;
|
||||
|
||||
private decimal _shadowVeryShortPeriodTotal;
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
private decimal _equalPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SeparatingLines"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public SeparatingLines(string name)
|
||||
: base(name, Math.Max(Math.Max(CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod),
|
||||
CandleSettings.Get(CandleSettingType.Equal).AveragePeriod) + 1 + 1)
|
||||
{
|
||||
_shadowVeryShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod;
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_equalAveragePeriod = CandleSettings.Get(CandleSettingType.Equal).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SeparatingLines"/> class.
|
||||
/// </summary>
|
||||
public SeparatingLines()
|
||||
: this("SEPARATINGLINES")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _shadowVeryShortAveragePeriod)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyLongAveragePeriod)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _equalAveragePeriod)
|
||||
{
|
||||
_equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// opposite candles
|
||||
(int)GetCandleColor(window[1]) == -(int)GetCandleColor(input) &&
|
||||
// same open
|
||||
input.Open <= window[1].Open + GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[1]) &&
|
||||
input.Open >= window[1].Open - GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[1]) &&
|
||||
// belt hold: long body
|
||||
GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, input) &&
|
||||
(
|
||||
// with no lower shadow if bullish
|
||||
(GetCandleColor(input) == CandleColor.White &&
|
||||
GetLowerShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input)
|
||||
)
|
||||
||
|
||||
// with no upper shadow if bearish
|
||||
(GetCandleColor(input) == CandleColor.Black &&
|
||||
GetUpperShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input)
|
||||
)
|
||||
)
|
||||
)
|
||||
value = (int)GetCandleColor(input);
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryShort, window[_shadowVeryShortAveragePeriod]);
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod]);
|
||||
|
||||
_equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]) -
|
||||
GetCandleRange(CandleSettingType.Equal, window[_equalAveragePeriod + 1]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_shadowVeryShortPeriodTotal = 0m;
|
||||
_bodyLongPeriodTotal = 0m;
|
||||
_equalPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Shooting Star candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - small real body
|
||||
/// - long upper shadow
|
||||
/// - no, or very short, lower shadow
|
||||
/// - gap up from prior real body
|
||||
/// The meaning of "short", "very short" and "long" is specified with SetCandleSettings;
|
||||
/// The returned value is negative(-1): shooting star is always bearish;
|
||||
/// The user should consider that a shooting star must appear in an uptrend, while this function does not consider it
|
||||
/// </remarks>
|
||||
public class ShootingStar : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
private readonly int _shadowLongAveragePeriod;
|
||||
private readonly int _shadowVeryShortAveragePeriod;
|
||||
|
||||
private decimal _bodyShortPeriodTotal;
|
||||
private decimal _shadowLongPeriodTotal;
|
||||
private decimal _shadowVeryShortPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ShootingStar"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public ShootingStar(string name)
|
||||
: base(name, Math.Max(Math.Max(CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod, CandleSettings.Get(CandleSettingType.ShadowLong).AveragePeriod),
|
||||
CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod) + 1 + 1)
|
||||
{
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod;
|
||||
_shadowLongAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowLong).AveragePeriod;
|
||||
_shadowVeryShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ShootingStar"/> class.
|
||||
/// </summary>
|
||||
public ShootingStar()
|
||||
: this("SHOOTINGSTAR")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyShortAveragePeriod)
|
||||
{
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowLongAveragePeriod)
|
||||
{
|
||||
_shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowVeryShortAveragePeriod)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// small rb
|
||||
GetRealBody(input) < GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) &&
|
||||
// long upper shadow
|
||||
GetUpperShadow(input) > GetCandleAverage(CandleSettingType.ShadowLong, _shadowLongPeriodTotal, input) &&
|
||||
// very short lower shadow
|
||||
GetLowerShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input) &&
|
||||
// gap up
|
||||
GetRealBodyGapUp(input, window[1])
|
||||
)
|
||||
value = -1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]);
|
||||
|
||||
_shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input) -
|
||||
GetCandleRange(CandleSettingType.ShadowLong, window[_shadowLongAveragePeriod]);
|
||||
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryShort, window[_shadowVeryShortAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyShortPeriodTotal = 0;
|
||||
_shadowLongPeriodTotal = 0;
|
||||
_shadowVeryShortPeriodTotal = 0;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Short Line Candle candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - short real body
|
||||
/// - short upper and lower shadow
|
||||
/// The meaning of "short" is specified with SetCandleSettings
|
||||
/// The returned value is positive(+1) when white, negative (-1) when black;
|
||||
/// it does not mean bullish or bearish
|
||||
/// </remarks>
|
||||
public class ShortLineCandle : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
private readonly int _shadowShortAveragePeriod;
|
||||
|
||||
private decimal _bodyShortPeriodTotal;
|
||||
private decimal _shadowShortPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ShortLineCandle"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public ShortLineCandle(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod, CandleSettings.Get(CandleSettingType.ShadowShort).AveragePeriod) + 1)
|
||||
{
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod;
|
||||
_shadowShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ShortLineCandle"/> class.
|
||||
/// </summary>
|
||||
public ShortLineCandle()
|
||||
: this("SHORTLINECANDLE")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyShortAveragePeriod)
|
||||
{
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowShortAveragePeriod)
|
||||
{
|
||||
_shadowShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (GetRealBody(input) < GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) &&
|
||||
GetUpperShadow(input) < GetCandleAverage(CandleSettingType.ShadowShort, _shadowShortPeriodTotal, input) &&
|
||||
GetLowerShadow(input) < GetCandleAverage(CandleSettingType.ShadowShort, _shadowShortPeriodTotal, input)
|
||||
)
|
||||
value = (int)GetCandleColor(input);
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]);
|
||||
|
||||
_shadowShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowShort, input) -
|
||||
GetCandleRange(CandleSettingType.ShadowShort, window[_shadowShortAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyShortPeriodTotal = 0m;
|
||||
_shadowShortPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Spinning Top candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - small real body
|
||||
/// - shadows longer than the real body
|
||||
/// The meaning of "short" is specified with SetCandleSettings
|
||||
/// The returned value is positive(+1) when white or negative(-1) when black;
|
||||
/// it does not mean bullish or bearish
|
||||
/// </remarks>
|
||||
public class SpinningTop : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
|
||||
private decimal _bodyShortPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SpinningTop"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public SpinningTop(string name)
|
||||
: base(name, CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod + 1)
|
||||
{
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SpinningTop"/> class.
|
||||
/// </summary>
|
||||
public SpinningTop()
|
||||
: this("SPINNINGTOP")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyShortAveragePeriod)
|
||||
{
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (GetRealBody(input) < GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) &&
|
||||
GetUpperShadow(input) > GetRealBody(input) &&
|
||||
GetLowerShadow(input) > GetRealBody(input)
|
||||
)
|
||||
value = (int)GetCandleColor(input);
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyShortPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Stalled Pattern candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - three white candlesticks with consecutively higher closes
|
||||
/// - first candle: long white
|
||||
/// - second candle: long white with no or very short upper shadow opening within or near the previous white real body
|
||||
/// and closing higher than the prior candle
|
||||
/// - third candle: small white that gaps away or "rides on the shoulder" of the prior long real body(= it's at
|
||||
/// the upper end of the prior real body)
|
||||
/// The meanings of "long", "very short", "short", "near" are specified with SetCandleSettings;
|
||||
/// The returned value is negative(-1): stalled pattern is always bearish;
|
||||
/// The user should consider that stalled pattern is significant when it appears in uptrend, while this function
|
||||
/// does not consider it
|
||||
/// </remarks>
|
||||
public class StalledPattern : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
private readonly int _shadowVeryShortAveragePeriod;
|
||||
private readonly int _nearAveragePeriod;
|
||||
|
||||
private decimal[] _bodyLongPeriodTotal = new decimal[3];
|
||||
private decimal _bodyShortPeriodTotal;
|
||||
private decimal _shadowVeryShortPeriodTotal;
|
||||
private decimal[] _nearPeriodTotal = new decimal[3];
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StalledPattern"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public StalledPattern(string name)
|
||||
: base(name, Math.Max(Math.Max(CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod),
|
||||
Math.Max(CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod, CandleSettings.Get(CandleSettingType.Near).AveragePeriod)) + 2 + 1)
|
||||
{
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod;
|
||||
_shadowVeryShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod;
|
||||
_nearAveragePeriod = CandleSettings.Get(CandleSettingType.Near).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StalledPattern"/> class.
|
||||
/// </summary>
|
||||
public StalledPattern()
|
||||
: this("STALLEDPATTERN")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyLongAveragePeriod)
|
||||
{
|
||||
_bodyLongPeriodTotal[2] += GetCandleRange(CandleSettingType.BodyLong, window[2]);
|
||||
_bodyLongPeriodTotal[1] += GetCandleRange(CandleSettingType.BodyLong, window[1]);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyShortAveragePeriod)
|
||||
{
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowVeryShortAveragePeriod)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, window[1]);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _nearAveragePeriod)
|
||||
{
|
||||
_nearPeriodTotal[2] += GetCandleRange(CandleSettingType.Near, window[2]);
|
||||
_nearPeriodTotal[1] += GetCandleRange(CandleSettingType.Near, window[1]);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st white
|
||||
GetCandleColor(window[2]) == CandleColor.White &&
|
||||
// 2nd white
|
||||
GetCandleColor(window[1]) == CandleColor.White &&
|
||||
// 3rd white
|
||||
GetCandleColor(input) == CandleColor.White &&
|
||||
// consecutive higher closes
|
||||
input.Close > window[1].Close && window[1].Close > window[2].Close &&
|
||||
// 1st: long real body
|
||||
GetRealBody(window[2]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal[2], window[2]) &&
|
||||
// 2nd: long real body
|
||||
GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal[1], window[1]) &&
|
||||
// very short upper shadow
|
||||
GetUpperShadow(window[1]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, window[1]) &&
|
||||
// opens within/near 1st real body
|
||||
window[1].Open > window[2].Open &&
|
||||
window[1].Open <= window[2].Close + GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal[2], window[2]) &&
|
||||
// 3rd: small real body
|
||||
GetRealBody(input) < GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) &&
|
||||
// rides on the shoulder of 2nd real body
|
||||
input.Open >= window[1].Close - GetRealBody(input) - GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal[1], window[1])
|
||||
)
|
||||
value = -1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
for (var i = 2; i >= 1; i--)
|
||||
{
|
||||
_bodyLongPeriodTotal[i] += GetCandleRange(CandleSettingType.BodyLong, window[i]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[i + _bodyLongAveragePeriod]);
|
||||
_nearPeriodTotal[i] += GetCandleRange(CandleSettingType.Near, window[i]) -
|
||||
GetCandleRange(CandleSettingType.Near, window[i + _nearAveragePeriod]);
|
||||
}
|
||||
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]);
|
||||
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, window[1]) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryShort, window[_bodyShortAveragePeriod + 1]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = new decimal[3];
|
||||
_bodyShortPeriodTotal = 0;
|
||||
_shadowVeryShortPeriodTotal = 0;
|
||||
_nearPeriodTotal = new decimal[3];
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Stick Sandwich candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: black candle
|
||||
/// - second candle: white candle that trades only above the prior close(low > prior close)
|
||||
/// - third candle: black candle with the close equal to the first candle's close
|
||||
/// The meaning of "equal" is specified with SetCandleSettings
|
||||
/// The returned value is always positive(+1): stick sandwich is always bullish;
|
||||
/// The user should consider that stick sandwich is significant when coming in a downtrend,
|
||||
/// while this function does not consider it
|
||||
/// </remarks>
|
||||
public class StickSandwich : CandlestickPattern
|
||||
{
|
||||
private readonly int _equalAveragePeriod;
|
||||
|
||||
private decimal _equalPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StickSandwich"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public StickSandwich(string name)
|
||||
: base(name, CandleSettings.Get(CandleSettingType.Equal).AveragePeriod + 2 + 1)
|
||||
{
|
||||
_equalAveragePeriod = CandleSettings.Get(CandleSettingType.Equal).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StickSandwich"/> class.
|
||||
/// </summary>
|
||||
public StickSandwich()
|
||||
: this("STICKSANDWICH")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _equalAveragePeriod)
|
||||
{
|
||||
_equalPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// first black
|
||||
GetCandleColor(window[2]) == CandleColor.Black &&
|
||||
// second white
|
||||
GetCandleColor(window[1]) == CandleColor.White &&
|
||||
// third black
|
||||
GetCandleColor(input) == CandleColor.Black &&
|
||||
// 2nd low > prior close
|
||||
window[1].Low > window[2].Close &&
|
||||
// 1st and 3rd same close
|
||||
input.Close <= window[2].Close + GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[2]) &&
|
||||
input.Close >= window[2].Close - GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[2])
|
||||
)
|
||||
value = 1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[2]) -
|
||||
GetCandleRange(CandleSettingType.Equal, window[_equalAveragePeriod + 2]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_equalPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Takuri (Dragonfly Doji with very long lower shadow) candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - doji body
|
||||
/// - open and close at the high of the day = no or very short upper shadow
|
||||
/// - very long lower shadow
|
||||
/// The meaning of "doji", "very short" and "very long" is specified with SetCandleSettings
|
||||
/// The returned value is always positive(+1) but this does not mean it is bullish: takuri must be considered
|
||||
/// relatively to the trend
|
||||
/// </remarks>
|
||||
public class Takuri : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyDojiAveragePeriod;
|
||||
private readonly int _shadowVeryShortAveragePeriod;
|
||||
private readonly int _shadowVeryLongAveragePeriod;
|
||||
|
||||
private decimal _bodyDojiPeriodTotal;
|
||||
private decimal _shadowVeryShortPeriodTotal;
|
||||
private decimal _shadowVeryLongPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Takuri"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public Takuri(string name)
|
||||
: base(name, Math.Max(Math.Max(CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod, CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod),
|
||||
CandleSettings.Get(CandleSettingType.ShadowVeryLong).AveragePeriod) + 1)
|
||||
{
|
||||
_bodyDojiAveragePeriod = CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod;
|
||||
_shadowVeryShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod;
|
||||
_shadowVeryLongAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryLong).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Takuri"/> class.
|
||||
/// </summary>
|
||||
public Takuri()
|
||||
: this("TAKURI")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyDojiAveragePeriod)
|
||||
{
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowVeryShortAveragePeriod)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowVeryLongAveragePeriod)
|
||||
{
|
||||
_shadowVeryLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryLong, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, input) &&
|
||||
GetUpperShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input) &&
|
||||
GetLowerShadow(input) > GetCandleAverage(CandleSettingType.ShadowVeryLong, _shadowVeryLongPeriodTotal, input)
|
||||
)
|
||||
value = 1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input) -
|
||||
GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod]);
|
||||
|
||||
_shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryShort, window[_shadowVeryShortAveragePeriod]);
|
||||
|
||||
_shadowVeryLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryLong, input) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryLong, window[_shadowVeryLongAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyDojiPeriodTotal = 0m;
|
||||
_shadowVeryShortPeriodTotal = 0m;
|
||||
_shadowVeryLongPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Tasuki Gap candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - upside (downside) gap
|
||||
/// - first candle after the window: white(black) candlestick
|
||||
/// - second candle: black(white) candlestick that opens within the previous real body and closes under(above)
|
||||
/// the previous real body inside the gap
|
||||
/// - the size of two real bodies should be near the same
|
||||
/// The meaning of "near" is specified with SetCandleSettings
|
||||
/// The returned value is positive(+1) when bullish or negative(-1) when bearish;
|
||||
/// The user should consider that tasuki gap is significant when it appears in a trend, while this function does
|
||||
/// not consider it
|
||||
/// </remarks>
|
||||
public class TasukiGap : CandlestickPattern
|
||||
{
|
||||
private readonly int _nearAveragePeriod;
|
||||
|
||||
private decimal _nearPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TasukiGap"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public TasukiGap(string name)
|
||||
: base(name, CandleSettings.Get(CandleSettingType.Near).AveragePeriod + 2 + 1)
|
||||
{
|
||||
_nearAveragePeriod = CandleSettings.Get(CandleSettingType.Near).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TasukiGap"/> class.
|
||||
/// </summary>
|
||||
public TasukiGap()
|
||||
: this("TASUKIGAP")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _nearAveragePeriod)
|
||||
{
|
||||
_nearPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
(
|
||||
// upside gap
|
||||
GetRealBodyGapUp(window[1], window[2]) &&
|
||||
// 1st: white
|
||||
GetCandleColor(window[1]) == CandleColor.White &&
|
||||
// 2nd: black
|
||||
GetCandleColor(input) == CandleColor.Black &&
|
||||
// that opens within the white rb
|
||||
input.Open < window[1].Close && input.Open > window[1].Open &&
|
||||
// and closes under the white rb
|
||||
input.Close < window[1].Open &&
|
||||
// inside the gap
|
||||
input.Close > Math.Max(window[2].Close, window[2].Open) &&
|
||||
// size of 2 rb near the same
|
||||
Math.Abs(GetRealBody(window[1]) - GetRealBody(input)) < GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal, window[1])
|
||||
) ||
|
||||
(
|
||||
// downside gap
|
||||
GetRealBodyGapDown(window[1], window[2]) &&
|
||||
// 1st: black
|
||||
GetCandleColor(window[1]) == CandleColor.Black &&
|
||||
// 2nd: white
|
||||
GetCandleColor(input) == CandleColor.White &&
|
||||
// that opens within the black rb
|
||||
input.Open < window[1].Open && input.Open > window[1].Close &&
|
||||
// and closes above the black rb
|
||||
input.Close > window[1].Open &&
|
||||
// inside the gap
|
||||
input.Close < Math.Min(window[2].Close, window[2].Open) &&
|
||||
// size of 2 rb near the same
|
||||
Math.Abs(GetRealBody(window[1]) - GetRealBody(input)) < GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal, window[1])
|
||||
)
|
||||
)
|
||||
value = (int)GetCandleColor(window[1]);
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_nearPeriodTotal += GetCandleRange(CandleSettingType.Near, window[1]) -
|
||||
GetCandleRange(CandleSettingType.Near, window[_nearAveragePeriod + 1]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_nearPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Three Black Crows candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - three consecutive and declining black candlesticks
|
||||
/// - each candle must have no or very short lower shadow
|
||||
/// - each candle after the first must open within the prior candle's real body
|
||||
/// - the first candle's close should be under the prior white candle's high
|
||||
/// The meaning of "very short" is specified with SetCandleSettings
|
||||
/// The returned value is negative (-1): three black crows is always bearish;
|
||||
/// The user should consider that 3 black crows is significant when it appears after a mature advance or at high levels,
|
||||
/// while this function does not consider it
|
||||
/// </remarks>
|
||||
public class ThreeBlackCrows : CandlestickPattern
|
||||
{
|
||||
private readonly int _shadowVeryShortAveragePeriod;
|
||||
|
||||
private decimal[] _shadowVeryShortPeriodTotal = new decimal[3];
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ThreeBlackCrows"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public ThreeBlackCrows(string name)
|
||||
: base(name, CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod + 3 + 1)
|
||||
{
|
||||
_shadowVeryShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ThreeBlackCrows"/> class.
|
||||
/// </summary>
|
||||
public ThreeBlackCrows()
|
||||
: this("THREEBLACKCROWS")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _shadowVeryShortAveragePeriod)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal[2] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[2]);
|
||||
_shadowVeryShortPeriodTotal[1] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[1]);
|
||||
_shadowVeryShortPeriodTotal[0] += GetCandleRange(CandleSettingType.ShadowVeryShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// white
|
||||
GetCandleColor(window[3]) == CandleColor.White &&
|
||||
// 1st black
|
||||
GetCandleColor(window[2]) == CandleColor.Black &&
|
||||
// very short lower shadow
|
||||
GetLowerShadow(window[2]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[2], window[2]) &&
|
||||
// 2nd black
|
||||
GetCandleColor(window[1]) == CandleColor.Black &&
|
||||
// very short lower shadow
|
||||
GetLowerShadow(window[1]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[1], window[1]) &&
|
||||
// 3rd black
|
||||
GetCandleColor(input) == CandleColor.Black &&
|
||||
// very short lower shadow
|
||||
GetLowerShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[0], input) &&
|
||||
// 2nd black opens within 1st black's rb
|
||||
window[1].Open < window[2].Open && window[1].Open > window[2].Close &&
|
||||
// 3rd black opens within 2nd black's rb
|
||||
input.Open < window[1].Open && input.Open > window[1].Close &&
|
||||
// 1st black closes under prior candle's high
|
||||
window[3].High > window[2].Close &&
|
||||
// three declining
|
||||
window[2].Close > window[1].Close &&
|
||||
// three declining
|
||||
window[1].Close > input.Close
|
||||
)
|
||||
value = -1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
for (var i = 2; i >= 0; i--)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal[i] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[i]) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryShort, window[i + _shadowVeryShortAveragePeriod]);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_shadowVeryShortPeriodTotal = new decimal[3];
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Three Inside Up/Down candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long white(black) real body
|
||||
/// - second candle: short real body totally engulfed by the first
|
||||
/// - third candle: black(white) candle that closes lower(higher) than the first candle's open
|
||||
/// The meaning of "short" and "long" is specified with SetCandleSettings
|
||||
/// The returned value is positive (+1) for the three inside up or negative (-1) for the three inside down;
|
||||
/// The user should consider that a three inside up is significant when it appears in a downtrend and a three inside
|
||||
/// down is significant when it appears in an uptrend, while this function does not consider the trend
|
||||
/// </remarks>
|
||||
public class ThreeInside : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
private decimal _bodyShortPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ThreeInside"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public ThreeInside(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod) + 2 + 1)
|
||||
{
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ThreeInside"/> class.
|
||||
/// </summary>
|
||||
public ThreeInside()
|
||||
: this("THREEINSIDE")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyLongAveragePeriod - 2 && Samples < Period - 2)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyShortAveragePeriod - 1 && Samples < Period - 1)
|
||||
{
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st: long
|
||||
GetRealBody(window[2]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[2]) &&
|
||||
// 2nd: short
|
||||
GetRealBody(window[1]) <= GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, window[1]) &&
|
||||
// engulfed by 1st
|
||||
Math.Max(window[1].Close, window[1].Open) < Math.Max(window[2].Close, window[2].Open) &&
|
||||
Math.Min(window[1].Close, window[1].Open) > Math.Min(window[2].Close, window[2].Open) &&
|
||||
// 3rd: opposite to 1st
|
||||
((GetCandleColor(window[2]) == CandleColor.White && GetCandleColor(input) == CandleColor.Black && input.Close < window[2].Open) ||
|
||||
// and closing out
|
||||
(GetCandleColor(window[2]) == CandleColor.Black && GetCandleColor(input) == CandleColor.White && input.Close > window[2].Open)
|
||||
)
|
||||
)
|
||||
value = -(int)GetCandleColor(window[2]);
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[2 + _bodyLongAveragePeriod]);
|
||||
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, window[1]) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[1 + _bodyShortAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = 0;
|
||||
_bodyShortPeriodTotal = 0;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Three Line Strike candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - three white soldiers (three black crows): three white (black) candlesticks with consecutively higher (lower) closes,
|
||||
/// each opening within or near the previous real body
|
||||
/// - fourth candle: black (white) candle that opens above (below) prior candle's close and closes below (above)
|
||||
/// the first candle's open
|
||||
/// The meaning of "near" is specified with SetCandleSettings;
|
||||
/// The returned value is positive (+1) when bullish or negative (-1) when bearish;
|
||||
/// The user should consider that 3-line strike is significant when it appears in a trend in the same direction of
|
||||
/// the first three candles, while this function does not consider it
|
||||
/// </remarks>
|
||||
public class ThreeLineStrike : CandlestickPattern
|
||||
{
|
||||
private readonly int _nearAveragePeriod;
|
||||
|
||||
private decimal[] _nearPeriodTotal = new decimal[4];
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ThreeLineStrike"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public ThreeLineStrike(string name)
|
||||
: base(name, CandleSettings.Get(CandleSettingType.Near).AveragePeriod + 3 + 1)
|
||||
{
|
||||
_nearAveragePeriod = CandleSettings.Get(CandleSettingType.Near).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ThreeLineStrike"/> class.
|
||||
/// </summary>
|
||||
public ThreeLineStrike()
|
||||
: this("THREELINESTRIKE")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _nearAveragePeriod)
|
||||
{
|
||||
_nearPeriodTotal[3] += GetCandleRange(CandleSettingType.Near, window[3]);
|
||||
_nearPeriodTotal[2] += GetCandleRange(CandleSettingType.Near, window[2]);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// three with same color
|
||||
GetCandleColor(window[3]) == GetCandleColor(window[2]) &&
|
||||
GetCandleColor(window[2]) == GetCandleColor(window[1]) &&
|
||||
// 4th opposite color
|
||||
(int)GetCandleColor(input) == -(int)GetCandleColor(window[1]) &&
|
||||
// 2nd opens within/near 1st rb
|
||||
window[2].Open >= Math.Min(window[3].Open, window[3].Close) - GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal[3], window[3]) &&
|
||||
window[2].Open <= Math.Max(window[3].Open, window[3].Close) + GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal[3], window[3]) &&
|
||||
// 3rd opens within/near 2nd rb
|
||||
window[1].Open >= Math.Min(window[2].Open, window[2].Close) - GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal[2], window[2]) &&
|
||||
window[1].Open <= Math.Max(window[2].Open, window[2].Close) + GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal[2], window[2]) &&
|
||||
(
|
||||
(
|
||||
// if three white
|
||||
GetCandleColor(window[1]) == CandleColor.White &&
|
||||
// consecutive higher closes
|
||||
window[1].Close > window[2].Close && window[2].Close > window[3].Close &&
|
||||
// 4th opens above prior close
|
||||
input.Open > window[1].Close &&
|
||||
// 4th closes below 1st open
|
||||
input.Close < window[3].Open
|
||||
) ||
|
||||
(
|
||||
// if three black
|
||||
GetCandleColor(window[1]) == CandleColor.Black &&
|
||||
// consecutive lower closes
|
||||
window[1].Close < window[2].Close && window[2].Close < window[3].Close &&
|
||||
// 4th opens below prior close
|
||||
input.Open < window[1].Close &&
|
||||
// 4th closes above 1st open
|
||||
input.Close > window[3].Open
|
||||
)
|
||||
)
|
||||
)
|
||||
value = (int)GetCandleColor(window[1]);
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
for (var i = 3; i >= 2; i--)
|
||||
{
|
||||
_nearPeriodTotal[i] += GetCandleRange(CandleSettingType.Near, window[i]) -
|
||||
GetCandleRange(CandleSettingType.Near, window[i + _nearAveragePeriod]);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_nearPeriodTotal = new decimal[4];
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Three Outside Up/Down candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first: black(white) real body
|
||||
/// - second: white(black) real body that engulfs the prior real body
|
||||
/// - third: candle that closes higher(lower) than the second candle
|
||||
/// The returned value is positive (+1) for the three outside up or negative (-1) for the three outside down;
|
||||
/// The user should consider that a three outside up must appear in a downtrend and three outside down must appear
|
||||
/// in an uptrend, while this function does not consider it
|
||||
/// </remarks>
|
||||
public class ThreeOutside : CandlestickPattern
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ThreeOutside"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public ThreeOutside(string name)
|
||||
: base(name, 3)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ThreeOutside"/> class.
|
||||
/// </summary>
|
||||
public ThreeOutside()
|
||||
: this("THREEOUTSIDE")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
(
|
||||
// white engulfs black
|
||||
GetCandleColor(window[1]) == CandleColor.White && GetCandleColor(window[2]) == CandleColor.Black &&
|
||||
window[1].Close > window[2].Open && window[1].Open < window[2].Close &&
|
||||
// third candle higher
|
||||
input.Close > window[1].Close
|
||||
)
|
||||
||
|
||||
(
|
||||
// black engulfs white
|
||||
GetCandleColor(window[1]) == CandleColor.Black && GetCandleColor(window[2]) == CandleColor.White &&
|
||||
window[1].Open > window[2].Close && window[1].Close < window[2].Open &&
|
||||
// third candle lower
|
||||
input.Close < window[1].Close
|
||||
)
|
||||
)
|
||||
value = (int)GetCandleColor(window[1]);
|
||||
else
|
||||
value = 0;
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Three Stars In The South candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long black candle with long lower shadow
|
||||
/// - second candle: smaller black candle that opens higher than prior close but within prior candle's range
|
||||
/// and trades lower than prior close but not lower than prior low and closes off of its low(it has a shadow)
|
||||
/// - third candle: small black marubozu(or candle with very short shadows) engulfed by prior candle's range
|
||||
/// The meanings of "long body", "short body", "very short shadow" are specified with SetCandleSettings;
|
||||
/// The returned value is positive (+1): 3 stars in the south is always bullish;
|
||||
/// The user should consider that 3 stars in the south is significant when it appears in downtrend, while this function
|
||||
/// does not consider it
|
||||
/// </remarks>
|
||||
public class ThreeStarsInSouth : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
private readonly int _shadowLongAveragePeriod;
|
||||
private readonly int _shadowVeryShortAveragePeriod;
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
private decimal _shadowLongPeriodTotal;
|
||||
private decimal[] _shadowVeryShortPeriodTotal = new decimal[2];
|
||||
private decimal _bodyShortPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ThreeStarsInSouth"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public ThreeStarsInSouth(string name)
|
||||
: base(name, Math.Max(Math.Max(CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod, CandleSettings.Get(CandleSettingType.ShadowLong).AveragePeriod),
|
||||
Math.Max(CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod)) + 2 + 1)
|
||||
{
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_shadowLongAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowLong).AveragePeriod;
|
||||
_shadowVeryShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod;
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ThreeStarsInSouth"/> class.
|
||||
/// </summary>
|
||||
public ThreeStarsInSouth()
|
||||
: this("THREESTARSINSOUTH")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyLongAveragePeriod)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowLongAveragePeriod)
|
||||
{
|
||||
_shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, window[2]);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _shadowVeryShortAveragePeriod)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal[1] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[1]);
|
||||
_shadowVeryShortPeriodTotal[0] += GetCandleRange(CandleSettingType.ShadowVeryShort, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyShortAveragePeriod)
|
||||
{
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st black
|
||||
GetCandleColor(window[2]) == CandleColor.Black &&
|
||||
// 2nd black
|
||||
GetCandleColor(window[1]) == CandleColor.Black &&
|
||||
// 3rd black
|
||||
GetCandleColor(input) == CandleColor.Black &&
|
||||
// 1st: long
|
||||
GetRealBody(window[2]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[2]) &&
|
||||
// with long lower shadow
|
||||
GetLowerShadow(window[2]) > GetCandleAverage(CandleSettingType.ShadowLong, _shadowLongPeriodTotal, window[2]) &&
|
||||
// 2nd: smaller candle
|
||||
GetRealBody(window[1]) < GetRealBody(window[2]) &&
|
||||
// that opens higher but within 1st range
|
||||
window[1].Open > window[2].Close && window[1].Open <= window[2].High &&
|
||||
// and trades lower than 1st close
|
||||
window[1].Low < window[2].Close &&
|
||||
// but not lower than 1st low
|
||||
window[1].Low >= window[2].Low &&
|
||||
// and has a lower shadow
|
||||
GetLowerShadow(window[1]) > GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[1], window[1]) &&
|
||||
// 3rd: small marubozu
|
||||
GetRealBody(input) < GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) &&
|
||||
GetLowerShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[0], input) &&
|
||||
GetUpperShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[0], input) &&
|
||||
// engulfed by prior candle's range
|
||||
input.Low > window[1].Low && input.High < window[1].High
|
||||
)
|
||||
value = 1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[2 + _bodyLongAveragePeriod]);
|
||||
|
||||
_shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, window[2]) -
|
||||
GetCandleRange(CandleSettingType.ShadowLong, window[2 + _shadowLongAveragePeriod]);
|
||||
|
||||
for (var i = 1; i >= 0; i--)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal[i] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[i]) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryShort, window[i + _shadowVeryShortAveragePeriod]);
|
||||
}
|
||||
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = 0;
|
||||
_shadowLongPeriodTotal = 0;
|
||||
_shadowVeryShortPeriodTotal = new decimal[2];
|
||||
_bodyShortPeriodTotal = 0;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Three Advancing White Soldiers candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - three white candlesticks with consecutively higher closes
|
||||
/// - Greg Morris wants them to be long, Steve Nison doesn't; anyway they should not be short
|
||||
/// - each candle opens within or near the previous white real body
|
||||
/// - each candle must have no or very short upper shadow
|
||||
/// - to differentiate this pattern from advance block, each candle must not be far shorter than the prior candle
|
||||
/// The meanings of "not short", "very short shadow", "far" and "near" are specified with SetCandleSettings;
|
||||
/// here the 3 candles must be not short, if you want them to be long use SetCandleSettings on BodyShort;
|
||||
/// The returned value is positive (+1): advancing 3 white soldiers is always bullish;
|
||||
/// The user should consider that 3 white soldiers is significant when it appears in downtrend, while this function
|
||||
/// does not consider it
|
||||
/// </remarks>
|
||||
public class ThreeWhiteSoldiers : CandlestickPattern
|
||||
{
|
||||
private readonly int _shadowVeryShortAveragePeriod;
|
||||
private readonly int _nearAveragePeriod;
|
||||
private readonly int _farAveragePeriod;
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
|
||||
private decimal[] _shadowVeryShortPeriodTotal = new decimal[3];
|
||||
private decimal[] _nearPeriodTotal = new decimal[3];
|
||||
private decimal[] _farPeriodTotal = new decimal[3];
|
||||
private decimal _bodyShortPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ThreeWhiteSoldiers"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public ThreeWhiteSoldiers(string name)
|
||||
: base(name, Math.Max(Math.Max(CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod),
|
||||
Math.Max(CandleSettings.Get(CandleSettingType.Far).AveragePeriod, CandleSettings.Get(CandleSettingType.Near).AveragePeriod)) + 2 + 1)
|
||||
{
|
||||
_shadowVeryShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod;
|
||||
_nearAveragePeriod = CandleSettings.Get(CandleSettingType.Near).AveragePeriod;
|
||||
_farAveragePeriod = CandleSettings.Get(CandleSettingType.Far).AveragePeriod;
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ThreeWhiteSoldiers"/> class.
|
||||
/// </summary>
|
||||
public ThreeWhiteSoldiers()
|
||||
: this("THREEWHITESOLDIERS")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _shadowVeryShortAveragePeriod)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal[2] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[2]);
|
||||
_shadowVeryShortPeriodTotal[1] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[1]);
|
||||
_shadowVeryShortPeriodTotal[0] += GetCandleRange(CandleSettingType.ShadowVeryShort, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _nearAveragePeriod)
|
||||
{
|
||||
_nearPeriodTotal[2] += GetCandleRange(CandleSettingType.Near, window[2]);
|
||||
_nearPeriodTotal[1] += GetCandleRange(CandleSettingType.Near, window[1]);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _farAveragePeriod)
|
||||
{
|
||||
_farPeriodTotal[2] += GetCandleRange(CandleSettingType.Far, window[2]);
|
||||
_farPeriodTotal[1] += GetCandleRange(CandleSettingType.Far, window[1]);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyShortAveragePeriod)
|
||||
{
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st white
|
||||
GetCandleColor(window[2]) == CandleColor.White &&
|
||||
// very short upper shadow
|
||||
GetUpperShadow(window[2]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[2], window[2]) &&
|
||||
// 2nd white
|
||||
GetCandleColor(window[1]) == CandleColor.White &&
|
||||
// very short upper shadow
|
||||
GetUpperShadow(window[1]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[1], window[1]) &&
|
||||
// 3rd white
|
||||
GetCandleColor(input) == CandleColor.White &&
|
||||
// very short upper shadow
|
||||
GetUpperShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[0], input) &&
|
||||
// consecutive higher closes
|
||||
input.Close > window[1].Close && window[1].Close > window[2].Close &&
|
||||
// 2nd opens within/near 1st real body
|
||||
window[1].Open > window[2].Open &&
|
||||
window[1].Open <= window[2].Close + GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal[2], window[2]) &&
|
||||
// 3rd opens within/near 2nd real body
|
||||
input.Open > window[1].Open &&
|
||||
input.Open <= window[1].Close + GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal[1], window[1]) &&
|
||||
// 2nd not far shorter than 1st
|
||||
GetRealBody(window[1]) > GetRealBody(window[2]) - GetCandleAverage(CandleSettingType.Far, _farPeriodTotal[2], window[2]) &&
|
||||
// 3rd not far shorter than 2nd
|
||||
GetRealBody(input) > GetRealBody(window[1]) - GetCandleAverage(CandleSettingType.Far, _farPeriodTotal[1], window[1]) &&
|
||||
// not short real body
|
||||
GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input)
|
||||
)
|
||||
value = 1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
for (var i = 2; i >= 0; i--)
|
||||
{
|
||||
_shadowVeryShortPeriodTotal[i] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[i]) -
|
||||
GetCandleRange(CandleSettingType.ShadowVeryShort, window[i + _shadowVeryShortAveragePeriod]);
|
||||
}
|
||||
|
||||
for (var i = 2; i >= 1; i--)
|
||||
{
|
||||
_farPeriodTotal[i] += GetCandleRange(CandleSettingType.Far, window[i]) -
|
||||
GetCandleRange(CandleSettingType.Far, window[i + _farAveragePeriod]);
|
||||
}
|
||||
|
||||
for (var i = 2; i >= 1; i--)
|
||||
{
|
||||
_nearPeriodTotal[i] += GetCandleRange(CandleSettingType.Near, window[i]) -
|
||||
GetCandleRange(CandleSettingType.Near, window[i + _nearAveragePeriod]);
|
||||
}
|
||||
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_shadowVeryShortPeriodTotal = new decimal[3];
|
||||
_nearPeriodTotal = new decimal[3];
|
||||
_farPeriodTotal = new decimal[3];
|
||||
_bodyShortPeriodTotal = 0;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Thrusting candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long black candle
|
||||
/// - second candle: white candle with open below previous day low and close into previous day body under the midpoint;
|
||||
/// to differentiate it from in-neck the close should not be equal to the black candle's close
|
||||
/// The meaning of "equal" is specified with SetCandleSettings
|
||||
/// The returned value is negative(-1): thrusting pattern is always bearish
|
||||
/// The user should consider that the thrusting pattern is significant when it appears in a downtrend and it could be
|
||||
/// even bullish "when coming in an uptrend or occurring twice within several days" (Steve Nison says), while this
|
||||
/// function does not consider the trend
|
||||
/// </remarks>
|
||||
public class Thrusting : CandlestickPattern
|
||||
{
|
||||
private readonly int _equalAveragePeriod;
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
|
||||
private decimal _equalPeriodTotal;
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Thrusting"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public Thrusting(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.Equal).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod) + 1 + 1)
|
||||
{
|
||||
_equalAveragePeriod = CandleSettings.Get(CandleSettingType.Equal).AveragePeriod;
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Thrusting"/> class.
|
||||
/// </summary>
|
||||
public Thrusting()
|
||||
: this("THRUSTING")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _equalAveragePeriod)
|
||||
{
|
||||
_equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyLongAveragePeriod)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st: black
|
||||
GetCandleColor(window[1]) == CandleColor.Black &&
|
||||
// long
|
||||
GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[1]) &&
|
||||
// 2nd: white
|
||||
GetCandleColor(input) == CandleColor.White &&
|
||||
// open below prior low
|
||||
input.Open < window[1].Low &&
|
||||
// close into prior body
|
||||
input.Close > window[1].Close + GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[1]) &&
|
||||
// under the midpoint
|
||||
input.Close <= window[1].Close + GetRealBody(window[1]) * 0.5m
|
||||
)
|
||||
value = -1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]) -
|
||||
GetCandleRange(CandleSettingType.Equal, window[_equalAveragePeriod + 1]);
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 1]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_equalPeriodTotal = 0m;
|
||||
_bodyLongPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Tristar candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - 3 consecutive doji days
|
||||
/// - the second doji is a star
|
||||
/// The meaning of "doji" is specified with SetCandleSettings
|
||||
/// The returned value is positive(+1) when bullish or negative(-1) when bearish
|
||||
/// </remarks>
|
||||
public class Tristar : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyDojiAveragePeriod;
|
||||
|
||||
private decimal _bodyDojiPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Tristar"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public Tristar(string name)
|
||||
: base(name, CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod + 2 + 1)
|
||||
{
|
||||
_bodyDojiAveragePeriod = CandleSettings.Get(CandleSettingType.BodyDoji).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Tristar"/> class.
|
||||
/// </summary>
|
||||
public Tristar()
|
||||
: this("TRISTAR")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyDojiAveragePeriod - 2 && Samples < Period - 2)
|
||||
{
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st: doji
|
||||
GetRealBody(window[2]) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, window[2]) &&
|
||||
// 2nd: doji
|
||||
GetRealBody(window[1]) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, window[2]) &&
|
||||
// 3rd: doji
|
||||
GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, window[2]))
|
||||
{
|
||||
value = 0;
|
||||
if (
|
||||
// 2nd gaps up
|
||||
GetRealBodyGapUp(window[1], window[2]) &&
|
||||
// 3rd is not higher than 2nd
|
||||
Math.Max(input.Open, input.Close) < Math.Max(window[1].Open, window[1].Close)
|
||||
)
|
||||
value = -1m;
|
||||
if (
|
||||
// 2nd gaps down
|
||||
GetRealBodyGapDown(window[1], window[2]) &&
|
||||
// 3rd is not lower than 2nd
|
||||
Math.Min(input.Open, input.Close) > Math.Min(window[1].Open, window[1].Close)
|
||||
)
|
||||
value = 1m;
|
||||
}
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, window[2]) -
|
||||
GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod + 2]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyDojiPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Two Crows candlestick pattern indicator
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long white candle
|
||||
/// - second candle: black real body
|
||||
/// - gap between the first and the second candle's real bodies
|
||||
/// - third candle: black candle that opens within the second real body and closes within the first real body
|
||||
/// The meaning of "long" is specified with SetCandleSettings
|
||||
/// The returned value is negative (-1): two crows is always bearish;
|
||||
/// The user should consider that two crows is significant when it appears in an uptrend, while this function
|
||||
/// does not consider the trend.
|
||||
/// </remarks>
|
||||
public class TwoCrows : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TwoCrows"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public TwoCrows(string name)
|
||||
: base(name, CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod + 2 + 1)
|
||||
{
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TwoCrows"/> class.
|
||||
/// </summary>
|
||||
public TwoCrows()
|
||||
: this("TWOCROWS")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyLongAveragePeriod - 2 && Samples < Period - 2)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input);
|
||||
}
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st: white
|
||||
GetCandleColor(window[2]) == CandleColor.White &&
|
||||
// long
|
||||
GetRealBody(window[2]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[2]) &&
|
||||
// 2nd: black
|
||||
GetCandleColor(window[1]) == CandleColor.Black &&
|
||||
// gapping up
|
||||
GetRealBodyGapUp(window[1], window[2]) &&
|
||||
// 3rd: black
|
||||
GetCandleColor(input) == CandleColor.Black &&
|
||||
// opening within 2nd rb
|
||||
input.Open < window[1].Open && input.Open > window[1].Close &&
|
||||
// closing within 1st rb
|
||||
input.Close > window[2].Open && input.Close < window[2].Close
|
||||
)
|
||||
value = -1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[2 + _bodyLongAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = 0m;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Unique Three River candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: long black candle
|
||||
/// - second candle: black harami candle with a lower low than the first candle's low
|
||||
/// - third candle: small white candle with open not lower than the second candle's low, better if its open and
|
||||
/// close are under the second candle's close
|
||||
/// The meaning of "short" and "long" is specified with SetCandleSettings
|
||||
/// The returned value is positive(+1): unique 3 river is always bullish and should appear in a downtrend
|
||||
/// to be significant, while this function does not consider the trend
|
||||
/// </remarks>
|
||||
public class UniqueThreeRiver : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
private decimal _bodyShortPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UniqueThreeRiver"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public UniqueThreeRiver(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod) + 2 + 1)
|
||||
{
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UniqueThreeRiver"/> class.
|
||||
/// </summary>
|
||||
public UniqueThreeRiver()
|
||||
: this("UNIQUETHREERIVER")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyLongAveragePeriod - 2 && Samples < Period - 2)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyShortAveragePeriod)
|
||||
{
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st: long
|
||||
GetRealBody(window[2]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[2]) &&
|
||||
// black
|
||||
GetCandleColor(window[2]) == CandleColor.Black &&
|
||||
// 2nd: black
|
||||
GetCandleColor(window[1]) == CandleColor.Black &&
|
||||
// harami
|
||||
window[1].Close > window[2].Close && window[1].Open <= window[2].Open &&
|
||||
// lower low
|
||||
window[1].Low < window[2].Low &&
|
||||
// 3rd: short
|
||||
GetRealBody(input) < GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) &&
|
||||
// white
|
||||
GetCandleColor(input) == CandleColor.White &&
|
||||
// open not lower
|
||||
input.Open > window[1].Low
|
||||
)
|
||||
value = 1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 2]);
|
||||
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = 0;
|
||||
_bodyShortPeriodTotal = 0;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Up/Down Gap Three Methods candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: white (black) candle
|
||||
/// - second candle: white(black) candle
|
||||
/// - upside(downside) gap between the first and the second real bodies
|
||||
/// - third candle: black(white) candle that opens within the second real body and closes within the first real body
|
||||
/// The returned value is positive(+1) when bullish or negative(-1) when bearish;
|
||||
/// The user should consider that up/downside gap 3 methods is significant when it appears in a trend, while this
|
||||
/// function does not consider it
|
||||
/// </remarks>
|
||||
public class UpDownGapThreeMethods : CandlestickPattern
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UpDownGapThreeMethods"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public UpDownGapThreeMethods(string name)
|
||||
: base(name, 2 + 1)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UpDownGapThreeMethods"/> class.
|
||||
/// </summary>
|
||||
public UpDownGapThreeMethods()
|
||||
: this("UPDOWNGAPTHREEMETHODS")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st and 2nd of same color
|
||||
GetCandleColor(window[2]) == GetCandleColor(window[1]) &&
|
||||
// 3rd opposite color
|
||||
(int)GetCandleColor(window[1]) == -(int)GetCandleColor(input) &&
|
||||
// 3rd opens within 2nd rb
|
||||
input.Open < Math.Max(window[1].Close, window[1].Open) &&
|
||||
input.Open > Math.Min(window[1].Close, window[1].Open) &&
|
||||
// 3rd closes within 1st rb
|
||||
input.Close < Math.Max(window[2].Close, window[2].Open) &&
|
||||
input.Close > Math.Min(window[2].Close, window[2].Open) &&
|
||||
((
|
||||
// when 1st is white
|
||||
GetCandleColor(window[2]) == CandleColor.White &&
|
||||
// upside gap
|
||||
GetRealBodyGapUp(window[1], window[2])
|
||||
) ||
|
||||
(
|
||||
// when 1st is black
|
||||
GetCandleColor(window[2]) == CandleColor.Black &&
|
||||
// downside gap
|
||||
GetRealBodyGapDown(window[1], window[2])
|
||||
)
|
||||
)
|
||||
)
|
||||
value = (int)GetCandleColor(window[2]);
|
||||
else
|
||||
value = 0;
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* 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.CandlestickPatterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Upside Gap Two Crows candlestick pattern
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Must have:
|
||||
/// - first candle: white candle, usually long
|
||||
/// - second candle: small black real body
|
||||
/// - gap between the first and the second candle's real bodies
|
||||
/// - third candle: black candle with a real body that engulfs the preceding candle
|
||||
/// and closes above the white candle's close
|
||||
/// The meaning of "short" and "long" is specified with SetCandleSettings
|
||||
/// The returned value is negative(-1): upside gap two crows is always bearish;
|
||||
/// The user should consider that an upside gap two crows is significant when it appears in an uptrend,
|
||||
/// while this function does not consider the trend
|
||||
/// </remarks>
|
||||
public class UpsideGapTwoCrows : CandlestickPattern
|
||||
{
|
||||
private readonly int _bodyLongAveragePeriod;
|
||||
private readonly int _bodyShortAveragePeriod;
|
||||
|
||||
private decimal _bodyLongPeriodTotal;
|
||||
private decimal _bodyShortPeriodTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UpsideGapTwoCrows"/> class using the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
public UpsideGapTwoCrows(string name)
|
||||
: base(name, Math.Max(CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod, CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod) + 2 + 1)
|
||||
{
|
||||
_bodyLongAveragePeriod = CandleSettings.Get(CandleSettingType.BodyLong).AveragePeriod;
|
||||
_bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UpsideGapTwoCrows"/> class.
|
||||
/// </summary>
|
||||
public UpsideGapTwoCrows()
|
||||
: this("UPSIDEGAPTWOCROWS")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Samples >= Period; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="window">The window of data held in this indicator</param>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
if (Samples >= Period - _bodyLongAveragePeriod - 2 && Samples < Period - 2)
|
||||
{
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input);
|
||||
}
|
||||
|
||||
if (Samples >= Period - _bodyShortAveragePeriod - 1 && Samples < Period - 1)
|
||||
{
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input);
|
||||
}
|
||||
|
||||
return 0m;
|
||||
}
|
||||
|
||||
decimal value;
|
||||
if (
|
||||
// 1st: white
|
||||
GetCandleColor(window[2]) == CandleColor.White &&
|
||||
// long
|
||||
GetRealBody(window[2]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[2]) &&
|
||||
// 2nd: black
|
||||
GetCandleColor(window[1]) == CandleColor.Black &&
|
||||
// short
|
||||
GetRealBody(window[1]) <= GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, window[1]) &&
|
||||
// gapping up
|
||||
GetRealBodyGapUp(window[1], window[2]) &&
|
||||
// 3rd: black
|
||||
GetCandleColor(input) == CandleColor.Black &&
|
||||
// 3rd: engulfing prior rb
|
||||
input.Open > window[1].Open && input.Close < window[1].Close &&
|
||||
// closing above 1st
|
||||
input.Close > window[2].Close
|
||||
)
|
||||
value = -1m;
|
||||
else
|
||||
value = 0m;
|
||||
|
||||
// add the current range and subtract the first range: this is done after the pattern recognition
|
||||
// when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
|
||||
|
||||
_bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]) -
|
||||
GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 2]);
|
||||
|
||||
_bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, window[1]) -
|
||||
GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod + 1]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_bodyLongPeriodTotal = 0;
|
||||
_bodyShortPeriodTotal = 0;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// The Chaikin Money Flow Index (CMF) is a volume-weighted average of accumulation and distribution over
|
||||
/// a specified period.
|
||||
///
|
||||
/// CMF = n-day Sum of [(((C - L) - (H - C)) / (H - L)) x Vol] / n-day Sum of Vol
|
||||
///
|
||||
/// Where:
|
||||
/// n = number of periods, typically 21
|
||||
/// H = high
|
||||
/// L = low
|
||||
/// C = close
|
||||
/// Vol = volume
|
||||
///
|
||||
/// https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/cmf
|
||||
/// </summary>
|
||||
public class ChaikinMoneyFlow : TradeBarIndicator, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds the point-wise flow-sum and volume terms.
|
||||
/// </summary>
|
||||
private readonly Sum _flowRatioSum;
|
||||
|
||||
private readonly Sum _volumeSum;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => _flowRatioSum.IsReady;
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_volumeSum.Reset();
|
||||
_flowRatioSum.Reset();
|
||||
base.Reset();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ChaikinMoneyFlow class
|
||||
/// </summary>
|
||||
/// <param name="name">A name for the indicator</param>
|
||||
/// <param name="period">The period over which to perform computation</param>
|
||||
public ChaikinMoneyFlow(string name, int period)
|
||||
: base(name)
|
||||
{
|
||||
WarmUpPeriod = period;
|
||||
_flowRatioSum = new Sum(period);
|
||||
_volumeSum = new Sum(period);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ChaikinMoneyFlow class
|
||||
/// </summary>
|
||||
/// <param name="period">The period over which to perform computation</param>
|
||||
public ChaikinMoneyFlow(int period)
|
||||
: this($"CMF({period})", period)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value for this indicator from the given state.
|
||||
/// </summary>
|
||||
/// <param name="input">The input value to this indicator on this time step</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(TradeBar input)
|
||||
{
|
||||
var denominator = (input.High - input.Low);
|
||||
var flowRatio = denominator > 0
|
||||
? input.Volume * (input.Close - input.Low - (input.High - input.Close)) / denominator
|
||||
: 0m;
|
||||
|
||||
_flowRatioSum.Update(input.EndTime, flowRatio);
|
||||
_volumeSum.Update(input.EndTime, input.Volume);
|
||||
|
||||
return !IsReady || _volumeSum == 0m ? 0m : _flowRatioSum / _volumeSum;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is an alias for AccumulationDistributionOscillator (also known as Chaikin Oscillator).
|
||||
/// </summary>
|
||||
public class ChaikinOscillator : AccumulationDistributionOscillator
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChaikinOscillator"/> class using the specified parameters
|
||||
/// </summary>
|
||||
/// <param name="fastPeriod">The fast moving average period</param>
|
||||
/// <param name="slowPeriod">The slow moving average period</param>
|
||||
public ChaikinOscillator(int fastPeriod, int slowPeriod)
|
||||
: base($"ChaikinOscillator({fastPeriod},{slowPeriod})", fastPeriod, slowPeriod)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChaikinOscillator"/> class with a custom name
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="fastPeriod">The fast moving average period</param>
|
||||
/// <param name="slowPeriod">The slow moving average period</param>
|
||||
public ChaikinOscillator(string name, int fastPeriod, int slowPeriod)
|
||||
: base(name, fastPeriod, slowPeriod)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// This indicator computes the short stop and lower stop values of the Chande Kroll Stop Indicator.
|
||||
/// It is used to determine the optimal placement of a stop-loss order.
|
||||
/// </summary>
|
||||
public class ChandeKrollStop : BarIndicator, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
private readonly AverageTrueRange _atr;
|
||||
private readonly decimal _atrMult;
|
||||
|
||||
private readonly Maximum _underlyingMaximum;
|
||||
private readonly Minimum _underlyingMinimum;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the short stop of ChandeKrollStop.
|
||||
/// </summary>
|
||||
public IndicatorBase<IndicatorDataPoint> ShortStop { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the long stop of ChandeKrollStop.
|
||||
/// </summary>
|
||||
public IndicatorBase<IndicatorDataPoint> LongStop { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => Samples >= WarmUpPeriod;
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChandeKrollStop"/> class.
|
||||
/// </summary>
|
||||
/// <param name="atrPeriod">The period over which to compute the average true range.</param>
|
||||
/// <param name="atrMult">The ATR multiplier to be used to compute stops distance.</param>
|
||||
/// <param name="period">The period over which to compute the max of high stop and min of low stop.</param>
|
||||
/// <param name="movingAverageType">The type of smoothing used to smooth the true range values</param>
|
||||
public ChandeKrollStop(int atrPeriod, decimal atrMult, int period, MovingAverageType movingAverageType = MovingAverageType.Wilders)
|
||||
: this($"CKS({atrPeriod},{atrMult},{period})", atrPeriod, atrMult, period, movingAverageType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChandeKrollStop"/> class.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="atrPeriod">The period over which to compute the average true range.</param>
|
||||
/// <param name="atrMult">The ATR multiplier to be used to compute stops distance.</param>
|
||||
/// <param name="period">The period over which to compute the max of high stop and min of low stop.</param>
|
||||
/// <param name="movingAverageType">The type of smoothing used to smooth the true range values</param>
|
||||
public ChandeKrollStop(string name, int atrPeriod, decimal atrMult, int period, MovingAverageType movingAverageType = MovingAverageType.Wilders)
|
||||
: base(name)
|
||||
{
|
||||
WarmUpPeriod = atrPeriod + period - 1;
|
||||
|
||||
_atr = new AverageTrueRange(atrPeriod, movingAverageType);
|
||||
_atrMult = atrMult;
|
||||
_underlyingMaximum = new Maximum(atrPeriod);
|
||||
_underlyingMinimum = new Minimum(atrPeriod);
|
||||
|
||||
LongStop = new Minimum(name + "_Long", period);
|
||||
ShortStop = new Maximum(name + "_Short", period);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>The input is returned unmodified.</returns>
|
||||
protected override decimal ComputeNextValue(IBaseDataBar input)
|
||||
{
|
||||
_atr.Update(input);
|
||||
|
||||
_underlyingMaximum.Update(input.EndTime, input.High);
|
||||
var highStop = _underlyingMaximum.Current.Value - _atr.Current.Value * _atrMult;
|
||||
|
||||
_underlyingMinimum.Update(input.EndTime, input.Low);
|
||||
var lowStop = _underlyingMinimum.Current.Value + _atr.Current.Value * _atrMult;
|
||||
|
||||
ShortStop.Update(input.EndTime, highStop);
|
||||
LongStop.Update(input.EndTime, lowStop);
|
||||
|
||||
return input.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
_atr.Reset();
|
||||
_underlyingMaximum.Reset();
|
||||
_underlyingMinimum.Reset();
|
||||
ShortStop.Reset();
|
||||
LongStop.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// This indicator computes the Chande Momentum Oscillator (CMO).
|
||||
/// CMO calculation is mostly identical to RSI.
|
||||
/// The only difference is in the last step of calculation:
|
||||
/// RSI = gain / (gain+loss)
|
||||
/// CMO = (gain-loss) / (gain+loss)
|
||||
/// </summary>
|
||||
public class ChandeMomentumOscillator : WindowIndicator<IndicatorDataPoint>, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
private decimal _prevValue;
|
||||
private decimal _prevGain;
|
||||
private decimal _prevLoss;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChandeMomentumOscillator"/> class using the specified period.
|
||||
/// </summary>
|
||||
/// <param name="period">The period of the indicator</param>
|
||||
public ChandeMomentumOscillator(int period)
|
||||
: this($"CMO({period})", period)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChandeMomentumOscillator"/> class using the specified name and period.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="period">The period of the indicator</param>
|
||||
public ChandeMomentumOscillator(string name, int period)
|
||||
: base(name, period)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => Samples > Period;
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod => 1 + Period;
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <param name="window">The window for the input history</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IReadOnlyWindow<IndicatorDataPoint> window, IndicatorDataPoint input)
|
||||
{
|
||||
if (Samples == 1)
|
||||
{
|
||||
_prevValue = input.Value;
|
||||
return 0m;
|
||||
}
|
||||
|
||||
var difference = input.Value - _prevValue;
|
||||
|
||||
_prevValue = input.Value;
|
||||
|
||||
if (Samples > Period + 1)
|
||||
{
|
||||
_prevLoss *= (Period - 1);
|
||||
_prevGain *= (Period - 1);
|
||||
}
|
||||
|
||||
if (difference < 0)
|
||||
_prevLoss -= difference;
|
||||
else
|
||||
_prevGain += difference;
|
||||
|
||||
if (!IsReady)
|
||||
return 0m;
|
||||
|
||||
_prevLoss /= Period;
|
||||
_prevGain /= Period;
|
||||
|
||||
var sum = _prevGain + _prevLoss;
|
||||
return sum != 0 ? 100m * ((_prevGain - _prevLoss) / sum) : 0m;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_prevValue = 0;
|
||||
_prevGain = 0;
|
||||
_prevLoss = 0;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* 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 System.Linq;
|
||||
using QuantConnect.Data.Market;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// The ChoppinessIndex indicator is an indicator designed to determine if the market is choppy (trading sideways)
|
||||
/// or not choppy (trading within a trend in either direction)
|
||||
/// </summary>
|
||||
public class ChoppinessIndex : BarIndicator, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
|
||||
private readonly int _period;
|
||||
private readonly RollingWindow<decimal> _highs;
|
||||
private readonly RollingWindow<decimal> _lows;
|
||||
private readonly IndicatorBase<IBaseDataBar> _trueRange;
|
||||
private readonly RollingWindow<decimal> _trueRangeHistory;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => Samples >= WarmUpPeriod;
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new ChoppinessIndex indicator using the specified period and moving average type
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="period">The period used for rolling windows for highs and lows</param>
|
||||
public ChoppinessIndex(string name, int period)
|
||||
: base(name)
|
||||
{
|
||||
_period = period;
|
||||
|
||||
_trueRange = new TrueRange();
|
||||
_trueRangeHistory = new RollingWindow<decimal>(period);
|
||||
|
||||
_highs = new RollingWindow<decimal>(period);
|
||||
_lows = new RollingWindow<decimal>(period);
|
||||
|
||||
WarmUpPeriod = period;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new ChoppinessIndex indicator using the specified period
|
||||
/// </summary>
|
||||
/// <param name="period">The period used for rolling windows for highs and lows</param>
|
||||
public ChoppinessIndex(int period)
|
||||
: this($"CHOP({period})", period)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IBaseDataBar input)
|
||||
{
|
||||
// compute the true range
|
||||
_trueRange.Update(input);
|
||||
|
||||
// store candle high and low
|
||||
_highs.Add(input.High);
|
||||
_lows.Add(input.Low);
|
||||
|
||||
// store true range in rolling window
|
||||
if (_trueRange.IsReady)
|
||||
{
|
||||
_trueRangeHistory.Add(_trueRange.Current.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
_trueRangeHistory.Add(input.High - input.Low);
|
||||
}
|
||||
|
||||
if (IsReady)
|
||||
{
|
||||
// calculate max high and min low
|
||||
var maxHigh = _highs.Max();
|
||||
var minLow = _lows.Min();
|
||||
|
||||
if (maxHigh != minLow)
|
||||
{
|
||||
// return CHOP index
|
||||
return (decimal)(100.0 * Math.Log10(((double) _trueRangeHistory.Sum()) / ((double) (maxHigh - minLow))) / Math.Log10(_period));
|
||||
}
|
||||
else
|
||||
{
|
||||
// situation of maxHigh = minLow represents a totally "choppy" or stagnant market,
|
||||
// with no price movement at all.
|
||||
// It's the extreme case of consolidation, hence the maximum value of 100 for the index
|
||||
return 100m;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// return 0 when indicator is not ready
|
||||
return 0m;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_trueRange.Reset();
|
||||
_trueRangeHistory.Reset();
|
||||
_highs.Reset();
|
||||
_lows.Reset();
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the traditional commodity channel index (CCI)
|
||||
///
|
||||
/// CCI = (Typical Price - 20-period SMA of TP) / (.015 * Mean Deviation)
|
||||
/// Typical Price (TP) = (High + Low + Close)/3
|
||||
/// Constant = 0.015
|
||||
///
|
||||
/// There are four steps to calculating the Mean Deviation, first, subtract
|
||||
/// the most recent 20-period average of the typical price from each period's
|
||||
/// typical price. Second, take the absolute values of these numbers. Third,
|
||||
/// sum the absolute values. Fourth, divide by the total number of periods (20).
|
||||
/// </summary>
|
||||
public class CommodityChannelIndex : BarIndicator, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// This constant is used to ensure that CCI values fall between +100 and -100, 70% to 80% of the time
|
||||
/// </summary>
|
||||
private const decimal K = 0.015m;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of moving average
|
||||
/// </summary>
|
||||
public MovingAverageType MovingAverageType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Keep track of the simple moving average of the typical price
|
||||
/// </summary>
|
||||
public IndicatorBase<IndicatorDataPoint> TypicalPriceAverage { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Keep track of the mean absolute deviation of the typical price
|
||||
/// </summary>
|
||||
public IndicatorBase<IndicatorDataPoint> TypicalPriceMeanDeviation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CommodityChannelIndex class
|
||||
/// </summary>
|
||||
/// <param name="period">The period of the standard deviation and moving average (middle band)</param>
|
||||
/// <param name="movingAverageType">The type of moving average to be used</param>
|
||||
public CommodityChannelIndex(int period, MovingAverageType movingAverageType = MovingAverageType.Simple)
|
||||
: this($"CCI({period})", period, movingAverageType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CommodityChannelIndex class
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="period">The period of the standard deviation and moving average (middle band)</param>
|
||||
/// <param name="movingAverageType">The type of moving average to be used</param>
|
||||
public CommodityChannelIndex(string name, int period, MovingAverageType movingAverageType = MovingAverageType.Simple)
|
||||
: base(name)
|
||||
{
|
||||
WarmUpPeriod = period;
|
||||
MovingAverageType = movingAverageType;
|
||||
TypicalPriceAverage = movingAverageType.AsIndicator(name + "_TypicalPriceAvg", period);
|
||||
TypicalPriceMeanDeviation = new MeanAbsoluteDeviation(name + "_TypicalPriceMAD", period);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => TypicalPriceAverage.IsReady && TypicalPriceMeanDeviation.IsReady;
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IBaseDataBar input)
|
||||
{
|
||||
var typicalPrice = (input.High + input.Low + input.Close) / 3.0m;
|
||||
|
||||
TypicalPriceAverage.Update(input.EndTime, typicalPrice);
|
||||
TypicalPriceMeanDeviation.Update(input.EndTime, typicalPrice);
|
||||
|
||||
// compare this to zero, since if the mean deviation is very small we can get
|
||||
// precision errors due to non-floating point math
|
||||
var weightedMeanDeviation = K * TypicalPriceMeanDeviation.Current.Value;
|
||||
if (weightedMeanDeviation == 0.0m)
|
||||
{
|
||||
return 0.0m;
|
||||
}
|
||||
|
||||
return (typicalPrice - TypicalPriceAverage.Current.Value).SafeDivision(weightedMeanDeviation, Current.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
TypicalPriceAverage.Reset();
|
||||
TypicalPriceMeanDeviation.Reset();
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* 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 Python.Runtime;
|
||||
using QuantConnect.Data;
|
||||
using QuantConnect.Data.Market;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// This indicator is capable of wiring up two separate indicators into a single indicator
|
||||
/// such that the output of each will be sent to a user specified function.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This type is initialized such that there is no need to call the Update function. This indicator
|
||||
/// will have its values automatically updated each time a new piece of data is received from both
|
||||
/// the left and right indicators.
|
||||
/// </remarks>
|
||||
public class CompositeIndicator : IndicatorBase<IndicatorDataPoint>
|
||||
{
|
||||
/// <summary>
|
||||
/// Delegate type used to compose the output of two indicators into a new value.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A simple example would be to compute the difference between the two indicators (such as with MACD)
|
||||
/// (left, right) => left - right
|
||||
/// </remarks>
|
||||
/// <param name="left">The left indicator</param>
|
||||
/// <param name="right">The right indicator</param>
|
||||
/// <returns>And indicator result representing the composition of the two indicators</returns>
|
||||
public delegate IndicatorResult IndicatorComposer(IndicatorBase left, IndicatorBase right);
|
||||
|
||||
/// <summary>function used to compose the individual indicators</summary>
|
||||
private readonly IndicatorComposer _composer;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the 'left' indicator for the delegate
|
||||
/// </summary>
|
||||
public IndicatorBase Left { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the 'right' indicator for the delegate
|
||||
/// </summary>
|
||||
public IndicatorBase Right { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady
|
||||
{
|
||||
get { return Left.IsReady && Right.IsReady; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
Left.Reset();
|
||||
Right.Reset();
|
||||
base.Reset();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new CompositeIndicator capable of taking the output from the left and right indicators
|
||||
/// and producing a new value via the composer delegate specified
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="left">The left indicator for the 'composer'</param>
|
||||
/// <param name="right">The right indicator for the 'composer'</param>
|
||||
/// <param name="composer">Function used to compose the left and right indicators</param>
|
||||
public CompositeIndicator(string name, IndicatorBase left, IndicatorBase right, IndicatorComposer composer)
|
||||
: base(name)
|
||||
{
|
||||
_composer = composer;
|
||||
Left = left;
|
||||
Right = right;
|
||||
Name ??= $"COMPOSE({Left.Name},{Right.Name})";
|
||||
ConfigureEventHandlers();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new CompositeIndicator capable of taking the output from the left and right indicators
|
||||
/// and producing a new value via the composer delegate specified
|
||||
/// </summary>
|
||||
/// <param name="left">The left indicator for the 'composer'</param>
|
||||
/// <param name="right">The right indicator for the 'composer'</param>
|
||||
/// <param name="composer">Function used to compose the left and right indicators</param>
|
||||
public CompositeIndicator(IndicatorBase left, IndicatorBase right, IndicatorComposer composer)
|
||||
: this(null, left, right, composer)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="CompositeIndicator"/> using two indicators
|
||||
/// and a custom function.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the composite indicator.</param>
|
||||
/// <param name="left">The first indicator in the composition.</param>
|
||||
/// <param name="right">The second indicator in the composition.</param>
|
||||
/// <param name="handler">A Python function that processes the indicator values.</param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Thrown if the provided left or right indicator is not a valid QuantConnect Indicator object.
|
||||
/// </exception>
|
||||
public CompositeIndicator(string name, PyObject left, PyObject right, PyObject handler)
|
||||
: this(
|
||||
name,
|
||||
(IndicatorBase)left.GetIndicatorAsManagedObject(),
|
||||
(IndicatorBase)right.GetIndicatorAsManagedObject(),
|
||||
new IndicatorComposer(handler.SafeAs<Func<IndicatorBase, IndicatorBase, IndicatorResult>>())
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="CompositeIndicator"/> using two indicators
|
||||
/// and a custom function.
|
||||
/// </summary>
|
||||
/// <param name="left">The first indicator in the composition.</param>
|
||||
/// <param name="right">The second indicator in the composition.</param>
|
||||
/// <param name="handler">A Python function that processes the indicator values.</param>
|
||||
public CompositeIndicator(PyObject left, PyObject right, PyObject handler)
|
||||
: this(null, left, right, handler)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// and returns an instance of the <see cref="IndicatorResult"/> class
|
||||
/// </summary>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>An IndicatorResult object including the status of the indicator</returns>
|
||||
protected override IndicatorResult ValidateAndComputeNextValue(IndicatorDataPoint input)
|
||||
{
|
||||
return _composer.Invoke(Left, Right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Since this class overrides <see cref="ValidateAndComputeNextValue"/>, this method is a no-op
|
||||
/// </remarks>
|
||||
/// <param name="_">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IndicatorDataPoint _)
|
||||
{
|
||||
// this should never actually be invoked
|
||||
return _composer.Invoke(Left, Right).Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures the event handlers for Left.Updated and Right.Updated to update this instance when
|
||||
/// they both have new data.
|
||||
/// </summary>
|
||||
private void ConfigureEventHandlers()
|
||||
{
|
||||
// if either of these are constants then there's no reason
|
||||
bool leftIsConstant = Left.GetType().IsSubclassOfGeneric(typeof(ConstantIndicator<>));
|
||||
bool rightIsConstant = Right.GetType().IsSubclassOfGeneric(typeof(ConstantIndicator<>));
|
||||
|
||||
// wire up the Updated events such that when we get a new piece of data from both left and right
|
||||
// we'll call update on this indicator. It's important to note that the CompositeIndicator only uses
|
||||
// the timestamp that gets passed into the Update function, his compuation is soley a function
|
||||
// of the left and right indicator via '_composer'
|
||||
|
||||
IndicatorDataPoint newLeftData = null;
|
||||
IndicatorDataPoint newRightData = null;
|
||||
Left.Updated += (sender, updated) =>
|
||||
{
|
||||
newLeftData = updated;
|
||||
|
||||
// if we have left and right data (or if right is a constant) then we need to update
|
||||
if (newRightData != null || rightIsConstant)
|
||||
{
|
||||
var dataPoint = new IndicatorDataPoint { Time = MaxTime(updated) };
|
||||
Update(dataPoint);
|
||||
// reset these to null after each update
|
||||
newLeftData = null;
|
||||
newRightData = null;
|
||||
}
|
||||
};
|
||||
|
||||
Right.Updated += (sender, updated) =>
|
||||
{
|
||||
newRightData = updated;
|
||||
|
||||
// if we have left and right data (or if left is a constant) then we need to update
|
||||
if (newLeftData != null || leftIsConstant)
|
||||
{
|
||||
var dataPoint = new IndicatorDataPoint { Time = MaxTime(updated) };
|
||||
Update(dataPoint);
|
||||
// reset these to null after each update
|
||||
newLeftData = null;
|
||||
newRightData = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private DateTime MaxTime(IndicatorDataPoint updated)
|
||||
{
|
||||
return new DateTime(Math.Max(updated.Time.Ticks, Math.Max(Right.Current.Time.Ticks, Left.Current.Time.Ticks)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* 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 System.Linq;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the Connors Relative Strength Index (CRSI), a combination of
|
||||
/// the traditional Relative Strength Index (RSI), a Streak RSI (SRSI), and
|
||||
/// Percent Rank.
|
||||
/// This index is designed to provide a more robust measure of market strength
|
||||
/// by combining momentum, streak behavior, and price change.
|
||||
/// </summary>
|
||||
public class ConnorsRelativeStrengthIndex : Indicator, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Computes the traditional Relative Strength Index (RSI).
|
||||
/// </summary>
|
||||
private readonly RelativeStrengthIndex _rsi;
|
||||
|
||||
/// <summary>
|
||||
/// Computes the RSI based on consecutive price streaks (SRSI).
|
||||
/// </summary>
|
||||
private readonly RelativeStrengthIndex _srsi;
|
||||
|
||||
/// <summary>
|
||||
/// Stores recent price change ratios for calculating the Percent Rank.
|
||||
/// </summary>
|
||||
private readonly RollingWindow<decimal> _priceChangeRatios;
|
||||
|
||||
/// <summary>
|
||||
/// Tracks the current trend streak (positive or negative) of price movements.
|
||||
/// </summary>
|
||||
private int _trendStreak;
|
||||
|
||||
/// <summary>
|
||||
/// Stores the previous input data point.
|
||||
/// </summary>
|
||||
private IndicatorDataPoint _previousInput;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConnorsRelativeStrengthIndex"/> class.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the indicator instance.</param>
|
||||
/// <param name="rsiPeriod">The period for the RSI calculation.</param>
|
||||
/// <param name="rsiPeriodStreak">The period for the Streak RSI calculation.</param>
|
||||
/// <param name="lookBackPeriod">The period for calculating the Percent Rank.</param>
|
||||
public ConnorsRelativeStrengthIndex(string name, int rsiPeriod, int rsiPeriodStreak, int lookBackPeriod) : base(name)
|
||||
{
|
||||
_rsi = new RelativeStrengthIndex(rsiPeriod);
|
||||
_srsi = new RelativeStrengthIndex(rsiPeriodStreak);
|
||||
_priceChangeRatios = new RollingWindow<decimal>(lookBackPeriod);
|
||||
_trendStreak = 0;
|
||||
WarmUpPeriod = Math.Max(lookBackPeriod, Math.Max(_rsi.WarmUpPeriod, _srsi.WarmUpPeriod));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ConnorsRelativeStrengthIndex with specified RSI, Streak RSI,
|
||||
/// and lookBack periods, using a default name format based on the provided parameters.
|
||||
/// </summary>
|
||||
public ConnorsRelativeStrengthIndex(int rsiPeriod, int rsiPeriodStreak, int rocPeriod)
|
||||
: this($"CRSI({rsiPeriod},{rsiPeriodStreak},{rocPeriod})", rsiPeriod, rsiPeriodStreak, rocPeriod)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the indicator is ready for use.
|
||||
/// The indicator is ready when all its components (RSI, SRSI, and PriceChangeRatios) are ready.
|
||||
/// </summary>
|
||||
public override bool IsReady => _rsi.IsReady && _srsi.IsReady && _priceChangeRatios.IsReady;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the warm-up period required for the indicator to be ready.
|
||||
/// This is the maximum period of all components (RSI, SRSI, and PriceChangeRatios).
|
||||
/// </summary>
|
||||
public int WarmUpPeriod { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value for the Connors Relative Strength Index (CRSI) based on the latest input data point.
|
||||
/// The CRSI is calculated as the average of the traditional RSI, Streak RSI, and Percent Rank.
|
||||
/// </summary>
|
||||
/// <param name="input">The current input data point (typically the price data for the current period).</param>
|
||||
/// <returns>The computed CRSI value, which combines the RSI, Streak RSI, and Percent Rank into a single value.
|
||||
/// Returns zero if the indicator is not yet ready.</returns>
|
||||
protected override decimal ComputeNextValue(IndicatorDataPoint input)
|
||||
{
|
||||
// RSI
|
||||
_rsi.Update(input);
|
||||
|
||||
ComputeTrendStreak(input);
|
||||
_srsi.Update(new IndicatorDataPoint(input.EndTime, _trendStreak));
|
||||
|
||||
if (_previousInput == null || _previousInput.Value == 0)
|
||||
{
|
||||
_previousInput = input;
|
||||
_priceChangeRatios.Add(0m);
|
||||
return decimal.Zero;
|
||||
}
|
||||
|
||||
// PercentRank
|
||||
var relativeMagnitude = 0m;
|
||||
var priceChangeRatio = (input.Value - _previousInput.Value) / _previousInput.Value;
|
||||
|
||||
// Calculate PercentRank using only the previous values (exclude the current priceChangeRatio)
|
||||
if (_priceChangeRatios.IsReady)
|
||||
{
|
||||
relativeMagnitude = 100m * _priceChangeRatios.Count(x => x < priceChangeRatio) / _priceChangeRatios.Count;
|
||||
}
|
||||
|
||||
// Add the current priceChangeRatio to the rolling window for future calculations
|
||||
_priceChangeRatios.Add(priceChangeRatio);
|
||||
|
||||
_previousInput = input;
|
||||
|
||||
// CRSI
|
||||
if (IsReady)
|
||||
{
|
||||
// Calculate the CRSI only if all components are ready
|
||||
return (_rsi.Current.Value + _srsi.Current.Value + relativeMagnitude) / 3;
|
||||
}
|
||||
|
||||
// If not ready, return 0
|
||||
return decimal.Zero;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the trend streak based on the price change direction between the current and previous input.
|
||||
/// Resets the streak if the direction changes, otherwise increments or decrements it.
|
||||
/// </summary>
|
||||
/// <param name="input">The current input data point with price information.</param>
|
||||
private void ComputeTrendStreak(IndicatorDataPoint input)
|
||||
{
|
||||
if (_previousInput == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var change = input.Value - _previousInput.Value;
|
||||
// If the price changes direction (up to down or down to up), reset the trend streak
|
||||
if ((_trendStreak > 0 && change < 0) || (_trendStreak < 0 && change > 0))
|
||||
{
|
||||
_trendStreak = 0;
|
||||
}
|
||||
// Increment or decrement the trend streak based on price change direction
|
||||
if (change > 0)
|
||||
{
|
||||
_trendStreak++;
|
||||
}
|
||||
else if (change < 0)
|
||||
{
|
||||
_trendStreak--;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the indicator to its initial state. This clears all internal data and resets
|
||||
/// the RSI, Streak RSI, and PriceChangeRatios, as well as the trend streak counter.
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_rsi.Reset();
|
||||
_srsi.Reset();
|
||||
_priceChangeRatios.Reset();
|
||||
_trendStreak = 0;
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// An indicator that will always return the same value.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of input this indicator takes</typeparam>
|
||||
public sealed class ConstantIndicator<T> : IndicatorBase<T>
|
||||
where T : IBaseData
|
||||
{
|
||||
private readonly decimal _value;
|
||||
|
||||
/// <summary>
|
||||
/// Gets true since the ConstantIndicator is always ready to return the same value
|
||||
/// </summary>
|
||||
public override bool IsReady => true;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new ConstantIndicator that will always return the specified value
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="value">The constant value to be returned</param>
|
||||
public ConstantIndicator(string name, decimal value)
|
||||
: base(name)
|
||||
{
|
||||
_value = value;
|
||||
|
||||
// set this immediately so it always has the .Value property correctly set,
|
||||
// the time will be updated anytime this indicators Update method gets called.
|
||||
Current = new IndicatorDataPoint(DateTime.MinValue, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(T input)
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
|
||||
// re-initialize the current value, constant should ALWAYS return this value
|
||||
Current = new IndicatorDataPoint(DateTime.MinValue, _value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// A momentum indicator developed by Edwin “Sedge” Coppock in October 1965.
|
||||
/// The goal of this indicator is to identify long-term buying opportunities in the S&P500 and Dow Industrials.
|
||||
/// Source: http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:coppock_curve
|
||||
/// </summary>
|
||||
public class CoppockCurve : IndicatorBase<IndicatorDataPoint>, IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
private readonly RateOfChangePercent _longRoc;
|
||||
private readonly LinearWeightedMovingAverage _lwma;
|
||||
private readonly RateOfChangePercent _shortRoc;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => _lwma.IsReady;
|
||||
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
public int WarmUpPeriod { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CoppockCurve" /> indicator with its default values.
|
||||
/// </summary>
|
||||
public CoppockCurve()
|
||||
: this(11, 14, 10)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CoppockCurve"/> indicator
|
||||
/// </summary>
|
||||
/// <param name="shortRocPeriod">The period for the short ROC</param>
|
||||
/// <param name="longRocPeriod">The period for the long ROC</param>
|
||||
/// <param name="lwmaPeriod">The period for the LWMA</param>
|
||||
public CoppockCurve(int shortRocPeriod, int longRocPeriod, int lwmaPeriod)
|
||||
: this($"CC({shortRocPeriod},{longRocPeriod},{lwmaPeriod})", shortRocPeriod, longRocPeriod, lwmaPeriod)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CoppockCurve" /> indicator
|
||||
/// </summary>
|
||||
/// <param name="name">A name for the indicator</param>
|
||||
/// <param name="shortRocPeriod">The period for the short ROC</param>
|
||||
/// <param name="longRocPeriod">The period for the long ROC</param>
|
||||
/// <param name="lwmaPeriod">The period for the LWMA</param>
|
||||
public CoppockCurve(string name, int shortRocPeriod, int longRocPeriod, int lwmaPeriod)
|
||||
: base(name)
|
||||
{
|
||||
_shortRoc = new RateOfChangePercent(shortRocPeriod);
|
||||
_longRoc = new RateOfChangePercent(longRocPeriod);
|
||||
_lwma = new LinearWeightedMovingAverage(lwmaPeriod);
|
||||
|
||||
// Define our warmup
|
||||
// LWMA does not get updated until ROC are warmed up and ready, so add our periods.
|
||||
// Then minus 1 because on the same point ROC is ready LWMA will receive its first point.
|
||||
WarmUpPeriod = Math.Max(_shortRoc.WarmUpPeriod, _longRoc.WarmUpPeriod) + lwmaPeriod - 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
_shortRoc.Reset();
|
||||
_longRoc.Reset();
|
||||
_lwma.Reset();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the next value of this indicator from the given state
|
||||
/// </summary>
|
||||
/// <param name="input">The input given to the indicator</param>
|
||||
/// <returns>A new value for this indicator</returns>
|
||||
protected override decimal ComputeNextValue(IndicatorDataPoint input)
|
||||
{
|
||||
_shortRoc.Update(input);
|
||||
_longRoc.Update(input);
|
||||
if (!_longRoc.IsReady || !_shortRoc.IsReady)
|
||||
{
|
||||
return decimal.Zero;
|
||||
}
|
||||
_lwma.Update(input.EndTime, _shortRoc.Current.Value + _longRoc.Current.Value);
|
||||
return _lwma.Current.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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 System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using QuantConnect.Data.Market;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// The Correlation Indicator is a valuable tool in technical analysis, designed to quantify the degree of
|
||||
/// relationship between the price movements of a target security (e.g., a stock or ETF) and a reference
|
||||
/// market index. It measures how closely the target’s price changes are aligned with the fluctuations of
|
||||
/// the index over a specific period of time, providing insights into the target’s susceptibility to market
|
||||
/// movements.
|
||||
/// A positive correlation indicates that the target tends to move in the same direction as the market index,
|
||||
/// while a negative correlation suggests an inverse relationship. A correlation close to 0 implies a weak or
|
||||
/// no linear relationship.
|
||||
/// Commonly, the SPX index is employed as the benchmark for the overall market when calculating correlation,
|
||||
/// ensuring a consistent and reliable reference point. This helps traders and investors make informed decisions
|
||||
/// regarding the risk and behavior of the target security in relation to market trends.
|
||||
///
|
||||
/// The indicator only updates when both assets have a price for a time step. When a bar is missing for one of the assets,
|
||||
/// the indicator value fills forward to improve the accuracy of the indicator.
|
||||
/// </summary>
|
||||
public class Correlation : DualSymbolIndicator<IBaseDataBar>
|
||||
{
|
||||
/// <summary>
|
||||
/// Correlation type
|
||||
/// </summary>
|
||||
private readonly CorrelationType _correlationType;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when the indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => TargetDataPoints.IsReady && ReferenceDataPoints.IsReady;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Correlation indicator with the specified name, target, reference,
|
||||
/// and period values
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="targetSymbol">The target symbol of this indicator</param>
|
||||
/// <param name="period">The period of this indicator</param>
|
||||
/// <param name="referenceSymbol">The reference symbol of this indicator</param>
|
||||
/// <param name="correlationType">Correlation type</param>
|
||||
public Correlation(string name, Symbol targetSymbol, Symbol referenceSymbol, int period, CorrelationType correlationType = CorrelationType.Pearson)
|
||||
: base(name, targetSymbol, referenceSymbol, period)
|
||||
{
|
||||
// Assert the period is greater than two, otherwise the correlation can not be computed
|
||||
if (period < 2)
|
||||
{
|
||||
throw new ArgumentException($"Period parameter for Correlation indicator must be greater than 2 but was {period}");
|
||||
}
|
||||
_correlationType = correlationType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Correlation indicator with the specified target, reference,
|
||||
/// and period values
|
||||
/// </summary>
|
||||
/// <param name="targetSymbol">The target symbol of this indicator</param>
|
||||
/// <param name="period">The period of this indicator</param>
|
||||
/// <param name="referenceSymbol">The reference symbol of this indicator</param>
|
||||
/// <param name="correlationType">Correlation type</param>
|
||||
public Correlation(Symbol targetSymbol, Symbol referenceSymbol, int period, CorrelationType correlationType = CorrelationType.Pearson)
|
||||
: this($"Correlation({period})", targetSymbol, referenceSymbol, period, correlationType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the correlation value usuing symbols values
|
||||
/// correlation values assing into _correlation property
|
||||
/// </summary>
|
||||
protected override decimal ComputeIndicator()
|
||||
{
|
||||
var targetDataPoints = TargetDataPoints.Select(x => (double)x.Close);
|
||||
var referenceDataPoints = ReferenceDataPoints.Select(x => (double)x.Close);
|
||||
var newCorrelation = 0d;
|
||||
if (_correlationType == CorrelationType.Pearson)
|
||||
{
|
||||
newCorrelation = MathNet.Numerics.Statistics.Correlation.Pearson(targetDataPoints, referenceDataPoints);
|
||||
}
|
||||
if (_correlationType == CorrelationType.Spearman)
|
||||
{
|
||||
newCorrelation = MathNet.Numerics.Statistics.Correlation.Spearman(targetDataPoints, referenceDataPoints);
|
||||
}
|
||||
if (newCorrelation.IsNaNOrZero())
|
||||
{
|
||||
newCorrelation = 0;
|
||||
}
|
||||
return Extensions.SafeDecimalCast(newCorrelation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the different types of Correlation
|
||||
/// </summary>
|
||||
public enum CorrelationType
|
||||
{
|
||||
/// <summary>
|
||||
/// Pearson Correlation (Product-Moment Correlation):
|
||||
/// Measures the linear relationship between two datasets. The coefficient ranges from -1 to 1.
|
||||
/// A value of 1 indicates a perfect positive linear relationship, -1 indicates a perfect
|
||||
/// negative linear relationship, and 0 indicates no linear relationship.
|
||||
/// It assumes that both datasets are normally distributed and the relationship is linear.
|
||||
/// It is sensitive to outliers which can affect the correlation significantly.
|
||||
/// </summary>
|
||||
Pearson,
|
||||
/// <summary>
|
||||
/// Spearman Correlation (Rank Correlation):
|
||||
/// Measures the strength and direction of the monotonic relationship between two datasets.
|
||||
/// Instead of calculating the coefficient using raw data, it uses the rank of the data points.
|
||||
/// This method is non-parametric and does not assume a normal distribution of the datasets.
|
||||
/// It's useful when the data is not normally distributed or when the relationship is not linear.
|
||||
/// Spearman's correlation is less sensitive to outliers than Pearson's correlation.
|
||||
/// The coefficient also ranges from -1 to 1 with similar interpretations for the values,
|
||||
/// but it reflects monotonic relationships rather than only linear ones.
|
||||
/// </summary>
|
||||
Spearman
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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;
|
||||
using MathNet.Numerics.Statistics;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// This indicator computes the Covariance of two assets using the given Look-Back period.
|
||||
/// The Covariance of two assets is a measure of their co-movement.
|
||||
/// </summary>
|
||||
public class Covariance : DualSymbolIndicator<IBaseDataBar>
|
||||
{
|
||||
/// <summary>
|
||||
/// RollingWindow of returns of the target symbol in the given period
|
||||
/// </summary>
|
||||
private readonly RollingWindow<double> _targetReturns;
|
||||
|
||||
/// <summary>
|
||||
/// RollingWindow of returns of the reference symbol in the given period
|
||||
/// </summary>
|
||||
private readonly RollingWindow<double> _referenceReturns;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when the indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
public override bool IsReady => _targetReturns.IsReady && _referenceReturns.IsReady;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Covariance indicator with the specified name, target, reference,
|
||||
/// and period values
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="targetSymbol">The target symbol of this indicator</param>
|
||||
/// <param name="period">The period of this indicator</param>
|
||||
/// <param name="referenceSymbol">The reference symbol of this indicator</param>
|
||||
public Covariance(string name, Symbol targetSymbol, Symbol referenceSymbol, int period)
|
||||
: base(name, targetSymbol, referenceSymbol, 2)
|
||||
{
|
||||
// Assert the period is greater than two, otherwise the covariance can not be computed
|
||||
if (period < 2)
|
||||
{
|
||||
throw new ArgumentException($"Period parameter for Covariance indicator must be greater than 2 but was {period}.");
|
||||
}
|
||||
|
||||
_targetReturns = new RollingWindow<double>(period);
|
||||
_referenceReturns = new RollingWindow<double>(period);
|
||||
WarmUpPeriod += (period - 2) + 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Covariance indicator with the specified target, reference,
|
||||
/// and period values
|
||||
/// </summary>
|
||||
/// <param name="targetSymbol">The target symbol of this indicator</param>
|
||||
/// <param name="period">The period of this indicator</param>
|
||||
/// <param name="referenceSymbol">The reference symbol of this indicator</param>
|
||||
public Covariance(Symbol targetSymbol, Symbol referenceSymbol, int period)
|
||||
: this($"COV({period})", targetSymbol, referenceSymbol, period)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Covariance indicator with the specified name, period, target and
|
||||
/// reference values
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this indicator</param>
|
||||
/// <param name="period">The period of this indicator</param>
|
||||
/// <param name="targetSymbol">The target symbol of this indicator</param>
|
||||
/// <param name="referenceSymbol">The reference symbol of this indicator</param>
|
||||
/// <remarks>Constructor overload for backward compatibility.</remarks>
|
||||
public Covariance(string name, int period, Symbol targetSymbol, Symbol referenceSymbol)
|
||||
: this(name, targetSymbol, referenceSymbol, period)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the returns with the new given data point and the last given data point
|
||||
/// </summary>
|
||||
/// <param name="rollingWindow">The collection of data points from which we want
|
||||
/// to compute the return</param>
|
||||
/// <returns>The returns with the new given data point</returns>
|
||||
private static double GetNewReturn(IReadOnlyWindow<IBaseDataBar> rollingWindow)
|
||||
{
|
||||
return (double)(rollingWindow[0].Close.SafeDivision(rollingWindow[1].Close) - 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the covariance value of the target in relation with the reference
|
||||
/// using the target and reference returns
|
||||
/// </summary>
|
||||
protected override decimal ComputeIndicator()
|
||||
{
|
||||
if (TargetDataPoints.IsReady)
|
||||
{
|
||||
_targetReturns.Add(GetNewReturn(TargetDataPoints));
|
||||
}
|
||||
|
||||
if (ReferenceDataPoints.IsReady)
|
||||
{
|
||||
_referenceReturns.Add(GetNewReturn(ReferenceDataPoints));
|
||||
}
|
||||
|
||||
var covarianceComputed = _targetReturns.Covariance(_referenceReturns);
|
||||
|
||||
// Avoid division with NaN or by zero
|
||||
return (decimal)(!covarianceComputed.IsNaNOrZero() ? covarianceComputed : 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
_targetReturns.Reset();
|
||||
_referenceReturns.Reset();
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user