0% found this document useful (0 votes)
4 views28 pages

AMD Code

The document outlines the SMC_AMD_IFVG_Session_EA, a trading algorithm designed for MetaTrader 5 that utilizes a specific trading strategy based on market structure and price action. It incorporates features such as session and news filters, trade management techniques, and various input parameters for customization. The EA is intended for educational use and should be backtested and optimized before live trading.

Uploaded by

Ahmed Hussein
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views28 pages

AMD Code

The document outlines the SMC_AMD_IFVG_Session_EA, a trading algorithm designed for MetaTrader 5 that utilizes a specific trading strategy based on market structure and price action. It incorporates features such as session and news filters, trade management techniques, and various input parameters for customization. The EA is intended for educational use and should be backtested and optimized before live trading.

Uploaded by

Ahmed Hussein
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

//+------------------------------------------------------------------+

//| SMC_AMD_IFVG_Session_EA.mq5 |

//| AMD + IFVG Strategy (HTF H4 / LTF M15) |

//| |

//| Accumulation -> Manipulation (sweep) -> Displacement -> |

//| IFVG -> Body-close Confirmation -> Entry |

//| + Trade Management : BE @1R, trail after 2R, partial TP |

//| + Session filter : London & New York only |

//| + News filter : pause X min before & after high-impact |

//| events (MT5 economic calendar) |

//| |

//| NOTE: heuristic SMC logic. Backtest & optimise before live. |

//+------------------------------------------------------------------+

#property copyright "Generated for educational use"

#property version "1.20"

#property strict

#include <Trade/[Link]>

CTrade trade;

//==================================================================

// ENUMS

//==================================================================

enum ENUM_NEWS_IMP { NEWS_LOW = 1, NEWS_MED = 2, NEWS_HIGH = 3 };


//==================================================================

// INPUTS

//==================================================================

input group "=== General / Money Management ==="

input double InpRiskPercent = 1.0; // Risk per trade (% of balance). 0 = fixed lot

input double InpFixedLot = 0.10; // Fixed lot (used only when Risk % = 0)

input long InpMagic = 990120; // Magic number

input int InpSlippage = 30; // Max deviation (points)

input int InpMaxOpenTrades = 1; // Max simultaneous positions (this EA/symbol)

input group "=== Timeframes ==="

input ENUM_TIMEFRAMES InpLTF = PERIOD_M15; // Trading timeframe (attach chart to this)

input ENUM_TIMEFRAMES InpHTF = PERIOD_H4; // Higher timeframe

input group "=== HTF Trend Filter (optional) ==="

input bool InpUseHtfTrend = true; // Only trade in HTF trend direction

input int InpHtfEmaFast = 50; // HTF fast EMA

input int InpHtfEmaSlow = 200; // HTF slow EMA

input bool InpRequireHtfClose = true; // Require HTF close beyond fast EMA

input bool InpRequireStructure = false; // Require HH/HL (buy) or LH/LL (sell)

input int InpStructurePivot = 2; // Pivot strength

input int InpStructureBars = 120; // HTF bars scanned for structure

input group "=== Phase: Accumulation ==="


input int InpAccMin = 5; // Min accumulation candles

input int InpAccMax = 20; // Max accumulation candles

input double InpAccMaxRangeATR = 1.5; // Range height <= this * ATR (low volatility)

input group "=== Phase: Manipulation (Liquidity Sweep) ==="

input int InpSweepLookback = 6; // Bars searched for the sweep

input double InpSweepMinATR = 0.10; // Sweep extends >= this * ATR beyond range

input group "=== Phase: Displacement ==="

input double InpDispBodyATR = 0.8; // Displacement body >= this * ATR

input double InpDispBodyRatio = 0.60; // Body / total-range ratio

input bool InpDispCloseBeyondPrev = true; // Close beyond prior candle extreme

input group "=== Phase: IFVG + Confirmation ==="

input bool InpRequireFullBody = true; // Whole body beyond IFVG (wick close invalid)

input int InpConfirmWindow = 4; // Bars after displacement for confirmation

input group "=== Phase: Entry Model ==="

input bool InpUseRetracement = true; // true = limit into IFVG; false = market now

input int InpPendingExpiryBars = 12; // Pending-order expiry (bars)

