GoSPvC Posted August 23, 2012 Report Share Posted August 23, 2012 Folgende Lösung habe ich wieder mangels Möglichkeiten von NT finden müssen. Und zwar war es bei TS Terminal möglich, einfach per negativem Displacement DrawLine() in die Zukunft zeichnen zu lassen. DrawLine[-5](...) zeichnete somit 5 Bars in die Zukunft des Charts NT erlaubt leider kein negatives "barsAgo", sondern es muß umständlich umgangen werden; aber es geht. Auf BigMikeTrading[Punkt]com habe ich einen Ichimoku gefunden, der die Cloud in der Zukunft zeichnet. Hieraus habe ich das simple Plotten einer Linie in die ChartZukunft extrahiert. Ich bitte um Kommentare/Verbesserungen usw., falls nötig. Hier der Beispielcode: // Originalfile Ichimoku.cs - Developed by Tarantino - Found at bigmiketrading.com #region Using declarations using System; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Xml.Serialization; using System.Collections; using System.Collections.Generic; using NinjaTrader.Cbi; using NinjaTrader.Data; using NinjaTrader.Gui.Chart; using NinjaTrader.Indicator; using NinjaTrader.Strategy; #endregion Using declarations namespace NinjaTrader.Indicator { public class CB_PlotToFuture : Indicator { #region Parameters and Variables // Parameters: private int period = 10; // Variables: private DataSeries futurePlot = null; #endregion Parameters and Variables protected override void Initialize() { Add(new Plot(new Pen(Color.FromKnownColor(KnownColor.Orange), 1), PlotStyle.Line, "Plot0")); Plots[0].Pen.DashStyle = DashStyle.Solid; futurePlot = new DataSeries(this, MaximumBarsLookBack.Infinite); AutoScale = true; ScaleJustification = ScaleJustification.Right; Overlay = true; BarsRequired = period; PriceTypeSupported = false; PlotsConfigurable = false; CalculateOnBarClose = false; } protected override void OnBarUpdate() { #region First Bars in Chart if (Bars == null) { return; } //if (Data.BarsType.GetInstance(Bars.Period.Id).IsIntraday) { return; } //if (Bars.Period.Id == PeriodType.Day || Bars.Period.Id == PeriodType.Week || Bars.Period.Id == PeriodType.Month || Bars.Period.Id == PeriodType.Year) { return; } if (CurrentBar <= period) { return; } #endregion First Bars in Chart Plot0.Set(SMA(period)[0]); for (int i = 0; i <= period; i++) { futurePlot.Set(i, SMA(period)[0]); } futurePlot.Set(period - 1, Convert.ToDouble(null)); } #region Properties [browsable(false)] [XmlIgnore()] public DataSeries Plot0 { get { return Values[0]; } } [browsable(false)] [XmlIgnore] public DataSeries FuturePlot { get { return futurePlot; } } [Description("")] [GridCategory("Parameters")] [DisplayName("Parameter Nr. 0")] public int Period { get { return period; } set { period = Math.Max(1, value); } } [browsable(false)] public new int Displacement { get { return base.Displacement; } set { base.Displacement = 0; } } #endregion #region Override Plot() public override void Plot(Graphics graphics, Rectangle bounds, double min, double max) { //if ("check for no futurePlot") //{ // base.Plot(graphics, bounds, min, max); // We call base Plot() method to paint defined Plots // return; // if check for no futurePlot == true to avoid unnecessary calculations //} List<Point> points = new List<Point>(); int lastX = -1; double lastValue = -1; Pen pen = new Pen(Color.FromKnownColor(KnownColor.Red)); for (int idx = FirstBarIndexPainted - period; idx <= LastBarIndexPainted; idx++) { if (idx < 0 || idx >= BarsArray[0].Count || (!ChartControl.ShowBarsRequired && idx < BarsRequired)) { continue; } bool futurePlotHasValue = futurePlot.IsValidPlot(idx) && futurePlot.Get(idx) > 0; if (!futurePlotHasValue) { continue; } double value = futurePlot.Get(idx); int x = ChartControl.GetXByBarIdx(BarsArray[0], idx + period); if (lastX >= 0) { int y0 = ChartControl.GetYByValue(this, lastValue); int y1 = ChartControl.GetYByValue(this, value); if (points.Count == 0) // We have a start painting { points.Clear(); points.Add(new Point(lastX, y0)); points.Add(new Point(x, y1)); } else { int pos = points.Count; points.Insert(pos, new Point(x, y1)); } } // Save as previous Point lastX = x; lastValue = value; } if (points.Count > 0 && pen != null) { SmoothingMode oldSmoothingMode = graphics.SmoothingMode; graphics.SmoothingMode = SmoothingMode.AntiAlias; graphics.DrawLines(pen, points.ToArray()); graphics.SmoothingMode = oldSmoothingMode; points.Clear(); } pen.Dispose(); // Paint defined Plots base.Plot(graphics, bounds, min, max); } #endregion Override Plot() } } #region NinjaScript generated code namespace NinjaTrader.Indicator { public partial class Indicator : IndicatorBase { private CB_PlotToFuture[] cacheCB_PlotToFuture = null; // <-- Anpassen private static CB_PlotToFuture checkCB_PlotToFuture = new CB_PlotToFuture(); // <-- Anpassen public CB_PlotToFuture CB_PlotToFuture(int period) // <-- Anpassen - alle Parameter; kommagetrennt; keine lokalen Variablen { return CB_PlotToFuture(Input, period); // <-- Anpassen - alle Parameter; kommagetrennt; keine lokalen Variablen } public CB_PlotToFuture CB_PlotToFuture(Data.IDataSeries input, int period) // <-- Anpassen - alle Parameter; kommagetrennt; keine lokalen Variablen { if (cacheCB_PlotToFuture != null) // <-- Anpassen for (int idx = 0; idx < cacheCB_PlotToFuture.Length; idx++) // <-- Anpassen if (cacheCB_PlotToFuture[idx].Period == period /*&&*/ && cacheCB_PlotToFuture[idx].EqualsInput(input)) // <-- Anpassen - alle Parameter; &&-getrennt; keine lokalen Variablen return cacheCB_PlotToFuture[idx]; // <-- Anpassen lock (checkCB_PlotToFuture) // <-- Anpassen { checkCB_PlotToFuture.Period = period; // <-- Anpassen period = checkCB_PlotToFuture.Period; // <-- Anpassen // Alle Parameter; keine lokalen Variablen if (cacheCB_PlotToFuture != null) // <-- Anpassen for (int idx = 0; idx < cacheCB_PlotToFuture.Length; idx++) // <-- Anpassen if (cacheCB_PlotToFuture[idx].Period == period /*&&*/ && cacheCB_PlotToFuture[idx].EqualsInput(input)) // <-- Anpassen - alle Parameter; &&-getrennt; keine lokalen Variablen return cacheCB_PlotToFuture[idx]; // <-- Anpassen CB_PlotToFuture indicator = new CB_PlotToFuture(); // <-- Anpassen indicator.BarsRequired = BarsRequired; indicator.CalculateOnBarClose = CalculateOnBarClose; #if NT7 indicator.ForceMaximumBarsLookBack256 = ForceMaximumBarsLookBack256; indicator.MaximumBarsLookBack = MaximumBarsLookBack; #endif indicator.Input = input; indicator.Period = period; // <-- Anpassen // Alle Parameter; keine lokalen Variablen Indicators.Add(indicator); indicator.SetUp(); CB_PlotToFuture[] tmp = new CB_PlotToFuture[cacheCB_PlotToFuture == null ? 1 : cacheCB_PlotToFuture.Length + 1]; // <-- Anpassen if (cacheCB_PlotToFuture != null) // <-- Anpassen cacheCB_PlotToFuture.CopyTo(tmp, 0); // <-- Anpassen tmp[tmp.Length - 1] = indicator; cacheCB_PlotToFuture = tmp; // <-- Anpassen return indicator; } } } } namespace NinjaTrader.MarketAnalyzer { public partial class Column : ColumnBase { [Gui.Design.WizardCondition("Indicator")] public Indicator.CB_PlotToFuture CB_PlotToFuture(int period) // <-- Anpassen - alle Parameter; kopmmagetrennt; keine lokalen Variablen { return _indicator.CB_PlotToFuture(Input, period); // <-- Anpassen - alle Parameter; kommagetrennt; keine lokalen Variablen } public Indicator.CB_PlotToFuture CB_PlotToFuture(Data.IDataSeries input, int period) // <-- Anpassen - alle Parameter; kopmmagetrennt; keine lokalen Variablen { return _indicator.CB_PlotToFuture(input, period); // <-- Anpassen - alle Parameter; kopmmagetrennt; keine lokalen Variablen } } } namespace NinjaTrader.Strategy { public partial class Strategy : StrategyBase { [Gui.Design.WizardCondition("Indicator")] public Indicator.CB_PlotToFuture CB_PlotToFuture(int period) // <-- Anpassen - alle Parameter; kopmmagetrennt; keine lokalen Variablen { return _indicator.CB_PlotToFuture(Input, period); // <-- Anpassen - alle Parameter; kopmmagetrennt; keine lokalen Variablen } public Indicator.CB_PlotToFuture CB_PlotToFuture(Data.IDataSeries input, int period) // <-- Anpassen - alle Parameter; kopmmagetrennt; keine lokalen Variablen { if (InInitialize && input == null) throw new ArgumentException("You only can access an indicator with the default input/bar series from within the 'Initialize()' method"); return _indicator.CB_PlotToFuture(input, period);// <-- Anpassen - alle Parameter; kopmmagetrennt; keine lokalen Variablen } } } #endregion NinjaScript generated code 2 Quote Link to comment Share on other sites More sharing options...
GoSPvC Posted August 24, 2012 Author Report Share Posted August 24, 2012 Nach etwas herumtesten mit dem Code habe ich noch ein paar Bugs gefunden: futurePlot.Set(period - 1, Convert.ToDouble(null)); bringt nicht das von mir gewünschte Ergebnis. Eigentlich soll diese DataSeries nur in der ChartZukunft gezeichnet werden. Doch setzt man den Plot0 transparent, dann sieht man, dass der futurePlot "unter" dem Plot0 gezeichnet wird. Folgendes schafft hier Abhilfe: Plot0.Set(SMA(period)[0]); for (int i = 0; i <= period + 1; i++) { double value = i < period + 1 ? SMA(period)[0] : Convert.ToDouble(null); futurePlot.Set(i, value); } Als zweites habe ich die Beispieldaten des SMA() durch welche vom Momentum() ausgetauscht. Dabei ist mir aufgefallen, dass der futurePlot mit negativen Werten Probleme macht. Sobald ich (oder jemand anders??) eine Lösung hat, stell ich sie hier rein. 1 Quote Link to comment Share on other sites More sharing options...
GoSPvC Posted August 24, 2012 Author Report Share Posted August 24, 2012 Ich hab's gefunden:Folgende Zeilen unten in der override Plot()-Methode entscheidet: bool futurePlotHasValue = futurePlot.IsValidPlot(idx) && futurePlot.Get(idx) > 0; if (!futurePlotHasValue) { continue; } Hier werden nur gesetzte und >0 Werte zum plotten freigegeben.Nicht zu zeichnende Werte werden aber jetzt mit Convert.ToDouble(null) beschrieben. Also sollte obige Zeile einfach mit: bool futurePlotHasValue = futurePlot.IsValidPlot(idx) && futurePlot.Get(idx) != Convert.ToDouble(null); if (!futurePlotHasValue) { continue; } ersetzt werden, dann geht's auch mit negativen Werten. Eine Frage an jemanden, der sich auskennt: Ist eine 0 mit Datentyp double GLEICH einer null, die ToDouble convertiert ist?? Quote Link to comment Share on other sites More sharing options...
Eddy Posted August 24, 2012 Report Share Posted August 24, 2012 Eine Frage an jemanden, der sich auskennt: Ist eine 0 mit Datentyp double GLEICH einer null, die ToDouble convertiert ist?? double n = 0; if (n == Convert.ToDouble(null)) n = 1; else n = 2; Der Vergleich liefert n = 1. Quote Link to comment Share on other sites More sharing options...
GoSPvC Posted August 24, 2012 Author Report Share Posted August 24, 2012 Das heißt, durch setzen einer convertierten null wird der Wert nicht Invalid, sondern nur einfach 0.Da muss ich mir also nochmal was anderes überlegen,Danke Eddy Quote Link to comment Share on other sites More sharing options...
GoSPvC Posted August 24, 2012 Author Report Share Posted August 24, 2012 Jetzt aber: Mit futurePlot.Reset(barsAgo) kann einem Wert, der nicht mehr gezeichnet werden soll, Invalid gesetzt werden: Plot0.Set(SMA(period)[0]); for (int i = 0; i <= period; i++) { futurePlot.Set(i, SMA(period)[0]); } futurePlot.Reset(period + 1); Dadurch muß in der override Plot() nichtmehr auf >0 oder !=null getestet werden, sondern nur noch auf Valid: if (!futurePlot.IsValidPlot(idx)) { continue; } That's it !! Danke nochmal an Eddy...Hier jetzt nochmal der komplette (funktionierende) Code: #region Using declarations using System; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Xml.Serialization; using System.Collections; using System.Collections.Generic; using NinjaTrader.Cbi; using NinjaTrader.Data; using NinjaTrader.Gui.Chart; using NinjaTrader.Indicator; using NinjaTrader.Strategy; #endregion Using declarations namespace NinjaTrader.Indicator { public class CB_PlotToFuture : Indicator { #region Parameters and Variables // Parameters: private int period = 10; // Variables: private DataSeries futurePlot = null; #endregion Parameters and Variables protected override void Initialize() { Add(new Plot(new Pen(Color.FromKnownColor(KnownColor.Transparent), 1), PlotStyle.Line, "Plot0")); Plots[0].Pen.DashStyle = DashStyle.Solid; futurePlot = new DataSeries(this, MaximumBarsLookBack.Infinite); AutoScale = true; ScaleJustification = ScaleJustification.Right; Overlay = true; BarsRequired = period; PriceTypeSupported = false; PlotsConfigurable = false; CalculateOnBarClose = false; } protected override void OnBarUpdate() { #region First Bars in Chart if (Bars == null) { return; } //if (Data.BarsType.GetInstance(Bars.Period.Id).IsIntraday) { return; } //if (Bars.Period.Id == PeriodType.Day || Bars.Period.Id == PeriodType.Week || Bars.Period.Id == PeriodType.Month || Bars.Period.Id == PeriodType.Year) { return; } if (CurrentBar <= period) { return; } #endregion First Bars in Chart Plot0.Set(SMA(period)[0]); for (int i = 0; i <= period; i++) { futurePlot.Set(i, SMA(period)[0]); } futurePlot.Reset(period + 1); } #region Properties [browsable(false)] [XmlIgnore()] public DataSeries Plot0 { get { return Values[0]; } } [browsable(false)] [XmlIgnore] public DataSeries FuturePlot { get { return futurePlot; } } [Description("")] [GridCategory("Parameters")] [DisplayName("Parameter Nr. 0")] public int Period { get { return period; } set { period = Math.Max(1, value); } } [browsable(false)] public new int Displacement { get { return base.Displacement; } set { base.Displacement = 0; } } #endregion #region Override Plot() public override void Plot(Graphics graphics, Rectangle bounds, double min, double max) { // For advanced FillPolygon/brush plotting, see Imp_Ichimoku.cs //if ("check for no futurePlot") //{ // base.Plot(graphics, bounds, min, max); // We call base Plot() method to paint defined Plots // return; // if check for no futurePlot == true to avoid unnecessary calculations //} List<Point> points = new List<Point>(); int lastX = -1; double lastValue = -1; Pen pen = new Pen(Color.FromKnownColor(KnownColor.Red)); for (int idx = FirstBarIndexPainted - period; idx <= LastBarIndexPainted; idx++) { if (idx < 0 || idx >= BarsArray[0].Count || (!ChartControl.ShowBarsRequired && idx < BarsRequired)) { continue; } if (!futurePlot.IsValidPlot(idx)) { continue; } double value = futurePlot.Get(idx); int x = ChartControl.GetXByBarIdx(BarsArray[0], idx + period); if (lastX >= 0) { int y0 = ChartControl.GetYByValue(this, lastValue); int y1 = ChartControl.GetYByValue(this, value); if (points.Count == 0) // We have a start painting { points.Clear(); points.Add(new Point(lastX, y0)); points.Add(new Point(x, y1)); } else { int pos = points.Count; points.Insert(pos, new Point(x, y1)); } } // Save as previous Point lastX = x; lastValue = value; } if (points.Count > 0 && pen != null) { SmoothingMode oldSmoothingMode = graphics.SmoothingMode; graphics.SmoothingMode = SmoothingMode.AntiAlias; graphics.DrawLines(pen, points.ToArray()); graphics.SmoothingMode = oldSmoothingMode; points.Clear(); } pen.Dispose(); // Paint defined Plots base.Plot(graphics, bounds, min, max); } #endregion Override Plot() } } #region NinjaScript generated code namespace NinjaTrader.Indicator { public partial class Indicator : IndicatorBase { private CB_PlotToFuture[] cacheCB_PlotToFuture = null; // <-- Anpassen private static CB_PlotToFuture checkCB_PlotToFuture = new CB_PlotToFuture(); // <-- Anpassen public CB_PlotToFuture CB_PlotToFuture(int period) // <-- Anpassen - alle Parameter; kommagetrennt; keine lokalen Variablen { return CB_PlotToFuture(Input, period); // <-- Anpassen - alle Parameter; kommagetrennt; keine lokalen Variablen } public CB_PlotToFuture CB_PlotToFuture(Data.IDataSeries input, int period) // <-- Anpassen - alle Parameter; kommagetrennt; keine lokalen Variablen { if (cacheCB_PlotToFuture != null) // <-- Anpassen for (int idx = 0; idx < cacheCB_PlotToFuture.Length; idx++) // <-- Anpassen if (cacheCB_PlotToFuture[idx].Period == period /*&&*/ && cacheCB_PlotToFuture[idx].EqualsInput(input)) // <-- Anpassen - alle Parameter; &&-getrennt; keine lokalen Variablen return cacheCB_PlotToFuture[idx]; // <-- Anpassen lock (checkCB_PlotToFuture) // <-- Anpassen { checkCB_PlotToFuture.Period = period; // <-- Anpassen period = checkCB_PlotToFuture.Period; // <-- Anpassen // Alle Parameter; keine lokalen Variablen if (cacheCB_PlotToFuture != null) // <-- Anpassen for (int idx = 0; idx < cacheCB_PlotToFuture.Length; idx++) // <-- Anpassen if (cacheCB_PlotToFuture[idx].Period == period /*&&*/ && cacheCB_PlotToFuture[idx].EqualsInput(input)) // <-- Anpassen - alle Parameter; &&-getrennt; keine lokalen Variablen return cacheCB_PlotToFuture[idx]; // <-- Anpassen CB_PlotToFuture indicator = new CB_PlotToFuture(); // <-- Anpassen indicator.BarsRequired = BarsRequired; indicator.CalculateOnBarClose = CalculateOnBarClose; #if NT7 indicator.ForceMaximumBarsLookBack256 = ForceMaximumBarsLookBack256; indicator.MaximumBarsLookBack = MaximumBarsLookBack; #endif indicator.Input = input; indicator.Period = period; // <-- Anpassen // Alle Parameter; keine lokalen Variablen Indicators.Add(indicator); indicator.SetUp(); CB_PlotToFuture[] tmp = new CB_PlotToFuture[cacheCB_PlotToFuture == null ? 1 : cacheCB_PlotToFuture.Length + 1]; // <-- Anpassen if (cacheCB_PlotToFuture != null) // <-- Anpassen cacheCB_PlotToFuture.CopyTo(tmp, 0); // <-- Anpassen tmp[tmp.Length - 1] = indicator; cacheCB_PlotToFuture = tmp; // <-- Anpassen return indicator; } } } } namespace NinjaTrader.MarketAnalyzer { public partial class Column : ColumnBase { [Gui.Design.WizardCondition("Indicator")] public Indicator.CB_PlotToFuture CB_PlotToFuture(int period) // <-- Anpassen - alle Parameter; kopmmagetrennt; keine lokalen Variablen { return _indicator.CB_PlotToFuture(Input, period); // <-- Anpassen - alle Parameter; kommagetrennt; keine lokalen Variablen } public Indicator.CB_PlotToFuture CB_PlotToFuture(Data.IDataSeries input, int period) // <-- Anpassen - alle Parameter; kopmmagetrennt; keine lokalen Variablen { return _indicator.CB_PlotToFuture(input, period); // <-- Anpassen - alle Parameter; kopmmagetrennt; keine lokalen Variablen } } } namespace NinjaTrader.Strategy { public partial class Strategy : StrategyBase { [Gui.Design.WizardCondition("Indicator")] public Indicator.CB_PlotToFuture CB_PlotToFuture(int period) // <-- Anpassen - alle Parameter; kopmmagetrennt; keine lokalen Variablen { return _indicator.CB_PlotToFuture(Input, period); // <-- Anpassen - alle Parameter; kopmmagetrennt; keine lokalen Variablen } public Indicator.CB_PlotToFuture CB_PlotToFuture(Data.IDataSeries input, int period) // <-- Anpassen - alle Parameter; kopmmagetrennt; keine lokalen Variablen { if (InInitialize && input == null) throw new ArgumentException("You only can access an indicator with the default input/bar series from within the 'Initialize()' method"); return _indicator.CB_PlotToFuture(input, period);// <-- Anpassen - alle Parameter; kopmmagetrennt; keine lokalen Variablen } } } #endregion NinjaScript generated code Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.