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: 1874
- Modified: 18/06/2023 21:26
Note that publishing copyrighted material is strictly prohibited. If you believe there is copyrighted material in this section, please use the Copyright Infringement Notification form to submit a claim.
Comments
Log in to add a comment.
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.