input int InpMaxSetupAgeBars = 6; // Act only on recently-confirmed setups

input group "=== Take Profit (R:R) ==="

input double InpMinRR = 3.0; // Minimum R:R (1:3)

input double InpPreferredRR = 5.0; // Preferred / fallback R:R (1:5)


input bool InpUseSwingTP = true; // Target next swing liquidity

input int InpSwingLookback = 60; // Lookback for liquidity / swing TP

input double InpSlBufferATR = 0.20;// SL buffer beyond sweep (* ATR)

input group "=== Trade Management ==="

input bool InpUseBreakeven = true; // Move SL to BE

input double InpBeAtR = 1.0; // Move to BE at this R multiple

input int InpBeLockPoints = 5; // Lock this many points beyond entry

input bool InpUseTrailing = true; // Trail SL

input double InpTrailStartR = 2.0; // Start trailing at this R multiple

input bool InpTrailUseATR = true;// true = ATR trail; false = R-distance trail

input double InpTrailAtrMult = 1.5; // ATR multiplier (ATR trail)

input double InpTrailRDist = 1.0; // Distance in R (R trail)

input bool InpUsePartialTP = true;// Take partial profit

input double InpPartialAtR = 2.0; // Partial close at this R multiple

input double InpPartialPct = 50.0;// % of position to close

input group "=== Session Filter (broker SERVER time!) ==="

input bool InpUseSessions = true; // Only trade inside sessions below

input bool InpSess1Enable = true; // London session

input int InpSess1StartHour = 10; // London start hour (server)

input int InpSess1EndHour = 19; // London end hour (server)

input bool InpSess2Enable = true;// New York session

input int InpSess2StartHour = 15; // NY start hour (server)

input int InpSess2EndHour = 24; // NY end hour (server)


input group "=== News Filter (MT5 Economic Calendar) ==="

input bool InpUseNewsFilter = true; // Pause around news

input int InpNewsBeforeMin = 15; // Minutes BEFORE event to pause

input int InpNewsAfterMin = 15; // Minutes AFTER event to pause

input ENUM_NEWS_IMP InpNewsMinImp = NEWS_HIGH; // Minimum importance to react to

input group "=== Engine ==="

input int InpAtrPeriod = 14; // ATR period

input int InpMaxScanBars = 150; // History scanned each new bar

//==================================================================

// GLOBALS

//==================================================================

int g_atrHandle = INVALID_HANDLE;

int g_emaFastH = INVALID_HANDLE;

int g_emaSlowH = INVALID_HANDLE;

datetime g_lastBarTime = 0;

datetime g_lastBuySetup = 0;

datetime g_lastSellSetup= 0;

bool g_newsWarned = false;

double O[], H[], L[], C[];

datetime T[];
int N = 0;

struct SmcSetup

bool valid;

int dir;

double ifvgTop, ifvgBottom;

double manipLevel;

datetime dispTime;

double entry, sl, tp;

};

struct PosState

ulong ticket;

int dir;

double entry;

double oneR;

bool movedBE;

bool partialDone;

bool trailing;

};

PosState g_pos[];

//+------------------------------------------------------------------+
int OnInit()

g_atrHandle = iATR(_Symbol, InpLTF, InpAtrPeriod);

g_emaFastH = iMA(_Symbol, InpHTF, InpHtfEmaFast, 0, MODE_EMA, PRICE_CLOSE);

g_emaSlowH = iMA(_Symbol, InpHTF, InpHtfEmaSlow, 0, MODE_EMA, PRICE_CLOSE);

if(g_atrHandle==INVALID_HANDLE || g_emaFastH==INVALID_HANDLE ||
g_emaSlowH==INVALID_HANDLE)

{ Print("Indicator handle creation failed."); return(INIT_FAILED); }

[Link](InpMagic);

[Link](InpSlippage);

[Link](_Symbol);

if(InpAccMin < 3 || InpAccMin > InpAccMax)

{ Print("Invalid accumulation bounds."); return(INIT_PARAMETERS_INCORRECT); }

if(_Period != InpLTF)

Print("WARNING: chart timeframe (", EnumToString(_Period),

") differs from InpLTF (", EnumToString(InpLTF),

"). Detection uses InpLTF data; attaching to M15 is recommended.");

