Step3. Implement constructor |
The next step is implementation of constructor. At the beginning you implement your own constructor for indicator with all necessary parameters.
Depending on inherited class, you should specify a number of parameters to implement the constructor from base class:
Indicator type | Constructor |
---|---|
simple | #ctor(Int32, PortfolioAbsenceStrategy, Int32, Int32, SimpleAggregationType, InputValidationStrategy) |
bar | #ctor(Int32, PortfolioAbsenceStrategy, Int32, Int32, InputValidationStrategy) |
tick | #ctor(Int32, PortfolioAbsenceStrategy, Int32, Int32, TickAggregationType, InputValidationStrategy) |
two sets | #ctor(Int32, PortfolioAbsenceStrategy, Int32, Int32, Int32, SimpleAggregationType, InputValidationStrategy) |
1updatePointPeriodicity
1updateTimePeriodicity
1absenceStrategy
1seriesCount
1valuesPerSerie
1aggregationMethod
1validationStrategy
Lets consider an example of simple indicator:
1public class MyMovingAverage : BaseSimplePortfolioIndicator<double> 2{ 3 private int period; 4 5 public MyMovingAverage(TimeSpan updateTimePeriodicity, int seriesCount, int valuesPerSerie, int period) 6 : base(updateTimePeriodicity, PortfolioAbsenceStrategy.AbsenceSkip, seriesCount, valuesPerSerie, 7 SimpleAggregationType.AggregateAverage, InputValidationStrategy.ValidateAll) 8 { 9 this.period = period; 10 } 11}
Note 1: If you set validationStrategy parameter to ValidateAll value, data supplier wrappers in base classes validate incoming data and skip calls with double.NaN or double.Infinity values. But for many markets you cannot get valid volume values, so this flag is necessary to set for skipping volume value validation. The rule is very simple: if you use volume value in calculations set this flag, else do not.
Note 2: As you can see our technical indicators library supports time based indicators, with TimeSpan used as period. If you want to create time based indicator please call EnsureDateTime() function in constructor of time period use case (it forces indicator user to use Add method with DateTime).
1public class MyMovingAverage : BaseSimplePortfolioIndicator<double> 2{ 3 private int period; 4 5 public MyMovingAverage(TimeSpan updateTimePeriodicity, int seriesCount, int valuesPerSerie, TimeSpan period) 6 : base(updateTimePeriodicity, PortfolioAbsenceStrategy.AbsenceSkip, seriesCount, valuesPerSerie, 7 SimpleAggregationType.AggregateAverage, InputValidationStrategy.ValidateAll) 8 { 9 EnsureDateTime(); 10 this.period = period; 11 } 12}
Note 3: As you can see our technical indicators library provides Stable flag for all indicators, which indicates whether indicator values are already stable or more data is needed. If you need this flag for your indicator, you can use one of the following options:
Specify unstableValuesCount. Stable flag will be set after unstableValuesCount values will be calculated by indicator.
1public class MyMovingAverage : BaseSimplePortfolioIndicator<double> 2{ 3 private int period; 4 5 public MyMovingAverage(TimeSpan updateTimePeriodicity, int seriesCount, int valuesPerSerie, int period) 6 : base(updateTimePeriodicity, PortfolioAbsenceStrategy.AbsenceSkip, seriesCount, valuesPerSerie, 7 SimpleAggregationType.AggregateAverage, InputValidationStrategy.ValidateAll) 8 { 9 this.period = period; 10 unstableValuesCount = period; 11 } 12}
Specify unstablePeriod. Stable flag will be set after unstablePeriod delay from first calculated value.
1public class MyMovingAverage : BaseSimplePortfolioIndicator<double> 2{ 3 private int period; 4 5 public MyMovingAverage(TimeSpan updateTimePeriodicity, int seriesCount, int valuesPerSerie, TimeSpan period) 6 : base(updateTimePeriodicity, PortfolioAbsenceStrategy.AbsenceSkip, seriesCount, valuesPerSerie, 7 SimpleAggregationType.AggregateAverage, InputValidationStrategy.ValidateAll) 8 { 9 this.period = period; 10 unstableValuesCount = period; 11 } 12}
Use customStabilityFlag. Just unset it in constructor and set when you think that value is stable.
1public class MyMovingAverage : BaseSimplePortfolioIndicator<double> 2{ 3 private int period; 4 5 public MyMovingAverage(TimeSpan updateTimePeriodicity, int seriesCount, int valuesPerSerie, int period) 6 : base(updateTimePeriodicity, PortfolioAbsenceStrategy.AbsenceSkip, seriesCount, valuesPerSerie, 7 SimpleAggregationType.AggregateAverage, InputValidationStrategy.ValidateAll) 8 { 9 this.period = period; 10 customStabilityFlag = false; 11 } 12}