Вот код-< /p>
Код: Выделить всё
#region Using declarations
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.Gui.Tools;
#endregion
// Namespace for the custom indicator
namespace MyCustomIndicator
{
///
/// Donchian Channels with Offset. This version uses the highest high and the lowest low over a period of time, with an optional offset.
///
public class DonchianChannelsWithOffset : Indicator
{
private MAX max; // To calculate the highest high
private MIN min; // To calculate the lowest low
[Range(-100, 100), NinjaScriptProperty]
[Display(Name="Offset", Order=1, GroupName="Parameters")]
public int Offset { get; set; } // Offset for shifting the channels
protected override void OnStateChange()
{
// State.SetDefaults handles the initialization of the indicator's default settings.
if (State == State.SetDefaults)
{
Description = "Donchian Channels with Offset";
Name = "Donchian Channels with Offset";
IsOverlay = true;
IsSuspendedWhileInactive = true;
Period = 20; // Default lookback period of 20
AddPlot(Brushes.Goldenrod, "Mean"); // Midline plot
AddPlot(Brushes.DodgerBlue, "Upper"); // Upper plot
AddPlot(Brushes.DodgerBlue, "Lower"); // Lower plot
}
else if (State == State.DataLoaded)
{
// Once data is loaded, initialize the MAX and MIN indicators
max = MAX(High, Period);
min = MIN(Low, Period);
}
}
protected override void OnBarUpdate()
{
// Ensure enough bars have loaded
if (CurrentBar < Period)
return;
// Calculate the upper, lower, and midline
double upperVal = max[0];
double lowerVal = min[0];
double midlineVal = (upperVal + lowerVal) / 2;
// Apply the offset, shifting the values by 'Offset' bars
if (Offset != 0)
{
int shiftedBar = Math.Max(0, CurrentBar - Offset);
Values[1][0] = max[shiftedBar]; // Upper channel
Values[2][0] = min[shiftedBar]; // Lower channel
Values[0][0] = (Values[1][0] + Values[2][0]) / 2; // Mean (midline)
}
else
{
Values[1][0] = upperVal; // Upper channel
Values[2][0] = lowerVal; // Lower channel
Values[0][0] = midlineVal; // Mean (midline)
}
}
#region Properties
[Browsable(false)]
[XmlIgnore()]
public Series Upper
{
get { return Values[1]; }
}
[Browsable(false)]
[XmlIgnore()]
public Series Lower
{
get { return Values[2]; }
}
[Browsable(false)]
[XmlIgnore()]
public Series Mean
{
get { return Values[0]; }
}
[Range(1, int.MaxValue), NinjaScriptProperty]
[Display(Name="Period", Order=2, GroupName="Parameters")]
public int Period { get; set; }
#endregion
}
}
#region NinjaScript generated code. Neither change nor remove.
namespace MyCustomIndicator
{
public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
{
private DonchianChannelsWithOffset[] cacheDonchianChannelsWithOffset;
public DonchianChannelsWithOffset DonchianChannelsWithOffset(int period, int offset)
{
return DonchianChannelsWithOffset(Input, period, offset);
}
public DonchianChannelsWithOffset DonchianChannelsWithOffset(ISeries input, int period, int offset)
{
if (cacheDonchianChannelsWithOffset != null)
for (int idx = 0; idx < cacheDonchianChannelsWithOffset.Length; idx++)
if (cacheDonchianChannelsWithOffset[idx] != null &&
cacheDonchianChannelsWithOffset[idx].Period == period && cacheDonchianChannelsWithOffset[idx].Offset
== offset && cacheDonchianChannelsWithOffset[idx].EqualsInput(input))
return cacheDonchianChannelsWithOffset[idx];
return CacheIndicator(new DonchianChannelsWithOffset() { Period =
period, Offset = offset }, input, ref cacheDonchianChannelsWithOffset);
}
}
}
#endregion
Подробнее здесь: https://stackoverflow.com/questions/789 ... ipt-editor