Print("SMC_AMD_IFVG_Session_EA initialised on ", _Symbol);

return(INIT_SUCCEEDED);

}
void OnDeinit(const int reason)

if(g_atrHandle!=INVALID_HANDLE) IndicatorRelease(g_atrHandle);

if(g_emaFastH!=INVALID_HANDLE) IndicatorRelease(g_emaFastH);

if(g_emaSlowH!=INVALID_HANDLE) IndicatorRelease(g_emaSlowH);

//+------------------------------------------------------------------+

void OnTick()

// Trade management always runs (sessions/news do not stop managing open trades)

ManagePositions();

// New setups only on a new closed LTF bar

datetime curBar = iTime(_Symbol, InpLTF, 0);

if(curBar == g_lastBarTime) return;

g_lastBarTime = curBar;

// Execution filters (apply to NEW entries only)

if(InpUseSessions && !InSession()) return;

if(IsNewsBlock()) return;

if(!LoadBuffers()) return;

double atr = CurrentATR();

if(atr <= 0) return;


if(InpUseHtfTrend)

int bias = HtfBias();

if(bias > 0) TryBuy(atr);

else if(bias < 0) TrySell(atr);

else

if(!TryBuy(atr)) TrySell(atr); // no HTF gate -> scan both

bool TryBuy(double atr)

SmcSetup s = FindBuySetup(atr);

if([Link] && [Link] != g_lastBuySetup && CountMyOrders() < InpMaxOpenTrades)

if(ExecuteSetup(s)) { g_lastBuySetup = [Link]; return true; }

return false;

bool TrySell(double atr)

SmcSetup s = FindSellSetup(atr);

if([Link] && [Link] != g_lastSellSetup && CountMyOrders() < InpMaxOpenTrades)

if(ExecuteSetup(s)) { g_lastSellSetup = [Link]; return true; }


return false;

//==================================================================

// SESSION FILTER (server time)

//==================================================================

bool HourInWindow(int h, int start, int end)

// end==24 means midnight; supports wrap (e.g., 22 -> 5)

if(start == end) return false;

if(start < end) return (h >= start && h < end);

return (h >= start || h < end); // wraps midnight

bool InSession()

MqlDateTime dt; TimeToStruct(TimeCurrent(), dt);

int h = [Link];

bool ok = false;

if(InpSess1Enable && HourInWindow(h, InpSess1StartHour, InpSess1EndHour)) ok = true;

if(InpSess2Enable && HourInWindow(h, InpSess2StartHour, InpSess2EndHour)) ok = true;

return ok;

//==================================================================
// NEWS FILTER (MT5 economic calendar)

//==================================================================

bool NewsInRange(datetime from, datetime to, datetime now, string currency)

MqlCalendarValue values[];

int n = CalendarValueHistory(values, from, to, NULL, currency);

if(n <= 0) return false;

for(int i = 0; i < n; i++)

MqlCalendarEvent ev;

if(!CalendarEventById(values[i].event_id, ev)) continue;

if((int)[Link] < (int)InpNewsMinImp) continue;

datetime et = values[i].time;

if(now >= et - InpNewsBeforeMin*60 && now <= et + InpNewsAfterMin*60)

return true;

return false;

bool IsNewsBlock()

if(!InpUseNewsFilter) return false;


datetime now = TimeCurrent();

datetime from = now - (InpNewsAfterMin + 2)*60;

datetime to = now + (InpNewsBeforeMin + 2)*60;

string cur1 = SymbolInfoString(_Symbol, SYMBOL_CURRENCY_BASE);

string cur2 = SymbolInfoString(_Symbol, SYMBOL_CURRENCY_PROFIT);

bool blocked = false;

if(StringLen(cur1) > 0) blocked = NewsInRange(from, to, now, cur1);

if(!blocked && StringLen(cur2) > 0 && cur2 != cur1)

blocked = NewsInRange(from, to, now, cur2);

// If the calendar returns nothing ever, warn once (tester/broker may not support it)

if(!blocked && !g_newsWarned)

MqlCalendarValue probe[];

if(CalendarValueHistory(probe, now-86400, now+86400, NULL, cur1) <= 0)

