Economic Events On Chart free

by Spotware in category Other at 03/11/2021
Description

This indicator shows the current week economic news events on your charts in form of vertical lines.

It uses ForexFactory for getting news events data.

To see full info of news event right click on its vertical line.

Github: 

 

Notification Publishing copyrighted material is strictly prohibited. If you believe there is copyrighted material in this section you may use the Copyright Infringement Notification form to submit a claim.
Formula / Source Code
Language: C#
Trading Platform: cAlgocTrader
´╗┐using System;
using cAlgo.API;
using System.Collections.Generic;
using System.Xml;
using System.Net;
using System.Xml.Serialization;
using System.IO;
using System.Text;
using System.Linq;
using System.Globalization;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.Internet)]
    public class EconomicEventsOnChart : Indicator
    {
        private Color _colorHighImpact, _colorMediumImpact, _colorLowImpact, _colorOthers;

        private TextBlock _textBlock;

        [Parameter("Data URI", DefaultValue = "https://nfs.faireconomy.media/ff_calendar_thisweek.xml", Group = "General")]
        public string DataUri { get; set; }

        [Parameter("Only Symbol Events", DefaultValue = true, Group = "General")]
        public bool OnlySymbolEvents { get; set; }

        [Parameter("Show", DefaultValue = true, Group = "High Impact")]
        public bool ShowHighImpact { get; set; }

        [Parameter("Color", DefaultValue = "Red", Group = "High Impact")]
        public string ColorHighImpact { get; set; }

        [Parameter("Style", DefaultValue = LineStyle.Solid, Group = "High Impact")]
        public LineStyle LineStyleHighImpact { get; set; }

        [Parameter("Thickness", DefaultValue = 1, Group = "High Impact")]
        public int ThicknessHighImpact { get; set; }

        [Parameter("Show", DefaultValue = true, Group = "Medium Impact")]
        public bool ShowMediumImpact { get; set; }

        [Parameter("Color", DefaultValue = "Gold", Group = "Medium Impact")]
        public string ColorMediumImpact { get; set; }

        [Parameter("Style", DefaultValue = LineStyle.Solid, Group = "Medium Impact")]
        public LineStyle LineStyleMediumImpact { get; set; }

        [Parameter("Thickness", DefaultValue = 1, Group = "Medium Impact")]
        public int ThicknessMediumImpact { get; set; }

        [Parameter("Show", DefaultValue = true, Group = "Low Impact")]
        public bool ShowLowImpact { get; set; }

        [Parameter("Color", DefaultValue = "Yellow", Group = "Low Impact")]
        public string ColorLowImpact { get; set; }

        [Parameter("Style", DefaultValue = LineStyle.Solid, Group = "Low Impact")]
        public LineStyle LineStyleLowImpact { get; set; }

        [Parameter("Thickness", DefaultValue = 1, Group = "Low Impact")]
        public int ThicknessLowImpact { get; set; }

        [Parameter("Show", DefaultValue = false, Group = "Others")]
        public bool ShowOthers { get; set; }

        [Parameter("Color", DefaultValue = "Gray", Group = "Others")]
        public string ColorOthers { get; set; }

        [Parameter("Style", DefaultValue = LineStyle.Solid, Group = "Others")]
        public LineStyle LineStyleOthers { get; set; }

        [Parameter("Thickness", DefaultValue = 1, Group = "Others")]
        public int ThicknessOthers { get; set; }

        [Parameter("Show", DefaultValue = true, Group = "Text Block")]
        public bool ShowTextBlock { get; set; }

        [Parameter("Background Color", DefaultValue = "#969696", Group = "Text Block")]
        public string TextBlockBackgroundColor { get; set; }

        [Parameter("Color", DefaultValue = "White", Group = "Text Block")]
        public string TextBlockColor { get; set; }

        [Parameter("Horizontal Alignment", DefaultValue = HorizontalAlignment.Center, Group = "Text Block")]
        public HorizontalAlignment TextBlockHorizontalAlignment { get; set; }

        [Parameter("Vertical Alignment", DefaultValue = VerticalAlignment.Bottom, Group = "Text Block")]
        public VerticalAlignment TextBlockVerticalAlignment { get; set; }

        [Parameter("Text Alignment", DefaultValue = TextAlignment.Center, Group = "Text Block")]
        public TextAlignment TextBlockTextAlignment { get; set; }

        [Parameter("Font Weight", DefaultValue = FontWeight.Bold, Group = "Text Block")]
        public FontWeight TextBlockFontWeight { get; set; }

        protected override void Initialize()
        {
            RemoveEventLines();

            if (ShowTextBlock)
            {
                _textBlock = new TextBlock
                {
                    IsVisible = false,
                    HorizontalAlignment = TextBlockHorizontalAlignment,
                    VerticalAlignment = TextBlockVerticalAlignment,
                    BackgroundColor = GetColor(TextBlockBackgroundColor),
                    ForegroundColor = GetColor(TextBlockColor),
                    TextAlignment = TextBlockTextAlignment,
                    FontWeight = TextBlockFontWeight,
                    Padding = 5
                };

                Chart.AddControl(_textBlock);

                Chart.ObjectHoverChanged += Chart_ObjectHoverChanged;
            }

            _colorHighImpact = GetColor(ColorHighImpact);
            _colorMediumImpact = GetColor(ColorMediumImpact);
            _colorLowImpact = GetColor(ColorLowImpact);
            _colorOthers = GetColor(ColorOthers);

            var events = GetNewsEvents();

            DisplayEvents(events);
        }

        private void Chart_ObjectHoverChanged(ChartObjectHoverChangedEventArgs obj)
        {
            if (!obj.IsObjectHovered || obj.ChartObject == null || string.IsNullOrWhiteSpace(obj.ChartObject.Name) || !obj.ChartObject.Name.EndsWith("Event", StringComparison.OrdinalIgnoreCase))
            {
                _textBlock.IsVisible = false;

                return;
            }

            _textBlock.Text = string.Format("{0} | {1}", obj.ChartObject.Name.Replace(" | Event", string.Empty), obj.ChartObject.Comment);

            _textBlock.IsVisible = true;
        }

        public override void Calculate(int index)
        {
        }

        private IEnumerable<NewsEvent> GetNewsEvents()
        {
            using (var webClient = new WebClient())
            {
                var data = webClient.DownloadString(DataUri);

                return GetNewsEventsFromXml(data);
            }
        }

        private IEnumerable<NewsEvent> GetNewsEventsFromXml(string xml)
        {
            var xmlSerializer = new XmlSerializer(typeof(WeeklyEvents));

            var stream = new StringReader(xml);

            var weeklyEvents = xmlSerializer.Deserialize(stream) as WeeklyEvents;

            foreach (var newsEvent in weeklyEvents.Events)
            {
                var timeString = string.Format("{0} {1}", newsEvent.UtcDate, newsEvent.UtcTime);

                DateTimeOffset time;

                if (DateTimeOffset.TryParseExact(timeString, "MM-dd-yyyy h:mmtt", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out time))
                {
                    newsEvent.Time = time;
                }
            }

            return weeklyEvents.Events;
        }

        private void DisplayEvents(IEnumerable<NewsEvent> events)
        {
            foreach (var newsEvent in events)
            {
                if (!newsEvent.Time.HasValue
                    || (newsEvent.Impact == NewsEventImpact.High && !ShowHighImpact)
                    || (newsEvent.Impact == NewsEventImpact.Medium && !ShowMediumImpact)
                    || (newsEvent.Impact == NewsEventImpact.Low && !ShowLowImpact)
                    || ((newsEvent.Impact == NewsEventImpact.None || newsEvent.Impact == NewsEventImpact.Holiday) && !ShowOthers)
                    || (OnlySymbolEvents && !IsEventRelatedToSymbol(newsEvent.Currency))) continue;

                var lineSettings = GetLineSettings(newsEvent.Impact);

                var eventLine = Chart.DrawVerticalLine(string.Format("{0} | {1} | {2} | Event", newsEvent.Title, newsEvent.Currency, newsEvent.Impact), newsEvent.Time.Value.UtcDateTime, lineSettings.Color, lineSettings.Thickness, lineSettings.Style);

                var stringBuilder = new StringBuilder();

                if (!string.IsNullOrWhiteSpace(newsEvent.Forecast))
                {
                    stringBuilder.Append(string.Format("Forecast: {0} | ", newsEvent.Forecast));
                }

                if (!string.IsNullOrWhiteSpace(newsEvent.Previous))
                {
                    stringBuilder.Append(string.Format("Previous: {0} | ", newsEvent.Previous));
                }

                if (newsEvent.Time.HasValue)
                {
                    var time = newsEvent.Time.Value.ToOffset(Application.UserTimeOffset);

                    stringBuilder.Append(string.Format("Time: {0:s}", time));
                }

                eventLine.Comment = stringBuilder.ToString();
                eventLine.IsInteractive = true;
                eventLine.IsLocked = true;
            }
        }

        private bool IsEventRelatedToSymbol(string eventCurrency)
        {
            return SymbolName.StartsWith(eventCurrency, StringComparison.OrdinalIgnoreCase) || SymbolName.EndsWith(eventCurrency, StringComparison.OrdinalIgnoreCase);
        }

        private Color GetColor(string colorString, int alpha = 255)
        {
            var color = colorString[0] == '#' ? Color.FromHex(colorString) : Color.FromName(colorString);

            return Color.FromArgb(alpha, color);
        }

        private LineSettings GetLineSettings(NewsEventImpact impact)
        {
            switch (impact)
            {
                case NewsEventImpact.High:
                    return new LineSettings
                    {
                        Color = _colorHighImpact,
                        Style = LineStyleHighImpact,
                        Thickness = ThicknessHighImpact
                    };

                case NewsEventImpact.Medium:
                    return new LineSettings
                    {
                        Color = _colorMediumImpact,
                        Style = LineStyleMediumImpact,
                        Thickness = ThicknessMediumImpact
                    };

                case NewsEventImpact.Low:
                    return new LineSettings
                    {
                        Color = _colorLowImpact,
                        Style = LineStyleLowImpact,
                        Thickness = ThicknessLowImpact
                    };

                default:
                    return new LineSettings
                    {
                        Color = _colorOthers,
                        Style = LineStyleOthers,
                        Thickness = ThicknessOthers
                    };
            }
        }

        private void RemoveEventLines()
        {
            var chartObjects = Chart.Objects.ToArray();

            foreach (var chartObject in chartObjects)
            {
                if (chartObject.ObjectType != ChartObjectType.VerticalLine || !chartObject.IsInteractive || string.IsNullOrEmpty(chartObject.Name) || !chartObject.Name.EndsWith("Event", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                Chart.RemoveObject(chartObject.Name);
            }
        }
    }

    [XmlRoot("weeklyevents")]
    public class WeeklyEvents
    {
        [XmlElement("event")]
        public List<NewsEvent> Events { get; set; }
    }

    public class NewsEvent
    {
        [XmlElement("title")]
        public string Title { get; set; }

        [XmlElement("country")]
        public string Currency { get; set; }

        [XmlElement("date")]
        public string UtcDate { get; set; }

        [XmlElement("time")]
        public string UtcTime { get; set; }

        [XmlIgnore]
        public DateTimeOffset? Time { get; set; }

        [XmlElement("impact")]
        public NewsEventImpact Impact { get; set; }

        [XmlElement("previous")]
        public string Previous { get; set; }

        [XmlElement("forecast")]
        public string Forecast { get; set; }
    }

    public enum NewsEventImpact
    {
        None,

        High,

        Medium,

        Low,

        Holiday
    }

    public struct LineSettings
    {
        public Color Color { get; set; }

        public LineStyle Style { get; set; }

        public int Thickness { get; set; }
    }
}
Comments
0