#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
// The symbol index on which the drawing tool will be drawn.
private int _symbolIndex;
// 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="">The symbol index on which the drawing tool will be drawn.</param>
/// <param name="standardDeviations" type="Double" default="2">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 icon for the drawing tool.
DrawingSetIcon("StdDev Channels");
// 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 int[] {
22 ,81, 238, 255
}, C_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;
// 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
}
}