Print("NOTE: economic calendar returned no data for ", cur1,

". News filter may be unsupported on this broker/tester.");

g_newsWarned = true;

return blocked;

}
//==================================================================

// DATA

//==================================================================

bool LoadBuffers()

int want = MathMin(InpMaxScanBars + 60, 1000);

MqlRates r[];

ArraySetAsSeries(r, false);

int got = CopyRates(_Symbol, InpLTF, 0, want, r);

if(got < InpAccMax + InpSweepLookback + 10) return false;

N = got - 1;

ArrayResize(O,N); ArrayResize(H,N); ArrayResize(L,N);

ArrayResize(C,N); ArrayResize(T,N);

for(int i=0;i<N;i++){ O[i]=r[i].open; H[i]=r[i].high; L[i]=r[i].low; C[i]=r[i].close; T[i]=r[i].time; }

return true;

double CurrentATR()

double buf[];

if(CopyBuffer(g_atrHandle,0,0,2,buf)<2) return 0.0;

return buf[1];

}
//==================================================================

// HTF TREND (optional)

//==================================================================

int HtfBias()

double f[], s[];

if(CopyBuffer(g_emaFastH,0,0,2,f)<2) return 0;

if(CopyBuffer(g_emaSlowH,0,0,2,s)<2) return 0;

double fast=f[1], slow=s[1];

double htfClose=iClose(_Symbol, InpHTF, 1);

bool bull=(fast>slow), bear=(fast<slow);

if(InpRequireHtfClose){ bull=bull&&(htfClose>fast); bear=bear&&(htfClose<fast); }

if(InpRequireStructure){ int st=HtfStructure(); bull=bull&&(st>0); bear=bear&&(st<0); }

if(bull) return 1;

if(bear) return -1;

return 0;

int HtfStructure()

MqlRates r[];

ArraySetAsSeries(r,false);

int got = CopyRates(_Symbol, InpHTF, 0, InpStructureBars+2, r);


if(got < 4*InpStructurePivot+5) return 0;

int n = got-1;

double sh[]; double sl[];

int p = InpStructurePivot;

for(int i=p;i<n-p;i++)

bool isHigh=true, isLow=true;

for(int k=1;k<=p;k++)

if(r[i].high<=r[i-k].high || r[i].high<=r[i+k].high) isHigh=false;

if(r[i].low >=r[i-k].low || r[i].low >=r[i+k].low ) isLow=false;

if(isHigh){ int z=ArraySize(sh); ArrayResize(sh,z+1); sh[z]=r[i].high; }

if(isLow ){ int z=ArraySize(sl); ArrayResize(sl,z+1); sl[z]=r[i].low; }

int nh=ArraySize(sh), nl=ArraySize(sl);

if(nh<2||nl<2) return 0;

bool hh=sh[nh-1]>sh[nh-2], hl=sl[nl-1]>sl[nl-2];

bool lh=sh[nh-1]<sh[nh-2], ll=sl[nl-1]<sl[nl-2];

if(hh&&hl) return 1;

if(lh&&ll) return -1;

return 0;

}
//==================================================================

// RANGE HELPERS

//==================================================================

double HighestHigh(int from,int to){ double m=-DBL_MAX; for(int i=from;i<=to;i++) if(H[i]>m)m=H[i];


return m; }

double LowestLow (int from,int to){ double m= DBL_MAX; for(int i=from;i<=to;i++) if(L[i]<m)m=L[i];
return m; }

//==================================================================

// BUY SETUP

//==================================================================

SmcSetup FindBuySetup(double atr)

SmcSetup out; [Link]=false; [Link]=1;

int newest=N-1, pStart=newest-1, pEnd=InpAccMin+InpSweepLookback+2;

for(int p=pStart; p>=pEnd; p--)

double body=C[p]-O[p], range=H[p]-L[p];

if(C[p]<=O[p]) continue;

if(body<InpDispBodyATR*atr) continue;

if(range<=0||body/range<InpDispBodyRatio) continue;

if(InpDispCloseBeyondPrev && C[p]<=H[p-1]) continue;

if(L[p+1]<=H[p-1]) continue;

double gapBottom=H[p-1], gapTop=L[p+1];


