One million gold

MQL5 专家 外汇

指定

//+------------------------------------------------------------------+
//| Expert - Advanced Scalper + Smart Grid (MQL5) |
//| Features: News filter (CSV), Spread filter, Session filter |
//| Dynamic Lot (ATR), Auto Distance Grid, Max Exposure, Drawdown |
//| Volatility filter, Spread explosion block, Night Mode, Timeout |
//| Profit Lock, Recovery Time-Out |
//| Note: Test extensively on demo before live. |
//+------------------------------------------------------------------+
#property copyright "XSprint"
#property version "1.00"
#property strict

#include <Trade\Trade.mqh>
CTrade trade;

//------ INPUTS ------
input double DefaultLot = 0.01; // Default lot
input double MaxExposureLots = 0.20; // Max total lots exposure
input int GridMaxLevels = 4; // Max grid steps
input int GridStepPoints = 150; // Base grid distance in points
input double GridMultiplier[] = {1.0,1.0,2.0,2.0}; // Multipliers per level
input int ATRPeriod = 14;
input double ATRMultiplierForLot = 0.01; // lot = DefaultLot * (ATR / ATRMultiplierForLot) capped
input int MinSpreadPoints = 10; // max allowed spread (points) to open trades
input double MaxSpreadExplosionFactor = 4.0; // block if spread > factor * avgSpread
input int AvgSpreadPeriod = 200; // period to calculate avg spread
input int VolatilityPeriod = 50; // lookback for volatility filter
input double MaxVolatilityPoints = 600; // if volatility > this, block entries
input double DailyDrawdownPercent = 10.0; // stop EA if drawdown % reached
input int NewsBlockMinutesBefore = 30; // block minutes before news
input int NewsBlockMinutesAfter = 45; // block minutes after news
input int RecoveryConsecutiveLosses = 3; // trigger timeout after n losses
input int RecoveryTimeoutMinutes = 60; // minutes to stop after consecutive losses
input double ProfitLockPercent = 0.3; // lock grid when profit target reached as % balance
input bool LondonSessionOnly = true; // restrict to London+NY session default
input int LondonStartHour = 8; // local broker server hours (adjustable)
input int LondonEndHour = 17;
input int NYStartHour = 12;
input int NYEndHour = 21;
input bool NightModeDisableAsia = true; // disable heavy scalping in Asia

// Files
string NewsFile = "news_schedule.csv"; // place in MQL5/Files/

//------ GLOBALS ------
double avgSpread = 0.0;
int spreadSamples = 0;
int consecutiveLosses = 0;
datetime recoveryStopUntil = 0;
bool allowTrading = true;

// Grid tracking structure
struct GridOrder {
   ulong ticket;
   double volume;
   double openPrice;
   bool isBuy;
};
CArrayObj gridOrders;

//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
  {
   gridOrders.Clear();
   // initialize avg spread
   avgSpread = GetAvgSpread();
   Print("XSprint initialized. AvgSpread=", avgSpread);
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Deinit |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   // cleanup
  }

//+------------------------------------------------------------------+
//| OnTick |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(!allowTrading) return;

   // recovery timeout check
   if(TimeCurrent() < recoveryStopUntil)
     {
      // still in recovery timeout
      return;
     }

   // spread check
   double spread = SymbolInfoDouble(_Symbol,SYMBOL_SPREAD); // in points
   UpdateAvgSpread(spread);

   if(spread > MinSpreadPoints)
     {
      // Spread too high -> no new trades
      // but allow managing existing trades
     }

   if(IsSpreadExplosion(spread))
     {
      Print("Spread explosion detected, blocking new trades. Spread=",spread," avg=",avgSpread);
      return;
     }

   // news filter
   if(IsNewsBlocked(TimeCurrent()))
     {
      // block opening new trades
      return;
     }

   // session filter
   if(!IsSessionAllowed(TimeCurrent()))
     {
      return;
     }

   // volatility filter
   double vol = CalculateVolatility();
   if(vol > MaxVolatilityPoints)
     {
      // too volatile
      return;
     }

   // dynamic lot calculation
   double lot = CalculateDynamicLot();

   // Check max exposure
   double currentLots = GetCurrentExposureLots();
   if(currentLots >= MaxExposureLots)
     {
      Print("Max exposure reached. Current lots=", currentLots);
      return;
     }

   // trading logic: combination of simple scalping entry + grid management
   ManageOpenGrid();

   // decide new scalping entry
   if(CanOpenNewTrade(spread, lot))
     {
      // Decide direction using short term trend (MA)
      bool wantBuy = IsShortTermBull();
      double price = wantBuy ? SymbolInfoDouble(_Symbol,SYMBOL_ASK) : SymbolInfoDouble(_Symbol,SYMBOL_BID);
      OpenScalp(wantBuy, lot);
     }
  }

