Lean  $LEAN_TAG$
ShootingStar.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 
17 using System;
19 
21 {
22  /// <summary>
23  /// Shooting Star candlestick pattern
24  /// </summary>
25  /// <remarks>
26  /// Must have:
27  /// - small real body
28  /// - long upper shadow
29  /// - no, or very short, lower shadow
30  /// - gap up from prior real body
31  /// The meaning of "short", "very short" and "long" is specified with SetCandleSettings;
32  /// The returned value is negative(-1): shooting star is always bearish;
33  /// The user should consider that a shooting star must appear in an uptrend, while this function does not consider it
34  /// </remarks>
36  {
37  private readonly int _bodyShortAveragePeriod;
38  private readonly int _shadowLongAveragePeriod;
39  private readonly int _shadowVeryShortAveragePeriod;
40 
41  private decimal _bodyShortPeriodTotal;
42  private decimal _shadowLongPeriodTotal;
43  private decimal _shadowVeryShortPeriodTotal;
44 
45  /// <summary>
46  /// Initializes a new instance of the <see cref="ShootingStar"/> class using the specified name.
47  /// </summary>
48  /// <param name="name">The name of this indicator</param>
49  public ShootingStar(string name)
50  : base(name, Math.Max(Math.Max(CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod, CandleSettings.Get(CandleSettingType.ShadowLong).AveragePeriod),
51  CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod) + 1 + 1)
52  {
53  _bodyShortAveragePeriod = CandleSettings.Get(CandleSettingType.BodyShort).AveragePeriod;
54  _shadowLongAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowLong).AveragePeriod;
55  _shadowVeryShortAveragePeriod = CandleSettings.Get(CandleSettingType.ShadowVeryShort).AveragePeriod;
56  }
57 
58  /// <summary>
59  /// Initializes a new instance of the <see cref="ShootingStar"/> class.
60  /// </summary>
61  public ShootingStar()
62  : this("SHOOTINGSTAR")
63  {
64  }
65 
66  /// <summary>
67  /// Gets a flag indicating when this indicator is ready and fully initialized
68  /// </summary>
69  public override bool IsReady
70  {
71  get { return Samples >= Period; }
72  }
73 
74  /// <summary>
75  /// Computes the next value of this indicator from the given state
76  /// </summary>
77  /// <param name="window">The window of data held in this indicator</param>
78  /// <param name="input">The input given to the indicator</param>
79  /// <returns>A new value for this indicator</returns>
80  protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input)
81  {
82  if (!IsReady)
83  {
84  if (Samples >= Period - _bodyShortAveragePeriod)
85  {
86  _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input);
87  }
88 
89  if (Samples >= Period - _shadowLongAveragePeriod)
90  {
91  _shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input);
92  }
93 
94  if (Samples >= Period - _shadowVeryShortAveragePeriod)
95  {
96  _shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input);
97  }
98 
99  return 0m;
100  }
101 
102  decimal value;
103  if (
104  // small rb
105  GetRealBody(input) < GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) &&
106  // long upper shadow
107  GetUpperShadow(input) > GetCandleAverage(CandleSettingType.ShadowLong, _shadowLongPeriodTotal, input) &&
108  // very short lower shadow
109  GetLowerShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input) &&
110  // gap up
111  GetRealBodyGapUp(input, window[1])
112  )
113  value = -1m;
114  else
115  value = 0m;
116 
117  // add the current range and subtract the first range: this is done after the pattern recognition
118  // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle)
119 
120  _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) -
121  GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]);
122 
123  _shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input) -
124  GetCandleRange(CandleSettingType.ShadowLong, window[_shadowLongAveragePeriod]);
125 
126  _shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input) -
127  GetCandleRange(CandleSettingType.ShadowVeryShort, window[_shadowVeryShortAveragePeriod]);
128 
129  return value;
130  }
131 
132  /// <summary>
133  /// Resets this indicator to its initial state
134  /// </summary>
135  public override void Reset()
136  {
137  _bodyShortPeriodTotal = 0;
138  _shadowLongPeriodTotal = 0;
139  _shadowVeryShortPeriodTotal = 0;
140  base.Reset();
141  }
142  }
143 }