int sweepStart=p-1-InpSweepLookback, sweepEnd=p-1;

if(sweepStart<0) continue;

double manipLow=LowestLow(sweepStart,sweepEnd);

int accEnd=sweepStart-1;

if(accEnd<InpAccMin-1) continue;

bool accFound=false; double rangeHigh=0,rangeLow=0;

for(int L1=InpAccMax; L1>=InpAccMin; L1--)

int accStart=accEnd-L1+1; if(accStart<0) continue;

double rh=HighestHigh(accStart,accEnd), rl=LowestLow(accStart,accEnd);

if((rh-rl)<=InpAccMaxRangeATR*atr){ rangeHigh=rh; rangeLow=rl; accFound=true; break; }

if(!accFound) continue;

if(manipLow > rangeLow - InpSweepMinATR*atr) continue;

int confirmBar=-1, cEnd=MathMin(p+InpConfirmWindow,newest);

for(int q=p+1;q<=cEnd;q++)

bool bull=(C[q]>O[q]), closeOK=(C[q]>gapTop);

bool fullOK=InpRequireFullBody?(MathMin(O[q],C[q])>gapTop):closeOK;

if(bull&&closeOK&&fullOK){ confirmBar=q; break; }

if(confirmBar<0) continue;
if(newest-confirmBar>InpMaxSetupAgeBars) continue;

if(C[newest]<=gapTop) continue;

double sl=manipLow-InpSlBufferATR*atr;

double entry=InpUseRetracement?gapTop:SymbolInfoDouble(_Symbol,SYMBOL_ASK);

double risk=entry-sl; if(risk<=0) continue;

double tp=BuildTP(+1,entry,risk,atr);

if((tp-entry)/risk<InpMinRR) continue;

[Link]=true; [Link]=gapTop; [Link]=gapBottom;

[Link]=manipLow; [Link]=T[p]; [Link]=entry; [Link]=sl; [Link]=tp;

return out;

return out;

//==================================================================

// SELL SETUP

//==================================================================

SmcSetup FindSellSetup(double atr)

SmcSetup out; [Link]=false; [Link]=-1;

int newest=N-1, pStart=newest-1, pEnd=InpAccMin+InpSweepLookback+2;

for(int p=pStart; p>=pEnd; p--)


{

double body=O[p]-C[p], range=H[p]-L[p];

if(C[p]>=O[p]) continue;

if(body<InpDispBodyATR*atr) continue;

if(range<=0||body/range<InpDispBodyRatio) continue;

if(InpDispCloseBeyondPrev && C[p]>=L[p-1]) continue;

if(H[p+1]>=L[p-1]) continue;

double gapTop=L[p-1], gapBottom=H[p+1];

int sweepStart=p-1-InpSweepLookback, sweepEnd=p-1;

if(sweepStart<0) continue;

double manipHigh=HighestHigh(sweepStart,sweepEnd);

int accEnd=sweepStart-1;

if(accEnd<InpAccMin-1) continue;

bool accFound=false; double rangeHigh=0,rangeLow=0;

for(int L1=InpAccMax; L1>=InpAccMin; L1--)

int accStart=accEnd-L1+1; if(accStart<0) continue;

double rh=HighestHigh(accStart,accEnd), rl=LowestLow(accStart,accEnd);

if((rh-rl)<=InpAccMaxRangeATR*atr){ rangeHigh=rh; rangeLow=rl; accFound=true; break; }

if(!accFound) continue;

if(manipHigh < rangeHigh + InpSweepMinATR*atr) continue;


int confirmBar=-1, cEnd=MathMin(p+InpConfirmWindow,newest);

for(int q=p+1;q<=cEnd;q++)

bool bear=(C[q]<O[q]), closeOK=(C[q]<gapBottom);

bool fullOK=InpRequireFullBody?(MathMax(O[q],C[q])<gapBottom):closeOK;

if(bear&&closeOK&&fullOK){ confirmBar=q; break; }

if(confirmBar<0) continue;

if(newest-confirmBar>InpMaxSetupAgeBars) continue;

if(C[newest]>=gapBottom) continue;

double sl=manipHigh+InpSlBufferATR*atr;

double entry=InpUseRetracement?gapBottom:SymbolInfoDouble(_Symbol,SYMBOL_BID);

double risk=sl-entry; if(risk<=0) continue;

double tp=BuildTP(-1,entry,risk,atr);

if((entry-tp)/risk<InpMinRR) continue;

[Link]=true; [Link]=gapTop; [Link]=gapBottom;

[Link]=manipHigh; [Link]=T[p]; [Link]=entry; [Link]=sl; [Link]=tp;

return out;

return out;

}
//==================================================================