//+------------------------------------------------------------------+
//| Utilities & Core Logic |
//+------------------------------------------------------------------+

double GetAvgSpread()
  {
   double s=0;
   int cnt=0;
   for(int i=0;i<MathMin(AvgSpreadPeriod,Bars(_Symbol,PERIOD_M1));i++)
     {
      double high = iHigh(_Symbol,PERIOD_M1,i);
      double low = iLow(_Symbol,PERIOD_M1,i);
      double spr = (high - low) / SymbolInfoDouble(_Symbol,SYMBOL_POINT); // approximate rough
      s += spr;
      cnt++;
     }
   if(cnt==0) return(SymbolInfoDouble(_Symbol,SYMBOL_SPREAD));
   return(s/cnt);
  }

void UpdateAvgSpread(double current)
  {
   // simple rolling average
   spreadSamples++;
   avgSpread = ((avgSpread*(spreadSamples-1)) + current) / spreadSamples;
  }

bool IsSpreadExplosion(double spread)
  {
   if(avgSpread <= 0) return(false);
   if(spread > avgSpread * MaxSpreadExplosionFactor) return(true);
   return(false);
  }

// News filter: read CSV with date/time of important news
bool IsNewsBlocked(datetime nowtime)
  {
   // try read file once per tick
   string lines[];
   if(!FileIsExist(NewsFile))
     {
      // no file -> not blocked
      return(false);
     }
   int handle = FileOpen(NewsFile,FILE_READ|FILE_ANSI);
   if(handle < 0) return(false);
   while(!FileIsEnding(handle))
     {
      string row = FileReadString(handle);
      if(StringTrim(row) == "") continue;
      // expected CSV: YYYY-MM-DD,HH:MM,importance,desc
      string parts[];
      int pc = StringSplit(row,',',parts);
      if(pc<2) continue;
      string dstr = parts[0];
      string tstr = parts[1];
      string dt = dstr + " " + tstr + ":00";
      datetime newsTime = StringToTime(dt);
      if(newsTime==0) continue;
      // if within before/after window
      if( nowtime >= (newsTime - NewsBlockMinutesBefore*60) && nowtime <= (newsTime + NewsBlockMinutesAfter*60) )
        {
         FileClose(handle);
         return(true);
        }
     }
   FileClose(handle);
   return(false);
  }

// session allowed check
bool IsSessionAllowed(datetime nowtime)
  {
   // use server time hours
   MqlDateTime t;
   TimeToStruct(nowtime,t);
   int h = t.hour;
   if(LondonSessionOnly)
     {
      // allow London or NY
      bool inLondon = (h >= LondonStartHour && h < LondonEndHour);
      bool inNY = (h >= NYStartHour && h < NYEndHour);
      if(!(inLondon || inNY))
         return(false);
     }
   if(NightModeDisableAsia)
     {
      // block typical Asia hours (00:00 - 06:00 server)
      if(h >= 0 && h < 6) return(false);
     }
   return(true);
  }

// volatility measure: high-low over last VolatilityPeriod M1 bars
double CalculateVolatility()
  {
   int bars = MathMin(VolatilityPeriod,Bars(_Symbol,PERIOD_M1)-1);
   if(bars <= 1) return(0);
   double high = iHigh(_Symbol,PERIOD_M1,ArrayMaximum(iHighArray(_Symbol,PERIOD_M1,bars)));
   double low = iLow(_Symbol,PERIOD_M1,ArrayMinimum(iLowArray(_Symbol,PERIOD_M1,bars)));
   double vol = (high - low) / SymbolInfoDouble(_Symbol,SYMBOL_POINT);
   // fallback simple calc
   double h = iHigh(_Symbol,PERIOD_M1,0);
   double l = iLow(_Symbol,PERIOD_M1,0);
   return(MathAbs(h-l)/SymbolInfoDouble(_Symbol,SYMBOL_POINT));
  }

