#region Using declarations
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Gui.Chart;
using System.Xml;
using System.Net;
using System.Net.Cache;
using System.IO;
using System.Text;
using System.Globalization;
#endregion
///
/// jtEconNews2a - johnthom.com - 10/19/09 (please do not remove this line)
/// with bugfix added by Fat Tails 11/25/01
namespace NinjaTrader.Indicator
{
///
///
/// NOTE: If you are reading this because you are getting errors pertaining to date parsing then please do this:
///
/// 1) Set 'debug' to true in the indicator settings.
/// 2) Open an Output Window.
/// 3) Refresh your chart.
/// 4) Do a select all of the Output Window text and post it on my blog entry here... http://www.johnthom.com/2009/10/economic-news-indicator.html
///
/// I will attempt to fix the issue. I have done this once before but apparently there are certain
/// country specific date parsing issues that I've still to address.
///
/// ============================================================================================
///
/// This is my version of the old Metatrader FFCal indicator. I stuck with using ForexFactory
/// as I think their events are more inclusive than econoday and fxstreet.
///
/// Change Log:
///
/// 10/19/09 - Fixed a bug with date/time parsing in a non-"en-US" culture. Thanks
/// Harry104, from Berlin, for all your help tacking this down. Also, updated
/// "No more News" messages to be more helpful.
///
/// 10/29/09 - Added properties and logic to for a background. Fixed bugs. Improved effeciency.
///
/// 11/02/09 - Final version. Code cleanup. Only bug fixes from this point on.
///
///
[Description("jtEconNews2b - Display upcoming economic news events from ForexFactory.com")]
public class jtEconNews2b : Indicator
{
///
/// Internal class used to hold news event state.
///
public class NewsEvent {
public int ID;
public string Title;
public string Country;
public string Date;
public string Time;
public string Impact;
public string Forecast;
public string Previous;
[XmlIgnore()]
public DateTime DateTimeLocal;
public override string ToString(){
return string.Format("ID: {0}, Title: {1}, Country: {2}, Date: {3}, Time: {4}, Impact: {5}, Forecast: {6}, Previous: {7}, DateTimeLocal: {8}",
ID, Title, Country, Date, Time,Impact, Forecast, Previous, DateTimeLocal);
}
}
// class variables
private const string ffNewsUrl = @"http://www.forexfactory.com/ffcal_week_this.xml";
private const string TIME = "Time";
private const string IMPACT = "Impact";
private const string DESC = "News Event Description (prev/forecast)";
private const float TIME_PAD = 10;
private const float IMPACT_PAD = 10;
private const float DESC_PAD = 0;
private NewsEvent[] newsEvents = null;
private DateTime lastNewsUpdate = DateTime.MinValue;
private string lastLoadError;
private SolidBrush headerTitleBrush;
private SolidBrush lineHighBrush;
private SolidBrush lineMedBrush;
private SolidBrush lineLowBrush;
private SolidBrush lineNormalBrush;
private System.Collections.Generic.List list;
private float widestTimeCol = 0;
private float widestImpactCol = 0;
private float widestDescCol = 0;
private float totalHeight = 0;
private float longestLine = 0;
private int lastNewsPtr = 0;
private DateTime lastMinute;
// Must specify that culture that should be used to parse the ForexFactory date/time data.
private CultureInfo ffDateTimeCulture = CultureInfo.CreateSpecificCulture("en-US");
// property variables
private bool debug = false;
private float topOffset = 20;
private float leftOffset = 10;
private int maxNewsItems = 10; // max to display
private int newsRefeshInterval = 15;
private int newsItemPtr = 0;
private bool use24timeFormat = false;
private bool todaysNewsOnly = true;
private bool sendAlerts = true;
private int alertInterval = 15;
private string alertWavFileName = "Alert1.wav"; // some fonts and colors changed by Fat Tails
///
private Font titleFont = new Font("Arial", 1, FontStyle.Italic | FontStyle.Bold);
private Font headerFont = new Font("Arial", 1, FontStyle.Bold); // this should be a property
private Font lineFont = new Font("Arial", 10, FontStyle.Regular);
private Font lineAlertFont = new Font("Arial", 10, FontStyle.Bold | FontStyle.Italic);
private bool usaOnly = false;
private bool showLowPriority = true;
private Color headerColor = Color.Black; // some colors changed by Fat Tails January 25, 2011
private Color lineHighColor = Color.Red; //
private Color lineMedColor = Color.Yellow; //
private Color lineLowColor = Color.GreenYellow; //
private Color lineNormalColor = Color.LightSkyBlue; // added by Fat Tails January 25, 2011
private Color backgroundColor = Color.Black; //
private Color borderColor = Color.SlateBlue; //
private bool showBackground = true;
private int backgroundOpacity = 255;
///
/// This method is used to configure the indicator and is called once before any bar data is loaded.
///
protected override void Initialize()
{
this.Name="jtEconNews2b"; // changed by Fat Tails January 25, 2011
CalculateOnBarClose = false;
Overlay = true;
PriceTypeSupported = false;
ZOrder = int.MaxValue;;
headerTitleBrush = new SolidBrush(headerColor);
lineHighBrush = new SolidBrush(lineHighColor);
lineMedBrush = new SolidBrush(lineMedColor);
lineLowBrush = new SolidBrush(lineLowColor);
lineNormalBrush = new SolidBrush (lineNormalColor); // added by Fat Tails January 25, 2011
list = new System.Collections.Generic.List();
lastNewsPtr = -1;
lastMinute = DateTime.MinValue;
LoadNews();
}
///
/// This will be called on Initialization and then every news refresh interval. If an
/// error occurs calling the website then it will take another interval before we
/// try again.
///
private void LoadNews(){
lastNewsUpdate = DateTime.Now;
lastLoadError = null;
try {
if (debug){
Print("LoadNews()....");
string[] patts = CultureInfo.CurrentCulture.DateTimeFormat.GetAllDateTimePatterns();
Print("All DateTime Patterns for culture: " + CultureInfo.CurrentCulture.Name);
foreach(string patt in patts){
Print(" " + patt);
}
Print("End of DateTime Patterns");
}
// add a random query string to defeat server side caching.
string urltweak = ffNewsUrl + "?x=" + Convert.ToString(DateTime.Now.Ticks);
if (debug) Print("Loading news from URL: " + urltweak);
HttpWebRequest newsReq = (HttpWebRequest)HttpWebRequest.Create(urltweak);
newsReq.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.Reload);
// fetch the xml doc from the web server
using (HttpWebResponse newsResp = (HttpWebResponse)newsReq.GetResponse()){
// check that we got a valid reponse
if (newsResp != null && newsResp.StatusCode == HttpStatusCode.OK){
// read the response stream into and xml document
Stream receiveStream = newsResp.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
StreamReader readStream = new StreamReader( receiveStream, encode );
string xmlString = readStream.ReadToEnd();
if (debug) Print("RAW http response: " + xmlString);
XmlDocument newsDoc = new XmlDocument();
newsDoc.LoadXml(xmlString);
if (debug) Print("XML news event node count: " + newsDoc.DocumentElement.ChildNodes.Count );
// build collection of events
System.Collections.ArrayList list = new System.Collections.ArrayList();
int itemId = 0;
foreach(XmlNode xmlNode in newsDoc.DocumentElement.ChildNodes){
NewsEvent newsEvent = new NewsEvent();
newsEvent.Time = xmlNode.SelectSingleNode("time").InnerText;
if (string.IsNullOrEmpty(newsEvent.Time)) continue; // ignore tentative events!
newsEvent.Date = xmlNode.SelectSingleNode("date").InnerText;
// assembly and convert event date/time to local time.
if (debug) Print(string.Format("About to parse Date '{0}', Time '{1}'", newsEvent.Date, newsEvent.Time));
newsEvent.DateTimeLocal = DateTime.SpecifyKind(DateTime.Parse( newsEvent.Date + " " + newsEvent.Time, ffDateTimeCulture), DateTimeKind.Utc).ToLocalTime();
if (debug) Print("Succesfully parsed datetime: " + newsEvent.DateTimeLocal.ToString() + " to local time.");
// filter events based on settings...
DateTime startTime = DateTime.Now;
DateTime endTime = startTime.AddDays(1);
// filter news events based on various property settings...
if (newsEvent.DateTimeLocal >= startTime && (!todaysNewsOnly || newsEvent.DateTimeLocal.Date < endTime.Date))
{
newsEvent.ID = ++itemId;
newsEvent.Country = xmlNode.SelectSingleNode("country").InnerText;
if (usaOnly && newsEvent.Country != "USD") continue;
newsEvent.Forecast = xmlNode.SelectSingleNode("forecast").InnerText;
newsEvent.Impact = xmlNode.SelectSingleNode("impact").InnerText;
if (!showLowPriority && newsEvent.Impact.ToUpper() == "LOW") continue;
newsEvent.Previous = xmlNode.SelectSingleNode("previous").InnerText;
newsEvent.Title = xmlNode.SelectSingleNode("title").InnerText;
list.Add(newsEvent);
if (debug) Print("Added: " + newsEvent.ToString());
}
}
// load the array
newsEvents = (NewsEvent[])list.ToArray(typeof(NewsEvent));
if (debug) Print("Added a total of " + list.Count + " events to array.");
} else {
// handle unexpected scenarios...
if (newsResp == null) throw new Exception("Web response was null.");
else throw new Exception("Web response status code = " + newsResp.StatusCode.ToString());
}
}
} catch (Exception ex){
Print(ex.ToString());
lastLoadError = ex.Message;
}
}
///
/// Called on each bar update event (incoming tick)
///
protected override void OnBarUpdate()
{
// we only need to update at most every minute since this is the max granularity of the
// date/time of the news events. This saves a little wear and tear.
if (Time[0] >= lastMinute.AddMinutes(1))
{
if (debug) Print("OnBarUpdate running...");
lastMinute = Time[0];
// download the news data every news refresh interval (not bar interval).
if (lastNewsUpdate.AddMinutes(newsRefeshInterval) < DateTime.Now){
LoadNews();
}
newsItemPtr = -1; // this will indicate that there are no pending items at this time.
// set pointer to the first "pending" news item in the list based on current datetime.
if (newsEvents != null && newsEvents.Length > 0)
{
for(int x = 0; x < newsEvents.Length ; x++){
NewsEvent item = newsEvents[x];
if (item.DateTimeLocal >= DateTime.Now ){
newsItemPtr = x;
break;
}
}
BuildList();
}
}
}
private void BuildList(){
if (debug) Print("Building List. lastNewsPtr: " + lastNewsPtr + " newsItemPtr: " + newsItemPtr);
list = new System.Collections.Generic.List();
// add headers
TextLine line = new TextLine(headerFont, headerTitleBrush);
line.timeColumn = new TextColumn(TIME_PAD, TIME);
line.impactColumn = new TextColumn(IMPACT_PAD, IMPACT);
line.descColumn = new TextColumn(DESC_PAD, DESC);
list.Add(line);
int lineCnt = 0;
// add detail lines...
for (int x = newsItemPtr; x < newsEvents.Length; x++){
lineCnt++;
// limit the number of pending events to be displayed.
if (lineCnt > maxNewsItems) break;
NewsEvent item = newsEvents[x];
// Set the brush color and alert priority based on event impact level.
Priority alertPriority = Priority.Low;
SolidBrush lineBrush = lineNormalBrush;
if (item.Impact.ToUpper() == "HIGH"){
lineBrush = lineHighBrush;
alertPriority = Priority.High;
} else if (item.Impact.ToUpper() == "MEDIUM"){
lineBrush = lineMedBrush;
alertPriority = Priority.Medium;
} else if (item.Impact.ToUpper() == "LOW"){
lineBrush = lineLowBrush;
}
// Format time based on option selected.
string tempTime = null;
if (use24timeFormat){
tempTime = item.DateTimeLocal.ToString(" HH:mm", ffDateTimeCulture);
} else {
tempTime = item.DateTimeLocal.ToString("hh:mm tt", ffDateTimeCulture);
}
// if we are displaying all pending news then include the month/day as part of the time.
if (!todaysNewsOnly){
tempTime = item.DateTimeLocal.ToString("MM/dd ") + tempTime;
}
// if alerts are enable, check to see if event is within alert range.
Font tempFont;
TimeSpan diff = item.DateTimeLocal - DateTime.Now;
if (sendAlerts && diff.TotalMinutes <= alertInterval ){
tempFont = lineAlertFont;
Alert("jtEconNewsAlert"+item.ID,alertPriority, string.Format( "News Alert: {0} {1}: {2}" , item.DateTimeLocal,item.Country, item.Title),alertWavFileName, Int32.MaxValue, lineBrush.Color, Color.White);
} else {
tempFont = lineFont;
}
// create a text line for the event details
line = new TextLine(tempFont, lineBrush);
line.timeColumn = new TextColumn(TIME_PAD, tempTime);
line.impactColumn = new TextColumn(IMPACT_PAD, item.Impact);
string templine = null;
if (item.Previous.Trim().Length == 0 && item.Forecast.Trim().Length == 0){
templine = string.Format("{0}{1}", usaOnly?"":item.Country+": " , item.Title);
} else {
templine = string.Format("{0}{1} ({2}/{3})", usaOnly?"":item.Country+": " , item.Title, item.Previous, item.Forecast );
}
line.descColumn = new TextColumn(DESC_PAD, templine);
list.Add(line);
}
}
public override void Plot(Graphics graphics, Rectangle bounds, double min, double max)
{
base.Plot(graphics, bounds, min, max);
float yOffset = bounds.Y + topOffset;
float xOffset = bounds.X + leftOffset;
graphics.DrawString("jtEconNews2a - news courtesy of ForexFactory.com - all times are local", titleFont, headerTitleBrush, xOffset, yOffset);
yOffset += titleFont.Height;
if (lastLoadError != null){ // an error occurred trying to load the xml data.
graphics.DrawString("News load error: " + lastLoadError , lineFont,lineHighBrush, xOffset, yOffset);
} else if (newsItemPtr == -1){ // there is no new news data yet.
string tempString;
if (todaysNewsOnly){
tempString = "(There are no pending news events for the rest of the day.)";
} else {
tempString = "(There are no pending news events at this time.)";
}
graphics.DrawString(tempString , lineFont, lineMedBrush, xOffset, yOffset);
}
else
{
widestTimeCol = 0;
widestImpactCol = 0;
widestDescCol = 0;
totalHeight = 0;
// pre-calc the max column widths and total line height
foreach(TextLine tLine in list){
float f = tLine.timeColumn.GetLength(graphics, tLine.font);
if (f > widestTimeCol) widestTimeCol = f;
f = tLine.impactColumn.GetLength(graphics, tLine.font);
if (f > widestImpactCol) widestImpactCol = f;
f = tLine.descColumn.GetLength(graphics, tLine.font);
if (f > widestDescCol) widestDescCol = f;
totalHeight += tLine.font.Height;
}
longestLine = widestTimeCol + widestImpactCol + widestDescCol;
// display graphics...
if (showBackground){
Brush backBrush = new SolidBrush(Color.FromArgb(backgroundOpacity, backgroundColor));
graphics.FillRectangle(backBrush, xOffset, yOffset, longestLine, totalHeight);
backBrush.Dispose();
Pen borderPen = new Pen(borderColor);
graphics.DrawRectangle(borderPen, xOffset, yOffset, longestLine, totalHeight);
borderPen.Dispose();
}
float tempy = yOffset;
foreach(TextLine tLine in list){
float tempx = xOffset;
graphics.DrawString(tLine.timeColumn.text, tLine.font, tLine.brush, tempx, tempy);
tempx += widestTimeCol;
graphics.DrawString(tLine.impactColumn.text, tLine.font, tLine.brush, tempx, tempy);
tempx += widestImpactCol;
graphics.DrawString(tLine.descColumn.text, tLine.font, tLine.brush, tempx, tempy);
tempy += tLine.font.Height;
}
}
}
///
/// Utility classes to encapsulate the graphical requirements for each line and column of data
///
private class TextColumn {
public TextColumn(float padding, string text){
this.padding = padding;
this.text = text;
}
public float padding;
public string text;
public float GetLength(Graphics graphics, Font font){
return graphics.MeasureString(text, font).Width + padding;
}
}
private class TextLine {
public TextLine(Font font, Brush brush){
this.graphics = graphics;
this.font = font;
this.brush = brush;
}
public TextColumn timeColumn;
public TextColumn impactColumn;
public TextColumn descColumn;
public Font font;
public Brush brush;
private Graphics graphics;
}
#region Properties
[Description("Offset from top of window.")]
[Category("Display")]
public float TopOffset
{
get { return topOffset; }
set { topOffset = value; }
}
[Description("Offset from left of window.")]
[Category("Display")]
public float LeftOffset
{
get { return leftOffset; }
set { leftOffset = value; }
}
[Description("Enable or disable background display.")]
[Category("Display")]
public bool ShowBackground
{
get { return showBackground; }
set { showBackground = value; }
}
[Description("Max number of pending news events to display.")]
[Category("Filter News")]
public int MaxNewsItems
{
get { return maxNewsItems; }
set { maxNewsItems = value; }
}
[Description("News refresh interval in minutes.")]
[Category("Parameters")]
public int NewsRefeshInterval
{
get { return newsRefeshInterval; }
set { newsRefeshInterval = value; }
}
[Description("Time display format, true for 24 hour, false for AM/PM")]
[Category("Display")]
public bool Use24HourTimeFormat
{
get { return use24timeFormat; }
set { use24timeFormat = value; }
}
[Description("Debug to OutputWindow")]
[Category("Debug")]
public bool Debug
{
get { return debug; }
set { debug = value; }
}
[Description("Show only todays news events.")]
[Category("Filter News")]
public bool TodaysNewsOnly
{
get { return todaysNewsOnly; }
set { todaysNewsOnly = value; }
}
[Description("Send alerts to the Alerts Window.")]
[Category("Alerts")]
public bool UseAlerts
{
get { return sendAlerts; }
set { sendAlerts = value; }
}
[Description("Number of minutes to warn before an event.")]
[Category("Alerts")]
public int WarningInterval
{
get { return alertInterval; }
set { alertInterval = value; }
}
[Description("Alert wav file, blank to turn off audio alerts.")]
[Category("Alerts")]
public string AlertWavFileName
{
get { return alertWavFileName; }
set { alertWavFileName = value; }
}
[Description("Header Font. This font is used determine the columns widths. The size of this font should be larger than the others.")]
[Category("Fonts")]
[XmlIgnore()]
public Font HeaderFont
{
get { return headerFont; }
set { headerFont = value; }
}
[Browsable(false)]
public string HeaderFontSerialize
{
get { return NinjaTrader.Gui.Design.SerializableFont.ToString(headerFont); }
set { headerFont = NinjaTrader.Gui.Design.SerializableFont.FromString(value); }
}
[Description("Default Event Font")]
[Category("Fonts")]
[XmlIgnore()]
public Font DefaultFont
{
get { return lineFont; }
set { lineFont = value; }
}
[Browsable(false)]
public string DefaultFontSerialize
{
get { return NinjaTrader.Gui.Design.SerializableFont.ToString(lineFont); }
set { lineFont = NinjaTrader.Gui.Design.SerializableFont.FromString(value); }
}
[Description("Warning Event Font")]
[Category("Fonts")]
[XmlIgnore()]
public Font WarningFont
{
get { return lineAlertFont; }
set { lineAlertFont = value; }
}
[Browsable(false)]
public string WarningFontSerialize
{
get { return NinjaTrader.Gui.Design.SerializableFont.ToString(lineAlertFont); }
set { lineAlertFont = NinjaTrader.Gui.Design.SerializableFont.FromString(value); }
}
[Description("Show only US events.")]
[Category("Filter News")]
public bool USOnlyEvents
{
get { return usaOnly; }
set { usaOnly = value; }
}
[Description("Show on US events.")]
[Category("Filter News")]
public bool ShowLowPriority
{
get { return showLowPriority; }
set { showLowPriority = value; }
}
[XmlIgnore()]
[Description("Header Color")]
[Category("Colors")]
public Color HeaderColor
{
get { return headerColor; }
set { headerColor = value; }
}
[Browsable(false)]
public string HeaderColorSerialize
{
get { return NinjaTrader.Gui.Design.SerializableColor.ToString(headerColor); }
set { headerColor = NinjaTrader.Gui.Design.SerializableColor.FromString(value); }
}
[XmlIgnore()]
[Description("High Priority Color")]
[Category("Colors")]
public Color HighPriorityColor
{
get { return lineHighColor; }
set { lineHighColor = value; }
}
[Browsable(false)]
public string HighPriorityColorSerialize
{
get { return NinjaTrader.Gui.Design.SerializableColor.ToString(lineHighColor); }
set { lineHighColor = NinjaTrader.Gui.Design.SerializableColor.FromString(value); }
}
[XmlIgnore()]
[Description("Medium Priority Color")]
[Category("Colors")]
public Color MediumPriorityColor
{
get { return lineMedColor; }
set { lineMedColor = value; }
}
[Browsable(false)]
public string MediumPriorityColorSerialize
{
get { return NinjaTrader.Gui.Design.SerializableColor.ToString(lineMedColor); }
set { lineMedColor = NinjaTrader.Gui.Design.SerializableColor.FromString(value); }
}
[XmlIgnore()]
[Description("Low Priority Color")]
[Category("Colors")]
public Color LowPriorityColor
{
get { return lineLowColor; }
set { lineLowColor = value; }
}
[Browsable(false)]
public string LowPriorityColorSerialize
{
get { return NinjaTrader.Gui.Design.SerializableColor.ToString(lineLowColor); }
set { lineLowColor = NinjaTrader.Gui.Design.SerializableColor.FromString(value); }
}
[XmlIgnore()] // added by Fat Tails January 25, 2011
[Description("Normal Priority Color")]
[Category("Colors")]
public Color NormalColor
{
get { return lineNormalColor; }
set { lineNormalColor = value; }
}
[Browsable(false)]
public string NormalColorSerialize
{
get { return NinjaTrader.Gui.Design.SerializableColor.ToString(lineNormalColor); }
set { lineNormalColor = NinjaTrader.Gui.Design.SerializableColor.FromString(value); }
}
[XmlIgnore()]
[Description("Background Color")]
[Category("Colors")]
public Color BackgroundColor
{
get { return backgroundColor; }
set { backgroundColor = value; }
}
[Browsable(false)]
public string BackgroundColorSerialize
{
get { return NinjaTrader.Gui.Design.SerializableColor.ToString(backgroundColor); }
set { backgroundColor = NinjaTrader.Gui.Design.SerializableColor.FromString(value); }
}
[XmlIgnore()]
[Description("Border Color")]
[Category("Colors")]
public Color BorderColor
{
get { return borderColor; }
set { borderColor = value; }
}
[Browsable(false)]
public string BorderColorSerialize
{
get { return NinjaTrader.Gui.Design.SerializableColor.ToString(borderColor); }
set { borderColor = NinjaTrader.Gui.Design.SerializableColor.FromString(value); }
}
[Description("Background Opacity")]
[Category("Colors")]
public int BackgroundOpacity
{
get { return backgroundOpacity; }
set { backgroundOpacity = value; }
}
#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 jtEconNews2b[] cachejtEconNews2b = null;
private static jtEconNews2b checkjtEconNews2b = new jtEconNews2b();
///
/// jtEconNews2b - Display upcoming economic news events from ForexFactory.com
///
///
public jtEconNews2b jtEconNews2b(int newsRefeshInterval)
{
return jtEconNews2b(Input, newsRefeshInterval);
}
///
/// jtEconNews2b - Display upcoming economic news events from ForexFactory.com
///
///
public jtEconNews2b jtEconNews2b(Data.IDataSeries input, int newsRefeshInterval)
{
if (cachejtEconNews2b != null)
for (int idx = 0; idx < cachejtEconNews2b.Length; idx++)
if (cachejtEconNews2b[idx].NewsRefeshInterval == newsRefeshInterval && cachejtEconNews2b[idx].EqualsInput(input))
return cachejtEconNews2b[idx];
lock (checkjtEconNews2b)
{
checkjtEconNews2b.NewsRefeshInterval = newsRefeshInterval;
newsRefeshInterval = checkjtEconNews2b.NewsRefeshInterval;
if (cachejtEconNews2b != null)
for (int idx = 0; idx < cachejtEconNews2b.Length; idx++)
if (cachejtEconNews2b[idx].NewsRefeshInterval == newsRefeshInterval && cachejtEconNews2b[idx].EqualsInput(input))
return cachejtEconNews2b[idx];
jtEconNews2b indicator = new jtEconNews2b();
indicator.BarsRequired = BarsRequired;
indicator.CalculateOnBarClose = CalculateOnBarClose;
#if NT7
indicator.ForceMaximumBarsLookBack256 = ForceMaximumBarsLookBack256;
indicator.MaximumBarsLookBack = MaximumBarsLookBack;
#endif
indicator.Input = input;
indicator.NewsRefeshInterval = newsRefeshInterval;
Indicators.Add(indicator);
indicator.SetUp();
jtEconNews2b[] tmp = new jtEconNews2b[cachejtEconNews2b == null ? 1 : cachejtEconNews2b.Length + 1];
if (cachejtEconNews2b != null)
cachejtEconNews2b.CopyTo(tmp, 0);
tmp[tmp.Length - 1] = indicator;
cachejtEconNews2b = 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
{
///
/// jtEconNews2b - Display upcoming economic news events from ForexFactory.com
///
///
[Gui.Design.WizardCondition("Indicator")]
public Indicator.jtEconNews2b jtEconNews2b(int newsRefeshInterval)
{
return _indicator.jtEconNews2b(Input, newsRefeshInterval);
}
///
/// jtEconNews2b - Display upcoming economic news events from ForexFactory.com
///
///
public Indicator.jtEconNews2b jtEconNews2b(Data.IDataSeries input, int newsRefeshInterval)
{
return _indicator.jtEconNews2b(input, newsRefeshInterval);
}
}
}
// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
public partial class Strategy : StrategyBase
{
///
/// jtEconNews2b - Display upcoming economic news events from ForexFactory.com
///
///
[Gui.Design.WizardCondition("Indicator")]
public Indicator.jtEconNews2b jtEconNews2b(int newsRefeshInterval)
{
return _indicator.jtEconNews2b(Input, newsRefeshInterval);
}
///
/// jtEconNews2b - Display upcoming economic news events from ForexFactory.com
///
///
public Indicator.jtEconNews2b jtEconNews2b(Data.IDataSeries input, int newsRefeshInterval)
{
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.jtEconNews2b(input, newsRefeshInterval);
}
}
}
#endregion