// TAKE PROFIT (1:3 min, 1:5 fallback)

//==================================================================

double BuildTP(int dir,double entry,double risk,double atr)

int newest=N-1, from=MathMax(0,newest-InpSwingLookback);

double rrFallback=(dir>0)?entry+InpPreferredRR*risk:entry-InpPreferredRR*risk;

if(!InpUseSwingTP) return rrFallback;

if(dir>0){ double sh=HighestHigh(from,newest); if(sh>entry&&(sh-entry)/risk>=InpMinRR) return sh; }

else { double slw=LowestLow(from,newest); if(slw<entry&&(entry-slw)/risk>=InpMinRR) return


slw; }

return rrFallback;

//==================================================================

// EXECUTION

//==================================================================

bool ExecuteSetup(const SmcSetup &s)

int dig=(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS);

double entry=NormalizeDouble([Link],dig);

double sl=NormalizeDouble([Link],dig);

double tp=NormalizeDouble([Link],dig);

double lots=CalcLot(MathAbs(entry-sl));

if(lots<=0){ Print("Lot calc 0 — skip."); return false; }


string note="AMD_IFVG";

if(!InpUseRetracement)

if([Link]>0) return [Link](lots,_Symbol,0.0,sl,tp,note);

else return [Link](lots,_Symbol,0.0,sl,tp,note);

datetime expiry=TimeCurrent()+InpPendingExpiryBars*PeriodSeconds(InpLTF);

if([Link]>0)

double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);

if(entry>=ask) return [Link](lots,_Symbol,0.0,sl,tp,note);

return [Link](lots,entry,_Symbol,sl,tp,ORDER_TIME_SPECIFIED,expiry,note);

else

double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);

if(entry<=bid) return [Link](lots,_Symbol,0.0,sl,tp,note);

return [Link](lots,entry,_Symbol,sl,tp,ORDER_TIME_SPECIFIED,expiry,note);

//==================================================================

// POSITION SIZING (SL distance == Risk%)


//==================================================================

double CalcLot(double slPriceDistance)

double minLot=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);

double maxLot=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);

double step=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);

if(InpRiskPercent<=0.0) return ClampLot(InpFixedLot,minLot,maxLot,step);

double tickVal=SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE);

double tickSize=SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE);

if(tickSize<=0||tickVal<=0||slPriceDistance<=0) return ClampLot(InpFixedLot,minLot,maxLot,step);

double riskMoney=AccountInfoDouble(ACCOUNT_BALANCE)*InpRiskPercent/100.0;

double lossPerLot=(slPriceDistance/tickSize)*tickVal;

if(lossPerLot<=0) return minLot;

return ClampLot(riskMoney/lossPerLot,minLot,maxLot,step);

double ClampLot(double lots,double minLot,double maxLot,double step)

if(step>0) lots=MathFloor(lots/step)*step;

lots=MathMax(minLot,MathMin(maxLot,lots));

return NormalizeDouble(lots,2);

}
//==================================================================

// TRADE MANAGEMENT

//==================================================================

int FindPosState(ulong ticket){ for(int i=0;i<ArraySize(g_pos);i++) if(g_pos[i].ticket==ticket) return i;


return -1; }

void RegisterPosition(ulong ticket)

if(!PositionSelectByTicket(ticket)) return;

int dir=(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)?1:-1;

double entry=PositionGetDouble(POSITION_PRICE_OPEN);

double psl=PositionGetDouble(POSITION_SL);

double oneR=(psl>0)?MathAbs(entry-psl):0.0;

if(oneR<=0) return;

int idx=ArraySize(g_pos); ArrayResize(g_pos,idx+1);

g_pos[idx].ticket=ticket; g_pos[idx].dir=dir; g_pos[idx].entry=entry;

