1 minute forex scalping strategy without indicators
1 minute forex scalping strategy without indicators
Hi guys,
here is my naked Chart 1-Minute Forex Scalping Strategy (No Indicators!)
I’ve seen a lot of posts lately about cluttered charts—people relying on MACD, RSI, and overlapping moving averages just to scalp the 1-minute time frame. Honestly, I found that all that noise just causes analysis paralysis. So, I stripped my charts completely bare. Today, I want to share my pure price action, 1-minute scalping strategy that relies purely on market structure and liquidity pools.
1.Mark the Zones:First, analyze the 15-minute chart to establish your daily bias and map out major support and resistance levels.
2.Wait for the Sweep:Drop to the 1-minute chart. Wait patiently for the price to sweep a recent swing low (for a buy) or a swing high (for a sell).
3.Identify a Break of Structure:After the sweep, look for an impulsive reversal. For a buy, price must break above the most recent lower high, confirming the sweep was just a liquidity grab.
4.Time The Entry:Don't chase the initial move! Wait for a pullback into the "golden zone." Enter when the price retraces to the 0.5 to 0.618 Fibonacci level of that impulsive leg, or target the M1 order block left behind.5.Set Risk Management:Place a tight stop loss 1 to 2 pips beyond the sweep candle’s wick. Target the next obvious liquidity pool for a 1:2 risk-to-reward ratio.Why It WorksBy trading naked charts, you react to actual market mechanics rather than lagging math equations.
It requires intense discipline, but once you train your eyes to read these sweeps, the 1-minute chart becomes incredibly clear.Who else is scalping naked charts?
Drop your thoughts below!
Take a care,
have a great trades,
bye bye.
here is my naked Chart 1-Minute Forex Scalping Strategy (No Indicators!)
I’ve seen a lot of posts lately about cluttered charts—people relying on MACD, RSI, and overlapping moving averages just to scalp the 1-minute time frame. Honestly, I found that all that noise just causes analysis paralysis. So, I stripped my charts completely bare. Today, I want to share my pure price action, 1-minute scalping strategy that relies purely on market structure and liquidity pools.
1.Mark the Zones:First, analyze the 15-minute chart to establish your daily bias and map out major support and resistance levels.
2.Wait for the Sweep:Drop to the 1-minute chart. Wait patiently for the price to sweep a recent swing low (for a buy) or a swing high (for a sell).
3.Identify a Break of Structure:After the sweep, look for an impulsive reversal. For a buy, price must break above the most recent lower high, confirming the sweep was just a liquidity grab.
4.Time The Entry:Don't chase the initial move! Wait for a pullback into the "golden zone." Enter when the price retraces to the 0.5 to 0.618 Fibonacci level of that impulsive leg, or target the M1 order block left behind.5.Set Risk Management:Place a tight stop loss 1 to 2 pips beyond the sweep candle’s wick. Target the next obvious liquidity pool for a 1:2 risk-to-reward ratio.Why It WorksBy trading naked charts, you react to actual market mechanics rather than lagging math equations.
It requires intense discipline, but once you train your eyes to read these sweeps, the 1-minute chart becomes incredibly clear.Who else is scalping naked charts?
Drop your thoughts below!
Take a care,
have a great trades,
bye bye.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: 1 minute forex scalping strategy without indicators
Plus i tried to prepare usefull script to detect such zones for you 
Here is a custom MQL4 indicator designed specifically for the 1-minute scalping strategy. It uses dynamic lookback arrays to identify the most recent market structure extremes and renders "buy-side" and "sell-side" liquidity zones.
MQL4 Source Code: Liquidity Sweep Zones
Save this script as an .mq4 file. It relies on standard C++ style syntax with #property strict enabled for memory safety and clean execution.
Here is a custom MQL4 indicator designed specifically for the 1-minute scalping strategy. It uses dynamic lookback arrays to identify the most recent market structure extremes and renders "buy-side" and "sell-side" liquidity zones.
MQL4 Source Code: Liquidity Sweep Zones
Save this script as an .mq4 file. It relies on standard C++ style syntax with #property strict enabled for memory safety and clean execution.
Code: Select all
//+------------------------------------------------------------------+
//| Liquidity_Sweep_Zones.mq4 |
//| Detects dynamic buy/sell liquidity pools |
//+------------------------------------------------------------------+
#property copyright "Automated Zone Detector"
#property version "1.00"
#property strict
#property indicator_chart_window
input int InpLookbackBars = 40; // Lookback Period (Bars)
input int InpZoneWidthPips = 2; // Zone Depth (Pips)
input color InpSweepHighColor = clrLightCoral; // Sell Side Liquidity (Sweep High)
input color InpSweepLowColor = clrLightGreen; // Buy Side Liquidity (Sweep Low)
//+------------------------------------------------------------------+
int OnInit()
{
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
// Clean up graphical objects when the indicator is removed
ObjectsDeleteAll(0, "LiqPool_");
}
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
// Ensure enough data is loaded
if (rates_total < InpLookbackBars) return(0);
// Isolate recent market structure extremes
int highest_idx = ArrayMaximum(high, InpLookbackBars, 1);
int lowest_idx = ArrayMinimum(low, InpLookbackBars, 1);
double swing_high = high[highest_idx];
double swing_low = low[lowest_idx];
// Handle 3/5 digit broker pricing
double pip_multiplier = (Digits() == 3 || Digits() == 5) ? 10.0 : 1.0;
double zone_height = InpZoneWidthPips * Point() * pip_multiplier;
// Render structural liquidity rectangles extending slightly into the future
DrawZone("LiqPool_High", time[highest_idx], swing_high, Time[0] + PeriodSeconds()*10, swing_high - zone_height, InpSweepHighColor);
DrawZone("LiqPool_Low", time[lowest_idx], swing_low, Time[0] + PeriodSeconds()*10, swing_low + zone_height, InpSweepLowColor);
return(rates_total);
}
//+------------------------------------------------------------------+
//| Helper function to manage OBJ_RECTANGLE states |
//+------------------------------------------------------------------+
void DrawZone(string obj_name, datetime t1, double p1, datetime t2, double p2, color clr)
{
if(ObjectFind(0, obj_name) < 0)
{
ObjectCreate(0, obj_name, OBJ_RECTANGLE, 0, t1, p1, t2, p2);
ObjectSetInteger(0, obj_name, OBJPROP_COLOR, clr);
ObjectSetInteger(0, obj_name, OBJPROP_BACK, true);
ObjectSetInteger(0, obj_name, OBJPROP_FILL, true);
ObjectSetInteger(0, obj_name, OBJPROP_HIDDEN, true);
}
else
{
// Update coordinates dynamically on new ticks
ObjectSetInteger(0, obj_name, OBJPROP_TIME1, t1);
ObjectSetDouble(0, obj_name, OBJPROP_PRICE1, p1);
ObjectSetInteger(0, obj_name, OBJPROP_TIME2, t2);
ObjectSetDouble(0, obj_name, OBJPROP_PRICE2, p2);
}
}
//+------------------------------------------------------------------+Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: 1 minute forex scalping strategy without indicators
Logic BreakdownDynamic Arrays:
The script uses ArrayMaximum and ArrayMinimum to scan the defined lookback period and grab the precise index of the swing points.Object Management: Instead of flooding the chart with overlapping boxes, the DrawZone helper function creates two persistent OBJ_RECTANGLE entities and simply recalculates their coordinates on every tick. This is computationally inexpensive and keeps the chart clean.Broker Independence: The pip_multiplier logic automatically adjusts for standard 4-digit and fractional 5-digit pricing models.
1.Open MetaEditor:Press F4 in your MT4 terminal to open the IDE.
2.Create a New Custom Indicator:Select "New" -> "Custom Indicator", name it Liquidity_Sweep_Zones, and click Finish.
3.Compile the Code:Overwrite the generated template with the provided MQL4 code and press F7 to compile.4.Apply to Chart:Return to MT4, locate the newly compiled script in your Navigator panel, and drag it onto your 1-minute chart.
The script uses ArrayMaximum and ArrayMinimum to scan the defined lookback period and grab the precise index of the swing points.Object Management: Instead of flooding the chart with overlapping boxes, the DrawZone helper function creates two persistent OBJ_RECTANGLE entities and simply recalculates their coordinates on every tick. This is computationally inexpensive and keeps the chart clean.Broker Independence: The pip_multiplier logic automatically adjusts for standard 4-digit and fractional 5-digit pricing models.
1.Open MetaEditor:Press F4 in your MT4 terminal to open the IDE.
2.Create a New Custom Indicator:Select "New" -> "Custom Indicator", name it Liquidity_Sweep_Zones, and click Finish.
3.Compile the Code:Overwrite the generated template with the provided MQL4 code and press F7 to compile.4.Apply to Chart:Return to MT4, locate the newly compiled script in your Navigator panel, and drag it onto your 1-minute chart.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: 1 minute forex scalping strategy without indicators
And i prepared second version, where i have implemented alert notifications:
Code: Select all
//+------------------------------------------------------------------+
//| Liquidity_Sweep_Zones.mq4 |
//| Detects dynamic buy/sell liquidity pools |
//+------------------------------------------------------------------+
#property copyright "Automated Zone Detector"
#property version "1.10"
#property strict
#property indicator_chart_window
// Zone Inputs
input int InpLookbackBars = 40; // Lookback Period (Bars)
input int InpZoneWidthPips = 2; // Zone Depth (Pips)
input color InpSweepHighColor = clrLightCoral; // Sell Side Liquidity (Sweep High)
input color InpSweepLowColor = clrLightGreen; // Buy Side Liquidity (Sweep Low)
// Alert Inputs
input bool InpEnableAlerts = true; // Master Alert Toggle
input bool InpEnablePush = true; // Send Push Notifications
input bool InpEnableSound = true; // Play Sound
input string InpSoundFile = "alert.wav"; // Alert Sound File (WAV format)
//+------------------------------------------------------------------+
int OnInit()
{
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
ObjectsDeleteAll(0, "LiqPool_");
}
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
if (rates_total < InpLookbackBars) return(0);
// Isolate recent market structure extremes
int highest_idx = ArrayMaximum(high, InpLookbackBars, 1);
int lowest_idx = ArrayMinimum(low, InpLookbackBars, 1);
double swing_high = high[highest_idx];
double swing_low = low[lowest_idx];
double pip_multiplier = (Digits() == 3 || Digits() == 5) ? 10.0 : 1.0;
double zone_height = InpZoneWidthPips * Point() * pip_multiplier;
double sell_zone_bottom = swing_high - zone_height;
double buy_zone_top = swing_low + zone_height;
// Render structural liquidity rectangles
DrawZone("LiqPool_High", time[highest_idx], swing_high, Time[0] + PeriodSeconds()*10, sell_zone_bottom, InpSweepHighColor);
DrawZone("LiqPool_Low", time[lowest_idx], swing_low, Time[0] + PeriodSeconds()*10, buy_zone_top, InpSweepLowColor);
// --- ALERT LOGIC ---
// Use a static datetime to persist the state between ticks
static datetime last_alert_time = 0;
// Only evaluate if alerts are on and we haven't alerted on this specific M1 candle yet
if(InpEnableAlerts && Time[0] != last_alert_time)
{
bool alert_triggered = false;
string alert_msg = "";
// Check if current Close is inside the Sell Side Liquidity Zone
if(Close[0] >= sell_zone_bottom && Close[0] <= swing_high)
{
alert_msg = Symbol() + " M" + IntegerToString(Period()) + ": Price entered SELL Liquidity Zone";
alert_triggered = true;
}
// Check if current Close is inside the Buy Side Liquidity Zone
else if(Close[0] <= buy_zone_top && Close[0] >= swing_low)
{
alert_msg = Symbol() + " M" + IntegerToString(Period()) + ": Price entered BUY Liquidity Zone";
alert_triggered = true;
}
// Dispatch notifications
if(alert_triggered)
{
if(InpEnablePush)
{
SendNotification(alert_msg);
}
if(InpEnableSound)
{
PlaySound(InpSoundFile);
}
// Log to the Experts tab for debugging
Print(alert_msg);
// Lock the state for the remainder of this candle
last_alert_time = Time[0];
}
}
return(rates_total);
}
//+------------------------------------------------------------------+
void DrawZone(string obj_name, datetime t1, double p1, datetime t2, double p2, color clr)
{
if(ObjectFind(0, obj_name) < 0)
{
ObjectCreate(0, obj_name, OBJ_RECTANGLE, 0, t1, p1, t2, p2);
ObjectSetInteger(0, obj_name, OBJPROP_COLOR, clr);
ObjectSetInteger(0, obj_name, OBJPROP_BACK, true);
ObjectSetInteger(0, obj_name, OBJPROP_FILL, true);
ObjectSetInteger(0, obj_name, OBJPROP_HIDDEN, true);
}
else
{
ObjectSetInteger(0, obj_name, OBJPROP_TIME1, t1);
ObjectSetDouble(0, obj_name, OBJPROP_PRICE1, p1);
ObjectSetInteger(0, obj_name, OBJPROP_TIME2, t2);
ObjectSetDouble(0, obj_name, OBJPROP_PRICE2, p2);
}
}
//+------------------------------------------------------------------+Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: 1 minute forex scalping strategy without indicators
And in case, you would like to try it as fully automated AI, you can try this script, it should work for you.
But do not forget to test it first
Here is the complete EA code. It integrates the previous zone-detection logic, adds a state-tracking mechanism using a Magic Number, and handles the OrderSend routing with integrated Stop Loss and Take Profit parameters.
MQL4 Source Code: Liquidity Sweep Auto-Scalper
But do not forget to test it first
Here is the complete EA code. It integrates the previous zone-detection logic, adds a state-tracking mechanism using a Magic Number, and handles the OrderSend routing with integrated Stop Loss and Take Profit parameters.
MQL4 Source Code: Liquidity Sweep Auto-Scalper
Code: Select all
//+------------------------------------------------------------------+
//| Liquidity_Sweep_Scalper_EA.mq4 |
//| Automated Execution for Liquidity Pool Sweeps |
//+------------------------------------------------------------------+
#property copyright "Automated Zone Scalper EA"
#property version "1.00"
#property strict
// --- Trading Parameters ---
input double InpLotSize = 0.10; // Fixed Lot Size
input int InpStopLossPips = 5; // Stop Loss (Pips)
input int InpTakeProfitPips = 10; // Take Profit (Pips)
input int InpMaxSlippage = 3; // Max Slippage (Pips)
input int InpMagicNumber = 999111; // EA Identifier
// --- Zone Parameters ---
input int InpLookbackBars = 40; // Lookback Period (Bars)
input int InpZoneWidthPips = 2; // Zone Depth (Pips)
input color InpSweepHighColor = clrLightCoral;
input color InpSweepLowColor = clrLightGreen;
//+------------------------------------------------------------------+
int OnInit()
{
// Validate inputs
if(InpStopLossPips <= 0 || InpTakeProfitPips <= 0)
{
Print("Invalid SL/TP configuration.");
return(INIT_PARAMETERS_INCORRECT);
}
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
ObjectsDeleteAll(0, "LiqPool_");
}
void OnTick()
{
// Ensure enough historical data is available
if (Bars < InpLookbackBars) return;
// 1. Calculate Pricing Variables
double pip_size = (Digits() == 3 || Digits() == 5) ? 10.0 * Point() : Point();
int slippage_points = (Digits() == 3 || Digits() == 5) ? InpMaxSlippage * 10 : InpMaxSlippage;
// 2. Identify Market Structure Extremes
int highest_idx = iHighest(Symbol(), Period(), MODE_HIGH, InpLookbackBars, 1);
int lowest_idx = iLowest(Symbol(), Period(), MODE_LOW, InpLookbackBars, 1);
double swing_high = High[highest_idx];
double swing_low = Low[lowest_idx];
double zone_height = InpZoneWidthPips * pip_size;
double sell_zone_bottom = swing_high - zone_height;
double buy_zone_top = swing_low + zone_height;
// 3. Render GUI (Optional for EAs, but helpful for visual debugging)
DrawZone("LiqPool_High", Time[highest_idx], swing_high, Time[0] + PeriodSeconds()*10, sell_zone_bottom, InpSweepHighColor);
DrawZone("LiqPool_Low", Time[lowest_idx], swing_low, Time[0] + PeriodSeconds()*10, buy_zone_top, InpSweepLowColor);
// 4. State Management: Check for open positions managed by this EA
if(HasOpenPositions(InpMagicNumber)) return; // Lock execution if a trade is active
// 5. Execution Logic
double ask = MarketInfo(Symbol(), MODE_ASK);
double bid = MarketInfo(Symbol(), MODE_BID);
// SELL Condition: Price enters the upper liquidity zone
if(Close[0] >= sell_zone_bottom && Close[0] <= swing_high)
{
double sl = NormalizeDouble(bid + (InpStopLossPips * pip_size), Digits());
double tp = NormalizeDouble(bid - (InpTakeProfitPips * pip_size), Digits());
int ticket = OrderSend(Symbol(), OP_SELL, InpLotSize, bid, slippage_points, sl, tp, "Liq Sweep Sell", InpMagicNumber, 0, clrRed);
if(ticket < 0) Print("OrderSend Error: ", GetLastError());
}
// BUY Condition: Price enters the lower liquidity zone
else if(Close[0] <= buy_zone_top && Close[0] >= swing_low)
{
double sl = NormalizeDouble(ask - (InpStopLossPips * pip_size), Digits());
double tp = NormalizeDouble(ask + (InpTakeProfitPips * pip_size), Digits());
int ticket = OrderSend(Symbol(), OP_BUY, InpLotSize, ask, slippage_points, sl, tp, "Liq Sweep Buy", InpMagicNumber, 0, clrBlue);
if(ticket < 0) Print("OrderSend Error: ", GetLastError());
}
}
//+------------------------------------------------------------------+
//| Helper: Check if EA has open positions |
//+------------------------------------------------------------------+
bool HasOpenPositions(int magic_num)
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == magic_num)
{
return true;
}
}
}
return false;
}
//+------------------------------------------------------------------+
//| Helper: Manage GUI objects |
//+------------------------------------------------------------------+
void DrawZone(string obj_name, datetime t1, double p1, datetime t2, double p2, color clr)
{
if(ObjectFind(0, obj_name) < 0)
{
ObjectCreate(0, obj_name, OBJ_RECTANGLE, 0, t1, p1, t2, p2);
ObjectSetInteger(0, obj_name, OBJPROP_COLOR, clr);
ObjectSetInteger(0, obj_name, OBJPROP_BACK, true);
ObjectSetInteger(0, obj_name, OBJPROP_FILL, true);
ObjectSetInteger(0, obj_name, OBJPROP_HIDDEN, true);
}
else
{
ObjectSetInteger(0, obj_name, OBJPROP_TIME1, t1);
ObjectSetDouble(0, obj_name, OBJPROP_PRICE1, p1);
ObjectSetInteger(0, obj_name, OBJPROP_TIME2, t2);
ObjectSetDouble(0, obj_name, OBJPROP_PRICE2, p2);
}
}
//+------------------------------------------------------------------+Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: 1 minute forex scalping strategy without indicators
Architecture Breakdown
1.) OnTick() Hook: This replaces OnCalculate(). It fires every time the broker pushes a new price quote.
2.) The Magic Number: A unique integer (999111) is assigned to every trade this specific EA executes. The HasOpenPositions function iterates through the terminal's active order pool and checks this ID. If an order exists, the EA bypasses the entry logic, preventing rapid-fire duplicate orders in the same zone.
3.) Data Retrieval Shift: Instead of using the pre-populated arrays from OnCalculate (like high[] and low[]), the EA pulls structural data directly from the terminal using iHighest and iLowest.
4.) Price Normalization: The NormalizeDouble function is critical here. 1-minute charts have highly volatile fractional pricing. Sending un-normalized doubles to the broker's API will result in Error 130 (ERR_INVALID_STOPS).
1.) OnTick() Hook: This replaces OnCalculate(). It fires every time the broker pushes a new price quote.
2.) The Magic Number: A unique integer (999111) is assigned to every trade this specific EA executes. The HasOpenPositions function iterates through the terminal's active order pool and checks this ID. If an order exists, the EA bypasses the entry logic, preventing rapid-fire duplicate orders in the same zone.
3.) Data Retrieval Shift: Instead of using the pre-populated arrays from OnCalculate (like high[] and low[]), the EA pulls structural data directly from the terminal using iHighest and iLowest.
4.) Price Normalization: The NormalizeDouble function is critical here. 1-minute charts have highly volatile fractional pricing. Sending un-normalized doubles to the broker's API will result in Error 130 (ERR_INVALID_STOPS).
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: 1 minute forex scalping strategy without indicators
Plus i got idea how to make it more robust, i extend it with trailing stop mechanism.
To implement a dynamic trailing stop, the EA needs to shift from a "fire and forget" model to continuous trade management.
When you introduce a trailing stop, the EA must evaluate the profit of open positions on every single tick. To prevent the EA from spamming your broker's server with modification requests for every micro-pip movement, we will introduce a Trailing Step. This ensures the Stop Loss only moves when the price has advanced by a meaningful, predefined increment.
Here is the fully updated EA with the integrated trailing stop logic.
Updated MQL4 Source Code: EA with Trailing Stop
To implement a dynamic trailing stop, the EA needs to shift from a "fire and forget" model to continuous trade management.
When you introduce a trailing stop, the EA must evaluate the profit of open positions on every single tick. To prevent the EA from spamming your broker's server with modification requests for every micro-pip movement, we will introduce a Trailing Step. This ensures the Stop Loss only moves when the price has advanced by a meaningful, predefined increment.
Here is the fully updated EA with the integrated trailing stop logic.
Updated MQL4 Source Code: EA with Trailing Stop
Code: Select all
//+------------------------------------------------------------------+
//| Liquidity_Sweep_Scalper_EA.mq4 |
//| Automated Execution with Dynamic Trailing Stop |
//+------------------------------------------------------------------+
#property copyright "Automated Zone Scalper EA"
#property version "1.10"
#property strict
// --- Trading Parameters ---
input double InpLotSize = 0.10; // Fixed Lot Size
input int InpStopLossPips = 5; // Initial Stop Loss (Pips)
input int InpTakeProfitPips = 10; // Take Profit (Pips)
input int InpMaxSlippage = 3; // Max Slippage (Pips)
input int InpMagicNumber = 999111; // EA Identifier
// --- Trailing Stop Parameters ---
input bool InpUseTrailingStop = true; // Enable Trailing Stop
input int InpTrailingStopPips = 4; // Distance behind price (Pips)
input int InpTrailingStepPips = 1; // Minimum move before adjusting (Pips)
// --- Zone Parameters ---
input int InpLookbackBars = 40; // Lookback Period (Bars)
input int InpZoneWidthPips = 2; // Zone Depth (Pips)
input color InpSweepHighColor = clrLightCoral;
input color InpSweepLowColor = clrLightGreen;
//+------------------------------------------------------------------+
int OnInit()
{
if(InpStopLossPips <= 0 || InpTakeProfitPips <= 0)
{
Print("Invalid SL/TP configuration.");
return(INIT_PARAMETERS_INCORRECT);
}
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
ObjectsDeleteAll(0, "LiqPool_");
}
void OnTick()
{
if (Bars < InpLookbackBars) return;
// 1. Calculate Pricing Variables
double pip_size = (Digits() == 3 || Digits() == 5) ? 10.0 * Point() : Point();
int slippage_points = (Digits() == 3 || Digits() == 5) ? InpMaxSlippage * 10 : InpMaxSlippage;
// 2. Manage Open Positions (Trailing Stop)
// This MUST happen before the HasOpenPositions check so it runs on every tick
if(InpUseTrailingStop)
{
ManageTrailingStops(pip_size);
}
// 3. State Management: Prevent multiple entries
if(HasOpenPositions(InpMagicNumber)) return;
// 4. Identify Market Structure Extremes
int highest_idx = iHighest(Symbol(), Period(), MODE_HIGH, InpLookbackBars, 1);
int lowest_idx = iLowest(Symbol(), Period(), MODE_LOW, InpLookbackBars, 1);
double swing_high = High[highest_idx];
double swing_low = Low[lowest_idx];
double zone_height = InpZoneWidthPips * pip_size;
double sell_zone_bottom = swing_high - zone_height;
double buy_zone_top = swing_low + zone_height;
// 5. Render GUI
DrawZone("LiqPool_High", Time[highest_idx], swing_high, Time[0] + PeriodSeconds()*10, sell_zone_bottom, InpSweepHighColor);
DrawZone("LiqPool_Low", Time[lowest_idx], swing_low, Time[0] + PeriodSeconds()*10, buy_zone_top, InpSweepLowColor);
// 6. Execution Logic
double ask = MarketInfo(Symbol(), MODE_ASK);
double bid = MarketInfo(Symbol(), MODE_BID);
// SELL Condition
if(Close[0] >= sell_zone_bottom && Close[0] <= swing_high)
{
double sl = NormalizeDouble(bid + (InpStopLossPips * pip_size), Digits());
double tp = NormalizeDouble(bid - (InpTakeProfitPips * pip_size), Digits());
int ticket = OrderSend(Symbol(), OP_SELL, InpLotSize, bid, slippage_points, sl, tp, "Liq Sweep Sell", InpMagicNumber, 0, clrRed);
if(ticket < 0) Print("OrderSend Error: ", GetLastError());
}
// BUY Condition
else if(Close[0] <= buy_zone_top && Close[0] >= swing_low)
{
double sl = NormalizeDouble(ask - (InpStopLossPips * pip_size), Digits());
double tp = NormalizeDouble(ask + (InpTakeProfitPips * pip_size), Digits());
int ticket = OrderSend(Symbol(), OP_BUY, InpLotSize, ask, slippage_points, sl, tp, "Liq Sweep Buy", InpMagicNumber, 0, clrBlue);
if(ticket < 0) Print("OrderSend Error: ", GetLastError());
}
}
//+------------------------------------------------------------------+
//| Subroutine: Manage Dynamic Trailing Stops |
//+------------------------------------------------------------------+
void ManageTrailingStops(double pip_size)
{
double trailing_dist = InpTrailingStopPips * pip_size;
double trailing_step = InpTrailingStepPips * pip_size;
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == InpMagicNumber)
{
// Manage BUY Order
if(OrderType() == OP_BUY)
{
double new_sl = NormalizeDouble(Bid - trailing_dist, Digits());
// Check if price is in profit enough to start trailing
if(Bid - OrderOpenPrice() > trailing_dist)
{
// Only modify if the new SL is higher than the old one by the trailing step
if(OrderStopLoss() < new_sl - trailing_step || OrderStopLoss() == 0)
{
bool res = OrderModify(OrderTicket(), OrderOpenPrice(), new_sl, OrderTakeProfit(), 0, clrGreen);
if(!res) Print("Error modifying Buy SL: ", GetLastError());
}
}
}
// Manage SELL Order
else if(OrderType() == OP_SELL)
{
double new_sl = NormalizeDouble(Ask + trailing_dist, Digits());
// Check if price is in profit enough to start trailing
if(OrderOpenPrice() - Ask > trailing_dist)
{
// Only modify if the new SL is lower than the old one by the trailing step
if(OrderStopLoss() > new_sl + trailing_step || OrderStopLoss() == 0)
{
bool res = OrderModify(OrderTicket(), OrderOpenPrice(), new_sl, OrderTakeProfit(), 0, clrRed);
if(!res) Print("Error modifying Sell SL: ", GetLastError());
}
}
}
}
}
}
}
//+------------------------------------------------------------------+
bool HasOpenPositions(int magic_num)
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == magic_num) return true;
}
}
return false;
}
//+------------------------------------------------------------------+
void DrawZone(string obj_name, datetime t1, double p1, datetime t2, double p2, color clr)
{
if(ObjectFind(0, obj_name) < 0)
{
ObjectCreate(0, obj_name, OBJ_RECTANGLE, 0, t1, p1, t2, p2);
ObjectSetInteger(0, obj_name, OBJPROP_COLOR, clr);
ObjectSetInteger(0, obj_name, OBJPROP_BACK, true);
ObjectSetInteger(0, obj_name, OBJPROP_FILL, true);
ObjectSetInteger(0, obj_name, OBJPROP_HIDDEN, true);
}
else
{
ObjectSetInteger(0, obj_name, OBJPROP_TIME1, t1);
ObjectSetDouble(0, obj_name, OBJPROP_PRICE1, p1);
ObjectSetInteger(0, obj_name, OBJPROP_TIME2, t2);
ObjectSetDouble(0, obj_name, OBJPROP_PRICE2, p2);
}
}
//+------------------------------------------------------------------+Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: 1 minute forex scalping strategy without indicators
Plus i have prepared versions for MT5 traders plus IC traders as well.
Transitioning from MQL4 to MQL5 requires a significant architectural shift. While MQL4 is highly procedural and treats everything as an "order," MQL5 is an object-oriented language that strictly separates Orders (requests to the broker), Deals (historical executions), and Positions (your current open exposure).
Since you are running this on IC Markets (IC Trader), the environment will almost certainly feature 5-digit fractional pricing and raw spreads.
To handle the complex MqlTradeRequest structures cleanly, this MT5 version utilizes the standard MQL5 #include <Trade\Trade.mqh> library. This wraps the execution logic into a robust, object-oriented CTrade class, handling slippage, re-quotes, and server routing natively.
MQL5 Source Code: Liquidity Sweep Auto-Scalper (MT5)
Key Changes for MT5 Architecture#include <Trade\Trade.mqh>: This removes the need for manual OrderSend structures and error logging, replacing them with trade.Buy(), trade.Sell(), and trade.PositionModify().Time Series Arrays: MT5 does not provide direct global access to High[], Low[], or Close[]. We instantiate local arrays on every tick and use CopyHigh, CopyLow, etc., to populate them. ArraySetAsSeries(..., true) is critical here; without it, index 0 would be the oldest bar on the chart, not the newest.Positions vs. Orders: The iteration loops inside HasOpenPositions and ManageTrailingStops have been rewritten to use PositionsTotal() and PositionGetTicket().Variable Typing: Variables like InpMagicNumber and ticket are updated to ulong (Unsigned Long), which is MT5's standard for ticket IDs and Magic Numbers.1.Open MetaEditor 5:Press F4 in your MT5 terminal to open the IDE.2.Create Expert Advisor:Select "New" -> "Expert Advisor (template)", name it Liquidity_Sweep_Scalper_MT5, and click Finish.3.Compile Code:Paste the provided C++ code and press F7 to compile.4.Enable Algo Trading:In your MT5 terminal, ensure the "Algo Trading" button on the top toolbar is pressed (it should turn green), then drag the EA onto your chart.
Transitioning from MQL4 to MQL5 requires a significant architectural shift. While MQL4 is highly procedural and treats everything as an "order," MQL5 is an object-oriented language that strictly separates Orders (requests to the broker), Deals (historical executions), and Positions (your current open exposure).
Since you are running this on IC Markets (IC Trader), the environment will almost certainly feature 5-digit fractional pricing and raw spreads.
To handle the complex MqlTradeRequest structures cleanly, this MT5 version utilizes the standard MQL5 #include <Trade\Trade.mqh> library. This wraps the execution logic into a robust, object-oriented CTrade class, handling slippage, re-quotes, and server routing natively.
MQL5 Source Code: Liquidity Sweep Auto-Scalper (MT5)
Code: Select all
//+------------------------------------------------------------------+
//| Liquidity_Sweep_Scalper_EA.mq5 |
//| Automated Execution with Dynamic Trailing Stop |
//| Optimized for MetaTrader 5 (IC Markets) |
//+------------------------------------------------------------------+
#property copyright "Automated Zone Scalper EA MT5"
#property version "1.20"
#include <Trade\Trade.mqh>
// Initialize the Trade Object
CTrade trade;
// --- Trading Parameters ---
input double InpLotSize = 0.10; // Fixed Lot Size
input int InpStopLossPips = 5; // Initial Stop Loss (Pips)
input int InpTakeProfitPips = 10; // Take Profit (Pips)
input int InpMaxSlippage = 3; // Max Slippage (Pips)
input ulong InpMagicNumber = 999111; // EA Identifier (ulong in MT5)
// --- Trailing Stop Parameters ---
input bool InpUseTrailingStop = true; // Enable Trailing Stop
input int InpTrailingStopPips = 4; // Distance behind price (Pips)
input int InpTrailingStepPips = 1; // Minimum move before adjusting (Pips)
// --- Zone Parameters ---
input int InpLookbackBars = 40; // Lookback Period (Bars)
input int InpZoneWidthPips = 2; // Zone Depth (Pips)
input color InpSweepHighColor = clrLightCoral;
input color InpSweepLowColor = clrLightGreen;
//+------------------------------------------------------------------+
int OnInit()
{
if(InpStopLossPips <= 0 || InpTakeProfitPips <= 0)
{
Print("Invalid SL/TP configuration.");
return(INIT_PARAMETERS_INCORRECT);
}
// Configure the CTrade object
trade.SetExpertMagicNumber(InpMagicNumber);
trade.SetDeviationInPoints(InpMaxSlippage * ((_Digits == 3 || _Digits == 5) ? 10 : 1));
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
ObjectsDeleteAll(0, "LiqPool_");
}
void OnTick()
{
// 1. Data Retrieval (MQL5 requires copying timeseries data to arrays)
double High[], Low[], Close[];
datetime Time[];
// Set arrays to behave like MQL4 (Index 0 = Current Bar)
ArraySetAsSeries(High, true);
ArraySetAsSeries(Low, true);
ArraySetAsSeries(Close, true);
ArraySetAsSeries(Time, true);
if(CopyHigh(_Symbol, _Period, 0, InpLookbackBars, High) < InpLookbackBars) return;
if(CopyLow(_Symbol, _Period, 0, InpLookbackBars, Low) < InpLookbackBars) return;
if(CopyClose(_Symbol, _Period, 0, 1, Close) < 1) return;
if(CopyTime(_Symbol, _Period, 0, InpLookbackBars, Time) < InpLookbackBars) return;
// 2. Calculate Pricing Variables
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double pip_size = (_Digits == 3 || _Digits == 5) ? 10.0 * point : point;
// 3. Manage Open Positions (Trailing Stop)
if(InpUseTrailingStop)
{
ManageTrailingStops(pip_size);
}
// 4. State Management: Prevent multiple entries
if(HasOpenPositions(InpMagicNumber)) return;
// 5. Identify Market Structure Extremes
int highest_idx = ArrayMaximum(High, 0, InpLookbackBars);
int lowest_idx = ArrayMinimum(Low, 0, InpLookbackBars);
double swing_high = High[highest_idx];
double swing_low = Low[lowest_idx];
double zone_height = InpZoneWidthPips * pip_size;
double sell_zone_bottom = swing_high - zone_height;
double buy_zone_top = swing_low + zone_height;
// 6. Render GUI
DrawZone("LiqPool_High", Time[highest_idx], swing_high, TimeCurrent() + PeriodSeconds()*10, sell_zone_bottom, InpSweepHighColor);
DrawZone("LiqPool_Low", Time[lowest_idx], swing_low, TimeCurrent() + PeriodSeconds()*10, buy_zone_top, InpSweepLowColor);
// 7. Execution Logic
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
// SELL Condition
if(Close[0] >= sell_zone_bottom && Close[0] <= swing_high)
{
double sl = NormalizeDouble(bid + (InpStopLossPips * pip_size), _Digits);
double tp = NormalizeDouble(bid - (InpTakeProfitPips * pip_size), _Digits);
trade.Sell(InpLotSize, _Symbol, bid, sl, tp, "Liq Sweep Sell");
}
// BUY Condition
else if(Close[0] <= buy_zone_top && Close[0] >= swing_low)
{
double sl = NormalizeDouble(ask - (InpStopLossPips * pip_size), _Digits);
double tp = NormalizeDouble(ask + (InpTakeProfitPips * pip_size), _Digits);
trade.Buy(InpLotSize, _Symbol, ask, sl, tp, "Liq Sweep Buy");
}
}
//+------------------------------------------------------------------+
//| Subroutine: Manage Dynamic Trailing Stops (MT5 Positions) |
//+------------------------------------------------------------------+
void ManageTrailingStops(double pip_size)
{
double trailing_dist = InpTrailingStopPips * pip_size;
double trailing_step = InpTrailingStepPips * pip_size;
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i); // Selects the position
if(PositionGetString(POSITION_SYMBOL) == _Symbol && PositionGetInteger(POSITION_MAGIC) == InpMagicNumber)
{
double current_sl = PositionGetDouble(POSITION_SL);
double open_price = PositionGetDouble(POSITION_PRICE_OPEN);
// Manage BUY Position
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
{
double current_bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double new_sl = NormalizeDouble(current_bid - trailing_dist, _Digits);
if(current_bid - open_price > trailing_dist)
{
if(current_sl < new_sl - trailing_step || current_sl == 0)
{
trade.PositionModify(ticket, new_sl, PositionGetDouble(POSITION_TP));
}
}
}
// Manage SELL Position
else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
{
double current_ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double new_sl = NormalizeDouble(current_ask + trailing_dist, _Digits);
if(open_price - current_ask > trailing_dist)
{
if(current_sl > new_sl + trailing_step || current_sl == 0)
{
trade.PositionModify(ticket, new_sl, PositionGetDouble(POSITION_TP));
}
}
}
}
}
}
//+------------------------------------------------------------------+
//| Helper: Check if EA has open positions |
//+------------------------------------------------------------------+
bool HasOpenPositions(ulong magic_num)
{
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
if(PositionGetSymbol(i) == _Symbol)
{
if(PositionGetInteger(POSITION_MAGIC) == magic_num) return true;
}
}
return false;
}
//+------------------------------------------------------------------+
//| Helper: Manage GUI objects |
//+------------------------------------------------------------------+
void DrawZone(string obj_name, datetime t1, double p1, datetime t2, double p2, color clr)
{
if(ObjectFind(0, obj_name) < 0)
{
ObjectCreate(0, obj_name, OBJ_RECTANGLE, 0, t1, p1, t2, p2);
ObjectSetInteger(0, obj_name, OBJPROP_COLOR, clr);
ObjectSetInteger(0, obj_name, OBJPROP_BACK, true);
ObjectSetInteger(0, obj_name, OBJPROP_FILL, true);
ObjectSetInteger(0, obj_name, OBJPROP_HIDDEN, true);
}
else
{
ObjectSetInteger(0, obj_name, OBJPROP_TIME1, t1);
ObjectSetDouble(0, obj_name, OBJPROP_PRICE1, p1);
ObjectSetInteger(0, obj_name, OBJPROP_TIME2, t2);
ObjectSetDouble(0, obj_name, OBJPROP_PRICE2, p2);
}
}
//+------------------------------------------------------------------+Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: 1 minute forex scalping strategy without indicators
And here it is for IC traders:
While MetaTrader uses MQL4/MQL5, cTrader's algorithmic trading engine (cTrader Automate) is built entirely on C#. It is a modern, object-oriented framework that is much faster and cleaner than MetaTrader, especially when handling things like volume normalization and UI drawing.
In cTrader, we don't use "Magic Numbers" to track trades; we use string Labels. Furthermore, cTrader handles lot-to-volume conversions natively, so we don't need complex normalizations to avoid broker rejections.
Here is the exact same 1-minute liquidity sweep strategy, fully translated into a C# cBot for cTrader:
cTrader Automate Source Code (C#)
Setup Instructions for cTrader
1.Open cTrader Automate:In your IC Markets cTrader platform, click on the Automate tab (the robot icon) on the left-hand sidebar.
2.Create a New cBot:Click the + New cBot button at the top of the list. Name it LiquiditySweepScalper.
3.Paste and Build:Replace all the default template code in the central editor with the C# code above. Click the Build button (hammer icon) at the top of the editor. If successful, you'll see a green "Build Succeeded" message.
4.Add an Instance:Click the + button next to your bot's name in the left menu to add an instance for a specific chart (e.g., EURUSD m1). Adjust your lot sizing in the parameters panel, and click the Play button to activate it.
Take a care and have a lot of scalps,
Bye bye
And if you have some improvments or any other ideas, let me know
Share it with us here.
While MetaTrader uses MQL4/MQL5, cTrader's algorithmic trading engine (cTrader Automate) is built entirely on C#. It is a modern, object-oriented framework that is much faster and cleaner than MetaTrader, especially when handling things like volume normalization and UI drawing.
In cTrader, we don't use "Magic Numbers" to track trades; we use string Labels. Furthermore, cTrader handles lot-to-volume conversions natively, so we don't need complex normalizations to avoid broker rejections.
Here is the exact same 1-minute liquidity sweep strategy, fully translated into a C# cBot for cTrader:
cTrader Automate Source Code (C#)
Code: Select all
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Internals;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class LiquiditySweepScalper : Robot
{
// --- Trading Parameters ---
[Parameter("Lot Size", DefaultValue = 0.1, MinValue = 0.01)]
public double LotSize { get; set; }
[Parameter("Stop Loss (Pips)", DefaultValue = 5)]
public double StopLossPips { get; set; }
[Parameter("Take Profit (Pips)", DefaultValue = 10)]
public double TakeProfitPips { get; set; }
// --- Trailing Stop Parameters ---
[Parameter("Enable Trailing Stop", DefaultValue = true, Group = "Trailing Stop")]
public bool UseTrailingStop { get; set; }
[Parameter("Trailing Stop (Pips)", DefaultValue = 4, Group = "Trailing Stop")]
public double TrailingStopPips { get; set; }
[Parameter("Trailing Step (Pips)", DefaultValue = 1, Group = "Trailing Stop")]
public double TrailingStepPips { get; set; }
// --- Zone Parameters ---
[Parameter("Lookback Period (Bars)", DefaultValue = 40, Group = "Zones")]
public int LookbackBars { get; set; }
[Parameter("Zone Depth (Pips)", DefaultValue = 2.0, Group = "Zones")]
public double ZoneWidthPips { get; set; }
private readonly string _botLabel = "LiqSweepBot";
protected override void OnStart()
{
// Fired when the bot starts
Print("Liquidity Sweep Scalper Initialized on {0}", SymbolName);
}
protected override void OnTick()
{
// Ensure enough data is loaded
if (Bars.Count < LookbackBars) return;
// 1. Manage Trailing Stops on every tick
if (UseTrailingStop)
{
ManageTrailingStops();
}
// 2. State Management: Prevent overlapping positions
if (Positions.Count(x => x.Label == _botLabel && x.SymbolName == SymbolName) > 0)
return;
// 3. Find Market Structure Extremes
double swingHigh = double.MinValue;
double swingLow = double.MaxValue;
int highestIdx = 0;
int lowestIdx = 0;
for (int i = 1; i <= LookbackBars; i++)
{
double high = Bars.HighPrices.Last(i);
double low = Bars.LowPrices.Last(i);
if (high > swingHigh)
{
swingHigh = high;
highestIdx = i;
}
if (low < swingLow)
{
swingLow = low;
lowestIdx = i;
}
}
double zoneHeight = ZoneWidthPips * Symbol.PipSize;
double sellZoneBottom = swingHigh - zoneHeight;
double buyZoneTop = swingLow + zoneHeight;
// 4. Render GUI Zones (Semi-transparent rectangles)
DateTime highTime = Bars.OpenTimes.Last(highestIdx);
DateTime lowTime = Bars.OpenTimes.Last(lowestIdx);
DateTime futureTime = Server.Time.AddMinutes(10); // Extend boxes 10 mins forward
Chart.DrawRectangle("LiqPool_High", highTime, swingHigh, futureTime, sellZoneBottom, Color.FromArgb(70, Color.LightCoral)).IsFilled = true;
Chart.DrawRectangle("LiqPool_Low", lowTime, swingLow, futureTime, buyZoneTop, Color.FromArgb(70, Color.LightGreen)).IsFilled = true;
// 5. Execution Logic
double currentClose = Bars.ClosePrices.Last(0);
double volumeInUnits = Symbol.QuantityToVolumeInUnits(LotSize);
// SELL Condition
if (currentClose >= sellZoneBottom && currentClose <= swingHigh)
{
ExecuteMarketOrder(TradeType.Sell, SymbolName, volumeInUnits, _botLabel, StopLossPips, TakeProfitPips);
}
// BUY Condition
else if (currentClose <= buyZoneTop && currentClose >= swingLow)
{
ExecuteMarketOrder(TradeType.Buy, SymbolName, volumeInUnits, _botLabel, StopLossPips, TakeProfitPips);
}
}
// --- Subroutine: Manage Dynamic Trailing Stops ---
private void ManageTrailingStops()
{
var activePositions = Positions.FindAll(_botLabel, SymbolName);
foreach (var position in activePositions)
{
if (position.TradeType == TradeType.Buy)
{
double newSl = Symbol.Bid - (TrailingStopPips * Symbol.PipSize);
// Check if price moved into profit by trailing distance
if (Symbol.Bid - position.EntryPrice >= TrailingStopPips * Symbol.PipSize)
{
if (position.StopLoss == null || position.StopLoss < newSl - (TrailingStepPips * Symbol.PipSize))
{
ModifyPosition(position, Math.Round(newSl, Symbol.Digits), position.TakeProfit);
}
}
}
else if (position.TradeType == TradeType.Sell)
{
double newSl = Symbol.Ask + (TrailingStopPips * Symbol.PipSize);
if (position.EntryPrice - Symbol.Ask >= TrailingStopPips * Symbol.PipSize)
{
if (position.StopLoss == null || position.StopLoss > newSl + (TrailingStepPips * Symbol.PipSize))
{
ModifyPosition(position, Math.Round(newSl, Symbol.Digits), position.TakeProfit);
}
}
}
}
}
}
}1.Open cTrader Automate:In your IC Markets cTrader platform, click on the Automate tab (the robot icon) on the left-hand sidebar.
2.Create a New cBot:Click the + New cBot button at the top of the list. Name it LiquiditySweepScalper.
3.Paste and Build:Replace all the default template code in the central editor with the C# code above. Click the Build button (hammer icon) at the top of the editor. If successful, you'll see a green "Build Succeeded" message.
4.Add an Instance:Click the + button next to your bot's name in the left menu to add an instance for a specific chart (e.g., EURUSD m1). Adjust your lot sizing in the parameters panel, and click the Play button to activate it.
Take a care and have a lot of scalps,
Bye bye
And if you have some improvments or any other ideas, let me know
Share it with us here.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.