using System; using System.Collections.Generic; using System.Text; using System.Drawing; using RightEdge.Indicators; using RightEdge.Common; /* This indicator is taken from IndicatorBaseIndicator in the RE Samples folder. Orginally it implemented an * On Balance Volume indicator. Daniel indicates SeriesCalculatorBaseWithValues would also have been a good * choice. * "RcntLowClose" returns lowest close within the interval. * These methods supply the elements of a series (with this indicator name) that is built by RE code * by calling the methods in this code. The methods are: * - Constructor * - Full series generator (not called in real time; performance item for simulation (note from Bill).) * - Next item generator (main working method.) * - Reset (Not needed for this strategy. There are no class variables to be reset. * The lbBars utility series is reset in the full method, though that could * have been done by Reset(). ) * See also RcntHighClose. * 1/24/2008 **/ namespace phgIndicators { // Use the Indicator Attribute to provide information such as the // name and description of your indicator. If you do not include // this attribute, your indicator will not show up in the indicator // list. [Indicator(System.Drawing.KnownColor.Blue, // Pick a color. Author = "Peter Gum", // Author's name. CompanyName = "phgyh@Yahoo.com", // Author's email address. Description = "Most recent low close.", // Brief title. GroupName = "User", // Indicator category. HelpText = "Plots the rolling lowest close for an interval. The interval (periods) is the only parameter.", // The Id attribute needs to be set to a unique code that will identify // your indicator. A GUID is a good candidate. // Visual Studio can generate these (MS GuidGen tool), or see www.guidgen.com Id = "{5056d9d1-e4d3-44c1-b5f1-796d3e2b8947}", // Generated at www.guidgen.com Name = "RcntLowClose", // Name of the indicator. DefaultDrawingPane="Price Pane")] // Plot pane default. // Indicators must be marked Serializable in order to be used in // trading systems. [Serializable] // Use the SeriesInputAttribute to specify how many inputs your indicator uses. // This is how RE figures out how to call the methods with the right parameters. [SeriesInputAttribute("Input", 1, Value = BarElement.Close)] // Class public class RcntLowClose : IndicatorBase // Class specification. { private int periods = 20; // Default periods in interval. private List lbBars = null; // Series kept to allow look-back for //- low in preceding interval. // Constructor /// Constructs an indicator instance. /// Attributes lets RE figure out with what parameters to call the method. [ConstructorArgument("Periods", ConstructorArgumentType.Integer, "20", 1)] public RcntLowClose(int Periods) // Constructor method. { this.periods = Periods; // Interval supplied to the constructor. lbBars = new List(); // New list of bars needed for look-back. } // Full series /// Calculates the values for an entire series. /// This is NOT called for live systems. /// This is available as a performance enhancement for simulation where the full series can be /// - generated at once. public override List CalcSeriesValues(IList bars) // Full method. { lbBars = new List(); // Reset of the lbBars series. return base.CalcSeriesValues(bars); // Base will regenerate the entire series by calling //- CalcNextValue for each bar. // The above return just does the following (note from Bill) //foreach (BarData bar in bars) { CalcNextValue(bar); } /* Comment out the base.return and provide your own implementation **ONLY** if you have an * optimal implementation that is BETTER than calling CalcNextValue for each bar. */ } // Next item in series /// Calculates the next value in the indicator series. public override double CalcNextValue(BarData bar) // Next method. { lbBars.Add(bar); // Reconstruction of symbol bars. Enables look-back. int lbBarIndex = lbBars.Count - 1; if (lbBarIndex < periods-1) // Still in leading bars. { return double.NaN; } else // lbBarIndex >= periods-1 // Step through bars in recent interval. { double low = bar.Close; for (int i = 1; i <= periods - 1; i += 1) { if( low > lbBars[lbBarIndex - i].Close ) low = lbBars[lbBarIndex - i].Close; } return low; } } // Next Value // Reset Not used in this case. //protected override void Reset() //{ //} } // Class } // Namespace