g_pos[idx].oneR=oneR; g_pos[idx].movedBE=false; g_pos[idx].partialDone=false;


g_pos[idx].trailing=false;

void PurgeClosed()

for(int i=ArraySize(g_pos)-1;i>=0;i--)

if(!PositionSelectByTicket(g_pos[i].ticket))

{ int last=ArraySize(g_pos)-1; g_pos[i]=g_pos[last]; ArrayResize(g_pos,last); }

}
void ManagePositions()

for(int i=PositionsTotal()-1;i>=0;i--)

ulong tk=PositionGetTicket(i); if(tk==0) continue;

if(PositionGetString(POSITION_SYMBOL)!=_Symbol) continue;

if(PositionGetInteger(POSITION_MAGIC)!=InpMagic) continue;

if(FindPosState(tk)<0) RegisterPosition(tk);

PurgeClosed();

if(ArraySize(g_pos)==0) return;

double atr=CurrentATR();

int dig=(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS);

double point=SymbolInfoDouble(_Symbol,SYMBOL_POINT);

long stopLvl=SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);

double minDist=stopLvl*point;

for(int i=0;i<ArraySize(g_pos);i++)

ulong tk=g_pos[i].ticket;

if(!PositionSelectByTicket(tk)) continue;

int dir=g_pos[i].dir;

double entry=g_pos[i].entry, oneR=g_pos[i].oneR;


double curSL=PositionGetDouble(POSITION_SL);

double curTP=PositionGetDouble(POSITION_TP);

double vol=PositionGetDouble(POSITION_VOLUME);

double px=(dir>0)?
SymbolInfoDouble(_Symbol,SYMBOL_BID):SymbolInfoDouble(_Symbol,SYMBOL_ASK);

double rMult=((px-entry)*dir)/oneR;

// Partial TP

if(InpUsePartialTP && !g_pos[i].partialDone && rMult>=InpPartialAtR)

double step=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);

double minLot=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);

double closeVol=vol*InpPartialPct/100.0;

if(step>0) closeVol=MathFloor(closeVol/step)*step;

double remain=vol-closeVol;

if(closeVol>=minLot && (remain>=minLot || remain<=0))

{ if([Link](tk,closeVol)) g_pos[i].partialDone=true; }

else g_pos[i].partialDone=true;

// Break-even

if(InpUseBreakeven && !g_pos[i].movedBE && rMult>=InpBeAtR)

double be=NormalizeDouble(entry+dir*InpBeLockPoints*point,dig);

bool ok=(dir>0)?(be>curSL && (px-be)>=minDist):(be<curSL && (be-px)>=minDist);


if(curSL==0.0) ok=(dir>0)?(px-be)>=minDist:(be-px)>=minDist;

if(ok && [Link](tk,be,curTP)){ g_pos[i].movedBE=true; curSL=be; }

// Trailing

if(InpUseTrailing && rMult>=InpTrailStartR)

double dist=InpTrailUseATR?InpTrailAtrMult*atr:InpTrailRDist*oneR;

if(dist>0)

double newSL=NormalizeDouble((dir>0)?px-dist:px+dist,dig);

bool improves=(dir>0)?(newSL>curSL):(newSL<curSL||curSL==0.0);

bool farEnough=(dir>0)?(px-newSL)>=minDist:(newSL-px)>=minDist;

if(dir>0 && newSL<entry) improves=false;

if(dir<0 && newSL>entry) improves=false;

if(improves && farEnough) [Link](tk,newSL,curTP);

//==================================================================

// ORDER COUNT

//==================================================================

int CountMyOrders()
{

int cnt=0;

for(int i=PositionsTotal()-1;i>=0;i--)

ulong tk=PositionGetTicket(i); if(tk==0) continue;

if(PositionGetString(POSITION_SYMBOL)==_Symbol &&
PositionGetInteger(POSITION_MAGIC)==InpMagic) cnt++;

for(int i=OrdersTotal()-1;i>=0;i--)

ulong tk=OrderGetTicket(i); if(tk==0) continue;

if(OrderGetString(ORDER_SYMBOL)==_Symbol && OrderGetInteger(ORDER_MAGIC)==InpMagic)


cnt++;

return cnt;

//+------------------------------------------------------------------+

You might also like