Category Trend  Published on 19/06/2023

HTS Channels

Description

The indicator creates channels from high and low values, which is helpful in the HTS strategy by Zsuirad Ńezrok.

 

New features:

- alarms,

- events (for robots).


using System;
using System.Linq;
using cAlgo.API;
using HtsChannels.Extensions;
using HtsChannels.DTOs;
using HtsChannels.Enums;
using HtsChannels.Events;
using HtsChannels.Models;
using HtsChannels.Providers;
using HtsChannels.Services;
using Color = cAlgo.API.Color;

namespace HtsChannels
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AutoRescale = false, AccessRights = AccessRights.FullAccess)]
    public class HtsChannels : Indicator
    {
        #region General

        [Parameter("Timeframe", Group = "General", DefaultValue = ParameterDefaultValues.General.SelectedTimeFrame)]
        public TimeframeValue SelectedTimeframe { get; init; }

        [Parameter(
            "Fast channel length",
            Group = "General",
            DefaultValue = ParameterDefaultValues.General.FastChannelLength,
            MinValue = 1,
            Step = 1)]
        public int FastChannelLength { get; init; }

        [Parameter(
            "Slow channel length",
            Group = "General",
            DefaultValue = ParameterDefaultValues.General.SlowChannelLength,
            MinValue = 1,
            Step = 1)]
        public int SlowChannelLength { get; init; }

        [Parameter(
            "Moving averages type",
            Group = "General",
            DefaultValue = ParameterDefaultValues.General.MovingAverageType)]
        public MovingAverageType MovingAveragesType { get; init; }

        #endregion

        #region Alerts

        [Parameter("Enable", Group = "Alerts", DefaultValue = ParameterDefaultValues.Alerts.AreAlertsEnabled)]
        public bool AreAlertsEnabled { get; init; }

        #endregion

        #region UI

        [Parameter(
            "Show fast channel position",
            Group = "UI",
            DefaultValue = ParameterDefaultValues.Ui.ShowFastChannelPosition)]
        public bool ShowFastChannelPosition { get; init; }

        [Parameter("Enable history", Group = "UI", DefaultValue = ParameterDefaultValues.Ui.AreAlertsHistoryEnabled)]
        public bool AreAlertsHistoryEnabled { get; init; }

        [Parameter("Text color", Group = "UI", DefaultValue = ParameterDefaultValues.Ui.UiTextColor)]
        public ColorName UiTextColor { get; init; }

        #endregion

        #region Crosses

        [Parameter(
            "Crosses above upper band of fast channel",
            Group = "Crosses",
            DefaultValue = ParameterDefaultValues.Crosses.AreCrossesAboveUpperBandOfFastChannelEnabled)]
        public bool AreCrossesAboveUpperBandOfFastChannelEnabled { get; init; }

        [Parameter(
            "Crosses below upper band of fast channel",
            Group = "Crosses",
            DefaultValue = ParameterDefaultValues.Crosses.AreCrossesBelowUpperBandOfFastChannelEnabled)]
        public bool AreCrossesBelowUpperBandOfFastChannelEnabled { get; init; }

        [Parameter(
            "Crosses above lower band of fast channel",
            Group = "Crosses",
            DefaultValue = ParameterDefaultValues.Crosses.AreCrossesAboveLowerBandOfFastChannelEnabled)]
        public bool AreCrossesAboveLowerBandOfFastChannelEnabled { get; init; }

        [Parameter(
            "Crosses below lower band of fast channel",
            Group = "Crosses",
            DefaultValue = ParameterDefaultValues.Crosses.AreCrossesBelowLowerBandOfFastChannelEnabled)]
        public bool AreCrossesBelowLowerBandOfFastChannelEnabled { get; init; }

        [Parameter(
            "Crosses above upper band of slow channel",
            Group = "Crosses",
            DefaultValue = ParameterDefaultValues.Crosses.AreCrossesAboveUpperBandOfSlowChannelEnabled)]
        public bool AreCrossesAboveUpperBandOfSlowChannelEnabled { get; init; }

        [Parameter(
            "Crosses below upper band of slow channel",
            Group = "Crosses",
            DefaultValue = ParameterDefaultValues.Crosses.AreCrossesBelowUpperBandOfSlowChannelEnabled)]
        public bool AreCrossesBelowUpperBandOfSlowChannelEnabled { get; init; }

        [Parameter(
            "Crosses above lower band of slow channel",
            Group = "Crosses",
            DefaultValue = ParameterDefaultValues.Crosses.AreCrossesAboveLowerBandOfSlowChannelEnabled)]
        public bool AreCrossesAboveLowerBandOfSlowChannelEnabled { get; init; }

        [Parameter(
            "Crosses below lower band of slow channel",
            Group = "Crosses",
            DefaultValue = ParameterDefaultValues.Crosses.AreCrossesBelowLowerBandOfSlowChannelEnabled)]
        public bool AreCrossesBelowLowerBandOfSlowChannelEnabled { get; init; }

        #endregion

        #region Events

        [Parameter("Enable", Group = "Events", DefaultValue = ParameterDefaultValues.Events.AreEventsEnabled)]
        public bool AreEventsEnabled { get; init; }

        public event Action<PriceCrossedBandEventArgs> PriceCrossedBand;

        #endregion

        #region Output

        [Output("Fast channel upper band", LineColor = "FF40E0D0")]
        public IndicatorDataSeries FastChannelUpperBand { get; init; }

        [Output("Fast channel lower band", LineColor = "FF40E0D0")]
        public IndicatorDataSeries FastChannelLowerBand { get; init; }

        [Output("Slow channel upper band", LineColor = "Red")]
        public IndicatorDataSeries SlowChannelUpperBand { get; init; }

        [Output("Slow channel lower band", LineColor = "Red")]
        public IndicatorDataSeries SlowChannelLowerBand { get; init; }

        #endregion

        public Channel FastChannel { get; private set; }

        public Channel SlowChannel { get; private set; }

        public ChannelPosition FastChannelPosition => FastChannel.GetPositionInRelationTo(SlowChannel);

        private const string FastChannelPositionTextName = "FastChannelPosition";
        private Bars _bars;
        private CrossService _crossService;
        private AlertService _alertService;
        private Color _uiTextColor;

        protected override void Initialize()
        {
            _bars = MarketData.GetBars(SelectedTimeframe.ToTimeFrame(TimeFrame));
            InitializeChannels();

            if (AreAlertsEnabled || ShowFastChannelPosition || AreEventsEnabled)
            {
                InitializeAlerts();
                InitializeEvents();
                InitializeUi();

                _bars.BarOpened += OnBarOpened;
            }
        }

        private void InitializeChannels()
        {
            FastChannel = new Channel(Indicators, _bars, FastChannelLength, MovingAveragesType);
            SlowChannel = new Channel(Indicators, _bars, SlowChannelLength, MovingAveragesType);
        }

        private void InitializeAlerts()
        {
            if (!AreAlertsEnabled)
            {
                return;
            }

            InitializeCrossService();

            var dateTimeProvider = new DateTimeProvider(this);
            _uiTextColor = Color.FromName(UiTextColor.ToString());
            var notificationService = new SoundNotificationService(
                dateTimeProvider,
                this,
                AreAlertsHistoryEnabled,
                _uiTextColor);
            _alertService = new AlertService(notificationService);
        }

        private void InitializeEvents()
        {
            if (!AreEventsEnabled)
            {
                return;
            }

            InitializeCrossService();
        }

        private void InitializeUi()
        {
            if (!ShowFastChannelPosition)
            {
                return;
            }

            _uiTextColor = Color.FromName(UiTextColor.ToString());
        }

        private void InitializeCrossService()
        {
            if (_crossService is not null)
            {
                return;
            }

            var crossesParameters = new CrossesParameters(
                AreCrossesAboveUpperBandOfFastChannelEnabled,
                AreCrossesBelowUpperBandOfFastChannelEnabled,
                AreCrossesAboveLowerBandOfFastChannelEnabled,
                AreCrossesBelowLowerBandOfFastChannelEnabled,
                AreCrossesAboveUpperBandOfSlowChannelEnabled,
                AreCrossesBelowUpperBandOfSlowChannelEnabled,
                AreCrossesAboveLowerBandOfSlowChannelEnabled,
                AreCrossesBelowLowerBandOfSlowChannelEnabled);
            _crossService = new CrossService(crossesParameters);
        }

        public override void Calculate(int index)
        {
            var timeframeIndex = _bars.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
            FastChannelUpperBand[index] = FastChannel.UpperBand.Result[timeframeIndex];
            FastChannelLowerBand[index] = FastChannel.LowerBand.Result[timeframeIndex];
            SlowChannelUpperBand[index] = SlowChannel.UpperBand.Result[timeframeIndex];
            SlowChannelLowerBand[index] = SlowChannel.LowerBand.Result[timeframeIndex];
        }

        private void OnBarOpened(BarOpenedEventArgs obj)
        {
            if (AreAlertsEnabled || AreEventsEnabled)
            {
                var lastBar = obj.Bars.LastClosedBar();
                var touchTypes = _crossService
                    .GetCrossesOfLastBar(lastBar, FastChannel, SlowChannel)
                    .ToList();
                
                if (AreAlertsEnabled)
                {
                    _alertService.AlertOnCrosses(touchTypes);
                }

                if (AreEventsEnabled)
                {
                    PriceCrossedBand?.Invoke(new PriceCrossedBandEventArgs(touchTypes, FastChannelPosition));
                }
            }

            if (ShowFastChannelPosition)
            {
                Chart.DrawStaticText(
                    FastChannelPositionTextName,
                    $"Fast channel position: {FastChannelPosition}",
                    VerticalAlignment.Top,
                    HorizontalAlignment.Right,
                    _uiTextColor);
            }
        }
    }
}

MA
matturczynski

Joined on 28.05.2023

  • Distribution: Free
  • Language: C#
  • Trading platform: cTrader Automate
  • File name: HTS Channels.algo
  • Rating: 5
  • Installs: 1482
Comments
Log in to add a comment.
MA
matturczynski · 1 year ago

If the indicator is not visible, it's necessary to change the access rights to full access

AccessRights = AccessRights.FullAccess

due to a bug on the Ctrader's side.