Specifiche
BUY
- Stochastic crosses below Buy Level (default 10) from above
- Current price above SMA100
- Max trades not exceeded
- Grid spacing respected for multiple positions
- Immediate entry on the current candle; no waiting for candle close.
- Stochastic crosses above Sell Level (default 90) from below
- Current price below SMA100
- Max trades not exceeded
- Grid spacing respected for multiple positions
- Immediate entry on the current candle; no waiting for candle close
- Maximum positions per direction: 10
- Grid layering: 2-5 pips apart (editable via Grid Step Pips)
- Fixed lot (FixedLot) or % of account risk (Risk Percent) selectable
- Stop Loss: Manual SL in pips (Stop Loss Pips) applied to all trades
- Take Profit: None (all trades rely on SL or manual close)
- Manual close safe: EA will not open new trades until stochastic crosses the levels again after a position is closed
Behavior Notes
1. Trades only open when SMA filter AND stochastic condition are met simultaneously.
2. If price moves back into neutral zones (around 50), no new trades are triggered unless stochastic crosses the defined Buy/Sell levels again.
3. EA continuously monitors each tick and respects grid spacing and max trades rules.
4. Fully customizable via inputs - stochastic periods, SMA period, Buy/Sell levels, lot size, risk, stop loss, grid spacing, and max trades.
How it Works (Step-by-Step)
1. Check SMA100
- Price above SMA100 → Only BUY trades allowed
- Price below SMA100 → Only SELL trades allowed
2. Check Stochastic
- BUY: crosses below Buy Level (default 10) → open BUY
- SELL: crosses above Sell Level (default 90) → open SELL
3. Check Grid
- New trades only if distance from last open ≥ GridStepPips (2-5 pips)
- Max 10 positions per direction
4. Apply Stop Loss
- * SL in pips as set in input
5. Manual Close Safe
- If trades are manually closed, EA waits for fresh stochastic cross before opening again
//+------------------------------------------------------------------+
//| Stochastic EA - MT5 (No TP, Manual Close Safe) |
//+------------------------------------------------------------------+
#property strict
#include <Trade/Trade.mqh>
CTrade trade;
//---------------- INPUTS ----------------//
input int KPeriod = 14;
input int DPeriod = 3;
input int Slowing = 3;
input int SMAPeriod = 100;
input bool UseRiskPct = false;
input double FixedLot = 0.10;
input double RiskPercent = 1.0;
input int StopLossPips = 20;
input int MaxTrades = 10;
input double GridStepPips = 2.0; // 2–5 pips
//---------------- GLOBALS ----------------//
int stochHandle;
int smaHandle;
double lotSize;
bool buyReady = true;
bool sellReady = true;
double lastK = 50.0; // previous stochastic
//+------------------------------------------------------------------+
int OnInit()
{
if(_Period != PERIOD_M1)
{
Alert("This EA works on M1 timeframe only.");
return INIT_FAILED;
}
stochHandle = iStochastic(_Symbol, PERIOD_M1,
KPeriod, DPeriod, Slowing,
MODE_SMA, STO_LOWHIGH);
smaHandle = iMA(_Symbol, PERIOD_M1,
SMAPeriod, 0, MODE_SMA, PRICE_CLOSE);
if(stochHandle == INVALID_HANDLE || smaHandle == INVALID_HANDLE)
return INIT_FAILED;
lotSize = LotSizeCalc();
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
double LotSizeCalc()
{
if(!UseRiskPct)
return FixedLot;
double riskMoney = AccountInfoDouble(ACCOUNT_BALANCE) * RiskPercent / 100.0;
double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
double slPoints = StopLossPips * _Point * 10;
double lot = riskMoney / (slPoints / _Point * tickValue);
return NormalizeDouble(lot, 2);
}
//+------------------------------------------------------------------+
int CountPositions(int type)
{
int count = 0;
for(int i=0; i<PositionsTotal(); i++)
{
if(PositionSelectByIndex(i))
{
if(PositionGetString(POSITION_SYMBOL) == _Symbol &&
PositionGetInteger(POSITION_TYPE) == type)
count++;
}
}
return count;
}
//+------------------------------------------------------------------+
double LastOpenPrice(int type)
{
for(int i=PositionsTotal()-1; i>=0; i--)
{
if(PositionSelectByIndex(i))
{
if(PositionGetString(POSITION_SYMBOL) == _Symbol &&
PositionGetInteger(POSITION_TYPE) == type)
return PositionGetDouble(POSITION_PRICE_OPEN);
}
}
return 0;
}
//+------------------------------------------------------------------+
void OnTick()
{
double k[2], sma[1];
if(CopyBuffer(stochHandle, 0, 0, 2, k) <= 0) return;
if(CopyBuffer(smaHandle, 0, 0, 1, sma) <= 0) return;
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double grid = GridStepPips * _Point * 10;
int buyCount = CountPositions(POSITION_TYPE_BUY);
int sellCount = CountPositions(POSITION_TYPE_SELL);
// ---------------- RESET FLAGS ----------------
if(buyCount == 0 && k[0] > 10) buyReady = true; // reset buy after zone crossed
if(sellCount == 0 && k[0] < 90) sellReady = true; // reset sell after zone crossed
// ---------------- BUY ENTRY ----------------
if(buyReady && k[1] > 10 && k[0] <= 10 && bid > sma[0] && buyCount < MaxTrades)
{
if(buyCount == 0 || bid < LastOpenPrice(POSITION_TYPE_BUY) - grid)
{
double sl = bid - StopLossPips * _Point * 10;
if(trade.Buy(lotSize, _Symbol, ask, sl, 0))
buyReady = false; // prevent re-entry until stochastic resets
}
}
// ---------------- SELL ENTRY ----------------
if(sellReady && k[1] < 90 && k[0] >= 90 && bid < sma[0] && sellCount < MaxTrades)
{
if(sellCount == 0 || ask > LastOpenPrice(POSITION_TYPE_SELL) + grid)
{
double sl = ask + StopLossPips * _Point * 10;
if(trade.Sell(lotSize, _Symbol, bid, sl, 0))
sellReady = false; // prevent re-entry until stochastic resets
}
}
// update previous stochastic
lastK = k[0];
}