Advanced Entry Hour Stepped by Naya
734 downloads / 404 views / Created: 14.06.2025 Average Rating: 0
Indicator Description
This indicator generates periodic entry signals at specified time intervals starting from a configurable anchor time.
Key Features
- Creates entry signals at regular intervals from a defined starting time
- Flexible configuration of anchor time (hour and minute)
- Adjustable entry period from 15 to 480 minutes in 15-minute steps
- Works with bar opening times for precise execution
- Designed for use in opening positions
Configuration Options
- Anchor Time: Set the starting hour (0-23) and minute (0-45 in 15-min steps)
- Entry Period: Choose interval between signals (15-480 minutes in 15-min increments)
- Base Price: Uses bar opening price for execution
How It Works
The indicator:
1. Takes the specified anchor time (e.g., 08:00)
2. Generates signals every X minutes (e.g., every 60 minutes)
3. Creates entries at these periodic intervals
4. Uses the bar's opening price for order execution
Usage Notes
- Best suited for strategies that benefit from time-based entries
- Ensure your broker's execution matches the indicator's timing
- Works with all timeframes but most effective with smaller timeframes
- Includes safety checks for time calculation
This tool is ideal for traders implementing:
- Time-based entry strategies
- Scheduled trading approaches
- Systematic position opening at regular intervals
Comments
using System;
using System.Collections.Generic;
using ForexStrategyBuilder.Infrastructure.Entities;
using ForexStrategyBuilder.Infrastructure.Enums;
using ForexStrategyBuilder.Infrastructure.Interfaces;
namespace ForexStrategyBuilder.Indicators.Custom
{
public class AdvancedEntryHourStepped : Indicator
{
public AdvancedEntryHourStepped()
{
IndicatorName = "Advanced Entry Hour Stepped";
PossibleSlots = SlotTypes.Open;
IsDeafultGroupAll = true;
IsGeneratable = false;
WarningMessage = "The indicator generates entry signals at periodic intervals starting from the specified anchor time." +
Environment.NewLine +
"Ensure the strategy time frame allows opening at these specific times.";
IndicatorAuthor = "NAYA +237674724684";
IndicatorVersion = "1.0";
IndicatorDescription = "Generates periodic entry signals based on specified time steps from an anchor time using bar open time.";
}
public override void Initialize(SlotTypes slotType)
{
SlotType = slotType;
IndParam.IsAllowLTF = false;
IndParam.ExecutionTime = ExecutionTime.AtBarOpening;
// Logic Parameter
IndParam.ListParam[0].Caption = "Logic";
IndParam.ListParam[0].ItemList = new[] { "Enter the market at periodic intervals" };
IndParam.ListParam[0].Index = 0;
IndParam.ListParam[0].Text = IndParam.ListParam[0].ItemList[0];
IndParam.ListParam[0].Enabled = true;
IndParam.ListParam[0].ToolTip = "Defines the core behavior of the indicator.";
// Anchor Hour
IndParam.ListParam[1].Caption = "Anchor Hour";
var hours = new List();
for (int i = 0; i <= 23; i += 1)
hours.Add(i.ToString());
IndParam.ListParam[1].ItemList = hours.ToArray();
IndParam.ListParam[1].Index = 0;
IndParam.ListParam[1].Text = IndParam.ListParam[1].ItemList[0];
IndParam.ListParam[1].Enabled = true;
IndParam.ListParam[1].ToolTip = "The hour component (0-23) of the anchor time.";
// Anchor Minute
IndParam.ListParam[2].Caption = "Anchor Minute";
var minutes = new List();
for (int i = 0; i <= 45; i += 15)
minutes.Add(i.ToString());
IndParam.ListParam[2].ItemList = minutes.ToArray();
IndParam.ListParam[2].Index = 0;
IndParam.ListParam[2].Text = IndParam.ListParam[2].ItemList[0];
IndParam.ListParam[2].Enabled = true;
IndParam.ListParam[2].ToolTip = "The minute component (0-59) of the anchor time.";
// Entry Period
IndParam.ListParam[3].Caption = "Entry Period (minutes)";
var periods = new List();
for (int i = 15; i <= 480; i += 15)
periods.Add(i.ToString());
IndParam.ListParam[3].ItemList = periods.ToArray();
IndParam.ListParam[3].Index = 0;
IndParam.ListParam[3].Text = IndParam.ListParam[3].ItemList[0];
IndParam.ListParam[3].Enabled = true;
IndParam.ListParam[3].ToolTip = "The interval (in minutes) between entry signals, starting from the anchor time. (15 to 1440 in steps of 15)";
// Base Price
IndParam.ListParam[4].Caption = "Base price";
IndParam.ListParam[4].ItemList = new[] { "Open" };
IndParam.ListParam[4].Index = 0;
IndParam.ListParam[4].Text = IndParam.ListParam[4].ItemList[0];
IndParam.ListParam[4].Enabled = true;
IndParam.ListParam[4].ToolTip = "The execution price of all entry orders.";
}
public override void Calculate(IDataSet dataSet)
{
DataSet = dataSet;
int anchorHour = int.TryParse(IndParam.ListParam[1].Text, out anchorHour) ? anchorHour : 0;
int anchorMinute = int.TryParse(IndParam.ListParam[2].Text, out anchorMinute) ? anchorMinute : 0;
int entryPeriod = int.TryParse(IndParam.ListParam[3].Text, out entryPeriod) ? Math.Max(15, entryPeriod) : 15;
const int firstBar = 2;
double[] signal = new double[Bars];
int anchorTotalMinutes = anchorHour * 60 + anchorMinute;
for (int bar = firstBar; bar < Bars; bar++)
{
// Use bar open time
DateTime openTime = Time[bar];
int openTotalMinutes = openTime.Hour * 60 + openTime.Minute;
// Calculate minutes since anchor time
int minutesSinceAnchor = (openTotalMinutes - anchorTotalMinutes + 1440) % 1440;
// Check if current time is a multiple of entryPeriod from anchor time
signal[bar] = (minutesSinceAnchor % entryPeriod == 0) ? Open[bar] : 0;
}
Component = new IndicatorComp[1];
Component[0] = new IndicatorComp
{
CompName = "Entry price",
DataType = IndComponentType.OpenPrice,
ChartType = IndChartType.NoChart,
ShowInDynInfo = false,
FirstBar = firstBar,
Value = signal
};
}
public override void SetDescription()
{
string anchorHourText = IndParam.ListParam[1].Text.PadLeft(2, '0');
string anchorMinuteText = IndParam.ListParam[2].Text.PadLeft(2, '0');
string entryPeriodText = IndParam.ListParam[3].Text;
string description = "Enter the market every {entryPeriodText} minutes starting from {anchorHourText}:{anchorMinuteText}";
EntryPointLongDescription = description;
EntryPointShortDescription = description;
}
public override string ToString()
{
string anchorHourText = IndParam.ListParam[1].Text.PadLeft(2, '0');
string anchorMinuteText = IndParam.ListParam[2].Text.PadLeft(2, '0');
string entryPeriodText = IndParam.ListParam[3].Text;
return "{IndicatorName} ({anchorHourText}:{anchorMinuteText}, {entryPeriodText} min)";
}
}
}
//+------------------------------------------------------------------+ //| AdvancedEntryHourStepped.mqh | //| Copyright (C) 2025 NAYA +237674724684 | //| NAYA +237674724684 | //+------------------------------------------------------------------+ #property copyright "Copyright (C) 2025 NAYA +237674724684" #property link "NAYA +237674724684" #property version "1.0" #property strict #include <Forexsb.com/Indicator.mqh> #include <Forexsb.com/Enumerations.mqh> //+------------------------------------------------------------------+ //| Class AdvancedEntryHourStepped | //+------------------------------------------------------------------+ class AdvancedEntryHourStepped : public Indicator { public: AdvancedEntryHourStepped(SlotTypes slotType); virtual void Calculate(DataSet &dataSet); virtual string ToString(); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ void AdvancedEntryHourStepped::AdvancedEntryHourStepped(SlotTypes slotType) { SlotType = slotType; IndicatorName = "Advanced Entry Hour Stepped"; IsAllowLTF = false; ExecTime = ExecutionTime_AtBarOpening; WarningMessage = "The indicator generates entry signals at periodic intervals starting from the specified anchor time. Ensure the strategy time frame allows opening at these specific times."; IsSeparateChart = false; IsDiscreteValues = false; IsDefaultGroupAll = true; } //+------------------------------------------------------------------+ //| Calculate indicator values | //+------------------------------------------------------------------+ void AdvancedEntryHourStepped::Calculate(DataSet &dataSet) { Data = GetPointer(dataSet); if(ArraySize(ListParam) < 5) { PrintFormat("%s Error: ListParam array size is %d, expected at least 5.", IndicatorName, ArraySize(ListParam)); return; } string anchorHourText = ListParam[1].Text; string anchorMinuteText = ListParam[2].Text; string entryPeriodText = ListParam[3].Text; int anchorHour = (int)StringToInteger(anchorHourText); int anchorMinute = (int)StringToInteger(anchorMinuteText); int entryPeriod = (int)StringToInteger(entryPeriodText); anchorHour = MathMax(0, MathMin(23, anchorHour)); anchorMinute = MathMax(0, MathMin(59, anchorMinute)); entryPeriod = MathMax(15, MathMin(1440, entryPeriod)); if (entryPeriod <= 0) { PrintFormat("%s Error: Entry Period must be greater than 0. Using default value of 15.", IndicatorName); entryPeriod = 15; } const int firstBar = 2; double signal[]; ArrayResize(signal, Data.Bars); ArrayInitialize(signal, 0); int anchorTotalMinutes = anchorHour * 60 + anchorMinute; for(int bar = firstBar; bar < Data.Bars; bar++) { MqlDateTime mqlTime; TimeToStruct(Data.Time[bar], mqlTime); int openTotalMinutes = mqlTime.hour * 60 + mqlTime.min; // Calculate minutes since anchor time int minutesSinceAnchor = (openTotalMinutes - anchorTotalMinutes + 1440) % 1440; // Check if current time is a multiple of entryPeriod from anchor time signal[bar] = (minutesSinceAnchor % entryPeriod == 0) ? Data.Open[bar] : 0; } ArrayResize(Component, 1); Component[0].DataType = IndComponentType_OpenPrice; Component[0].CompName = "Entry price"; Component[0].FirstBar = firstBar; Component[0].ShowInDynInfo = false; ArrayResize(Component[0].Value, Data.Bars); ArrayCopy(Component[0].Value, signal); } //+------------------------------------------------------------------+ //| Returns string representation of the indicator | //+------------------------------------------------------------------+ string AdvancedEntryHourStepped::ToString() { if(ArraySize(ListParam) < 4) return IndicatorName; string anchorHourText = ListParam[1].Text; string anchorMinuteText = ListParam[2].Text; string entryPeriodText = ListParam[3].Text; string anchorTimeFullText = StringFormat("%02d:%02d", (int)StringToInteger(anchorHourText), (int)StringToInteger(anchorMinuteText)); return StringFormat("%s (%s, %s min)", IndicatorName, anchorTimeFullText, entryPeriodText); } //+------------------------------------------------------------------+
Risk warning: Forex, spread bets and CFD are leveraged products. They may not be suitable for you as they carry a high degree of risk to your capital and you can lose more than your initial investment. You should ensure you understand all of the risks.
Copyright © 2006 - 2025, Forex Software Ltd.;
Copyright © 2006 - 2025, Forex Software Ltd.;