Lean  $LEAN_TAG$
ThreeLineStrike.cs
1 /*
2  * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
3  * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14 */
15 
16 using System;
18 
20 {
21  /// <summary>
22  /// Three Line Strike candlestick pattern
23  /// </summary>
24  /// <remarks>
25  /// Must have:
26  /// - three white soldiers (three black crows): three white (black) candlesticks with consecutively higher (lower) closes,
27  /// each opening within or near the previous real body
28  /// - fourth candle: black (white) candle that opens above (below) prior candle's close and closes below (above)
29  /// the first candle's open
30  /// The meaning of "near" is specified with SetCandleSettings;
31  /// The returned value is positive (+1) when bullish or negative (-1) when bearish;
32  /// The user should consider that 3-line strike is significant when it appears in a trend in the same direction of
33  /// the first three candles, while this function does not consider it
34  /// </remarks>
36  {
37  private readonly int _nearAveragePeriod;
38 
39  private decimal[] _nearPeriodTotal = new decimal[4];
40 
41  /// <summary>
42  /// Initializes a new instance of the <see cref="ThreeLineStrike"/> class using the specified name.
43  /// </summary>
44  /// <param name="name">The name of this indicator</param>
45  public ThreeLineStrike(string name)
46  : base(name, CandleSettings.Get(CandleSettingType.Near).AveragePeriod + 3 + 1)
47  {
48  _nearAveragePeriod = CandleSettings.Get(CandleSettingType.Near).AveragePeriod;
49  }
50 
51  /// <summary>
52  /// Initializes a new instance of the <see cref="ThreeLineStrike"/> class.
53  /// </summary>
54  public ThreeLineStrike()
55  : this("THREELINESTRIKE")
56  {
57  }
58 
59  /// <summary>
60  /// Gets a flag indicating when this indicator is ready and fully initialized
61  /// </summary>
62  public override bool IsReady
63  {
64  get { return Samples >= Period; }
65  }
66 
67  /// <summary>
68  /// Computes the next value of this indicator from the given state
69  /// </summary>
70  /// <param name="window">The window of data held in this indicator</param>
71  /// <param name="input">The input given to the indicator</param>
72  /// <returns>A new value for this indicator</returns>
73  protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
74  {
75  if (!IsReady)
76  {
77  if (Samples >= Period - _nearAveragePeriod)
78  {
79  _nearPeriodTotal[3] += GetCandleRange(CandleSettingType.Near, window[3]);
80  _nearPeriodTotal[2] += GetCandleRange(CandleSettingType.Near, window[2]);
81  }
82 
83  return 0m;
84  }
85 
86  decimal value;
87  if (
88  // three with same color
89  GetCandleColor(window[3]) == GetCandleColor(window[2]) &&
90  GetCandleColor(window[2]) == GetCandleColor(window[1]) &&
91  // 4th opposite color
92  (int)GetCandleColor(input) == -(int)GetCandleColor(window[1]) &&
93  // 2nd opens within/near 1st rb
94  window[2].Open >= Math.Min(window[3].Open, window[3].Close) - GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal[3], window[3]) &&
95  window[2].Open <= Math.Max(window[3].Open, window[3].Close) + GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal[3], window[3]) &&
96  // 3rd opens within/near 2nd rb
97  window[1].Open >= Math.Min(window[2].Open, window[2].Close) - GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal[2], window[2]) &&
98  window[1].Open <= Math.Max(window[2].Open, window[2].Close) + GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal[2], window[2]) &&
99  (
100  (
101  // if three white
102  GetCandleColor(window[1]) == CandleColor.White &&
103  // consecutive higher closes
104  window[1].Close > window[2].Close && window[2].Close > window[3].Close &&
105  // 4th opens above prior close
106  input.Open > window[1].Close &&
107  // 4th closes below 1st open
108  input.Close < window[3].Open
109  ) ||
110  (
111  // if three black
112  GetCandleColor(window[1]) == CandleColor.Black &&
113  // consecutive lower closes
114  window[1].Close < window[2].Close && window[2].Close < window[3].Close &&
115  // 4th opens below prior close
116  input.Open < window[1].Close &&
117  // 4th closes above 1st open
118  input.Close > window[3].Open
119  )
120  )
121  )
122  value = (int)GetCandleColor(window[1]);
123  else
124  value = 0m;
125 
126  // add the current range and subtract the first range: this is done after the pattern recognition
127  // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
128 
129  for (var i = 3; i >= 2; i--)
130  {
131  _nearPeriodTotal[i] += GetCandleRange(CandleSettingType.Near, window[i]) -
132  GetCandleRange(CandleSettingType.Near, window[i + _nearAveragePeriod]);
133  }
134 
135  return value;
136  }
137 
138  /// <summary>
139  /// Resets this indicator to its initial state
140  /// </summary>
141  public override void Reset()
142  {
143  _nearPeriodTotal = new decimal[4];
144  base.Reset();
145  }
146  }
147 }