// helper arrays for volatility (fallback utilities)
doubleArray iHighArray(string symbol,ENUM_TIMEFRAMES tf,int count)
  {
   doubleArray arr;
   arr.Resize(count);
   for(int i=0;i<count;i++) arr[i]=iHigh(symbol,tf,i);
   return(arr);
  }
doubleArray iLowArray(string symbol,ENUM_TIMEFRAMES tf,int count)
  {
   doubleArray arr;
   arr.Resize(count);
   for(int i=0;i<count;i++) arr[i]=iLow(symbol,tf,i);
   return(arr);
  }

// dynamic lot based on ATR
double CalculateDynamicLot()
  {
   double atr = iATR(_Symbol,PERIOD_M5,ATRPeriod,0);
   if(atr<=0) return(DefaultLot);
   // ATR is in price units, convert to points
   double atrPoints = atr / SymbolInfoDouble(_Symbol,SYMBOL_POINT);
   double lot = DefaultLot * MathMax(1.0, atrPoints * ATRMultiplierForLot);
   // cap lot so not exceed MaxExposure when combined
   double currentLots = GetCurrentExposureLots();
   double maxAdd = MathMax(0.0, MaxExposureLots - currentLots);
   lot = MathMin(lot, maxAdd);
   // round lot to minimal step
   double step = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
   lot = MathFloor(lot/step)*step;
   if(lot < SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN)) lot = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
   return(lot);
  }

// count current exposure lots on symbol
double GetCurrentExposureLots()
  {
   double sum=0;
   for(int i=0;i<PositionsTotal();i++)
     {
      ulong ticket = PositionGetTicket(i);
      if(PositionSelectByTicket(ticket))
        {
         if(PositionGetString(POSITION_SYMBOL)==_Symbol)
            sum += PositionGetDouble(POSITION_VOLUME);
        }
     }
   return(sum);
  }

// decide if can open new trade
bool CanOpenNewTrade(double spread, double lot)
  {
   if(spread > MinSpreadPoints) return(false);
   if(lot < SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN)) return(false);
   // check balance drawdown protection
   double balance = AccountInfoDouble(ACCOUNT_BALANCE);
   double equity = AccountInfoDouble(ACCOUNT_EQUITY);
   if((balance - equity)/balance*100.0 >= DailyDrawdownPercent) 
     {
      Print("Drawdown limit reached. Stopping EA.");
      allowTrading = false;
      return(false);
     }
   return(true);
  }

// simple short-term trend filter using moving averages
bool IsShortTermBull()
  {
   double maFast = iMA(_Symbol,PERIOD_M1,5,0,MODE_SMA,PRICE_CLOSE,0);
   double maSlow = iMA(_Symbol,PERIOD_M1,21,0,MODE_SMA,PRICE_CLOSE,0);
   return(maFast > maSlow);
  }

// Open scalp trade
void OpenScalp(bool buy, double lot)
  {
   trade.SetTypeFilling(ORDER_FILLING_FOK);
   trade.SetExpertMagicNumber(20251121);
   bool res=false;
   if(buy)
     res = trade.Buy(lot,NULL,0,0,"XSprint scalp");
   else
     res = trade.Sell(lot,NULL,0,0,"XSprint scalp");
   if(res)
     {
      ulong t = trade.ResultOrder();
      PrintFormat("Opened scalp %s ticket=%d lot=%.2f", buy?"BUY":"SELL", t, lot);
      // add to grid tracking as root position
      GridOrder *g = new GridOrder();
      g.ticket = t;
      g.volume = lot;
      g.openPrice = buy ? PositionGetDouble(POSITION_PRICE_OPEN) : PositionGetDouble(POSITION_PRICE_OPEN);
      g.isBuy = buy;
      gridOrders.Add(g);
     }
   else
     {
      Print("OpenScalp failed: ", trade.ResultRetcode(), " description: ", trade.ResultRetcodeDescription());
     }
  }

