public class BzvOpeningRange4 : Indicator { private string openTime = @"0930"; // Default setting for OpenTime private string rangeEndTime = @"0932"; // Default setting for RangeEndTime private string stopPlotTime = @"1600"; // When to stop plotting the lines. Must be outside the // defined range. private TimeSpan openTimeTS; public TimeSpan rangeEndTimeTS; private TimeSpan stopPlotTimeTS; private bool timeFormatErrorMsgGiven = false; private double highestHigh; private double lowestLow; private int highBar; private int lowBar; private bool testMsgGiven = false; private bool rangeCrosses = false; // True if range crosses date boundary private DateTime openDT; private DateTime rangeEndDT; private DateTime stopPlotDT; private DateTime openDate; private DateTime endDate; private bool daysRangeEndWa**** = false; // Indicates if the day's time range has been put in yet private Hashtable openingPriceRanges; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Enter the description for your new custom Indicator here."; Name = "BzvOpeningRange4"; Calculate = Calculate.OnPriceChange; IsOverlay = true; IsAutoScale = false; DisplayInDataBox = true; DrawOnPricePanel = true; DrawHorizontalGridLines = true; DrawVerticalGridLines = true; PaintPriceMarkers = true; ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right; //Disable this property if your indicator requires custom values that cumulate with each new market data event. //See Help Guide for additional information. IsSuspendedWhileInactive = true; AddPlot(Brushes.Orange, "RangeHighSeries"); AddPlot(Brushes.Orange, "RangeLowSeries"); } else if (State == State.Configure) { // Use this "unsupported method" to move the drawn lines behind the price bars: // Required for accurate readings; estimate only on historical data openTimeTS = convertTimeSetting(openTime); rangeEndTimeTS = convertTimeSetting(rangeEndTime);
Announcement
Collapse
Looking for a User App or Add-On built by the NinjaTrader community?
Visit NinjaTrader EcoSystem and our free User App Share!
Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less
Partner 728x90
Collapse
NinjaTrader
Int to string
Collapse
X
-
Int to string
I have attached part of the code for an indicator that plots open range. I would like to be able to add inputs for "openTime" and "rangeEndTime" so that I can optimize the range with the strategy analyzer. However, I cannot figure out how to add integer inputs and convert them to string variables so they can be used in establishing timespan. Any help would be greatly appreciated. Thanks.
Code:Tags: None
-
I use ToTime methods in my strategy to define trading times. I did not code this indicator myself, however, and I am unsure how to incorporate ToTime methods without having to redo the whole thing. Is there some language I'm overlooking that would simplify using inputs to define the time barriers?
Code:else if (State == State.Configure) { // Use this "unsupported method" to move the drawn lines behind the price bars: // Required for accurate readings; estimate only on historical data openTimeTS = convertTimeSetting(openTime); rangeEndTimeTS = convertTimeSetting(rangeEndTime); openingPriceRanges = new Hashtable(); if (String.IsNullOrEmpty(stopPlotTime)) { stopPlotTimeTS = openTimeTS; } else { stopPlotTimeTS = convertTimeSetting(stopPlotTime); } } rangeCrosses = (rangeEndTimeTS < openTimeTS); } // Hashtable openingPriceRanges = new Hashtable(); // Used to store range boudaries in a has table.... private struct BzvPriceRange { public double RangeHighPrice; public double RangeLowPrice; } protected override void OnBarUpdate() { // If we're on the first bar, do a reset and then get out... if (CurrentBar < 1) { doReset(); return; } // Wait until we have crossed at least one day boundary... if (Time[CurrentBar] >= Time[1]) { return; } // See if the current time passes over the "next" open time so that we need to // reset the "day"... openDT = openDate + openTimeTS; if (Time[0] >= openDT.AddDays(1)) { doReset(); } openDT = openDate + openTimeTS; rangeEndDT = endDate + rangeEndTimeTS; // If we're in the range (inclusive), then start tracking highs/lows... if (Time[0] >= openDT && Time[0] <= rangeEndDT) { if (High[0] > highestHigh) { highestHigh = High[0]; highBar = CurrentBar; } if (Low[0] < lowestLow) { lowestLow = Low[0]; lowBar = CurrentBar; } } // If we've passed the time range end, then plot... if (Time[0] > rangeEndDT) { daysRangeEndWa**** = true; // Handle stop plot time in a way that works with tick charts. if (Time[0] <= stopPlotDT) { // We've past the opening range. Plot the lines... // If previous plots are not set, then take it from the first // bar. Otherwise just do the current bar. (Just need to check // one of the plots.) if (RangeHighSeries[0] >= 1) { for (int idx = CurrentBar - highBar; idx >=0; idx--) { RangeHighSeries[idx] = (highestHigh); } for (int idx = CurrentBar - lowBar; idx >=0; idx--) { RangeLowSeries[idx] = (lowestLow); } // Now set the opening range for the day in the Hashtable. // This only happens once per day. DateTime todayDate = Times[BarsInProgress][0].Date; BzvPriceRange todayRange = new BzvPriceRange(); todayRange.RangeHighPrice = highestHigh; todayRange.RangeLowPrice = lowestLow; openingPriceRanges.Remove(todayDate); openingPriceRanges.Add(todayDate, todayRange); } else { RangeHighSeries[0] = (highestHigh); RangeLowSeries[0] = (lowestLow); } } } }
Comment
-
Hello zrobfrank,
To use ints instead of timespans you would need to change the variables to ints and where the timespans are used. For example the code
openTimeTS = convertTimeSetting(openTime);
Would need to be removed if you are using a int user input. Lets assume you made an int user input named OpenTime, wherever you had used openTimeTS in the code you would need to change that to use ToTime and the OpenTime. A simple example would be the following which also assumes you have a user input named CloseTime.
if (ToTime(Time[0]) >= OpenTime && ToTime(Time[0]) <= CloseTime)
{
}
In the UI you would type in the time as an integer like this: 74500JesseNinjaTrader Customer Service
Comment
-
I've modified the indicator and continue to get the error "OnBarUpdate: you're accessing an index with a value that is invalid". I have tried everything I can think of. Any help would be greatly appreciated. Thanks. (I cut out the last region to make it fit; I don't think that's where the problem is)
Code:#region Using declarations using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Xml.Serialization; using NinjaTrader.Cbi; using NinjaTrader.Gui; using NinjaTrader.Gui.Chart; using NinjaTrader.Gui.SuperDom; using NinjaTrader.Gui.Tools; using NinjaTrader.Data; using NinjaTrader.NinjaScript; using NinjaTrader.Core.FloatingPoint; using NinjaTrader.NinjaScript.DrawingTools; using System.Collections; #endregion namespace NinjaTrader.NinjaScript.Indicators { public class Orange : Indicator { private int openTime = 930; // Default setting for OpenTime private int rangeEndTime = 932; // Default setting for RangeEndTime private int stopPlotTime = 1600; // Default setting for StopPlotTime private TimeSpan openTimeTS; private TimeSpan rangeEndTimeTS; private TimeSpan stopPlotTimeTS; private bool timeFormatErrorMsgGiven = false; private double highestHigh; private double lowestLow; private int highBar; private int lowBar; private bool testMsgGiven = false; private bool rangeCrosses = false; // True if range crosses date boundary private DateTime openDT; private DateTime rangeEndDT; private DateTime stopPlotDT; private DateTime openDate; private DateTime endDate; private bool daysRangeEndWa**** = false; private Hashtable openingPriceRanges; private Series<double> rangeHighSeries; private Series<double> rangeLowSeries; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Enter the description for your new custom Indicator here."; Name = "Orange"; Calculate = Calculate.OnPriceChange; IsOverlay = true; IsAutoScale = false; DisplayInDataBox = true; DrawOnPricePanel = true; DrawHorizontalGridLines = true; DrawVerticalGridLines = true; PaintPriceMarkers = true; ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right; IsSuspendedWhileInactive = true; AddPlot(Brushes.Orange, "RangeHighSeries"); AddPlot(Brushes.Orange, "RangeLowSeries"); rangeEndMinutesIncrement = 60; } else if (State == State.Configure) { openTimeTS = ConvertTimeSetting(openTime.ToString()); rangeEndTimeTS = ConvertTimeSetting(rangeEndTime.ToString()); rangeEndTimeTS = openTimeTS.Add(TimeSpan.FromMinutes(rangeEndMinutesIncrement)); // Ensure that rangeEndTime is never less than openTime if (rangeEndTimeTS < openTimeTS) { rangeEndTimeTS = openTimeTS; } openingPriceRanges = new Hashtable(); stopPlotTimeTS = ConvertTimeSetting(stopPlotTime.ToString()); // Initialize the series only once rangeHighSeries = new Series<double>(this); rangeLowSeries = new Series<double>(this); rangeCrosses = (rangeEndTimeTS < openTimeTS); } } protected override void OnBarUpdate() { // If we're on the first bar, do a reset and then get out... if (CurrentBar < 1) { DoReset(); return; } // Wait until we have crossed at least one day boundary... if (Time[CurrentBar] >= Time[1]) { return; } // See if the current time passes over the "next" open time so that we need to // reset the "day"... openDT = openDate + openTimeTS; if (Time[0] >= openDT.AddDays(1)) { DoReset(); } openDT = openDate + openTimeTS; rangeEndDT = endDate + rangeEndTimeTS; if (CurrentBar < 10 || Highs[0].Count < 1 || Lows[0].Count < 1) { return; } // If we're in the range (inclusive), then start tracking highs/lows... if (Time[0] >= openDT && Time[0] <= rangeEndDT) { if (Highs[0][0] > highestHigh) { highestHigh = Highs[0][0]; highBar = CurrentBar; } if (Lows[0][0] < lowestLow) { lowestLow = Lows[0][0]; lowBar = CurrentBar; } } // If we've passed the time range end, then plot... if (Time[0] > rangeEndDT) { daysRangeEndWa**** = true; // Ensure that there are bars available at the current index if (rangeHighSeries.Count < 1 || rangeLowSeries.Count < 1) { return; } // Handle stop plot time in a way that works with tick charts. if (Time[0] <= stopPlotDT) { // We've past the opening range. Plot the lines... // If previous plots are not set, then take it from the first // bar. Otherwise, just do the current bar. (Just need to check // one of the plots.) if (rangeHighSeries[0] >= 1) { for (int idx = highBar; idx >= 0; idx--) { rangeHighSeries[idx] = highestHigh; } for (int idx = lowBar; idx >= 0; idx--) { rangeLowSeries[idx] = lowestLow; } // Now set the opening range for the day in the Hashtable. // This only happens once per day. DateTime todayDate = Times[BarsInProgress][0].Date; BzvPriceRange todayRange = new BzvPriceRange(); todayRange.RangeHighPrice = highestHigh; todayRange.RangeLowPrice = lowestLow; openingPriceRanges.Remove(todayDate); openingPriceRanges.Add(todayDate, todayRange); } else { rangeHighSeries[0] = highestHigh; rangeLowSeries[0] = lowestLow; } } } } private TimeSpan ConvertTimeSetting(string strTime) { int theHour; int theMins; TimeSpan theTime; // Convert time setting to TimeSpan type... if (strTime.Length == 4) { try { theHour = Convert.ToInt32(strTime.Substring(0, 2)); theMins = Convert.ToInt32(strTime.Substring(2, 2)); // Validate that the minutes are within the valid range (0 to 59) if (theMins < 0 || theMins >= 60) { MessageBox.Show("Invalid minutes value in time setting (" + strTime + "). Defaulting to 0930 in " + Name + "."); theTime = new TimeSpan(9, 30, 0); } else { theTime = new TimeSpan(theHour, theMins, 0); } } catch { MessageBox.Show("Invalid time setting format (" + strTime + "). Defaulting to 0930 in " + Name + "."); theTime = new TimeSpan(9, 30, 0); } } else { theTime = new TimeSpan(9, 30, 0); } return theTime; } private void DoReset() { // Figure out if range crosses a date boundary and set up for the condition... openDate = Time[0].Date; if (rangeCrosses) { endDate = openDate.AddDays(1); } else { endDate = openDate; } // Which date is the stopTime on? if (!rangeCrosses && stopPlotTimeTS <= openTimeTS) { stopPlotDT = openDate.AddDays(1) + stopPlotTimeTS; } else if (!rangeCrosses && stopPlotTimeTS >= rangeEndTimeTS) { stopPlotDT = endDate + stopPlotTimeTS; } else if (rangeCrosses && stopPlotTimeTS <= openTimeTS) { stopPlotDT = openDate.AddDays(1) + stopPlotTimeTS; } else if (rangeCrosses && stopPlotTimeTS >= rangeEndTimeTS) { stopPlotDT = endDate + stopPlotTimeTS; } highestHigh = 0; lowestLow = 9999999; highBar = 0; lowBar = 0; daysRangeEndWa**** = false; } public double GetRangeHighForDate(DateTime theDate) { Update(); DateTime keyDate = theDate.Date; BzvPriceRange theRange; double rangeHighPrice = -1.000; DateTime yesterDate = theDate.AddDays(-1).Date; if (openingPriceRanges.ContainsKey(keyDate)) { theRange = (BzvPriceRange)openingPriceRanges[keyDate]; rangeHighPrice = theRange.RangeHighPrice; } else if (openingPriceRanges.ContainsKey(yesterDate)) { theRange = (BzvPriceRange)openingPriceRanges[yesterDate]; rangeHighPrice = theRange.RangeHighPrice; } return rangeHighPrice; } public double GetRangeLowForDate(DateTime theDate) { Update(); DateTime keyDate = theDate.Date; BzvPriceRange theRange; double rangeLowPrice = -1.000; DateTime yesterDate = theDate.AddDays(-1).Date; if (openingPriceRanges.ContainsKey(keyDate)) { theRange = (BzvPriceRange)openingPriceRanges[keyDate]; rangeLowPrice = theRange.RangeLowPrice; } else if (openingPriceRanges.ContainsKey(yesterDate)) { theRange = (BzvPriceRange)openingPriceRanges[yesterDate]; rangeLowPrice = theRange.RangeLowPrice; } return rangeLowPrice; } #region Properties [NinjaScriptProperty] [Range(1, int.MaxValue)] [Display(Name="rangeEndMinutesIncrement", Order=1, GroupName="Parameters")] public int rangeEndMinutesIncrement { get; set; } [NinjaScriptProperty] [Range(1, int.MaxValue)] [Display(Name = "Session Start Time (hhmm)", Order = 1, GroupName = "Parameters")] public int OpenTime { get { return openTime; } set { openTime = value; } } // Change the type of RangeEndTime property to int [NinjaScriptProperty] [Range(2, int.MaxValue)] [Display(Name = "Opening range end time (hhmm)", Order = 2, GroupName = "Parameters")] public int RangeEndTime { get { return rangeEndTime; } set { rangeEndTime = value; } } [Browsable(false)] public Series<double> RangeHighSeries { get { Update(); return rangeHighSeries; } } [Browsable(false)] public Series<double> RangeLowSeries { get { Update(); return rangeLowSeries; } } // Change the type of StopPlotTime property to int [NinjaScriptProperty] [Range(3, int.MaxValue)] [Display(Name = "Time at which to stop plotting the lines (hhmm)", Order = 3, GroupName = "Parameters")] public int StopPlotTime { get { return stopPlotTime; } set { stopPlotTime = value; } } [Browsable(false)] public bool TodaysRangeIsIn { get { Update(); return daysRangeEndWa****; } } #endregion private struct BzvPriceRange { public double RangeHighPrice; public double RangeLowPrice; } } }
Comment
-
Hello zrobfrank,
That means one of the bars ago or index's that you used is incorrect. You would have to find the specific line having an error to be able to debug that type of message. The best solution is to add prints throughout your logic to see which prints get printed and which do not. Once the error happens you would look at which prints happened before the error to get an idea of which line of code is having a problem.JesseNinjaTrader Customer Service
Comment
Latest Posts
Collapse
Topics | Statistics | Last Post | ||
---|---|---|---|---|
Started by funk10101, Today, 11:35 AM
|
0 responses
0 views
0 likes
|
Last Post
by funk10101
Today, 11:35 AM
|
||
Started by samish18, Today, 11:26 AM
|
0 responses
1 view
0 likes
|
Last Post
by samish18
Today, 11:26 AM
|
||
Started by Trader146, 03-29-2024, 01:22 PM
|
2 responses
14 views
0 likes
|
Last Post
by Trader146
Today, 11:24 AM
|
||
Started by tsantospinto, 04-12-2024, 07:04 PM
|
7 responses
127 views
0 likes
|
Last Post
by aligator
Today, 11:08 AM
|
||
Started by futtrader, 04-21-2024, 01:50 AM
|
5 responses
56 views
0 likes
|
Last Post Today, 10:57 AM |
Comment