#region Namespaces using System; #endregion namespace ScriptCode { /// <summary> /// Drawing scripts are used for drawing a visual object. /// /// This script can be used in several ways: /// (1) It can be used on a chart by clicking the chart in order to set the drawing's anchor points. /// (2) It can be used from another script by having that script set the drawing's anchor points. /// </summary> public partial class MyDrawing : DrawingScriptBase // NEVER CHANGE THE CLASS NAME { #region Variables // Use for the symbol index on which the drawing tool will be drawn. private int _symbolIndex; // Use for the number of standard deviations distance from the linear regression line where to draw the channels. private double _standardDeviations; #endregion #region OnInitialize /// <summary> /// This function is called when a new drawing instance is created. /// </summary> /// -------------------------------------------------------------------------------------------------- /// THIS FUNCTION MUST ACCEPT THE SYMBOL INDEX PARAMETER AND SHOULD NOT ACCEPT ANY OTHER PARAMETERS. /// -------------------------------------------------------------------------------------------------- /// <param name="symbolIndex" type="Symbol" default="">Use for the symbol index on which the drawing tool will be drawn.</param> /// <param name="standardDeviations" type="Double" default="2">Use for the number of standard deviations distance from the linear regression line where to draw the channels.</param> public void OnInitialize( int symbolIndex, double standardDeviations) { // Initialize the drawing for the symbol to accept 2 anchor points. DrawingInitialize(symbolIndex, 2); // Set the symbol index. _symbolIndex = symbolIndex; // Set the standard deviations. _standardDeviations = standardDeviations; } #endregion #region OnChartSetup /// <summary> /// This function is used for setting up the drawing on the chart and registering its pens (see the DrawingRegisterPen function). /// </summary> public override void OnChartSetup() { // Register the pen with which to draw the channels. DrawingRegisterPen("Line Pen", new byte[] { 5, 110, 180, 255 }, AT_DashStyle.SOLID, 2); } #endregion #region OnDraw /// <summary> /// This function is used to draw the drawing by setting all of its anchor points, lines and labels on a virtual canvas. /// The canvas x-axis values are the date and time of the underlying symbol bars and its y-axis values are the symbol prices. /// /// The location of the drawing on the canvas is specified by the drawing anchor points, which can either be specified by /// clicking on a chart or from another script (see the Drawing functions). /// </summary> public override void OnDraw() { // Get the X value of anchor point 0. int x1 = DrawingAnchorPointBarShift(0); // Get the Y value of anchor point 0. double y1 = DrawingAnchorPointValue(0); // Get the X value of anchor point 1. int x2 = DrawingAnchorPointBarShift(1); // Get the Y value of anchor point 1. double y2 = DrawingAnchorPointValue(1); if (x1 < 0 || x2 < 0) return ; // Get the Double of bars in the drawing range. int length = Math.Abs(x1 - x2); // Get the minimum X. int minX = Math.Min(x1, x2); // Use for summing the X values. double sumX = 0; // Use for summing the Y values. double sumY = 0; // Use for summing the X times Y values. double sumXY = 0; // Use for summing the X powers 2 values. double sumXPow2 = 0; double b = 0; double a = 0; if (x1 > x2) { // Iterate over the values while calculating the linear regression parameters. for (int i = 0; i <= length - 1; i++) { sumX += x2 + i; sumY += DataClose(minX + i); sumXY += (x2 + i) * DataClose(minX + i); sumXPow2 += Math.Pow(x2 + i, 2); } } else { // Iterate over the values while calculating the linear regression parameters. for (int i = 0; i <= length - 1; i++) { sumX += x1 + i; sumY += DataClose(minX + i); sumXY += (x1 + i) * DataClose(minX + i); sumXPow2 += Math.Pow(x1 + i, 2); } } // Calculate the linear regression line intersect. b = (length * sumXY - (sumX * sumY)) / (length * sumXPow2 - (sumX * sumX)); // Calculate the linear regression slope. a = (sumY - b * sumX) / length; // Calculate the Y value of anchor point 1. y2 = a + b * x2; DrawingSetAnchorPoint(1, x2, y2); // Draw the middle line. DrawingSetLine("Line Pen", x1, y1, "", x2, y2, ""); // Calculate the mean Y value double meanY = sumY / length; // Use for the standard deviation. double SD = 0; for (int i = 0; i <= length - 1; i++) { SD += Math.Pow(meanY - DataClose(minX + i), 2); } // Calculate the standard deviation. SD = _standardDeviations * Math.Sqrt(SD / length); // Draw the upper channel. DrawingSetLine("Line Pen", x1, y1 + SD, "", x2, y2 + SD, ""); // Draw the lower channel. DrawingSetLine("Line Pen", x1, y1 - SD, "", x2, y2 - SD, ""); } #endregion } }

The Algorithmic Trading Software for Hedge Funds and Quants