// Manage grid orders: if price moves against any position open grid steps
void ManageOpenGrid()
  {
   // iterate positions on symbol
   for(int i=PositionsTotal()-1;i>=0;i--)
     {
      if(!PositionGetTicket(i)) continue;
     }
   // For simplicity, check root position from gridOrders
   for(int idx=0; idx<gridOrders.Total(); idx++)
     {
      GridOrder *g = (GridOrder*)gridOrders.At(idx);
      if(g==NULL) continue;
      // check if position still exists
      if(!PositionSelect(_Symbol)) continue;
      // find current price
      double price = g.isBuy ? SymbolInfoDouble(_Symbol,SYMBOL_BID) : SymbolInfoDouble(_Symbol,SYMBOL_ASK);
      double diffPoints = MathAbs((price - g.openPrice)/SymbolInfoDouble(_Symbol,SYMBOL_POINT));
      int levelsToOpen = MathFloor(diffPoints / GridStepPoints);
      // open additional levels up to GridMaxLevels
      int alreadyOpened = CountGridLevel(g.ticket);
      for(int lvl = alreadyOpened; lvl< MathMin(levelsToOpen, GridMaxLevels); lvl++)
        {
         double mult = GridMultiplier[MathMin(lvl, ArraySize(GridMultiplier)-1)];
         double addLot = g.volume * mult;
         // ensure exposure
         double currentLots = GetCurrentExposureLots();
         if(currentLots + addLot > MaxExposureLots) break;
         bool ok = false;
         if(g.isBuy)
           ok = trade.Sell(addLot,NULL,0,0,"XSprint grid"); // open opposite to hedge? Here we open same direction to average - adjust as design
         else
           ok = trade.Buy(addLot,NULL,0,0,"XSprint grid");
         if(ok)
           {
            ulong t = trade.ResultOrder();
            GridOrder *newg = new GridOrder();
            newg.ticket = t;
            newg.volume = addLot;
            newg.openPrice = price;
            newg.isBuy = !g.isBuy; // new direction
            gridOrders.Add(newg);
            PrintFormat("Opened grid lvl %d ticket=%d lot=%.2f", lvl, t, addLot);
           }
         else
           {
            Print("Grid open failed: ", trade.ResultRetcodeDescription());
           }
        }
     }

   // Profit lock / close grid if total profit reached
   double profit = CalculateSymbolProfit();
   double bal = AccountInfoDouble(ACCOUNT_BALANCE);
   if(profit >= bal * ProfitLockPercent/100.0)
     {
      Print("Profit lock reached. Closing all grid positions with profit=", profit);
      CloseAllSymbolPositions();
     }

   // auto drawdown stop (daily)
   double balance = AccountInfoDouble(ACCOUNT_BALANCE);
   double equity = AccountInfoDouble(ACCOUNT_EQUITY);
   double ddPercent = (balance - equity)/balance*100.0;
   if(ddPercent >= DailyDrawdownPercent)
     {
      Print("Drawdown auto-stop triggered: ", ddPercent, "%");
      allowTrading = false;
     }
  }

// Count number of grid levels for a root ticket (simple count by presence)
int CountGridLevel(ulong rootTicket)
  {
   int cnt=0;
   for(int i=0;i<gridOrders.Total();i++)
     {
      GridOrder *g = (GridOrder*)gridOrders.At(i);
      if(g==NULL) continue;
      if(g.ticket==rootTicket) cnt++;
     }
   return(cnt);
  }

// Calculate current profit on symbol (floating)
double CalculateSymbolProfit()
  {
   double p=0;
   for(int i=PositionsTotal()-1;i>=0;i--)
     {
      if(PositionGetTicket(i))
        {
         if(PositionGetString(POSITION_SYMBOL)==_Symbol)
            p += PositionGetDouble(POSITION_PROFIT);
        }
     }
   return(p);
  }

void CloseAllSymbolPositions()
  {
   for(int i=PositionsTotal()-1;i>=0;i--)
     {
      ulong t = PositionGetTicket(i);
      if(PositionSelectByTicket(t))
        {
         if(PositionGetString(POSITION_SYMBOL)==_Symbol)
           {
            double vol = PositionGetDouble(POSITION_VOLUME);
            bool isBuy = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY);
            if(isBuy) trade.PositionClose(t);
            else trade.PositionClose(t);
           }
        }
     }
  }

// Simple record of result to detect consecutive losses
void UpdateConsecutiveLosses()
  {
   // Use history to find last closed trades on this symbol
   ulong last_ticket = HistoryOrderGetTicket(HistoryOrderGetInteger(0));
   // This is placeholder: in real implementation track closed trades and check P/L sign
  }

