//+------------------------------------------------------------------+ //| AggressiveMA_Retest_TP4000.mq5 | //| MA7 crosses >=2 MAs = trend; re-enter on MA retests; | //| TP >= 4000 points + MA "magnet" partial TPs + Stochastic confirm | //+------------------------------------------------------------------+ #property strict #include CTrade Trade; // -------------------- INPUTS -------------------- input ulong MagicNumber = 777001; input double Lots = 0.01; input int SlippagePoints = 50; // MAs input int MA_7 = 7; input int MA_14 = 14; input int MA_21 = 21; input int MA_50 = 50; input int MA_140 = 140; input int MA_230 = 230; input int MA_1000= 1000; input int MA_1100= 1100; input int MA_1300= 1300; input ENUM_MA_METHOD MA_Method = MODE_EMA; input ENUM_APPLIED_PRICE MA_Price = PRICE_CLOSE; // Entry aggressiveness input int RetestBufferPoints = 250; // how close price must get to MA to count as "retest" input int CooldownBarsPerEntry = 1; // prevent same-bar spam entries // Stochastic confirm (instead of TRIX) input int StochK = 5; input int StochD = 3; input int StochSlowing = 3; input ENUM_MA_METHOD StochMethod = MODE_SMA; input ENUM_STO_PRICE StochPrice = STO_LOWHIGH; // Stoch quarter theory levels input double StochLvl_1 = 25.0; input double StochLvl_2 = 50.0; input double StochLvl_3 = 75.0; // PROFIT TAKING (what you asked for) input int TP_MinPoints = 4000; // hard TP distance from entry (server-side) input int BE_TriggerPoints = 4000; // optional: move SL to BE after this (set 0 to disable) input int BE_LockPoints = 200; // lock a little profit after BE trigger // Partial TP at profit thresholds (in addition to MA magnets) input bool UseProfitPartials = true; input int PT1_Points = 4000; input double PT1_ClosePct = 0.35; // close 35% at +4000 points input int PT2_Points = 8000; input double PT2_ClosePct = 0.35; // close 35% at +8000 points input int PT3_Points = 12000; input double PT3_ClosePct = 0.30; // close remaining at +12000 points (or let TP handle it) // MA Magnet partials input bool UseMAMagnets = true; input int MagnetBufferPoints = 250; // distance to MA to count as "hit" input double MagnetClosePct = 0.20; // close 20% each time a new MA magnet is hit // -------------------- HANDLES -------------------- int hMA7=-1,hMA14=-1,hMA21=-1,hMA50=-1,hMA140=-1,hMA230=-1,hMA1000=-1,hMA1100=-1,hMA1300=-1; int hStoch=-1; // -------------------- STATE -------------------- datetime lastEntryBarTime=0; // -------------------- HELPERS -------------------- double MidPrice() { double b=SymbolInfoDouble(_Symbol,SYMBOL_BID); double a=SymbolInfoDouble(_Symbol,SYMBOL_ASK); if(b<=0 || a<=0) return 0; return 0.5*(a+b); } bool Copy1(int handle, int shift, double &out) { double buf[]; ArraySetAsSeries(buf,true); if(CopyBuffer(handle,0,shift,1,buf)!=1) return false; out = buf[0]; return true; } bool CopyStoch(int shift, double &k, double &d) { double bk[], bd[]; ArraySetAsSeries(bk,true); ArraySetAsSeries(bd,true); // Stoch main is buffer 0, signal is buffer 1 in MQL5 if(CopyBuffer(hStoch,0,shift,1,bk)!=1) return false; if(CopyBuffer(hStoch,1,shift,1,bd)!=1) return false; k=bk[0]; d=bd[0]; return true; } bool GetMAValues(int shift, double &ma7,double &ma14,double &ma21,double &ma50,double &ma140,double &ma230, double &ma1000,double &ma1100,double &ma1300) { if(!Copy1(hMA7,shift,ma7)) return false; if(!Copy1(hMA14,shift,ma14)) return false; if(!Copy1(hMA21,shift,ma21)) return false; if(!Copy1(hMA50,shift,ma50)) return false; if(!Copy1(hMA140,shift,ma140)) return false; if(!Copy1(hMA230,shift,ma230)) return false; if(!Copy1(hMA1000,shift,ma1000)) return false; if(!Copy1(hMA1100,shift,ma1100)) return false; if(!Copy1(hMA1300,shift,ma1300)) return false; return true; } // Trend direction: // +1 bullish if MA7 above BOTH MA14 & MA21 (and preferably above others) // -1 bearish if MA7 below BOTH MA14 & MA21 int TrendDir(int shift, int &strengthOut) { strengthOut=0; double ma7,ma14,ma21,ma50,ma140,ma230,ma1000,ma1100,ma1300; if(!GetMAValues(shift,ma7,ma14,ma21,ma50,ma140,ma230,ma1000,ma1100,ma1300)) return 0; double others[7] = {ma14,ma21,ma50,ma140,ma230,ma1000,ma1100}; int above=0, below=0; for(int i=0;i<7;i++) { if(ma7 > others[i]) above++; if(ma7 < others[i]) below++; } bool bullConfirmed = (ma7 > ma14 && ma7 > ma21 && above>=2); bool bearConfirmed = (ma7 < ma14 && ma7 < ma21 && below>=2); if(bullConfirmed){ strengthOut=above; return +1; } if(bearConfirmed){ strengthOut=below; return -1; } return 0; } bool IsNewBar() { datetime t=iTime(_Symbol,PERIOD_CURRENT,0); static datetime prev=0; if(t!=prev){ prev=t; return true; } return false; } bool InCooldown() { datetime t=iTime(_Symbol,PERIOD_CURRENT,0); if(t==lastEntryBarTime) return true; return false; } int CountMyPositions() { int c=0; int total=(int)PositionsTotal(); for(int i=0;i vol) closeVol = vol; Trade.SetDeviationInPoints(SlippagePoints); return Trade.PositionClosePartial(ticket, closeVol); } void MoveSLToBE(ulong ticket, int lockPoints) { if(!PositionSelectByTicket(ticket)) return; long type = PositionGetInteger(POSITION_TYPE); double open=PositionGetDouble(POSITION_PRICE_OPEN); double sl =PositionGetDouble(POSITION_SL); double tp =PositionGetDouble(POSITION_TP); double newSL=sl; if(type==POSITION_TYPE_BUY) newSL = open + lockPoints*_Point; else newSL = open - lockPoints*_Point; // only improve SL if(type==POSITION_TYPE_BUY && (sl<=0 || newSL>sl)) Trade.PositionModify(ticket,newSL,tp); if(type==POSITION_TYPE_SELL && (sl<=0 || newSL 50, stronger if > 75 // bearish bias if K < 50, stronger if < 25 bool StochConfirms(int dir, int shift) { double k,d; if(!CopyStoch(shift,k,d)) return true; // if no data, don't block trades if(dir>0) return (k >= StochLvl_2); // >=50 if(dir<0) return (k <= StochLvl_2); // <=50 return false; } // Entry trigger: // 1) TrendDir says bull/bear (MA7 crossed 2+ MAs) // 2) price retests MA7 or any crossed MA (we’ll prioritize MA7 retest) // 3) stochastic confirms bool EntrySignal(int &dirOut) { int strength=0; int dir = TrendDir(1,strength); if(dir==0) return false; if(!StochConfirms(dir,1)) return false; double ma7,ma14,ma21,ma50,ma140,ma230,ma1000,ma1100,ma1300; if(!GetMAValues(0,ma7,ma14,ma21,ma50,ma140,ma230,ma1000,ma1100,ma1300)) return false; double price = MidPrice(); if(price<=0) return false; // aggressive: any retest near MA7 OR near any MA that MA7 is on the “trend side” of bool near7 = PriceNear(price, ma7, RetestBufferPoints); // “crossed” MAs are those that MA7 is above (bull) or below (bear) bool nearOther=false; if(dir>0) { if(ma7>ma14 && PriceNear(price,ma14,RetestBufferPoints)) nearOther=true; if(ma7>ma21 && PriceNear(price,ma21,RetestBufferPoints)) nearOther=true; if(ma7>ma50 && PriceNear(price,ma50,RetestBufferPoints)) nearOther=true; if(ma7>ma140&& PriceNear(price,ma140,RetestBufferPoints)) nearOther=true; if(ma7>ma230&& PriceNear(price,ma230,RetestBufferPoints)) nearOther=true; } else { if(ma7= 4000 points if(TP_MinPoints>0) { if(dir>0) tp = ask + TP_MinPoints*_Point; else tp = bid - TP_MinPoints*_Point; } bool ok=false; if(dir>0) ok = Trade.Buy(Lots,_Symbol,ask,0,tp,"MA7_retest_buy"); else ok = Trade.Sell(Lots,_Symbol,bid,0,tp,"MA7_retest_sell"); if(ok) lastEntryBarTime = iTime(_Symbol,PERIOD_CURRENT,0); return ok; } void ManagePositions() { int total=(int)PositionsTotal(); for(int i=0;i0 && profitPts>=PT1_Points && !GlobalVariableCheck(k1)) { ClosePartial(ticket, PT1_ClosePct); GlobalVariableSet(k1, TimeCurrent()); } if(PT2_Points>0 && profitPts>=PT2_Points && !GlobalVariableCheck(k2)) { ClosePartial(ticket, PT2_ClosePct); GlobalVariableSet(k2, TimeCurrent()); } if(PT3_Points>0 && profitPts>=PT3_Points && !GlobalVariableCheck(k3)) { ClosePartial(ticket, PT3_ClosePct); GlobalVariableSet(k3, TimeCurrent()); } } // ---- MOVE SL TO BE AFTER +4000 (optional) ---- if(BE_TriggerPoints>0 && profitPts>=BE_TriggerPoints) { string bek="BE_"+(string)ticket; if(!GlobalVariableCheck(bek)) { MoveSLToBE(ticket, BE_LockPoints); GlobalVariableSet(bek, TimeCurrent()); } } // ---- MA MAGNET PARTIAL TPs ---- if(UseMAMagnets) { double ma7,ma14,ma21,ma50,ma140,ma230,ma1000,ma1100,ma1300; if(!GetMAValues(0,ma7,ma14,ma21,ma50,ma140,ma230,ma1000,ma1100,ma1300)) continue; // target the "big magnets" first struct MMag { int p; double v; }; MMag mags[6] = { {MA_50, ma50}, {MA_140, ma140}, {MA_230, ma230}, {MA_1000, ma1000}, {MA_1100, ma1100}, {MA_1300, ma1300} }; for(int m=0;m<6;m++) { string key = MagnetKey(ticket, mags[m].p); if(GlobalVariableCheck(key)) continue; if(PriceNear(price, mags[m].v, MagnetBufferPoints)) { // close a chunk once per MA per ticket ClosePartial(ticket, MagnetClosePct); GlobalVariableSet(key, TimeCurrent()); } } } } } // -------------------- MQL5 EVENTS -------------------- int OnInit() { Trade.SetExpertMagicNumber((uint)MagicNumber); hMA7 = iMA(_Symbol,PERIOD_CURRENT,MA_7,0,MA_Method,MA_Price); hMA14 = iMA(_Symbol,PERIOD_CURRENT,MA_14,0,MA_Method,MA_Price); hMA21 = iMA(_Symbol,PERIOD_CURRENT,MA_21,0,MA_Method,MA_Price); hMA50 = iMA(_Symbol,PERIOD_CURRENT,MA_50,0,MA_Method,MA_Price); hMA140 = iMA(_Symbol,PERIOD_CURRENT,MA_140,0,MA_Method,MA_Price); hMA230 = iMA(_Symbol,PERIOD_CURRENT,MA_230,0,MA_Method,MA_Price); hMA1000 = iMA(_Symbol,PERIOD_CURRENT,MA_1000,0,MA_Method,MA_Price); hMA1100 = iMA(_Symbol,PERIOD_CURRENT,MA_1100,0,MA_Method,MA_Price); hMA1300 = iMA(_Symbol,PERIOD_CURRENT,MA_1300,0,MA_Method,MA_Price); hStoch = iStochastic(_Symbol,PERIOD_CURRENT,StochK,StochD,StochSlowing,StochMethod,StochPrice); if(hMA7<0 || hMA14<0 || hMA21<0 || hMA50<0 || hMA140<0 || hMA230<0 || hMA1000<0 || hMA1100<0 || hMA1300<0 || hStoch<0) return INIT_FAILED; return INIT_SUCCEEDED; } void OnDeinit(const int reason) { if(hMA7>0) IndicatorRelease(hMA7); if(hMA14>0) IndicatorRelease(hMA14); if(hMA21>0) IndicatorRelease(hMA21); if(hMA50>0) IndicatorRelease(hMA50); if(hMA140>0) IndicatorRelease(hMA140); if(hMA230>0) IndicatorRelease(hMA230); if(hMA1000>0) IndicatorRelease(hMA1000); if(hMA1100>0) IndicatorRelease(hMA1100); if(hMA1300>0) IndicatorRelease(hMA1300); if(hStoch>0) IndicatorRelease(hStoch); } void OnTick() { // manage first (locks profit fast) ManagePositions(); // entry logic if(InCooldown()) return; int dir=0; if(EntrySignal(dir)) { // aggressive: allow multiple positions, but you can cap if needed OpenTrade(dir); } }