- Discussing the article: "How to create a simple Multi-Currency Expert Advisor using MQL5 (Part 1): Indicator Signals based on ADX in combination with Parabolic SAR"
- M5 SMA-Cross scalping
- Summer holiday in forex market?
The EA avoids overtrading and stays inactive during low-volatility conditions.
Add a volume indicator as a filter:
or a volatility indicator as a filter:
Ryan L Johnson, 2025.11.08 14:29
A volatility filter based on 3 ATR's: a fast ATR, a middle ATR, and a slow ATRYou seem to have already diagnosed the problem with trading the holiday season--low liquidity and extraordinarily erratic price movements. Institutional traders generally thin out starting on the week of U.S. Thanksgiving and don't return until after New Year's Day. A time filter applied from Thanksgiving week through January 31st might do well in your case.
Accurate backtesting can generate a valuable Report that will show you the specific hours, days, and months that are winners versus losers.range = (highest - lowest)
if (range > threshold) signal()
I agree with adding a volume filter - don't allow a trade if the volume is below the average. Maybe you can also use trend strength filter instead of a volume filter. I don't know which is better.
Ryan L Johnson, 2025.04.29 19:52
This indicator calls 3 other subwindow indicators. All files go in your Indicators folder.So as not to leave the time filter implementation like a sea of question marks...
Forum on trading, automated trading systems and testing trading strategies
Issues with TimeHour Error when Coding EA
Ryan L Johnson, 2025.01.30 15:16
Inputs:
input group "---------------------------------------"; input group "Turn trading time filter on/off"; input bool UseTimer = true; input group "---------------------------------------"; input group "Use personal computer time to filter? ==> if false, broker time is used"; input bool UsePCtime = true; input group "---------------------------------------"; input group "Set time to enable trading ==> Intraday and overnight are supported"; input string StartTime = "21:00"; input group "---------------------------------------"; input group "Set time to disable trading"; input string StopTime = "16:00"; input group "---------------------------------------";
Variables on global scope:
datetime dLocalTime, dStartTime, dStopTime; ulong uLocalTime, uStartTime, uStopTime,
In OnTick():
dStartTime = StringToTime(StartTime); uStartTime = ulong(dStartTime); dStopTime = StringToTime(StopTime); uStopTime = ulong(dStopTime); if(UsePCtime == true) { dLocalTime = TimeLocal(); } else { dLocalTime = TimeCurrent(); } uLocalTime = ulong(dLocalTime); if(uStartTime < uStopTime) // intraday start trading time is earlier than intraday stop trading time { if(UseTimer == true) { if(uLocalTime >= uStartTime && uLocalTime < uStopTime) { runBot = true; if(timerPrinted != 1) { Print("Timer is ON. Current time is within set trading times. Bot is ON."); timerPrinted = 1; } } else { runBot = false; if(timerPrinted != 2) { Print("Timer is ON. Current time is outside of set trading times. Bot is OFF."); CancelOrder(); timerPrinted = 2; } } } } if(uStartTime > uStopTime) // intraday start trading time is later than intraday stop trading time { if(UseTimer == true) { if(uLocalTime >= uStopTime && uLocalTime < uStartTime) { runBot = false; if(timerPrinted != 2) { Print("Timer is ON. Current time is outside of set trading times. Bot is OFF."); timerPrinted = 2; } } else { runBot = true; if(timerPrinted != 1) { Print("Timer is ON. Current time is within set trading times. Bot is ON."); timerPrinted = 1; } } } } if(UseTimer == false) { runBot = true; if(timerPrinted != 3) { Print("Timer is OFF. Bot is ON."); timerPrinted = 3; } }
And then put your trading code inside:
if(runBot == true) { //all of your trading code }(I prefer to leave trade exits code outside of the time filter).
Thank you very much!
//+-------------------------------------------------------------------+ //| 10 Gold Scalper Entries - NO MARTINGALE | //| Small Capital of Rp. 20,000 - Strict Risk Management | //+-------------------------------------------------------------------+ #Property copyright "TraderHP-10EntryGold" #property version "1.00" #strict properties //--- Input Parameters input int Total Entries = 10; // Maximum number of entries input double LotPerEntry = 0.001; // Lots per entry (MICRO LOT) input int EntryDistance = 50; // Distance between entries (points) input int TakeProfit = 30; // TP per entry (points) input int StopLoss = 20; // SL per entry (points) input int Slippage = 5; // Slip input int MagicNumber = 88888; // Magic Number input bool UseTrendFilter = true; // Trend filter input int TrendPeriod = 20; // EMA trend period //--- Global Variables int entryCounter = 0; double entry Price[10]; int entryTickets[10]; last login date and time = 0; //--- Indicator Handle int emaHandle; double ema[]; //+-------------------------------------------------------------------+ //| Expert initialization function | //+-------------------------------------------------------------------+ int OnInit() { emaHandle = iMA(_Symbol, PERIOD_M5, TrendPeriod, 0, MODE_EMA, PRICE_CLOSE); ArraySetAsSeries(ema, true); // Initialize array ArrayInitialize(entryPrices, 0); ArrayInitialize(entryTickets, 0); // Calculate capital and risk double balance = AccountInfoDouble(ACCOUNT_BALANCE); double riskPerEntry = LotPerEntry * StopLoss * 0.01; // Estimated risk double totalRisk = riskPerEntry * TotalEntries; Print("=== 10 GOLD REGISTRATIONS ==="); Print("Capital: $", balance); Print("Lot/entry: ", LotPerEntry); Print("Risk/entry: ~$", riskPerEntry); Print("Total risk (10 entries): ~$", totalRisk); Print("WARNING: Micro lot trading only!"); if balance < 1.0) Alert("Capital too small! Minimum $1 required"); return(INIT_SUCCESS); } //+-------------------------------------------------------------------+ //| Expert tick function | //+-------------------------------------------------------------------+ void OnTick() { // Update trends if(UseTrendFilter) { CopyBuffer(emaHandle, 0, 0, 2, ema); if(ArraySize(ema) < 2) return; } // Check the number of open positions int openPositions = CountOpenPositions(); // If there is no position yet, find the first entry if (open position == 0 && entry counter == 0) { CheckFirstEntry(); } // If there are open positions, check for additional entries if (open positions > 0 && entry counter < TotalEntries) { Check Additional Entries(); } // Update comments on graph UpdateChartComment(); } //+-------------------------------------------------------------------+ //| Check the first entry based on the trend | //+-------------------------------------------------------------------+ void CheckForFirstEntry() { // Check if enough time has passed since the last entry if(TimeCurrent() - lastEntryTime < 300) // wait time 5 minutes return; Current Price (currentPrice) = SymbolInfoDouble(_Symbol, SYMBOL_BID); double emaValue = ema[0]; // Determine the trend direction int trendDirection = 0; if(current price > ema value + 10 * _points) trendDirection = 1; // Uptrend if (current price < ema value - 10 * _points) trendDirection = -1; // Downtrend if (trendDirection == 0) return; // No clear trend // Open the first entry if (trendDirection == 1) // BUY trend { OpenPosition(ORDER_TYPE_BUY, 0); } otherwise // SELL Trend { OpenPosition(ORDER_TYPE_SELL, 0); } } //+-------------------------------------------------------------------+ //| Check for additional entries | //+-------------------------------------------------------------------+ void CheckForAdditionalEntries() { // Entry between cooling times if(TimeCurrent() - lastEntryTime < 180) // wait time 3 minutes return; // Take the first position as a reference First Entry Price double = 0; int firstEntryType = -1; for (int i = 0; i < PositionsTotal(); i++) { if(PositionGetSymbol(i) == _Symbol && PositionGetInteger(POSITION_MAGIC) == MagicNumber) { firstEntryPrice = PositionGetDouble( POSITION_PRICE_OPEN ); firstEntryType = (int)PositionGetInteger(POSITION_TYPE); damage; } } if(firstEntryPrice == 0) return; Current Price (currentPrice) = SymbolInfoDouble(_Symbol, SYMBOL_BID); double distancePoints = MathAbs(currentPrice - firstEntryPrice) / _Point; // Check if the price has moved far enough to enter an additional order if (entry point distance >= entry distance && entry counter < total entries) { // Open additional entries in the same direction if (first entry type == BUY_POSITION_TYPE) { OpenPosition(ORDER_TYPE_BUY, entryCounter); } if (firstEntryType == POSITION_TYPE_SELL) { OpenPosition(ORDER_TYPE_SELL, entryCounter); } } } //+-------------------------------------------------------------------+ //| Open new position | //+-------------------------------------------------------------------+ void OpenPosition(ENUM_ORDER_TYPE orderType, int entryIndex) { MqlTradeRequest request; MqlTradeResult; ZeroMemory(request); ZeroMemory(result); double price, sl, tp; if (order_type == PURCHASE_ORDER_TYPE) { price = SymbolInfoDouble(_Symbol, SYMBOL_ASK); sl = price - StopLoss * _Point; tp = price + TakeProfit * _Point; } if not { price = SymbolInfoDouble(_Symbol, SYMBOL_BID); sl = price + StopLoss * _Point; tp = price - TakeProfit * _Point; } request.action = TRACT_DEAL; request.symbol = _Symbol; request volume = LotPerEntry; request type = order type; Asking price = price; request.sl = sl; request.tp = tp; request.deviation = Slippage; request.magic = Magic Number; request.comment = "Entry " + IntegerToString(entryIndex + 1) + "/" + IntegerToString(TotalEntries); if(OrderSend(request, result)) { // Save data entry entryPrices[entryCounter] = prices; entryTickets[entryCounter] = result.order; Entry counter++; lastEntryTime = TimeCurrent(); Print("Entry #", entryCounter, " opened with price: ", price, " Lot: ", LotPerEntry, "TP: ", tp, " SL: ", sl); } if not { Print("Entry failed! Error: ", GetLastError()); } } //+-------------------------------------------------------------------+ //| Calculate available positions | //+-------------------------------------------------------------------+ int CountOpenPositions() { int count = 0; for (int i = 0; i < PositionsTotal(); i++) { if(PositionGetSymbol(i) == _Symbol && PositionGetInteger(POSITION_MAGIC) == MagicNumber) { count++; } } return amount; } //+-------------------------------------------------------------------+ //| Calculate total profit/loss | //+-------------------------------------------------------------------+ double CalculateTotalProfit() { Double total profit = 0; for (int i = 0; i < PositionsTotal(); i++) { if(PositionGetSymbol(i) == _Symbol && PositionGetInteger(POSITION_MAGIC) == MagicNumber) { totalProfit += PositionGetDouble(POSITION_PROFIT); } } return total profit; } //+-------------------------------------------------------------------+ //| Update graph comments | //+-------------------------------------------------------------------+ void UpdateChartComment() { double totalProfit = CalculateTotalProfit(); int openPositions = CountOpenPositions(); string comment = "10 GOLD SELLER ENTRIES\n"; comment += "======\n"; comment += "Number of Entries: " + IntegerToString(entryCounter) + "/" + IntegerToString(TotalEntries) + "\n"; comment += "Open Positions: " + IntegerToString(openPositions) + "\n"; comment += "Total Profit: $" + DoubleToString(totalProfit, 2) + "\n"; comment += "Lot/Entry: " + DoubleToString(LotPerEntry, 3) + "\n"; comment += "Next entry distance: " + IntegerToString(EntryDistance) + " points\n"; if(entryCounter > 0) { comment += "\nEntrance Ticket Price:\n"; for(int i = 0; i < entry counter; i++) { if(entryPrices[i] > 0) comments += "#" + IntegerToString(i+1) + ": " + DoubleToString(entryPrices[i], 2) + "\n"; } } Comments(comments); } //+-------------------------------------------------------------------+ //| OnTrade Function | //+-------------------------------------------------------------------+ void OnTrade() { // Reset counter if all positions are closed if(CountOpenPositions() == 0) { entry counter = 0; ArrayInitialize(entryPrices, 0); ArrayInitialize(entryTickets, 0); Print("All positions closed. Reset entry counter."); } } //+-------------------------------------------------------------------+ //| Expert deinitialization function | //+-------------------------------------------------------------------+ void OnDeinit(const int reason) { Comment(""); }
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use