//+------------------------------------------------------------------+
//| End of EA |
//+------------------------------------------------------------------+

反馈

1
开发者 1
等级
(2)
项目
2
0%
仲裁
0
逾期
0
繁忙
1
开发者 1
等级
(2)
项目
1
100%
仲裁
2
0% / 100%
逾期
0
空闲
2
开发者 2
等级
项目
0
0%
仲裁
0
逾期
0
空闲
2
开发者 2
等级
(574)
项目
945
47%
仲裁
304
59% / 26%
逾期
125
13%
工作中
3
开发者 3
等级
(1)
项目
1
0%
仲裁
0
逾期
0
空闲
3
开发者 3
等级
项目
0
0%
仲裁
0
逾期
0
空闲
4
开发者 4
等级
项目
0
0%
仲裁
0
逾期
0
工作中
发布者: 2 代码
4
开发者 4
等级
(1)
项目
2
0%
仲裁
0
逾期
0
工作中
5
开发者 5
等级
(21)
项目
24
38%
仲裁
1
100% / 0%
逾期
3
13%
工作中
6
开发者 6
等级
(243)
项目
249
31%
仲裁
0
逾期
3
1%
空闲
发布者: 2 代码
相似订单
I’m looking for someone who’s proficient in pinescrip latest version. The candidate must understand dealing ranges. I will describe what I need for the range to be considered a dealing. It’s a 2 part indicator. Part 1 spots the dealing ranges based on my requirements and Prager 2: the script draws a circle from start to the end of dealing ranges then count some candles. The rest is simple math. But before moving to
I'm looking to create a Gold trading EA that focuses on rebate earnings rather than trading profits. The key requirement is for it to execute more than 20 trades per day without ending in a daily loss. Scope of work - Develop a Gold trading EA capable of executing over 20 trades per day. - Ensure that the daily trading results do not end in a loss. - Focus on rebate earnings rather than trading profits. Additional
I want an Expert Advisor that is based on core high-frequency scalping strategy. The EA will continuously place pending buy stop and sell stop orders at a fixed distance from the current Bid price, creating a grid around the price action. When price moves and triggers one of these orders, the EA will immediately close the opposite pending order and then place a new pair of buy and sell stop orders around the new
Hello. We are looking for a group of developers or a software company to create a website that offers services for forex and futures traders. We need assistance with website development, launching service sales, and monitoring traders' accounts. If you have experience building websites and integrating service sales, please apply for this job
MQL5 Freelance Job Request: Trading Board Relocation & Rebuild Title: Rebuild & Relocate Existing Trading Board (Confluence Signal System) – MT4/MT5 --- Description: I already have a fully working version of a trading board / signal dashboard that generates trade signals based on a confluence of multiple technical factors. The software is unlicensed, not copyrighted, and not protected, and I legally own the files. I
Hello. We are looking for a group of developers or a software company to create a website that offers services for forex and futures traders. We need assistance with website development, launching service sales, and monitoring traders' accounts. If you have experience building websites and integrating service sales, please apply for this job
EA Base on FVG 50+ USD
i want to work with an professional mql developer. it would be better if you have created EA or indicator related to FVG before. Higher Time Frame POI - W , D , 4H Lower Time Frame Entry - 4H , 1H , 15min The EA looks for HTF fvg and then looks for fvg in LTF. if you think you can do it, please contact me
Footprint-based Reversal Entry EA with Multi-Filter Logic We’re seeking an experienced MQL5 developer to build an MT5 EA that enters trades based on reversal patterns detected from the ClusterDelta #Footprint indicator (CME futures volume). The EA must be flexible enough to trade GBPUSD and USDJPY, with parameters adaptable to any pair. Core requirements (see attached specification for full details): Trend Filter
MT5 mobile delayed charts 400 - 1100 USD
I am looking for delayed charts—specifically charts delayed by one day—that maintain the same market conditions and price behavior as the live market, just shifted in time. This could be provided either by a broker that offers delayed-market data or by a standalone Android application similar to MetaTrader 5
i need any gold scalper or flip EA that works that with 100 dollars balance and you can make just 1 dollar daily. i dont really mind the strategy use by the developer , i just want something that can scalp gold and make 1 dollar daily

项目信息

预算
100 - 200 USD

客户

所下订单2
仲裁计数0