#region Updates /// Version 4.5 2nd attempt to correct intermittent 'startup' problem with missing boxes /// Version 4.4 Corrected missing code that messed up Statistics.... /// added second 'jump color' /// Version 4.3 added 'projected' opposite S/R level to draw before final box is drawn /// added Gray outline for the "active" S/R box being drawn /// Version 4.1 renamed Acoustic, Visualize, Support/Resistance, and Display /// to top of the selection panel. /// Commented out 'tst only' and unused variables. /// Version 4.0 Added Intermediate S/R boxes #endregion #region Using declarations using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; using System.Xml.Serialization; using NinjaTrader.Cbi; using NinjaTrader.Data; using NinjaTrader.Gui.Chart; using PASwh.Utility; #endregion // This namespace holds all indicators and is required. Do not change it. namespace NinjaTrader.Indicator { /// /// PriceActionSwing calculate swings /// calculates dynamic support/Resistance /// gathers statistics. /// [Description("PASwh Ver 4.5 .... 07-07-2010) modified by Will Hoerl. PriceActionSwing calculates swings, calculates S/R levels, and displays swing statistics.")] public class PASwh : Indicator { #region Variables //################################################################### #region Parameters //=================================================================== private SwingMode calcMode = SwingMode.Standard; private int calcSize = 8; private int dtbStrength = 15; private double psarAcceleration = 0.02; private double psarAccelerationMax = 0.2; private double psarAccelerationStep= 0.02; //=================================================================== #endregion #region Sounds //=================================================================== private bool activateAlertSound = false; private string alertFileName = "Alert2.wav"; //=================================================================== #endregion #region Chart Display //=================================================================== private ShowMode show = ShowMode.Both; private SwingLength swingText = SwingLength.Ticks; private bool showDuration = true; private bool showSwingPercentage = false; private VolumeMode showSwingVolume = VolumeMode.False; //=================================================================== #endregion #region Commented out ...... ABCD / Fib control //=================================================================== // private bool addAbcd = false; // private bool addFibExt = false; // private bool addFastFibRet = false; // private bool addSlowFibRet = false; //=================================================================== #endregion #region Chart Visual //=================================================================== private DashStyle lineStyle = DashStyle.Dash; private int lineWidth = 2; private Font textFont = new Font("Courier", 9, FontStyle.Regular); private int textOffset = 20; private int textOffsetPercentage= 60; private int textOffsetVolume = 40; private Color textColorHigher = Color.LimeGreen; private Color textColorLower = Color.Red; private Color textColorDtb = Color.Gold; private Color textColor = Color.Transparent; private Color tr = Color.Transparent; private double lengthValue = 0.0; private Color zigZagColorUp = Color.Blue; private Color zigZagColorDown = Color.Red; //=================================================================== #endregion #region commented out ...... Visualize Fibs //=================================================================== // private double fibValue1 = 61.8; // private double fibValue2 = 76.4; // private Color abcdLong = Color.SkyBlue; // private Color abcdShort = Color.IndianRed; // private int opacity = 2; //=================================================================== #endregion #region Statistic visual control //=================================================================== private StatisticPosition statisticPosition = StatisticPosition.False; private int statisticLength = 5; //=================================================================== #endregion #region Statistic //=================================================================== private string upStatSwing = ""; private string dnStatSwing = ""; private string upStatRel = ""; private string dnStatRel = ""; // all double, otherwise the digits are only cutted and not rounded by the output // Variables for the complete statistic private double overallAvgDnLength = 0; private double overallAvgUpLength = 0; private double overallUpLength = 0; private double overallDnLength = 0; private double overallAvgDnDuration= 0; private double overallAvgUpDuration= 0; private double overallUpDuration = 0; private double overallDnDuration = 0; // Variables for the short term statistic private double avgUpLength = 0; private double avgDnLength = 0; private double upLength = 0; private double dnLength = 0; private double avgUpDuration = 0; private double avgDnDuration = 0; private double upDuration = 0; private double dnDuration = 0; // Variables for the swing to swing relation statistic // Higher high private int hhCount = 0; private int hhCountHH = 0; private double hhCountHHPercent = 0; private int hhCountLH = 0; private double hhCountLHPercent = 0; private int hhCountHL = 0; private double hhCountHLPercent = 0; private int hhCountLL = 0; private double hhCountLLPercent = 0; // Lower high private int lhCount = 0; private int lhCountHH = 0; private double lhCountHHPercent = 0; private int lhCountLH = 0; private double lhCountLHPercent = 0; private int lhCountHL = 0; private double lhCountHLPercent = 0; private int lhCountLL = 0; private double lhCountLLPercent = 0; // Double top private int dtCount = 0; private int dtCountHH = 0; private double dtCountHHPercent = 0; private int dtCountLH = 0; private double dtCountLHPercent = 0; private int dtCountHL = 0; private double dtCountHLPercent = 0; private int dtCountLL = 0; private double dtCountLLPercent = 0; // Lower low private int llCount = 0; private int llCountHH = 0; private double llCountHHPercent = 0; private int llCountLH = 0; private double llCountLHPercent = 0; private int llCountHL = 0; private double llCountHLPercent = 0; private int llCountLL = 0; private double llCountLLPercent = 0; // Higher low private int hlCount = 0; private int hlCountHH = 0; private double hlCountHHPercent = 0; private int hlCountLH = 0; private double hlCountLHPercent = 0; private int hlCountHL = 0; private double hlCountHLPercent = 0; private int hlCountLL = 0; private double hlCountLLPercent = 0; // Double bottom private int dbCount = 0; private int dbCountHH = 0; private double dbCountHHPercent = 0; private int dbCountLH = 0; private double dbCountLHPercent = 0; private int dbCountHL = 0; private double dbCountHLPercent = 0; private int dbCountLL = 0; private double dbCountLLPercent = 0; //=================================================================== #endregion #region Swing values //=================================================================== private bool newLow = false; private bool newHigh = false; private int upCount = 0; private int dnCount = 0; private double curHigh = 0.0; private double curLow = 0.0; private double lastHigh = 0.0; private double lastLow = 0.0; private int curHighBar = 0; private int curLowBar = 0; private int lastHighBar = 0; private int lastLowBar = 0; private Relation curHighRel = Relation.Init; private Relation curLowRel = Relation.Init; private Relation lastHighRel = Relation.Init; private Relation lastLowRel = Relation.Init; private int curHighDur = 0; private int curLowDur = 0; private int lastHighDur = 0; private int lastLowDur = 0; private int curHighLength = 0; private int curLowLength = 0; private double lastHighLength = 0.0; private double lastLowLength = 0.0; private int length = 0; private int swingCounterUp = 0; private int swingCounterDn = 0; //=================================================================== #endregion #region Miscellaneous //=================================================================== private double dtbOffset = 0.0; private int trendDir = 0; private double psarValue = 0.0; private bool psarFlip = false; private double signalBarVolumeUp = 0; private double signalBarVolumeDn = 0; private DataSeries hi, lo, priceSwingRelation; private BoolSeries upFlip, dnFlip; private IDataSeries psar; private RichTextBox richTextBox = null; private Splitter splitter = null; private ToolStrip toolStrip = null; private ToolStripButton toolStripButton = null; private ToolStripSeparator toolStripSeparator = null; /// /// Used to control, that only one swing is set for each bar: 0 = no swing, -1 = down swing, 1 = up swing /// private int newSwing = 0; /// /// True = upwave - false = downwave /// private BoolSeries upWave; /// /// Contains all up swings. /// private List Hi = new List(); /// /// Contains all down swings. /// private List Lo = new List(); //=================================================================== #endregion #region Swing struct //=================================================================== /// /// Contains all information about a swing (bar number, price, length, duration, relation to the last swing). /// private struct Swings { /// /// Bar number of the swing. /// public int barNumber; /// /// Swing price. /// public double price; /// /// Swing length in ticks. /// public int length; /// /// Swing duration in bars. /// public int duration; /// /// Swing relation to the last swing. /// public Relation relation; /// /// Contains all information about a swing (bar number, price, length, duration, relation to the last swing). /// public Swings(int swingBarNumber, double swingPrice, int swingLength, int swingDuration, Relation swingRelation) { barNumber = swingBarNumber; price = swingPrice; length = swingLength; duration = swingDuration; relation = swingRelation; } } //=================================================================== #endregion #region Support Resistance //=================================================================== private bool drawSR = true; private int rectWidth = 8; private int sRL1 = 14; private int sRL2 = 22; private int sRL3 = 14; private Color sRresistcolor = Color.Red; private Color sRsupptcolor = Color.Blue; private Color sRtjumpcolorR = Color.Gold; private Color sRtjumpcolorS = Color.CornflowerBlue; private int sRopacity = 5; //-------working fields ---------- private double anchor1up = 0.0; private double anchor1upH = 0.0; private double anchor2up = 0.0; private double anchor2upH = 0.0; private double anchor1dn = 0.0; private double anchor1dnH = 0.0; private double anchor2dn = 0.0; private double anchor2dnH = 0.0; private int moveback = 0; private int newstop = 0; private bool newswingup = true; private bool newswingdn = true; private int zzswings = 0; private int srcurHighBar = 0; private int srcurLowBar = 0; private double srcurHigh = 0.0; private double srcurLow = 0.0; private int rectHalf = 0; //================================================================== #endregion //################################################################### #endregion /// /// This method is used to configure the indicator and is called once before any bar data is loaded. /// protected override void Initialize() #region Initialize { Add(new Plot(new Pen(Color.Gold, 3), PlotStyle.Dot, "DoubleBottom")); Add(new Plot(new Pen(Color.Red, 3), PlotStyle.Dot, "LowerLow")); Add(new Plot(new Pen(Color.Green, 3), PlotStyle.Dot, "HigherLow")); Add(new Plot(new Pen(Color.Gold, 3), PlotStyle.Dot, "DoubleTop")); Add(new Plot(new Pen(Color.Red, 3), PlotStyle.Dot, "LowerHigh")); Add(new Plot(new Pen(Color.Green, 3), PlotStyle.Dot, "HigherHigh")); AutoScale = true; CalculateOnBarClose = true; Overlay = true; PriceTypeSupported = false; priceSwingRelation = new DataSeries(this); hi = new DataSeries(this); lo = new DataSeries(this); upWave = new BoolSeries(this); dnFlip = new BoolSeries(this); upFlip = new BoolSeries(this); rectHalf = rectWidth / 2; } #endregion #region Draw text box for the statistic #if NT7 protected override void OnStartUp() { if (statisticPosition != StatisticPosition.False) { base.OnStartUp(); DockStyle dockStyle = DockStyle.Bottom; switch (statisticPosition) { case StatisticPosition.Bottom: dockStyle = DockStyle.Bottom; break; case StatisticPosition.Left: dockStyle = DockStyle.Left; break; case StatisticPosition.Right: dockStyle = DockStyle.Right; break; case StatisticPosition.Top: dockStyle = DockStyle.Top; break; default: dockStyle = DockStyle.Bottom; break; } splitter = new Splitter(); splitter.Name = "PASSplitter"; splitter.BackColor = Color.Black; splitter.Dock = dockStyle; splitter.Width = 5; ChartControl.Controls.Add(splitter); richTextBox = new RichTextBox(); richTextBox.Name = "PASRichTextBox"; richTextBox.Dock = dockStyle; richTextBox.ReadOnly = true; ChartControl.Controls.Add(richTextBox); Control[] control = ChartControl.Controls.Find("tsrTool",false); if(control.Length > 0) { toolStripSeparator = new ToolStripSeparator(); toolStripSeparator.Name = "PASSeperator"; toolStripButton = new ToolStripButton("Hide Statistic"); toolStripButton.Name = "PASButton"; toolStripButton.Text = "Hide Statistic"; toolStripButton.Click += ButtonClick; toolStrip = (ToolStrip)control[0]; toolStrip.Items.Add(toolStripSeparator); toolStrip.Items.Add(toolStripButton); } } } private void ButtonClick(object s, EventArgs e) { if (statisticPosition != StatisticPosition.False) { if(richTextBox == null) return; if(richTextBox.Visible) { richTextBox.Hide(); splitter.Hide(); toolStripButton.Text = "Show Statistic"; } else { splitter.Show(); richTextBox.Show(); toolStripButton.Text = "Hide Statistic"; } } } protected override void OnTermination() { if (statisticPosition != StatisticPosition.False) { if(richTextBox != null) ChartControl.Controls.RemoveByKey("PASRichTextBox"); if(splitter != null) ChartControl.Controls.RemoveByKey("PASSplitter"); if(toolStrip != null) { if (toolStripButton != null) toolStrip.Items.RemoveByKey("PASButton"); if (toolStripSeparator != null) toolStrip.Items.RemoveByKey("PASSeperator"); } richTextBox = null; splitter = null; toolStrip = null; toolStripButton = null; toolStripSeparator = null; base.OnTermination(); } } #endif #endregion /// /// Called on each bar update event (incoming tick) /// protected override void OnBarUpdate() { dnFlip.Set(false); upFlip.Set(false); switch (calcMode) { #region SwingMode.PSAR case SwingMode.PSAR: { // ###################################################################### // Initialize and checks to make sure the indicator can work correct // ###################################################################### // Set the PSAR value to to the psar series if (CurrentBar < 1 && psar == null) psar = ParabolicSAR(Input, psarAcceleration, psarAccelerationMax, psarAccelerationStep); // initialize if (CurrentBar == 1 && FirstTickOfBar) { curHighBar = curLowBar = CurrentBar; curHigh = High[0]; curLow = Low[0]; Swings up = new Swings(curHighBar, curHigh, 0, 0, curHighRel); Swings dn = new Swings(curLowBar , curLow , 0, 0, curLowRel); Hi.Add(up); Lo.Add(dn); upCount = Hi.Count; dnCount = Lo.Count; } if (CurrentBar < 3) return; // ###################################################################### // Look for new swings // ###################################################################### // upWave = true = up swing - false = down swing upWave.Set(psar[0] < Close[0] ? true : false); // Used for calculateOnBarClose = false if (FirstTickOfBar) { psarFlip = false; psarValue = psar[0]; } // Upflip - new swing high if (!psarFlip && !upWave[1] && High[0] >= psarValue) { psarFlip = true; newHigh = true; drawUpSwing(CurrentBar, High[0], false); } // Downflip - new swing low else if (!psarFlip && upWave[1] && Low[0] <= psarValue) { psarFlip = true; newLow = true; drawDnSwing(CurrentBar, Low[0], false); } // Update swing high else if (upWave[0] && High[0] > curHigh) { newHigh = true; drawUpSwing(CurrentBar, High[0], true); } // Update swing low else if (!upWave[0] && Low[0] < curLow) { newLow = true; drawDnSwing(CurrentBar, Low[0], true); } break; } #endregion #region SwingMode.Standard case SwingMode.Standard: { // ###################################################################### // Initialize and checks to make sure the indicator can work correct // ###################################################################### // initialize if (CurrentBar == 1 && FirstTickOfBar) { curHighBar = curLowBar = CurrentBar; curHigh = High[0]; curLow = Low[0]; Swings up = new Swings(curHighBar, curHigh, 0, 0, curHighRel); Swings dn = new Swings(curLowBar , curLow , 0, 0, curLowRel); Hi.Add(up); Lo.Add(dn); upCount = Hi.Count; dnCount = Lo.Count; } // Checks to make sure we have at least calcSize bars before continuing if (CurrentBar < calcSize) return; // ###################################################################### // Look for new swings - diffentiate between CalculatOnBarClose == true/false // ###################################################################### // Set newHigh and newLow true newHigh = newLow = true; //CalculatOnBarClose == true if (CalculateOnBarClose) { // For a new swing high in an uptrend, High[0] must be greater than the current swing high if (trendDir == 1 && High[0] <= curHigh) newHigh = false; // test if High[0] is higher than the last calcSize highs = new swing high if (newHigh) { for (int i = 1; i < calcSize + 1; i++) { if (High[0] <= High[i]) { newHigh = false; break; } } } // For a new swing low in a downtrend, Low[0] must be smaller than the current swing low if (trendDir == -1 && Low[0] >= curLow) newLow = false; // test if Low[0] is lower than the last calcSize lows = new swing low if (newLow) { for (int i = 1; i < calcSize + 1; i++) { if (Low[0] >= Low[i]) { newLow = false; break; } } } // New swing high and new swing low if (newHigh && newLow) { // Downtrend - ignore the swing high if (trendDir == -1) newHigh = false; // Uptrend - ignore the swing low else newLow = false; } } // CalculatOnBarClose == false else { // Used to controll, that only one swing is set for each bar if (FirstTickOfBar) newSwing = 0; // No swing or an up swing is found if (newSwing != -1) { // For a new swing high, High[0] must be greater than the current swing high if (trendDir == 1 && High[0] <= curHigh) newHigh = false; // test if High[0] is higher than the last calcSize highs = new swing high if (newHigh) { for (int i = 1; i < calcSize + 1; i++) { if (High[0] <= High[i]) { newHigh = false; break; } } // Found a swing high if (newHigh) newSwing = 1; } } // No swing or an down swing is found if (newSwing != 1) { // For a new swing low in a downtrend, Low[0] must be smaller than the current swing low if (trendDir == -1 && Low[0] >= curLow) newLow = false; // test if Low[0] is lower than the last calcSize lows = new swing low if (newLow) { for (int i = 1; i < calcSize + 1; i++) { if (Low[0] >= Low[i]) { newLow = false; break; } } // Found a swing low if (newLow) newSwing = -1; } } // Set newLow back to false if (newSwing == 1) newLow = false; // Set newHigh back to false if (newSwing == -1) newHigh = false; } int bar; double price; // Swing high if (newHigh) { // New swing high if (trendDir != 1) { bar = CurrentBar - HighestBar(High, CurrentBar - curLowBar); price = High[HighestBar(High, CurrentBar - curLowBar)]; drawUpSwing(bar, price, false); } // Update swing high else { bar = CurrentBar; price = High[0]; drawUpSwing(bar, price, true); } } // Swing high else if (newLow) { // New swing low if (trendDir != -1) { bar = CurrentBar - LowestBar(Low, CurrentBar - curHighBar); price = Low[LowestBar(Low, CurrentBar - curHighBar)]; drawDnSwing(bar, price, false); } // Update swing low else { bar = CurrentBar; price = Low[0]; drawDnSwing(bar, price, true); } } break; } #endregion #region SwingMode.ZigZagUTC case SwingMode.ZigZigUTC: { // ###################################################################### // Initialize and checks to make sure the indicator can work correct // ###################################################################### if (CurrentBar == 1 && FirstTickOfBar) { curHighBar = curLowBar = 1; curHigh = hi[0] = High[0]; curLow = lo[0] = Low[0]; Swings up = new Swings(curHighBar, curHigh, 0, 0, curHighRel); Swings dn = new Swings(curLowBar , curLow , 0, 0, curLowRel); Hi.Add(up); Lo.Add(dn); upCount = Hi.Count; dnCount = Lo.Count; return; } if (CurrentBar < 3) return; // Get high and low for last 'calcSize' number of bars hi.Set(MAX(High, calcSize)[0]); lo.Set(MIN(Low, calcSize)[0]); // Set initial trend direction if (trendDir == 0) { if (hi[0] > curHigh) { curHigh = hi[0]; curHighBar = CurrentBar; if (lo[0] > lo[1]) trendDir = 1; } if (lo[0] < curLow) { curLow = lo[0]; curLowBar = CurrentBar; if (hi[0] < hi[1]) trendDir = -1; } } // ###################################################################### // Look for new swings // ###################################################################### // Trend is up, look for new swing high if (trendDir == 1) { // Update swing high if (hi[0] > curHigh) { newHigh = true; drawUpSwing(CurrentBar, hi[0], true); } // New swing low else if (hi[0] < curHigh && lo[0] < lo[1]) { newLow = true; drawDnSwing(CurrentBar, lo[0], false); } } // Trend is down, look for new swing low else if (trendDir == -1) { // Update swing low if (lo[0] < curLow) { newLow = true; drawDnSwing(CurrentBar, lo[0], true); } // New swing high else if (lo[0] > curLow && hi[0] > hi[1]) { newHigh = true; drawUpSwing(CurrentBar, hi[0], false); } } break; } #endregion } #region Price swing relation // ###################################################################### // Price swing relation // ###################################################################### // Double bottom - set: +2 if (curLowRel == Relation.Double) priceSwingRelation.Set(2); // Double top - set: -2 else if (curHighRel == Relation.Double) priceSwingRelation.Set(-2); // Higher high and higher low - set: 1 else if (curHighRel == Relation.Higher && curLowRel == Relation.Higher) priceSwingRelation.Set(1); // Lower high and lower low - set: -1 else if (curHighRel == Relation.Lower && curLowRel == Relation.Lower) priceSwingRelation.Set(-1); // rest - set: 0 else priceSwingRelation.Set(0); #endregion #region Support Resist moving-rectangle //====================================================== { if (zzswings < (rectWidth +2)) { srcurHighBar = 2; srcurLowBar = 2; srcurHigh = High[0]; srcurLow = Low[0]; anchor1up = srcurLow + (TickSize * sRL1); anchor2up = srcurLow + (TickSize * sRL2); anchor1dn = srcurHigh - (TickSize * sRL1); anchor2dn = srcurHigh - (TickSize * sRL2); zzswings = zzswings + 1; } else { srcurLowBar = curLowBar; srcurLow = curLow; srcurHighBar = curHighBar; srcurHigh = curHigh; } //if (curLow < .5000) // { // srcurLowBar = 3; // srcurLow = Low[0]; // } //else // { // srcurLowBar = curLowBar; // srcurLow = curLow; // } //if (curHigh < .5000) // { // srcurHighBar = 3; // srcurHigh = High[0]; // } //else // { // srcurHighBar = curHighBar; // srcurHigh = curHigh; // } //DrawText("tst99"+CurrentBar,true,srcurLow.ToString()+" / "+srcurLowBar.ToString(),0,Low[0],-40,Color.White,textFont,StringAlignment.Center,tr,tr,0); if ((drawSR) && (CurrentBar > rectWidth)) { if (trendDir == 1) { newswingdn = true; { if (newswingup) { //--- Calculate Final Suppt Rectangle Position ----------- { moveback = Convert.ToInt32(CurrentBar - srcurLowBar); //DrawText("test0"+CurrentBar,true,moveback.ToString()+ "/"+CurrentBar.ToString()+"/"+srcurLowBar.ToString(),0,Low[0],-30, Color.White,textFont,StringAlignment.Center,tr,tr,0); if (moveback < rectWidth || moveback > 30) { moveback = rectWidth; newstop = 0; } else { moveback = moveback + rectHalf; newstop = moveback - rectWidth; if (moveback > CurrentBar) { moveback = CurrentBar - 1; newstop = 0; } } } //DrawText("test2"+CurrentBar,true,moveback.ToString()+ "/"+newstop.ToString(),0,Low[0],-60, Color.White,textFont,StringAlignment.Center,tr,tr,0); DrawRectangle("Supptf" + CurrentBar, true, moveback, anchor1dn, newstop, anchor2dn, Color.Transparent, sRsupptcolor, sRopacity); anchor1up = srcurLow + (TickSize * sRL1); anchor2up = srcurLow + (TickSize * sRL2); newswingup = false; } else if (High[0] > anchor2up) { DrawRectangle("JumpR" + CurrentBar, true, rectWidth, anchor1up, 0, anchor2up, Color.Transparent, sRtjumpcolorR, sRopacity); anchor1up = anchor1up + (TickSize * sRL3); anchor2up = anchor2up + (TickSize * sRL3); } } DrawRectangle("Resist", true, rectWidth, anchor1up, 0, anchor2up, Color.Gray, sRresistcolor, sRopacity); double anchor1tdn; double anchor2tdn; anchor1tdn = srcurHigh - (TickSize * sRL1); anchor2tdn = srcurHigh - (TickSize * sRL2); DrawRectangle("Suppt", true, rectWidth, anchor1tdn, 0, anchor2tdn, Color.Transparent, sRsupptcolor, sRopacity); } else if (trendDir == -1) { newswingup = true; { if (newswingdn) { //-------Calculate Final Resist Rectangle Position -------------------- { moveback = Convert.ToInt32(CurrentBar - srcurHighBar); if (moveback < rectWidth || moveback > 30) { moveback = rectWidth; newstop = 0; } else { moveback = moveback + rectHalf; newstop = moveback - rectWidth; if (moveback > CurrentBar) { moveback = CurrentBar - 1; newstop = 0; } } } //DrawText("test2"+CurrentBar,true,anchor1up.ToString()+ "/"+anchor2up.ToString()+"/"+newstop.ToString(),0,High[0],+60, Color.White,textFont,StringAlignment.Center,tr,tr,0); DrawRectangle("Resistf" + CurrentBar, true, moveback, anchor1up, newstop, anchor2up, Color.Transparent, sRresistcolor, sRopacity); anchor1dn = srcurHigh - (TickSize * sRL1); anchor2dn = srcurHigh - (TickSize * sRL2); newswingdn = false; } else if (Low[0] < anchor2dn) { DrawRectangle("JumpS" + CurrentBar, true, rectWidth, anchor1dn, 0, anchor2dn, Color.Transparent, sRtjumpcolorS, sRopacity); anchor1dn = anchor1dn - (TickSize * sRL3); anchor2dn = anchor2dn - (TickSize * sRL3); } } DrawRectangle("Suppt", true, rectWidth, anchor1dn, 0, anchor2dn, Color.Gray, sRsupptcolor, sRopacity); double anchor1tup; double anchor2tup; anchor1tup = srcurLow + (TickSize * sRL1); anchor2tup = srcurLow + (TickSize * sRL2); DrawRectangle("Resist", true, rectWidth, anchor1tup, 0, anchor2tup, Color.Transparent, sRresistcolor, sRopacity); } else { double val = 0; val = High[0] + ( TickSize * 4 ); DrawArrowDown("My dn arrow" + CurrentBar, true, 0, val, Color.Orange); } } } //====================================================== #endregion #region Commented out ...... ABCD entry area // ###################################################################### // ABCD entry area // ###################################################################### // if (addAbcd) // { // // Checks to make sure we have a lastHigh/lastLow // if (lastHigh == 0.0 || lastLow == 0.0) return; // // // variables for the draw expressions // int anchor1BarsAgo = 0; // int anchor2BarsAgo = 0; // int anchor3BarsAgo = 0; // double anchor1Y = 0.0; // double anchor2Y = 0.0; // double anchor3Y = 0.0; // double tmpStartY = 0.0; // Color fibColor = Color.Blue; // // if (trendDir == 1) // { // //tmpStartY = Math.Round((lastHigh - curLow), 6, MidpointRounding.AwayFromZero); // // values for the Fibonacci area // anchor1BarsAgo = CurrentBar - 8; // anchor1Y = curLow + 12; // anchor2BarsAgo = 0; // anchor2Y = curLow + 16; // fibColor = abcdShort; // DrawRectangle("FibArea", AutoScale, anchor1BarsAgo, anchor1Y, anchor2BarsAgo, // anchor2Y, Color.Transparent, fibColor, opacity + 3); // } // else // { // //tmpStartY = Math.Round((curHigh - lastLow), 6, MidpointRounding.AwayFromZero); // // values for the Fibonacci area // anchor1BarsAgo = CurrentBar - 8; // anchor1Y = curHigh - 12; // anchor2BarsAgo = 0; // anchor2Y = curHigh - 16; // fibColor = abcdLong; // DrawRectangle("FibArea", AutoScale, anchor1BarsAgo, anchor1Y, anchor2BarsAgo, // anchor2Y, Color.Transparent, fibColor, opacity); // } // // // } #endregion // ----------------------------------------------- #region Commented out ...... Fibonacci //if (newHigh) || (newLow) //{ #region Fibonacci extensions...commented out /* // ################################################################## // Fibonacci Extensions // ################################################################## if (addFibExt) { // Checks to make sure we have a lastHigh/lastLow if (lastHigh == 0.0 || lastLow == 0.0) return; // variables for the draw expressions int anchor1BarsAgo = 0; int anchor2BarsAgo = 0; int anchor3BarsAgo = 0; double anchor1Y = 0.0; double anchor2Y = 0.0; double anchor3Y = 0.0; // Unfinished higher low and downtrend if (Lo[Lo.Count - 1].relation == Relation.Higher && trendDir == -1) { anchor1BarsAgo = CurrentBar - lastLowBar; anchor2BarsAgo = CurrentBar - curHighBar; anchor3BarsAgo = CurrentBar - curLowBar; anchor1Y = lastLow; anchor2Y = curHigh; anchor3Y = curLow; DrawFibonacciExtensions("FibExtUp", false, anchor1BarsAgo, anchor1Y, anchor2BarsAgo, anchor2Y, anchor3BarsAgo, anchor3Y); } // Finished higher low and downtrend else if (Lo[Lo.Count - 1].relation == Relation.Higher && trendDir == 1) { anchor1BarsAgo = CurrentBar - lastLowBar; anchor2BarsAgo = CurrentBar - lastHighBar; anchor3BarsAgo = CurrentBar - curLowBar; anchor1Y = lastLow; anchor2Y = lastHigh; anchor3Y = curLow; DrawFibonacciExtensions("FibExtUp", false, anchor1BarsAgo, anchor1Y, anchor2BarsAgo, anchor2Y, anchor3BarsAgo, anchor3Y); } // Remove Fibonacci up retracement else RemoveDrawObject("FibExtUp"); // Unfinished lower high and uptrend if (Hi[Hi.Count - 1].relation == Relation.Lower && trendDir == 1) { anchor1BarsAgo = CurrentBar - lastHighBar; anchor2BarsAgo = CurrentBar - curLowBar; anchor3BarsAgo = CurrentBar - curHighBar; anchor1Y = lastHigh; anchor2Y = curLow; anchor3Y = curHigh; DrawFibonacciExtensions("FibExtDn", false, anchor1BarsAgo, anchor1Y, anchor2BarsAgo, anchor2Y, anchor3BarsAgo, anchor3Y); } // Finished lower high and uptrend else if (Hi[Hi.Count - 1].relation == Relation.Lower && trendDir == -1) { anchor1BarsAgo = CurrentBar - lastHighBar; anchor2BarsAgo = CurrentBar - lastLowBar; anchor3BarsAgo = CurrentBar - curHighBar; anchor1Y = lastHigh; anchor2Y = lastLow; anchor3Y = curHigh; DrawFibonacciExtensions("FibExtDn", false, anchor1BarsAgo, anchor1Y, anchor2BarsAgo, anchor2Y, anchor3BarsAgo, anchor3Y); } // Remove Fibonacci down retracement else RemoveDrawObject("FibExtDn"); } */ #endregion #region Fibonacci retracements....commented out /* // ################################################################## // Fibonacci retracements // ################################################################## if (addFastFibRet) { // variables for the draw expressions int anchor1BarsAgo = 0; int anchor2BarsAgo = 0; int anchor3BarsAgo = 0; double anchor1Y = 0.0; double anchor2Y = 0.0; double anchor3Y = 0.0; // up trend if (trendDir == 1) { // values for the Fibonacci retracement anchor1BarsAgo = CurrentBar - curLowBar; anchor1Y = curLow; anchor2BarsAgo = CurrentBar - curHighBar; anchor2Y = curHigh; } // down trend else { // values for the Fibonacci retracement anchor1BarsAgo = CurrentBar - curHighBar; anchor1Y = curHigh; anchor2BarsAgo = CurrentBar - curLowBar; anchor2Y = curLow; } DrawFibonacciRetracements("FastFibRet", AutoScale, anchor1BarsAgo, anchor1Y, anchor2BarsAgo, anchor2Y); } // Add the slow Fibonacci retracement to the chart if (addSlowFibRet) { // Checks to make sure we have a lastHigh/lastLow if (lastHigh == 0.0 || lastLow == 0.0) return; // variables for the draw expressions int anchor1BarsAgo = 0; int anchor2BarsAgo = 0; int anchor3BarsAgo = 0; double anchor1Y = 0.0; double anchor2Y = 0.0; double anchor3Y = 0.0; // up trend if (trendDir == 1) { // values for the Fibonacci retracement anchor1BarsAgo = CurrentBar - lastHighBar; anchor1Y = lastHigh; anchor2BarsAgo = CurrentBar - curLowBar; anchor2Y = curLow; } // down trend else { // values for the Fibonacci retracement anchor1BarsAgo = CurrentBar - lastLowBar; anchor1Y = lastLow; anchor2BarsAgo = CurrentBar - curHighBar; anchor2Y = curHigh; } if ((trendDir == 1 && curHigh < lastHigh) || (trendDir == -1 && curLow > lastLow)) DrawFibonacciRetracements("SlowFibRet", AutoScale, anchor1BarsAgo, anchor1Y, anchor2BarsAgo, anchor2Y); else RemoveDrawObject("SlowFibRet"); } */ #endregion //} #endregion } #region Calculate and visualize up swing values /// /// Calculate the up swing and visualize it. /// /// Bar number /// High price /// Swing high update private void drawUpSwing(int bar, double high, bool updateHigh) { string output = null; // New swing high if (!updateHigh) { trendDir = 1; lastHigh = curHigh; lastHighBar = curHighBar; lastHighRel = curHighRel; curHighBar = bar; curHigh = high; swingCounterUp++; upFlip.Set(true); if (!CalculateOnBarClose && showSwingVolume != VolumeMode.False) signalBarVolumeDn = Volume[0]; if (activateAlertSound) PlaySound(alertFileName); if (statisticPosition != StatisticPosition.False) dnStatistic(); } // Update swing high else { // Reset the up dot plot DoubleTop.Reset(CurrentBar-curHighBar); HigherHigh.Reset(CurrentBar-curHighBar); LowerHigh.Reset(CurrentBar-curHighBar); // Remove the last up swing from the list Hi.RemoveAt(Hi.Count - 1); curHighBar = bar; curHigh = high; if (!CalculateOnBarClose && showSwingVolume != VolumeMode.False) signalBarVolumeDn = Volume[0]; } // ##### Set the length of the up swing ############################# curHighLength = Convert.ToInt32(Math.Round((curHigh - curLow) / TickSize, 0, MidpointRounding.AwayFromZero)); // ##### Set the duration of the up swing ########################### curHighDur = curHighBar - curLowBar; // ##### Relation to the last up swing ############################## // Calculate the offset for a double top. dtbOffset = ATR(14)[CurrentBar - curHighBar] * dtbStrength / 100; // double top if (curHigh < lastHigh + dtbOffset && curHigh > lastHigh - dtbOffset) curHighRel = Relation.Double; // higher high else if (curHigh > lastHigh) curHighRel = Relation.Higher; // lower high else curHighRel = Relation.Lower; // ##### Add the swing high to the list of swing highs. ############# Swings up = new Swings(curHighBar, curHigh, curHighLength, curHighDur, curHighRel); Hi.Add(up); // Set the number of all up swings. upCount = Hi.Count - 1; // ##### Set the zigzag up line ##################################### if (ShowMode.Both == show || ShowMode.ZigZagLines == show) { DrawLine("ZigZagUp" + swingCounterUp, AutoScale, CurrentBar - curLowBar, curLow, CurrentBar - curHighBar, curHigh, zigZagColorUp, lineStyle, lineWidth); } // ##### Set the up swing price or the up swing length ############## if (SwingLength.False != swingText) { // Set the up swing length switch (swingText) { // Swing length in ticks case SwingLength.Ticks: output = curHighLength.ToString(); break; // Swing length in points case SwingLength.Points: output = (curHighLength * TickSize).ToString(); break; // Swing price case SwingLength.SwingPrice: output = curHigh.ToString(); break; // Swing price and points case SwingLength.SwingPriceAndPoints: output = curHigh.ToString() + " / " + (curHighLength * TickSize).ToString(); break; // Swing price and ticks case SwingLength.SwingPriceAndTicks: output = curHigh.ToString() + " / " + curHighLength.ToString(); break; // Swing length in percent case SwingLength.Percent: output = (Math.Round((100.0 / curLow * (curHighLength * TickSize)), 2, MidpointRounding.AwayFromZero)).ToString(); break; } } // Test if curHigh is HH, LH or DT and set the textcolor switch (curHighRel) { // Higher high case Relation.Higher: textColor = textColorHigher; break; // Lower high case Relation.Lower: textColor = textColorLower; break; // Double top case Relation.Double: textColor = textColorDtb; break; } // Add swing duration to the swing text output if (showDuration) { if (SwingLength.False != swingText) output = output + " / " + curHighDur.ToString(); else output = curHighDur.ToString(); } if (output != null) { DrawText("High" + swingCounterUp, AutoScale, output.ToString(), CurrentBar - curHighBar, curHigh, textOffset, textColor, textFont, StringAlignment.Center, Color.Transparent, Color.Transparent, 0); } // Add swing percentage to the output if (showSwingPercentage && curLowLength != 0) { double value = Math.Round(100.0 / Math.Abs(curLowLength) * curHighLength, 1); DrawText("UpPerc" + swingCounterUp, AutoScale, value.ToString() + "%", CurrentBar - curHighBar, curHigh, textOffsetPercentage, textColor, textFont, StringAlignment.Center, Color.Transparent, Color.Transparent, 0); } // ##### Set the up dot plot ######################################## if (ShowMode.Both == show || ShowMode.Dots == show) { switch (curHighRel) { // Higher high case Relation.Higher: HigherHigh.Set(CurrentBar - curHighBar, curHigh); break; // Lower high case Relation.Lower: LowerHigh.Set(CurrentBar - curHighBar, curHigh); break; // Double top case Relation.Double: DoubleTop.Set(CurrentBar - curHighBar, curHigh); break; } } // ##### Set the up volume ########################################## if (showSwingVolume != VolumeMode.False) { double swingVolume = 0.0; string volumeOutput = ""; // Absolute swing volume for (int i = 0; i < curHighDur; i++) { swingVolume = swingVolume + Volume[i]; } // Add the rest of the bar volume which trade after the low of the bar if (!CalculateOnBarClose) swingVolume = swingVolume + (Volume[CurrentBar - curLowBar] - signalBarVolumeUp); // Relativ swing volume if (showSwingVolume == VolumeMode.Relativ) { swingVolume = Math.Round(swingVolume / curHighDur, 0, MidpointRounding.AwayFromZero); // Output - Diameter sign isn't represented correct - use Latin capital letter O with stroke instead volumeOutput = "\u00D8 "; } if (swingVolume > 10000000000) { swingVolume = Math.Round(swingVolume / 1000000000, 0, MidpointRounding.AwayFromZero); volumeOutput = volumeOutput + swingVolume.ToString() + "B"; } else if (swingVolume > 10000000) { swingVolume = Math.Round(swingVolume / 1000000, 0, MidpointRounding.AwayFromZero); volumeOutput = volumeOutput + swingVolume.ToString() + "M"; } else if (swingVolume > 10000) { swingVolume = Math.Round(swingVolume / 1000, 0, MidpointRounding.AwayFromZero); volumeOutput = volumeOutput + swingVolume.ToString() + "K"; } else volumeOutput = volumeOutput + swingVolume.ToString(); DrawText("UpVolume" + swingCounterUp, AutoScale, volumeOutput, CurrentBar - curHighBar, curHigh, textOffsetVolume, textColor, textFont, StringAlignment.Center, Color.Transparent, Color.Transparent, 0); } } #endregion #region Calculate and visualize down swing values /// /// Calculate the down swing and visualize it. /// /// Bar number /// Low price /// Swing low update private void drawDnSwing(int bar, double low, bool updateLow) { string output = null; // New swing low if (!updateLow) { trendDir = -1; lastLow = curLow; lastLowBar = curLowBar; lastLowRel = curLowRel; curLowBar = bar; curLow = low; swingCounterDn++; dnFlip.Set(true); if (!CalculateOnBarClose && showSwingVolume != VolumeMode.False) signalBarVolumeUp = Volume[0]; if (activateAlertSound) PlaySound(alertFileName); if (statisticPosition != StatisticPosition.False) upStatistic(); } // Update swing low else { // Reset the down dot plot DoubleBottom.Reset(CurrentBar-curLowBar); LowerLow.Reset(CurrentBar-curLowBar); HigherLow.Reset(CurrentBar-curLowBar); // Remove the last down swing from the list Lo.RemoveAt(Lo.Count - 1); curLowBar = bar; curLow = low; if (!CalculateOnBarClose && showSwingVolume != VolumeMode.False) signalBarVolumeUp = Volume[0]; } // ##### Set the length of the down swing ########################### curLowLength = Convert.ToInt32(Math.Round((curLow - curHigh) / TickSize, 0, MidpointRounding.AwayFromZero)); // ##### Set the duration of the down swing ######################### curLowDur = curLowBar - curHighBar; // ##### Relation to the last down swing ############################ // Calculate the offset for a double bottom. dtbOffset= ATR(14)[CurrentBar - curLowBar] * dtbStrength / 100; // double bottom if (curLow > lastLow - dtbOffset && curLow < lastLow + dtbOffset) curLowRel = Relation.Double; // lower low else if (curLow < lastLow) curLowRel = Relation.Lower; // higher low else curLowRel = Relation.Higher; // ##### Add the swing low to the list of swing lows. ############### Swings dn = new Swings(curLowBar, curLow, curLowLength, curLowDur, curLowRel); Lo.Add(dn); // Set the number of all down swings. dnCount = Lo.Count - 1; // ##### Set the zigzag down line ################################### if (ShowMode.Both == show || ShowMode.ZigZagLines == show) { DrawLine("ZigZagDown" + swingCounterDn, AutoScale, CurrentBar - curHighBar, curHigh, CurrentBar - curLowBar, curLow, zigZagColorDown, lineStyle, lineWidth); } // ##### Set the down swing price or the down swing length ########## if (SwingLength.False != swingText) { // Set the down swing length switch (swingText) { // Swing length in ticks case SwingLength.Ticks: output = curLowLength.ToString(); break; // Swing length in points case SwingLength.Points: output = (curLowLength * TickSize).ToString(); break; // Swing price case SwingLength.SwingPrice: output = curLow.ToString(); break; // Swing price and points case SwingLength.SwingPriceAndPoints: output = curLow.ToString() + " / " + (curLowLength * TickSize).ToString(); break; // Swing price and ticks case SwingLength.SwingPriceAndTicks: output = curLow.ToString() + " / " + curLowLength.ToString(); break; // Swing length in percent case SwingLength.Percent: output = (Math.Round((100.0 / curHigh * (curLowLength * TickSize)), 2, MidpointRounding.AwayFromZero)).ToString(); break; } } // Test if curLow is HL, LL or DB and set the textcolor switch (curLowRel) { // Higher low case Relation.Higher: textColor = textColorHigher; break; // Lower low case Relation.Lower: textColor = textColorLower; break; // Double bottom case Relation.Double: textColor = textColorDtb; break; } // Add swing duration to the swing text output if (showDuration) { if (SwingLength.False != swingText) output = output + " / " + curLowDur.ToString(); else output = curLowDur.ToString(); } if (output != null) { int tempcurLowLength = curLowLength * -1; DrawText("Low" + swingCounterDn, AutoScale, output.ToString(), CurrentBar - curLowBar, curLow, -textOffset, textColor, textFont, StringAlignment.Center, Color.Transparent, Color.Transparent, 0); } // Add swing percentage to the output if (showSwingPercentage && curHighLength != 0) { double value = Math.Round(100.0 / curHighLength * Math.Abs(curLowLength), 1); DrawText("DnPerc" + swingCounterDn, AutoScale, value.ToString() + "%", CurrentBar - curLowBar, curLow, -textOffsetPercentage, textColor, textFont, StringAlignment.Center, Color.Transparent, Color.Transparent, 0); } // ##### Set the down dot plot ###################################### if (ShowMode.Both == show || ShowMode.Dots == show) { switch (curLowRel) { // Higher low case Relation.Higher: HigherLow.Set(CurrentBar - curLowBar, curLow); break; // Lower low case Relation.Lower: LowerLow.Set(CurrentBar - curLowBar, curLow); break; // Double bottom case Relation.Double: DoubleBottom.Set(CurrentBar - curLowBar, curLow); break; } } // ##### Set the down volume ######################################## if (showSwingVolume != VolumeMode.False) { double swingVolume = 0.0; string volumeOutput = ""; // Absolute swing volume for (int i = 0; i < curLowDur; i++) { swingVolume = swingVolume + Volume[i]; } // Add the rest of the bar volume which trade after the high of the bar if (!CalculateOnBarClose) swingVolume = swingVolume + (Volume[CurrentBar - curHighBar] - signalBarVolumeDn); // Relativ swing volume if (showSwingVolume == VolumeMode.Relativ) { swingVolume = Math.Round(swingVolume / curLowDur, 0, MidpointRounding.AwayFromZero); // Output - Diameter sign isn't represented correct - Latin capital letter O with stroke instead volumeOutput = "\u00D8 "; } if (swingVolume > 10000000000) { swingVolume = Math.Round(swingVolume / 1000000000, 0, MidpointRounding.AwayFromZero); volumeOutput = volumeOutput + swingVolume.ToString() + "B"; } else if (swingVolume > 10000000) { swingVolume = Math.Round(swingVolume / 1000000, 0, MidpointRounding.AwayFromZero); volumeOutput = volumeOutput + swingVolume.ToString() + "M"; } else if (swingVolume > 10000) { swingVolume = Math.Round(swingVolume / 1000, 0, MidpointRounding.AwayFromZero); volumeOutput = volumeOutput + swingVolume.ToString() + "K"; } else volumeOutput = volumeOutput + swingVolume.ToString(); DrawText("DnVolume" + swingCounterDn, AutoScale, volumeOutput, CurrentBar - curLowBar, curLow, -textOffsetVolume, textColor, textFont, StringAlignment.Center, Color.Transparent, Color.Transparent, 0); } } #endregion #region Statistic /// /// Calculate the up part of the statistic. /// private void upStatistic() { upCount = Hi.Count - 1; if (upCount == 0) return; // Calculate the average length of all up swings overallUpLength = overallUpLength + Hi[upCount].length; overallAvgUpLength = Math.Round(overallUpLength / upCount, 0, MidpointRounding.AwayFromZero); // Calculate the average duration of all up swings overallUpDuration = overallUpDuration + Hi[upCount].duration; overallAvgUpDuration= Math.Round(overallUpDuration / upCount, 0, MidpointRounding.AwayFromZero); // Short statistic if (upCount >= statisticLength) { // calculate the average for the last x up swings upLength = 0; upDuration = 0; for (int i = 0; i < statisticLength; i++) { upLength = upLength + Hi[upCount - i].length; upDuration = upDuration + Hi[upCount - i].duration; } avgUpLength = Math.Round(upLength / statisticLength, 0, MidpointRounding.AwayFromZero); avgUpDuration = Math.Round(upDuration / statisticLength, 0, MidpointRounding.AwayFromZero); } // Build string for the statistic output upStatSwing = "Up: " + upCount + " - Length all/last: " + overallAvgUpLength + "/" + avgUpLength + " - Bars all/last: " + overallAvgUpDuration + "/" + avgUpDuration; // Higher high if (lastHighRel == Relation.Higher) { // Higher high counter hhCount++; // Counter for the swings after the higher high if (curHighRel == Relation.Higher) hhCountHH++; // Higher high if (curHighRel == Relation.Lower) hhCountLH++; // Lower high if (lastLowRel == Relation.Higher) hhCountHL++; // Higher low if (lastLowRel == Relation.Lower) hhCountLL++; // Lower low // Calculate the percent values hhCountLHPercent = Math.Round(100.0 / hhCount * hhCountLH, 1, MidpointRounding.AwayFromZero); hhCountHHPercent = Math.Round(100.0 / hhCount * hhCountHH, 1, MidpointRounding.AwayFromZero); hhCountHLPercent = Math.Round(100.0 / hhCount * hhCountHL, 1, MidpointRounding.AwayFromZero); hhCountLLPercent = Math.Round(100.0 / hhCount * hhCountLL, 1, MidpointRounding.AwayFromZero); } // Lower high if (lastHighRel == Relation.Lower) { // Lower high counter lhCount++; // Counter for the swings after the lower high if (curHighRel == Relation.Higher) lhCountHH++; // Higher high if (curHighRel == Relation.Lower) lhCountLH++; // Lower high if (lastLowRel == Relation.Higher) lhCountHL++; // Higher low if (lastLowRel == Relation.Lower) lhCountLL++; // Lower low // Calculate the percent values lhCountLHPercent = Math.Round(100.0 / lhCount * lhCountLH, 1, MidpointRounding.AwayFromZero); lhCountHHPercent = Math.Round(100.0 / lhCount * lhCountHH, 1, MidpointRounding.AwayFromZero); lhCountHLPercent = Math.Round(100.0 / lhCount * lhCountHL, 1, MidpointRounding.AwayFromZero); lhCountLLPercent = Math.Round(100.0 / lhCount * lhCountLL, 1, MidpointRounding.AwayFromZero); } // Double top if (lastHighRel == Relation.Double) { // Double top counter dtCount++; // Counter for the swings after the double top if (curHighRel == Relation.Higher) dtCountHH++; // Higher high if (curHighRel == Relation.Lower) dtCountLH++; // Lower high if (lastLowRel == Relation.Higher) dtCountHL++; // Higher low if (lastLowRel == Relation.Lower) dtCountLL++; // Lower low // Calculate the percent values dtCountLHPercent = Math.Round(100.0 / dtCount * dtCountLH, 1, MidpointRounding.AwayFromZero); dtCountHHPercent = Math.Round(100.0 / dtCount * dtCountHH, 1, MidpointRounding.AwayFromZero); dtCountHLPercent = Math.Round(100.0 / dtCount * dtCountHL, 1, MidpointRounding.AwayFromZero); dtCountLLPercent = Math.Round(100.0 / dtCount * dtCountLL, 1, MidpointRounding.AwayFromZero); } // Build string for the statistic output upStatRel = "HH (" + hhCount + ") followed by - HH: " + hhCountHHPercent + "%" + " - LH: " + hhCountLHPercent + "%" + " - HL: " + hhCountHLPercent + "%" + " - LL: " + hhCountLLPercent + "%" + "\nLH (" + lhCount + ") followed by - HH: " + lhCountHHPercent + "%" + " - LH: " + lhCountLHPercent + "%" + " - HL: " + lhCountHLPercent + "%" + " - LL: " + lhCountLLPercent + "%" + "\nDT (" + dtCount + ") followed by - HH: " + dtCountHHPercent + "%" + " - LH: " + dtCountLHPercent + "%" + " - HL: " + dtCountHLPercent + "%" + " - LL: " + dtCountLLPercent + "%"; // Draw statistic drawStatistic(); } /// /// Calculate the down part of the statistic. /// private void dnStatistic() { dnCount = Lo.Count - 1; if (dnCount == 0) return; // Calculate the average length of all down swings overallDnLength = overallDnLength + Lo[dnCount].length; overallAvgDnLength = Math.Round(overallDnLength / dnCount, 0, MidpointRounding.AwayFromZero); // Calculate the average duration of all down swings overallDnDuration = overallDnDuration + Lo[dnCount].duration; overallAvgDnDuration= Math.Round(overallDnDuration / dnCount, 0, MidpointRounding.AwayFromZero); // Short statistic if (dnCount >= statisticLength) { // calculate the average for the last x dn swings dnLength = 0; dnDuration = 0; for (int i = 0; i < statisticLength; i++) { dnLength = dnLength + Lo[dnCount - i].length; dnDuration = dnDuration + Lo[dnCount - i].duration; } avgDnLength = Math.Round(dnLength / statisticLength, 0, MidpointRounding.AwayFromZero); avgDnDuration = Math.Round(dnDuration / statisticLength, 0, MidpointRounding.AwayFromZero); } dnStatSwing = "Dn: " + dnCount + " - Length all/last: " + overallAvgDnLength + "/" + avgDnLength + " - Bars all/last: " + overallAvgDnDuration + "/" + avgDnDuration; // Lower low if (lastLowRel == Relation.Lower) { // Lower low counter llCount++; // Counter for the swings after the lower low if (lastHighRel == Relation.Higher) llCountHH++; // Higher high if (lastHighRel == Relation.Lower) llCountLH++; // Lower high if (curLowRel == Relation.Higher) llCountHL++; // Higher low if (curLowRel == Relation.Lower) llCountLL++; // Lower low // Calculate the percent values llCountLHPercent = Math.Round(100.0 / llCount * llCountLH, 1, MidpointRounding.AwayFromZero); llCountHHPercent = Math.Round(100.0 / llCount * llCountHH, 1, MidpointRounding.AwayFromZero); llCountHLPercent = Math.Round(100.0 / llCount * llCountHL, 1, MidpointRounding.AwayFromZero); llCountLLPercent = Math.Round(100.0 / llCount * llCountLL, 1, MidpointRounding.AwayFromZero); } // Higher low if (lastLowRel == Relation.Higher) { // Higher low counter hlCount++; // Counter for the swings after the higher low if (lastHighRel == Relation.Higher) hlCountHH++; // Higher high if (lastHighRel == Relation.Lower) hlCountLH++; // Lower high if (curLowRel == Relation.Higher) hlCountHL++; // Higher low if (curLowRel == Relation.Lower) hlCountLL++; // Lower low // Calculate the percent values hlCountLHPercent = Math.Round(100.0 / hlCount * hlCountLH, 1, MidpointRounding.AwayFromZero); hlCountHHPercent = Math.Round(100.0 / hlCount * hlCountHH, 1, MidpointRounding.AwayFromZero); hlCountHLPercent = Math.Round(100.0 / hlCount * hlCountHL, 1, MidpointRounding.AwayFromZero); hlCountLLPercent = Math.Round(100.0 / hlCount * hlCountLL, 1, MidpointRounding.AwayFromZero); } // Double bottom if (lastLowRel == Relation.Double) { // Double bottom counter dbCount++; // Counter for the swings after the double bottom if (lastHighRel == Relation.Higher) dbCountHH++; // Higher high if (lastHighRel == Relation.Lower) dbCountLH++; // Lower high if (curLowRel == Relation.Higher) dbCountHL++; // Higher low if (curLowRel == Relation.Lower) dbCountLL++; // Lower low // Calculate the percent values dbCountLHPercent = Math.Round(100.0 / dbCount * dbCountLH, 1, MidpointRounding.AwayFromZero); dbCountHHPercent = Math.Round(100.0 / dbCount * dbCountHH, 1, MidpointRounding.AwayFromZero); dbCountHLPercent = Math.Round(100.0 / dbCount * dbCountHL, 1, MidpointRounding.AwayFromZero); dbCountLLPercent = Math.Round(100.0 / dbCount * dbCountLL, 1, MidpointRounding.AwayFromZero); } // Build string for the statistic output dnStatRel = "LL (" + llCount + ") followed by - HH: " + llCountHHPercent + "%" + " - LH: " + llCountLHPercent + "%" + " - HL: " + llCountHLPercent + "%" + " - LL: " + llCountLLPercent + "%" + "\nHL (" + hlCount + ") followed by - HH: " + hlCountHHPercent + "%" + " - LH: " + hlCountLHPercent + "%" + " - HL: " + hlCountHLPercent + "%" + " - LL: " + hlCountLLPercent + "%" + "\nDB (" + dbCount + ") followed by - HH: " + dbCountHHPercent + "%" + " - LH: " + dbCountLHPercent + "%" + " - HL: " + dbCountHLPercent + "%" + " - LL: " + dbCountLLPercent + "%"; // Draw statistic drawStatistic(); } /// /// Draw a text field with the up and down statistic. /// private void drawStatistic() { #if NT7 richTextBox.Text = upStatSwing + "\n" + dnStatSwing + "\n\n" + upStatRel + "\n\n" + dnStatRel; #else TextPosition textPosition = TextPosition.TopLeft; switch (statisticPosition) { case StatisticPosition.BottomLeft: textPosition = TextPosition.BottomLeft; break; case StatisticPosition.BottomRight: textPosition = TextPosition.BottomRight; break; case StatisticPosition.TopLeft: textPosition = TextPosition.TopLeft; break; case StatisticPosition.TopRight: textPosition = TextPosition.TopRight; break; default: textPosition = TextPosition.TopRight; break; } DrawTextFixed("Statistic", upStatSwing + "\n" + dnStatSwing + "\n\n" + upStatRel + "\n\n" + dnStatRel, textPosition); #endif } #endregion #region Properties //################################################################### #region Plots and Dataseries //=================================================================== /// /// Save the value for the current price position in relation to the swings: /// -2 double top, -1 lower high/low, 0 price is nowhere, 1 higher high/low, 2 double bottom /// [Browsable(false)] // this line prevents the data series from being displayed in the indicator properties dialog, do not remove public DataSeries PriceSwingRelation { get { return priceSwingRelation; } } /// /// Gets a value indicating if an up flip occured (true = up flip - false = no up flip). /// [Browsable(false)] // this line prevents the data series from being displayed in the indicator properties dialog, do not remove public BoolSeries UpFlip { get { return upFlip; } } /// /// Gets a value indicating if a down flip occured (true = down flip - false = no down flip). /// [Browsable(false)] // this line prevents the data series from being displayed in the indicator properties dialog, do not remove public BoolSeries DnFlip { get { return dnFlip; } } [Browsable(false)] // this line prevents the data series from being displayed in the indicator properties dialog, do not remove [XmlIgnore()] // this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove public DataSeries DoubleBottom { get { return Values[0]; } } [Browsable(false)] // this line prevents the data series from being displayed in the indicator properties dialog, do not remove [XmlIgnore()] // this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove public DataSeries LowerLow { get { return Values[1]; } } [Browsable(false)] // this line prevents the data series from being displayed in the indicator properties dialog, do not remove [XmlIgnore()] // this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove public DataSeries HigherLow { get { return Values[2]; } } [Browsable(false)] // this line prevents the data series from being displayed in the indicator properties dialog, do not remove [XmlIgnore()] // this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove public DataSeries DoubleTop { get { return Values[3]; } } [Browsable(false)] // this line prevents the data series from being displayed in the indicator properties dialog, do not remove [XmlIgnore()] // this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove public DataSeries LowerHigh { get { return Values[4]; } } [Browsable(false)] // this line prevents the data series from being displayed in the indicator properties dialog, do not remove [XmlIgnore()] // this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove public DataSeries HigherHigh { get { return Values[5]; } } //=================================================================== #endregion #region Parameters //=================================================================== /// /// Double top and bottom strength. /// [Description("Double top and bottom strength.")] [Category("Parameters")] [Gui.Design.DisplayName("DB/DT strength")] public int DtbStrength { get { return dtbStrength; } set { dtbStrength = Math.Max(1, value); } } /// /// For Standard or ZigZagUTC mode - small value = small swings - bigger value = bigger swings. /// [Description("For Standard or ZigZagUTC mode - small value = small swings - bigger value = bigger swings.")] [Category("Parameters")] [Gui.Design.DisplayName("Calculation size")] public int CalcSize { get { return calcSize; } set { calcSize = Math.Max(1, value); } } /// /// Swing calculation mode. /// [Description("Swing calculation mode.")] [Category("Parameters")] [Gui.Design.DisplayName("Calculation mode")] public SwingMode CalcMode { get { return calcMode; } set { calcMode = value; } } /// /// For PSAR mode only - The initial acceleration factor. /// [Description("For PSAR mode only - The initial acceleration factor.")] [Category("Parameters")] [Gui.Design.DisplayNameAttribute("PSAR Acceleration")] public double PsarAcceleration { get { return psarAcceleration; } set { psarAcceleration = Math.Max(0.00, value); } } /// /// For PSAR mode only - The acceleration step factor. /// [Description("For PSAR mode only - The acceleration step factor.")] [Category("Parameters")] [Gui.Design.DisplayNameAttribute("PSAR Acceleration step")] public double PsarAccelerationStep { get { return psarAccelerationStep; } set { psarAccelerationStep = Math.Max(0.02, value); } } /// /// For PSAR mode only - The maximum acceleration. /// [Description("For PSAR mode only - The maximum acceleration.")] [Category("Parameters")] [Gui.Design.DisplayNameAttribute("PSAR Acceleration max")] public double PsarAccelerationMax { get { return psarAccelerationMax; } set { psarAccelerationMax = Math.Max(0.02, value); } } //=================================================================== #endregion #region Sounds //=================================================================== [Description("Play a sound when a new swing occured.")] [Category("Sounds")] [Gui.Design.DisplayName("Sound Alert")] public bool ActivateAlertSound { get { return activateAlertSound; } set { activateAlertSound = value; } } [Description("Enter the soundfile name which must be located in 'installation path/NinjaTrader 6.5/sounds'. e.g. 'Alert1.wav'")] [Gui.Design.DisplayName("Soundfile Name")] [Category("Sounds")] public String AlertFileName { get { return alertFileName; } set { alertFileName = value; } } //=================================================================== #endregion #region Chart Display //=================================================================== [Description("Show swing length in ticks/points/percent or show the current swing price or nothing.")] [Gui.Design.DisplayName("Swing length")] [Category("Chart Display")] public SwingLength SwingText { get { return swingText; } set { swingText = value; } } [Description("How to visualize the swings. e.g. zigzag lines, dots, both.")] [Gui.Design.DisplayName("Swing visualization")] [Category("Chart Display")] public ShowMode Show { get { return show; } set { show = value; } } [Description("Show swing duration.")] [Gui.Design.DisplayName("Swing duration")] [Category("Chart Display")] public bool ShowDuration { get { return showDuration; } set { showDuration = value; } } [Description("Show swing relation to the last swing.")] [Gui.Design.DisplayName("Swing percentage")] [Category("Chart Display")] public bool ShowSwingPercentage { get { return showSwingPercentage; } set { showSwingPercentage = value; } } [Description("Show swing volume as average for each bar, absolute or nothing.")] [Gui.Design.DisplayName("Swing volume")] [Category("Chart Display")] public VolumeMode ShowVol { get { return showSwingVolume; } set { showSwingVolume = value; } } [Description("Show statistic and choose where it should be placed. (The last swing is not included in the statistic.)")] [Gui.Design.DisplayName("Statistic")] [Category("Chart Display")] public StatisticPosition StatPosition { get { return statisticPosition; } set { statisticPosition = value; } } [Description("Number of the last swings used for average swing length and duration calculation.")] [Gui.Design.DisplayNameAttribute("Statistic number of swings")] [Category("Chart Display")] public int StatisticLength { get { return statisticLength; } set { statisticLength = Math.Max(1, value); } } //=================================================================== #endregion #region Chart Visual //=================================================================== [Description("Dashstyle for the zigzag lines.")] [Gui.Design.DisplayNameAttribute("Line Style")] [Category("Chart Visual")] public DashStyle LineStyle { get { return lineStyle; } set { lineStyle = value; } } [Description("Line width for the zigzag lines.")] [Gui.Design.DisplayNameAttribute("Line Width")] [Category("Chart Visual")] public int LineWidth { get { return lineWidth; } set { lineWidth = Math.Max(1, value); } } [XmlIgnore()] [Description("Text font.")] [Gui.Design.DisplayNameAttribute("Text font")] [Category("Chart Visual")] public Font TextFont { get { return textFont; } set { textFont = value; } } [Browsable(false)] public string textFontSerialize { get { return NinjaTrader.Gui.Design.SerializableFont.ToString(textFont); } set { textFont = NinjaTrader.Gui.Design.SerializableFont.FromString(value); } } [Description("The text offset value in pixels from the specified swing high/low.")] [Gui.Design.DisplayNameAttribute("Text offset length / duration")] [Category("Chart Visual")] public int TextOffset { get { return textOffset; } set { textOffset = Math.Max(1, value); } } [Description("The text offset for the swing length relation to the last swing in percentage value in pixels from the specified swing high/low.")] [Gui.Design.DisplayNameAttribute("Text offset percentage")] [Category("Chart Visual")] public int TextOffsetPercentage { get { return textOffsetPercentage; } set { textOffsetPercentage = Math.Max(1, value); } } [Description("The text offset for the swing volume in pixels from the specified swing high/low.")] [Gui.Design.DisplayNameAttribute("Text offset volume")] [Category("Chart Visual")] public int TextOffsetVolume { get { return textOffsetVolume; } set { textOffsetVolume = Math.Max(1, value); } } [Description("Color of higher low/high.")] [Gui.Design.DisplayNameAttribute("Text color higher")] [Category("Chart Visual")] public Color TextColorHigher { get { return textColorHigher; } set { textColorHigher = value; } } [Browsable(false)] public string textColorHigherSerialize { get { return NinjaTrader.Gui.Design.SerializableColor.ToString(textColorHigher); } set { textColorHigher = NinjaTrader.Gui.Design.SerializableColor.FromString(value); } } [Description("Color of lower low/high.")] [Gui.Design.DisplayNameAttribute("Text color lower")] [Category("Chart Visual")] public Color TextColorLower { get { return textColorLower; } set { textColorLower = value; } } [Browsable(false)] public string textColorLowerSerialize { get { return NinjaTrader.Gui.Design.SerializableColor.ToString(textColorLower); } set { textColorLower = NinjaTrader.Gui.Design.SerializableColor.FromString(value); } } [Description("Color of double bottem/top.")] [Gui.Design.DisplayNameAttribute("Text color DTB")] [Category("Chart Visual")] public Color TextColorDtb { get { return textColorDtb; } set { textColorDtb = value; } } [Browsable(false)] public string textColorDTBSerialize { get { return NinjaTrader.Gui.Design.SerializableColor.ToString(textColorDtb); } set { textColorDtb = NinjaTrader.Gui.Design.SerializableColor.FromString(value); } } [Description("Color of zigzag up lines.")] [Gui.Design.DisplayNameAttribute("ZigZag color up")] [Category("Chart Visual")] public Color ZigZagColorUp { get { return zigZagColorUp; } set { zigZagColorUp = value; } } [Browsable(false)] public string zigZagColorUpSerialize { get { return NinjaTrader.Gui.Design.SerializableColor.ToString(zigZagColorUp); } set { zigZagColorUp = NinjaTrader.Gui.Design.SerializableColor.FromString(value); } } [Description("Color of zigzag down lines.")] [Gui.Design.DisplayNameAttribute("ZigZag color down")] [Category("Chart Visual")] public Color ZigZagColorDown { get { return zigZagColorDown; } set { zigZagColorDown = value; } } [Browsable(false)] public string zigZagColorDownSerialize { get { return NinjaTrader.Gui.Design.SerializableColor.ToString(zigZagColorDown); } set { zigZagColorDown = NinjaTrader.Gui.Design.SerializableColor.FromString(value); } } //=================================================================== #endregion #region Chart Support & Resistance //================================================================== [Description("Draw Support/Resistance Lines on the chart")] [Category("Chart Supp_Resist")] public bool DrawSR { get { return drawSR; } set { drawSR = value; } } [Description("Line Width for S/R Lines")] [Category("Chart Supp_Resist")] public int RectWidth { get { return rectWidth; } set { rectWidth = Math.Max(1, value); } } [Description("# of Ticks Up/DN for first edge of S/R Area")] [Category("Chart Supp_Resist")] public int SRL1 { get { return sRL1; } set { sRL1 = Math.Max(1, value); } } [Description("# of Ticks Up/Dn for second edge S/R Area")] [Category("Chart Supp_Resist")] public int SRL2 { get { return sRL2; } set { sRL2 = Math.Max(1, value); } } [Description("# of Ticks Up/Dn for successive S/R Areas when price passes through the first S/R area")] [Category("Chart Supp_Resist")] public int SRL3 { get { return sRL3; } set { sRL3 = Math.Max(1, value); } } [Description("Opacity for S/R 1=lightest 10=darkest")] [Category("Chart Supp_Resist")] public int SRopacity { get { return sRopacity; } set { sRopacity = Math.Max(1, value); } } [XmlIgnore()] [Description("Color for Resistance Rectangle")] [Category("Chart Supp_Resist")] public Color SRresistcolor { get { return sRresistcolor; } set { sRresistcolor = value; } } // Serialize color object [Browsable(false)] public string sRresistcolorSerialize { get { return NinjaTrader.Gui.Design.SerializableColor.ToString(sRresistcolor);} set {sRresistcolor = NinjaTrader.Gui.Design.SerializableColor.FromString(value);} } [XmlIgnore()] [Description("Color for Support Rectangle")] [Category("Chart Supp_Resist")] public Color SRsupptcolor { get { return sRsupptcolor; } set { sRsupptcolor = value; } } // Serialize color object [Browsable(false)] public string sRsupptcolorSerialize { get { return NinjaTrader.Gui.Design.SerializableColor.ToString(sRsupptcolor);} set {sRsupptcolor = NinjaTrader.Gui.Design.SerializableColor.FromString(value);} } [XmlIgnore()] [Description("Color for 'Jump' Resistance Rectangle...(when price runs through the zone) ")] [Category("Chart Supp_Resist")] public Color SRtjumpcolorR { get { return sRtjumpcolorR; } set { sRtjumpcolorR = value; } } // Serialize color object [Browsable(false)] public string sRtjumpcolorRSerialize { get { return NinjaTrader.Gui.Design.SerializableColor.ToString(sRtjumpcolorR);} set {sRtjumpcolorR = NinjaTrader.Gui.Design.SerializableColor.FromString(value);} } [XmlIgnore()] [Description("Color for 'Jump' Support Rectangle...(when price runs through the zone) ")] [Category("Chart Supp_Resist")] public Color SRtjumpcolorS { get { return sRtjumpcolorS; } set { sRtjumpcolorS = value; } } // Serialize color object [Browsable(false)] public string sRtjumpcolorSSerialize { get { return NinjaTrader.Gui.Design.SerializableColor.ToString(sRtjumpcolorS);} set {sRtjumpcolorS = NinjaTrader.Gui.Design.SerializableColor.FromString(value);} } //================================================================== #endregion #region Commented Out ...... Feature //=================================================================== // [Description("Show AB=CD pattern entry area.")] // [Gui.Design.DisplayNameAttribute("ABCD entry area")] // [Category("Feature")] // public bool AddAbcd // { // get { return addAbcd; } // set { addAbcd = value; } // } // [Description("Show Fibonacci extensions.")] // [Gui.Design.DisplayNameAttribute("Fib extensions")] // [Category("Feature")] // public bool AddFibExt // { // get { return addFibExt; } // set { addFibExt = value; } // } // [Description("Show slow Fibonacci retracement.")] // [Gui.Design.DisplayNameAttribute("Fib retracement")] // [Category("Feature")] // public bool AddSlowFibRet // { // get { return addSlowFibRet; } // set { addSlowFibRet = value; } // } // [Description("Show fast Fibonacci retracement.")] // [Gui.Design.DisplayNameAttribute("Fib retracement (fast)")] // [Category("Feature")] // public bool AddFastFibRet // { // get { return addFastFibRet; } // set { addFastFibRet = value; } // } //=================================================================== #endregion #region Commented Out ...... Visualize features //=================================================================== //[Description("Color of the Fibonacci long area.")] //[Gui.Design.DisplayNameAttribute("ABCD color long entry")] //[Category("Visualize features")] //public Color AbcdLong //{ // get { return abcdLong; } // set { abcdLong = value; } //} //[Browsable(false)] //public string AbcdLongSerialize //{ // get { return NinjaTrader.Gui.Design.SerializableColor.ToString(abcdLong); } // set { abcdLong = NinjaTrader.Gui.Design.SerializableColor.FromString(value); } //} // //[Description("Color of the Fibonacci short area.")] //[Gui.Design.DisplayNameAttribute("ABCD color short entry")] //[Category("Visualize features")] //public Color AbcdShort //{ // get { return abcdShort; } // set { abcdShort = value; } //} //[Browsable(false)] //public string abcdShortSerialize //{ // get { return NinjaTrader.Gui.Design.SerializableColor.ToString(abcdShort); } // set { abcdShort = NinjaTrader.Gui.Design.SerializableColor.FromString(value); } //} // //[Description("First value for the Fibonacci retracement area.")] //[Gui.Design.DisplayNameAttribute("ABCD Fib value 1)")] //[Category("Visualize features")] //public double FibValue1 //{ // get { return fibValue1; } // set { fibValue1 = Math.Max(0.0001, Math.Min(99.9999, value)); } //} // //[Description("Second value for the Fibonacci retracement area.")] //[Gui.Design.DisplayNameAttribute("ABCD Fib value 2")] //[Category("Visualize features")] //public double FibValue2 //{ // get { return fibValue2; } // set { fibValue2 = Math.Max(0.0001, Math.Min(99.9999, value)); } //} // //[Description("Opacity of the Fibonacci area.")] //[Gui.Design.DisplayNameAttribute("Color Fib area opacity")] //[Category("Visualize features")] //public int Opacity //{ // get { return opacity; } // set { opacity = Math.Max(1, value); } //} // //=================================================================== #endregion //################################################################### #endregion } } #region enums namespace PASwh.Utility { /// /// How to visualize the swings. e.g. Both, Dots, ZigZagLines. /// public enum ShowMode { Both, Dots, ZigZagLines, } /// /// Show swing length in ticks/points/percent or show the current swing price or nothing. /// public enum SwingLength { False, Ticks, Points, SwingPrice, Percent, SwingPriceAndPoints, SwingPriceAndTicks, } /// /// Contains information about the relation of the swing to the last swing. /// public enum Relation { Init, Double, Higher, Lower, } /// /// Swing calculation mode. /// public enum SwingMode { Standard, ZigZigUTC, PSAR, } /// /// Show swing volume as average volume for each bar, absolute or none. /// public enum VolumeMode { Absolute, False, Relativ, } /// /// Position for the statistic. /// public enum StatisticPosition { #if NT7 Bottom, False, Left, Right, Top, #else BottomLeft, BottomRight, False, TopLeft, TopRight, #endif } } #endregion #region NinjaScript generated code. Neither change nor remove. // This namespace holds all indicators and is required. Do not change it. namespace NinjaTrader.Indicator { public partial class Indicator : IndicatorBase { private PASwh[] cachePASwh = null; private static PASwh checkPASwh = new PASwh(); /// /// PASwh Ver 4.5 .... 07-07-2010) modified by Will Hoerl. PriceActionSwing calculates swings, calculates S/R levels, and displays swing statistics. /// /// public PASwh PASwh(SwingMode calcMode, int calcSize, int dtbStrength, double psarAcceleration, double psarAccelerationMax, double psarAccelerationStep) { return PASwh(Input, calcMode, calcSize, dtbStrength, psarAcceleration, psarAccelerationMax, psarAccelerationStep); } /// /// PASwh Ver 4.5 .... 07-07-2010) modified by Will Hoerl. PriceActionSwing calculates swings, calculates S/R levels, and displays swing statistics. /// /// public PASwh PASwh(Data.IDataSeries input, SwingMode calcMode, int calcSize, int dtbStrength, double psarAcceleration, double psarAccelerationMax, double psarAccelerationStep) { if (cachePASwh != null) for (int idx = 0; idx < cachePASwh.Length; idx++) if (cachePASwh[idx].CalcMode == calcMode && cachePASwh[idx].CalcSize == calcSize && cachePASwh[idx].DtbStrength == dtbStrength && Math.Abs(cachePASwh[idx].PsarAcceleration - psarAcceleration) <= double.Epsilon && Math.Abs(cachePASwh[idx].PsarAccelerationMax - psarAccelerationMax) <= double.Epsilon && Math.Abs(cachePASwh[idx].PsarAccelerationStep - psarAccelerationStep) <= double.Epsilon && cachePASwh[idx].EqualsInput(input)) return cachePASwh[idx]; lock (checkPASwh) { checkPASwh.CalcMode = calcMode; calcMode = checkPASwh.CalcMode; checkPASwh.CalcSize = calcSize; calcSize = checkPASwh.CalcSize; checkPASwh.DtbStrength = dtbStrength; dtbStrength = checkPASwh.DtbStrength; checkPASwh.PsarAcceleration = psarAcceleration; psarAcceleration = checkPASwh.PsarAcceleration; checkPASwh.PsarAccelerationMax = psarAccelerationMax; psarAccelerationMax = checkPASwh.PsarAccelerationMax; checkPASwh.PsarAccelerationStep = psarAccelerationStep; psarAccelerationStep = checkPASwh.PsarAccelerationStep; if (cachePASwh != null) for (int idx = 0; idx < cachePASwh.Length; idx++) if (cachePASwh[idx].CalcMode == calcMode && cachePASwh[idx].CalcSize == calcSize && cachePASwh[idx].DtbStrength == dtbStrength && Math.Abs(cachePASwh[idx].PsarAcceleration - psarAcceleration) <= double.Epsilon && Math.Abs(cachePASwh[idx].PsarAccelerationMax - psarAccelerationMax) <= double.Epsilon && Math.Abs(cachePASwh[idx].PsarAccelerationStep - psarAccelerationStep) <= double.Epsilon && cachePASwh[idx].EqualsInput(input)) return cachePASwh[idx]; PASwh indicator = new PASwh(); indicator.BarsRequired = BarsRequired; indicator.CalculateOnBarClose = CalculateOnBarClose; #if NT7 indicator.ForceMaximumBarsLookBack256 = ForceMaximumBarsLookBack256; indicator.MaximumBarsLookBack = MaximumBarsLookBack; #endif indicator.Input = input; indicator.CalcMode = calcMode; indicator.CalcSize = calcSize; indicator.DtbStrength = dtbStrength; indicator.PsarAcceleration = psarAcceleration; indicator.PsarAccelerationMax = psarAccelerationMax; indicator.PsarAccelerationStep = psarAccelerationStep; Indicators.Add(indicator); indicator.SetUp(); PASwh[] tmp = new PASwh[cachePASwh == null ? 1 : cachePASwh.Length + 1]; if (cachePASwh != null) cachePASwh.CopyTo(tmp, 0); tmp[tmp.Length - 1] = indicator; cachePASwh = tmp; return indicator; } } } } // This namespace holds all market analyzer column definitions and is required. Do not change it. namespace NinjaTrader.MarketAnalyzer { public partial class Column : ColumnBase { /// /// PASwh Ver 4.5 .... 07-07-2010) modified by Will Hoerl. PriceActionSwing calculates swings, calculates S/R levels, and displays swing statistics. /// /// [Gui.Design.WizardCondition("Indicator")] public Indicator.PASwh PASwh(SwingMode calcMode, int calcSize, int dtbStrength, double psarAcceleration, double psarAccelerationMax, double psarAccelerationStep) { return _indicator.PASwh(Input, calcMode, calcSize, dtbStrength, psarAcceleration, psarAccelerationMax, psarAccelerationStep); } /// /// PASwh Ver 4.5 .... 07-07-2010) modified by Will Hoerl. PriceActionSwing calculates swings, calculates S/R levels, and displays swing statistics. /// /// public Indicator.PASwh PASwh(Data.IDataSeries input, SwingMode calcMode, int calcSize, int dtbStrength, double psarAcceleration, double psarAccelerationMax, double psarAccelerationStep) { return _indicator.PASwh(input, calcMode, calcSize, dtbStrength, psarAcceleration, psarAccelerationMax, psarAccelerationStep); } } } // This namespace holds all strategies and is required. Do not change it. namespace NinjaTrader.Strategy { public partial class Strategy : StrategyBase { /// /// PASwh Ver 4.5 .... 07-07-2010) modified by Will Hoerl. PriceActionSwing calculates swings, calculates S/R levels, and displays swing statistics. /// /// [Gui.Design.WizardCondition("Indicator")] public Indicator.PASwh PASwh(SwingMode calcMode, int calcSize, int dtbStrength, double psarAcceleration, double psarAccelerationMax, double psarAccelerationStep) { return _indicator.PASwh(Input, calcMode, calcSize, dtbStrength, psarAcceleration, psarAccelerationMax, psarAccelerationStep); } /// /// PASwh Ver 4.5 .... 07-07-2010) modified by Will Hoerl. PriceActionSwing calculates swings, calculates S/R levels, and displays swing statistics. /// /// public Indicator.PASwh PASwh(Data.IDataSeries input, SwingMode calcMode, int calcSize, int dtbStrength, double psarAcceleration, double psarAccelerationMax, double psarAccelerationStep) { 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.PASwh(input, calcMode, calcSize, dtbStrength, psarAcceleration, psarAccelerationMax, psarAccelerationStep); } } } #endregion