Update news event data retrieval due to Cloudflare scraping protections on Forex Factory
This commit is contained in:
parent
20768cebac
commit
c318149d5a
@ -1,31 +1,17 @@
|
|||||||
#region Using declarations
|
#region Using declarations
|
||||||
|
using NinjaTrader.Gui;
|
||||||
|
using NinjaTrader.Gui.Chart;
|
||||||
|
using NinjaTrader.Gui.Tools;
|
||||||
|
using SharpDX;
|
||||||
|
using SharpDX.DirectWrite;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Net.Http;
|
||||||
using System.Text;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Input;
|
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Xml.Serialization;
|
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.Net.Http;
|
|
||||||
using SharpDX.DirectWrite;
|
|
||||||
using SharpDX;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
using System.Xml;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Windows.Markup;
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
//This namespace holds Indicators in this folder and is required. Do not change it.
|
//This namespace holds Indicators in this folder and is required. Do not change it.
|
||||||
@ -82,11 +68,11 @@ namespace NinjaTrader.NinjaScript.Indicators
|
|||||||
HttpClient client = new HttpClient();
|
HttpClient client = new HttpClient();
|
||||||
client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
|
client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
|
||||||
|
|
||||||
string newsUrl = "https://www.forexfactory.com/calendar?day=" + DateTime.Now.ToString("MMMdd.yyyy").ToLower();
|
string newsUrl = "https://nfs.faireconomy.media/ff_calendar_thisweek.json";
|
||||||
HttpResponseMessage response = await client.GetAsync(newsUrl);
|
HttpResponseMessage response = await client.GetAsync(newsUrl);
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
string responseBody = await response.Content.ReadAsStringAsync();
|
|
||||||
|
|
||||||
|
string responseBody = await response.Content.ReadAsStringAsync();
|
||||||
ParseNewsEvents(responseBody);
|
ParseNewsEvents(responseBody);
|
||||||
|
|
||||||
ForceRefresh();
|
ForceRefresh();
|
||||||
@ -97,66 +83,40 @@ namespace NinjaTrader.NinjaScript.Indicators
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ParseNewsEvents(string html)
|
private void ParseNewsEvents(string json)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Regex to match the rows with class "calendar__row"
|
var events = Regex.Matches(json, @"\{[^}]*\}");
|
||||||
var rowRegex = new Regex(@"<tr[^>]*class=""[^""]*calendar__row[^""]*""[^>]*>(.*?)</tr>", RegexOptions.Singleline);
|
|
||||||
|
|
||||||
// Regex to extract time and title from the row
|
foreach (Match eventMatch in events)
|
||||||
var timeRegex = new Regex(@"<td[^>]*class=""[^""]*calendar__time[^""]*""[^>]*>(.*?)</td>", RegexOptions.Singleline);
|
|
||||||
var currencyRegex = new Regex(@"<td[^>]*class=""[^""]*calendar__currency[^""]*""[^>]*>(.*?)</td>", RegexOptions.Singleline);
|
|
||||||
var titleRegex = new Regex(@"<span[^>]*class=""[^""]*calendar__event-title[^""]*""[^>]*>(.*?)</span>", RegexOptions.Singleline);
|
|
||||||
|
|
||||||
var rowMatches = rowRegex.Matches(html);
|
|
||||||
foreach (Match rowMatch in rowMatches)
|
|
||||||
{
|
{
|
||||||
string rowContent = rowMatch.Groups[1].Value;
|
string eventString = eventMatch.Value;
|
||||||
|
|
||||||
var timeMatch = timeRegex.Match(rowContent);
|
string date = ExtractJsonValue(eventString, "date");
|
||||||
var currencyMatch = currencyRegex.Match(rowContent);
|
string currency = ExtractJsonValue(eventString, "country");
|
||||||
var titleMatch = titleRegex.Match(rowContent);
|
string title = ExtractJsonValue(eventString, "title");
|
||||||
|
|
||||||
if (timeMatch.Success && titleMatch.Success)
|
DateTime eventTime = DateTime.Parse(date);
|
||||||
{
|
if (eventTime.Date != currentDate)
|
||||||
string time = timeMatch.Groups[1].Value.Trim();
|
continue;
|
||||||
string currency = currencyMatch.Groups[1].Value.Trim();
|
|
||||||
string title = titleMatch.Groups[1].Value.Trim();
|
|
||||||
|
|
||||||
// Remove any extraneous HTML tags from the time string
|
string time = eventTime.ToString("hh:mmtt").ToLower();
|
||||||
time = Regex.Replace(time, "<.*?>", string.Empty);
|
|
||||||
|
|
||||||
// Convert the time to the user's time zone
|
|
||||||
time = ConvertToUserTimeZone(time);
|
|
||||||
|
|
||||||
newsEvents.Add(new NewsEvent { Time = time, Currency = currency, Title = title });
|
newsEvents.Add(new NewsEvent { Time = time, Currency = currency, Title = title });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Print("Error parsing news events: " + ex.Message);
|
Print("Error parsing news events: " + ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ConvertToUserTimeZone(string time)
|
private string ExtractJsonValue(string json, string key)
|
||||||
{
|
{
|
||||||
try
|
string pattern = $"\"{key}\":\"(.*?)\"";
|
||||||
{
|
Match match = Regex.Match(json, pattern);
|
||||||
// Assumed to be in US Eastern Time
|
return match.Success ? match.Groups[1].Value : string.Empty;
|
||||||
DateTime easternTime = DateTime.ParseExact(time, "h:mmtt", System.Globalization.CultureInfo.InvariantCulture);
|
|
||||||
TimeZoneInfo easternTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
|
|
||||||
|
|
||||||
DateTime userTime = TimeZoneInfo.ConvertTime(easternTime, easternTimeZone, Core.Globals.GeneralOptions.TimeZoneInfo);
|
|
||||||
|
|
||||||
// Format the time as "hh:mmtt" (e.g., "06:30am")
|
|
||||||
return userTime.ToString("hh:mmtt").ToLower();
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
return time; // Return original time if conversion fails
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnBarUpdate() {
|
protected override void OnBarUpdate() {
|
||||||
|
Loading…
Reference in New Issue
Block a user