{"id":2866,"date":"2025-07-04T21:31:03","date_gmt":"2025-07-04T19:31:03","guid":{"rendered":"https:\/\/store.market-trader.de\/?page_id=2866"},"modified":"2025-07-04T21:41:50","modified_gmt":"2025-07-04T19:41:50","slug":"selbst-programmiert-expert-advisor-moving-average-crossover","status":"publish","type":"page","link":"https:\/\/ea-marketplace.com\/en\/self-programmed-expert-advisor-moving-average-crossover\/","title":{"rendered":"Step-by-step: Writing your own Expert Advisor in MQL5"},"content":{"rendered":"\r\n\r\n<h2 class=\"wp-block-heading\">Self-coded Expert Advisor \u201cMoving Average Crossover\u201d<\/h2>\r\n\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\">Introduction<\/h3>\r\n\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This Expert Advisor (EA) <strong>\u201cMA_Cross\u201d<\/strong> for MetaTrader 5 automates the detection and trading of a trend-following setup based on two Exponential Moving Averages (EMA) and the Average True Range (ATR).<br><br>It demonstrates how to do the following in MQL5:<\/p>\r\n\r\n\r\n\r\n\r\n<ol class=\"wp-block-list\">\r\n<li>Create and read <strong>indicators<\/strong><\/li>\r\n\r\n\r\n\r\n\r\n<li>Detect <strong>signals<\/strong> (crossover and volatility filter)<\/li>\r\n\r\n\r\n\r\n\r\n<li>Implement <strong>risk management<\/strong> via stop-loss, take-profit, and lot sizing<\/li>\r\n\r\n\r\n\r\n\r\n<li><strong>Place and monitor orders<\/strong><\/li>\r\n\r\n\r\n\r\n\r\n<li>Dynamically adjust a <strong>trailing stop<\/strong><\/li>\r\n<\/ol>\r\n\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The goal is to show how to work cleanly with indicator handles in MQL5 and build a complete, running EA.<\/p>\r\n\r\n\r\n\r\n\r\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\r\n\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Code Overview<\/h2>\r\n\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\">Libraries and trade object<\/h3>\r\n\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>#include &lt;Trade\\Trade.mqh&gt;   \/\/ Include CTrade class for order functions\r\nCTrade trade;               \/\/ Trade object for sending and modifying orders\r\n<\/code><\/pre>\r\n\r\n\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><em>Trade.mqh<\/em> provides the <strong>CTrade<\/strong> class, which makes it easy to place market orders (buy\/sell) and modify existing positions.<\/p>\r\n\r\n\r\n\r\n\r\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\r\n\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\">Input parameters<\/h3>\r\n\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>input int    FastEMAPeriod   = 10;            \/\/ Period for fast EMA\r\ninput int    SlowEMAPeriod   = 50;            \/\/ Period for slow EMA\r\ninput int    ATRPeriod       = 14;            \/\/ ATR period\r\ninput double RiskPercent     = 1.0;           \/\/ Max risk per trade in % of the account\r\ninput double RewardRiskRatio = 2.0;           \/\/ TP-to-SL ratio (e.g., 1:2)\r\ninput bool   UseTrailingStop = true;          \/\/ Enable trailing stop?\r\ninput string CommentText     = \"EMA_Cross_ATR\";\/\/ Comment for all orders\r\n<\/code><\/pre>\r\n\r\n\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">These <strong>inputs<\/strong> let you adjust all key parameters (EMA periods, ATR, risk, R:R ratio, trailing stop) directly in the tester or EA properties.<\/p>\r\n\r\n\r\n\r\n\r\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\r\n\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\">Global handles for indicators<\/h3>\r\n\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>int fastHandle;    \/\/ Handle for fast EMA (FastEMAPeriod)\r\nint slowHandle;    \/\/ Handle for slow EMA (SlowEMAPeriod)\r\nint atrHandle;     \/\/ Handle for ATR (ATRPeriod)\r\n<\/code><\/pre>\r\n\r\n\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Indicators in MQL5 are created via <strong>handles<\/strong>. These integers store references that are later used to read values using <code>CopyBuffer()<\/code>.<\/p>\r\n\r\n\r\n\r\n\r\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\r\n\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\">OnInit()<\/h3>\r\n\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>int OnInit()\r\n  {\r\n   \/\/ Create EMA handles\r\n   fastHandle = iMA(_Symbol, PERIOD_CURRENT, FastEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);\r\n   slowHandle = iMA(_Symbol, PERIOD_CURRENT, SlowEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);\r\n   \/\/ Create ATR handle\r\n   atrHandle  = iATR(_Symbol, PERIOD_CURRENT, ATRPeriod);\r\n\r\n   \/\/ Check if all handles are valid\r\n   if(fastHandle == INVALID_HANDLE\r\n      || slowHandle == INVALID_HANDLE\r\n      || atrHandle  == INVALID_HANDLE)\r\n     {\r\n      Print(\"Error creating indicator handles\");\r\n      return(INIT_FAILED);\r\n     }\r\n\r\n   return(INIT_SUCCEEDED);\r\n  }\r\n<\/code><\/pre>\r\n\r\n\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li><strong>iMA(&#8230;)<\/strong> and <strong>iATR(&#8230;)<\/strong> return the handles.<\/li>\r\n\r\n\r\n\r\n\r\n<li>If a handle is <strong>INVALID_HANDLE<\/strong>, initialization fails.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n\r\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\r\n\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\">CalculateLot()<\/h3>\r\n\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>double CalculateLot(bool isBuy, double stopLossPrice)\r\n  {\r\n   \/\/ Entry price (Ask for buy, Bid for sell)\r\n   double entryPrice = isBuy\r\n                       ? SymbolInfoDouble(_Symbol, SYMBOL_ASK)\r\n                       : SymbolInfoDouble(_Symbol, SYMBOL_BID);\r\n   \/\/ Distance Entry \u2194 Stop-loss in price units\r\n   double distance   = MathAbs(entryPrice - stopLossPrice);\r\n   \/\/ Amount we are allowed to risk at most\r\n   double riskAmount = AccountInfoDouble(ACCOUNT_BALANCE) * RiskPercent \/ 100.0;\r\n   \/\/ Tick value and tick size for the symbol\r\n   double tickValue  = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);\r\n   double tickSize   = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);\r\n   double pointValue = tickValue \/ tickSize;\r\n   \/\/ Raw lot calculation: risk \/ (distance \u00d7 point value)\r\n   double lots       = riskAmount \/ (distance * pointValue);\r\n   \/\/ Round to allowed volume steps\r\n   double step       = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);\r\n   double minLot     = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);\r\n   double maxLot     = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);\r\n   lots = MathFloor(lots \/ step) * step;\r\n   if(lots &lt; minLot) lots = minLot;\r\n   if(lots &gt; maxLot) lots = maxLot;\r\n   return(lots);\r\n  }\r\n<\/code><\/pre>\r\n\r\n\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This function computes the <strong>lot size<\/strong> so that, if the stop-loss is hit, the maximum risk amount is not exceeded.<\/p>\r\n\r\n\r\n\r\n\r\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\r\n\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\">OnTick()<\/h3>\r\n\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>void OnTick()\r\n  {\r\n   \/\/ 1) Current Bid\/Ask prices\r\n   double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);\r\n   double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);\r\n\r\n   \/\/ 2) Buffers for the last 2 values of each indicator\r\n   double fastBuf&#91;2], slowBuf&#91;2], atrBuf&#91;2];\r\n\r\n   \/\/ 3) Copy indicator values (current = index 0, previous = index 1)\r\n   if(CopyBuffer(fastHandle, 0, 0, 2, fastBuf) &lt;= 0 ||\r\n      CopyBuffer(slowHandle, 0, 0, 2, slowBuf) &lt;= 0 ||\r\n      CopyBuffer(atrHandle,  0, 0, 2, atrBuf)  &lt;= 0)\r\n     {\r\n      Print(\"Error copying indicator data\");\r\n      return;\r\n     }\r\n\r\n   \/\/ 4) Assign buffer data\r\n   double fastEMA    = fastBuf&#91;0], fastEMAold = fastBuf&#91;1];\r\n   double slowEMA    = slowBuf&#91;0], slowEMAold = slowBuf&#91;1];\r\n   double atrNow     = atrBuf&#91;0],  atrOld     = atrBuf&#91;1];\r\n\r\n   \/\/ 5) Check whether a position is already open\r\n   bool positionExists = PositionSelect(_Symbol);\r\n\r\n   \/\/ \u2014 Enter only if no position is open \u2014\r\n   if(!positionExists)\r\n     {\r\n      \/\/ Long signal: EMA10 crosses EMA50 up + ATR rising\r\n      bool longSignal  = (fastEMAold &lt; slowEMAold)\r\n                         &amp;&amp; (fastEMA &gt; slowEMA)\r\n                         &amp;&amp; (atrNow &gt; atrOld);\r\n      \/\/ Short signal: EMA10 crosses EMA50 down\r\n      bool shortSignal = (fastEMAold &gt; slowEMAold)\r\n                         &amp;&amp; (fastEMA &lt; slowEMA);\r\n\r\n      \/\/ Long entry\r\n      if(longSignal)\r\n        {\r\n         double sl  = ask - 1.5 * atrNow;\r\n         double tp  = ask + RewardRiskRatio * (ask - sl);\r\n         double lot = CalculateLot(true, sl);\r\n         if(trade.Buy(lot, NULL, ask, sl, tp, CommentText))\r\n            Print(\"Opened long at \", ask, \" SL=\", sl, \" TP=\", tp);\r\n        }\r\n      \/\/ Short entry\r\n      else if(shortSignal)\r\n        {\r\n         double sl  = bid + 1.5 * atrNow;\r\n         double tp  = bid - RewardRiskRatio * (sl - bid);\r\n         double lot = CalculateLot(false, sl);\r\n         if(trade.Sell(lot, NULL, bid, sl, tp, CommentText))\r\n            Print(\"Opened short at \", bid, \" SL=\", sl, \" TP=\", tp);\r\n        }\r\n     }\r\n   \/\/ \u2014 Trailing stop if a position is open and enabled \u2014\r\n   else if(UseTrailingStop)\r\n     {\r\n      ulong ticket = PositionGetInteger(POSITION_TICKET);\r\n      ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);\r\n      double newSL = (type == POSITION_TYPE_BUY)\r\n                     ? bid - atrNow\r\n                     : ask + atrNow;\r\n      trade.PositionModify(ticket, newSL, 0);\r\n     }\r\n  }\r\n<\/code><\/pre>\r\n\r\n\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">In <strong>OnTick()<\/strong>, indicators are evaluated, signals are detected, orders are sent, and the stop-loss is dynamically trailed when needed.<\/p>\r\n\r\n\r\n\r\n\r\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\r\n\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\">OnDeinit()<\/h3>\r\n\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>void OnDeinit(const int reason)\r\n  {\r\n   if(fastHandle != INVALID_HANDLE) IndicatorRelease(fastHandle);\r\n   if(slowHandle != INVALID_HANDLE) IndicatorRelease(slowHandle);\r\n   if(atrHandle  != INVALID_HANDLE) IndicatorRelease(atrHandle);\r\n  }\r\n<\/code><\/pre>\r\n\r\n\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">When removing the EA, all <strong>indicator handles are released<\/strong> to avoid memory leaks and other issues.<\/p>\r\n\r\n\r\n\r\n\r\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\r\n\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Explanation of the key steps<\/h2>\r\n\r\n\r\n\r\n\r\n<ol class=\"wp-block-list\">\r\n<li><strong>Creating handles and reading values<\/strong>\r\n<ul class=\"wp-block-list\">\r\n<li><strong>iMA() \/ iATR()<\/strong> each return a <strong>handle<\/strong> in <code>OnInit()<\/code>, i.e., a numeric reference to the indicator.<\/li>\r\n\r\n\r\n\r\n\r\n<li>In <strong>OnTick()<\/strong>, <code>CopyBuffer(handle, 0, shift, count, buffer)<\/code> fetches current and previous values into a local array.<\/li>\r\n\r\n\r\n\r\n\r\n<li>Advantage: more efficient than repeated direct calls and allows access to historical bars.<\/li>\r\n<\/ul>\r\n<\/li>\r\n\r\n\r\n\r\n\r\n<li><strong>Crossover detection<\/strong><br><code>bool longSignal = (fastEMAold &lt; slowEMAold) &amp;&amp; (fastEMA &gt; slowEMA) &amp;&amp; (atrNow &gt; atrOld); bool shortSignal = (fastEMAold &gt; slowEMAold) &amp;&amp; (fastEMA &lt; slowEMA);<\/code>\r\n<ul class=\"wp-block-list\">\r\n<li><strong>fastEMAold<\/strong> and <strong>slowEMAold<\/strong> are the EMA values of the previous bar; <strong>fastEMA<\/strong> and <strong>slowEMA<\/strong> are those of the current bar.<\/li>\r\n\r\n\r\n\r\n\r\n<li>A <strong>long signal<\/strong> occurs when the fast EMA crosses above the slow EMA <strong>and<\/strong> ATR shows rising volatility.<\/li>\r\n\r\n\r\n\r\n\r\n<li>A <strong>short signal<\/strong> occurs when crossing from above to below, without an ATR filter.<\/li>\r\n<\/ul>\r\n<\/li>\r\n\r\n\r\n\r\n\r\n<li><strong>Risk management &amp; lot sizing<\/strong>\r\n<ul class=\"wp-block-list\">\r\n<li><strong>Stop-loss<\/strong> is set to <strong>1.5 \u00d7 ATR<\/strong>:\r\n<ul class=\"wp-block-list\">\r\n<li>Long: SL = Ask \u2013 1.5 \u00d7 ATR<\/li>\r\n\r\n\r\n\r\n\r\n<li>Short: SL = Bid + 1.5 \u00d7 ATR<\/li>\r\n<\/ul>\r\n<\/li>\r\n\r\n\r\n\r\n\r\n<li><strong>Take-profit<\/strong> so that the risk-reward ratio is 1:2:\r\n<ul class=\"wp-block-list\">\r\n<li>TP distance = 2 \u00d7 SL distance<\/li>\r\n<\/ul>\r\n<\/li>\r\n\r\n\r\n\r\n\r\n<li>In <code>CalculateLot()<\/code>, the lot size ensures that, if the stop-loss is hit, at most <strong>RiskPercent%<\/strong> of the account balance is lost.<\/li>\r\n\r\n\r\n\r\n\r\n<li><code>SymbolInfoDouble(..., SYMBOL_TRADE_TICK_VALUE)<\/code> and <code>SYMBOL_TRADE_TICK_SIZE<\/code> are used to correctly account for the cash value per point.<\/li>\r\n<\/ul>\r\n<\/li>\r\n\r\n\r\n\r\n\r\n<li><strong>Order placement<\/strong>\r\n<ul class=\"wp-block-list\">\r\n<li>With <code>trade.Buy(lot, NULL, price, sl, tp, CommentText)<\/code> and<br><code>trade.Sell(...)<\/code> a market order is sent with defined SL and TP.<\/li>\r\n\r\n\r\n\r\n\r\n<li><code>CTrade<\/code> handles error processing, slippage, and returns the order ticket.<\/li>\r\n<\/ul>\r\n<\/li>\r\n\r\n\r\n\r\n\r\n<li><strong>Trailing stop (optional)<\/strong>\r\n<ul class=\"wp-block-list\">\r\n<li>Once a position is open and <code>UseTrailingStop == true<\/code>, the EA moves the stop-loss by <strong>1 \u00d7 ATR<\/strong> behind current price on every tick:\r\n<ul class=\"wp-block-list\">\r\n<li>Long: new SL = Bid \u2013 ATR<\/li>\r\n\r\n\r\n\r\n\r\n<li>Short: new SL = Ask + ATR<\/li>\r\n<\/ul>\r\n<\/li>\r\n\r\n\r\n\r\n\r\n<li>This provides a <strong>dynamic lock-in<\/strong> of accrued profit.<\/li>\r\n<\/ul>\r\n<\/li>\r\n\r\n\r\n\r\n\r\n<li><strong>Cleanup in OnDeinit()<\/strong>\r\n<ul class=\"wp-block-list\">\r\n<li>All created indicator handles (<code>fastHandle<\/code>, <code>slowHandle<\/code>, <code>atrHandle<\/code>) are released with <code>IndicatorRelease(handle)<\/code> to free resources properly.<\/li>\r\n<\/ul>\r\n<\/li>\r\n<\/ol>\r\n\r\n\r\n\r\n\r\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\r\n\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">With these clearly structured steps, you learn how to:<\/p>\r\n\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Create and read indicators efficiently<\/li>\r\n\r\n\r\n\r\n\r\n<li>Detect signals precisely<\/li>\r\n\r\n\r\n\r\n\r\n<li>Implement responsible risk management<\/li>\r\n\r\n\r\n\r\n\r\n<li>Manage market orders professionally<\/li>\r\n\r\n\r\n\r\n\r\n<li>Implement dynamic stop-loss strategies<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><\/p>\r\n\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Summary<\/h2>\r\n\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This EA demonstrates a complete MQL5 workflow:<\/p>\r\n\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li><strong>Clean separation<\/strong> between initialization (<code>OnInit<\/code>), main logic (<code>OnTick<\/code>), and cleanup (<code>OnDeinit<\/code>).<\/li>\r\n\r\n\r\n\r\n\r\n<li><strong>Handle-based<\/strong> indicator usage with <code>CopyBuffer()<\/code>.<\/li>\r\n\r\n\r\n\r\n\r\n<li><strong>Simple trend-following strategy<\/strong> based on two EMAs plus a volatility filter.<\/li>\r\n\r\n\r\n\r\n\r\n<li><strong>Careful risk management<\/strong> using stop-loss, take-profit, and dynamic lot sizing.<\/li>\r\n\r\n\r\n\r\n\r\n<li><strong>Optional automation<\/strong> of a trailing stop.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">With this commented example, you get a solid foundation to develop your own strategies in MQL5 and understand how to implement automated trading systems professionally. Good luck with your next steps in MQL5 programming!<\/p>\r\n\r\n\r\n\r\n\r\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\r\n\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Source Code MA_Cross.mq5<\/h2>\r\n\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>\/\/+------------------------------------------------------------------+\r\n\/\/|                                                   MA_Cross.mq5   |\r\n\/\/|        EMA Crossover + ATR Filter for MetaTrader 5 (MQL5)        |\r\n\/\/+------------------------------------------------------------------+\r\n#include &lt;Trade\\Trade.mqh&gt;                                  \/\/ Include CTrade class for order functions\r\nCTrade trade;                                              \/\/ Trade object\r\n\r\n\/\/\u2014 Input parameters \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\r\ninput int    FastEMAPeriod    = 10;                       \/\/ Period for fast EMA\r\ninput int    SlowEMAPeriod    = 50;                       \/\/ Period for slow EMA\r\ninput int    ATRPeriod        = 14;                       \/\/ ATR period\r\ninput double RiskPercent      = 1.0;                      \/\/ Max risk per trade in % (e.g., 1 = 1%)\r\ninput double RewardRiskRatio  = 2.0;                      \/\/ Risk\u2013reward ratio (e.g., 1:2)\r\ninput bool   UseTrailingStop  = true;                     \/\/ Enable trailing stop?\r\ninput string CommentText      = \"EMA_Cross_ATR\";          \/\/ Comment text for orders\r\n\r\n\/\/\u2014 Global indicator handles \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\r\nint fastHandle;                                           \/\/ Handle for fast EMA\r\nint slowHandle;                                           \/\/ Handle for slow EMA\r\nint atrHandle;                                            \/\/ Handle for ATR\r\n\r\n\/\/+------------------------------------------------------------------+\r\n\/\/| OnInit: Initialization when the EA is loaded                     |\r\n\/\/+------------------------------------------------------------------+\r\nint OnInit()\r\n  {\r\n   \/\/ Create EMA handles with symbol, timeframe, period, shift, method, price\r\n   fastHandle = iMA(_Symbol, PERIOD_CURRENT, FastEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);\r\n   slowHandle = iMA(_Symbol, PERIOD_CURRENT, SlowEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);\r\n   \/\/ Create ATR handle with symbol, timeframe, period\r\n   atrHandle  = iATR(_Symbol, PERIOD_CURRENT, ATRPeriod);\r\n\r\n   \/\/ Check if handles are valid\r\n   if(fastHandle==INVALID_HANDLE || slowHandle==INVALID_HANDLE || atrHandle==INVALID_HANDLE)\r\n     {\r\n      Print(\"Error creating indicator handles\");\r\n      return(INIT_FAILED);                               \/\/ Abort init on error\r\n     }\r\n   return(INIT_SUCCEEDED);                                \/\/ All good\r\n  }\r\n\r\n\/\/+------------------------------------------------------------------+\r\n\/\/| CalculateLot: Lot size based on SL distance                      |\r\n\/\/+------------------------------------------------------------------+\r\ndouble CalculateLot(bool isBuy, double stopLossPrice)\r\n  {\r\n   \/\/ 1) Determine entry price depending on buy\/sell\r\n   double entryPrice = isBuy\r\n                       ? SymbolInfoDouble(_Symbol, SYMBOL_ASK)\r\n                       : SymbolInfoDouble(_Symbol, SYMBOL_BID);\r\n   \/\/ 2) Distance SL \u2194 entry\r\n   double distance   = MathAbs(entryPrice - stopLossPrice);\r\n   \/\/ 3) Risk amount (balance \u00d7 risk %)\r\n   double riskAmount = AccountInfoDouble(ACCOUNT_BALANCE) * RiskPercent \/ 100.0;\r\n   \/\/ 4) Point value for symbol (TickValue \/ TickSize)\r\n   double tickValue  = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);\r\n   double tickSize   = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);\r\n   double pointValue = tickValue \/ tickSize;\r\n   \/\/ 5) Raw lots = risk \/ (distance \u00d7 point value)\r\n   double lots       = riskAmount \/ (distance * pointValue);\r\n   \/\/ 6) Round to minimum lot step\r\n   double step       = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);\r\n   double minLot     = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);\r\n   double maxLot     = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);\r\n   lots = MathFloor(lots \/ step) * step;\r\n   if(lots &lt; minLot) lots = minLot;\r\n   if(lots &gt; maxLot) lots = maxLot;\r\n   return(lots);                                          \/\/ Return final lot size\r\n  }\r\n\r\n\/\/+------------------------------------------------------------------+\r\n\/\/| OnTick: Main logic on every tick                                 |\r\n\/\/+------------------------------------------------------------------+\r\nvoid OnTick()\r\n  {\r\n   \/\/ 1) Get current bid\/ask\r\n   double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);\r\n   double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);\r\n\r\n   \/\/ 2) Buffers for current and previous indicator values\r\n   double fastBuf&#91;2], slowBuf&#91;2], atrBuf&#91;2];\r\n   \/\/ 3) Copy data from handles\r\n   if(CopyBuffer(fastHandle, 0, 0, 2, fastBuf) &lt;= 0 ||\r\n      CopyBuffer(slowHandle, 0, 0, 2, slowBuf) &lt;= 0 ||\r\n      CopyBuffer(atrHandle,  0, 0, 2, atrBuf)  &lt;= 0)\r\n     {\r\n      Print(\"Error copying indicator data\");\r\n      return;                                             \/\/ Abort on error\r\n     }\r\n\r\n   \/\/ 4) Assign values: &#91;0] = current, &#91;1] = previous\r\n   double fastEMA    = fastBuf&#91;0];\r\n   double fastEMAold = fastBuf&#91;1];\r\n   double slowEMA    = slowBuf&#91;0];\r\n   double slowEMAold = slowBuf&#91;1];\r\n   double atrNow     = atrBuf&#91;0];\r\n   double atrOld     = atrBuf&#91;1];\r\n\r\n   \/\/ 5) Check if a position is already open\r\n   bool positionExists = PositionSelect(_Symbol);\r\n\r\n   \/\/ \u2014 Entry if no position is open \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\r\n   if(!positionExists)\r\n     {\r\n      \/\/ Long if EMA cross up + ATR rising\r\n      bool longSignal  = (fastEMAold &lt; slowEMAold) &amp;&amp; (fastEMA &gt; slowEMA) &amp;&amp; (atrNow &gt; atrOld);\r\n      \/\/ Short if EMA cross down\r\n      bool shortSignal = (fastEMAold &gt; slowEMAold) &amp;&amp; (fastEMA &lt; slowEMA);\r\n\r\n      if(longSignal)  \/\/ Long entry\r\n        {\r\n         double sl  = ask - 1.5 * atrNow;                                         \/\/ SL = entry \u2212 1.5\u00d7ATR\r\n         double tp  = ask + RewardRiskRatio * (ask - sl);                        \/\/ TP = entry + 2\u00d7risk\r\n         double lot = CalculateLot(true, sl);                                    \/\/ Compute lot\r\n         if(trade.Buy(lot, NULL, ask, sl, tp, CommentText))                      \/\/ Send buy order\r\n            Print(\"Opened long at \", ask, \" SL=\", sl, \" TP=\", tp);            \r\n        }\r\n      else if(shortSignal) \/\/ Short entry\r\n        {\r\n         double sl  = bid + 1.5 * atrNow;                                         \/\/ SL = entry + 1.5\u00d7ATR\r\n         double tp  = bid - RewardRiskRatio * (sl - bid);                        \/\/ TP = entry \u2212 2\u00d7risk\r\n         double lot = CalculateLot(false, sl);                                   \/\/ Compute lot\r\n         if(trade.Sell(lot, NULL, bid, sl, tp, CommentText))                     \/\/ Send sell order\r\n            Print(\"Opened short at \", bid, \" SL=\", sl, \" TP=\", tp);\r\n        }\r\n     }\r\n   \/\/ \u2014 Trailing stop if a position is open \u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\r\n   else if(UseTrailingStop)\r\n     {\r\n      ulong ticket = PositionGetInteger(POSITION_TICKET);                        \/\/ Position ticket\r\n      ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);\r\n      double newSL;\r\n      if(type == POSITION_TYPE_BUY)                                             \/\/ If long\r\n         newSL = bid - atrNow;                                                   \/\/ SL = Bid \u2212 1\u00d7ATR\r\n      else                                                                       \/\/ If short\r\n         newSL = ask + atrNow;                                                   \/\/ SL = Ask + 1\u00d7ATR\r\n\r\n      trade.PositionModify(ticket, newSL, 0);                                   \/\/ Adjust SL\r\n     }\r\n  }\r\n\r\n\/\/+------------------------------------------------------------------+\r\n\/\/| OnDeinit: Release handles                                        |\r\n\/\/+------------------------------------------------------------------+\r\nvoid OnDeinit(const int reason)\r\n  {\r\n   if(fastHandle != INVALID_HANDLE)  IndicatorRelease(fastHandle);             \/\/ Release fast EMA\r\n   if(slowHandle != INVALID_HANDLE)  IndicatorRelease(slowHandle);             \/\/ Release slow EMA\r\n   if(atrHandle  != INVALID_HANDLE)  IndicatorRelease(atrHandle);              \/\/ Release ATR\r\n  }\r\n\/\/+------------------------------------------------------------------+\r\n<\/code><\/pre>\r\n\r\n\r\n","protected":false},"excerpt":{"rendered":"<p>Self-coded Expert Advisor \u201cMoving Average Crossover\u201d Introduction This Expert Advisor (EA) \u201cMA_Cross\u201d for MetaTrader 5 automates the detection and trading [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-2866","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/ea-marketplace.com\/en\/wp-json\/wp\/v2\/pages\/2866","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ea-marketplace.com\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ea-marketplace.com\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ea-marketplace.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ea-marketplace.com\/en\/wp-json\/wp\/v2\/comments?post=2866"}],"version-history":[{"count":2,"href":"https:\/\/ea-marketplace.com\/en\/wp-json\/wp\/v2\/pages\/2866\/revisions"}],"predecessor-version":[{"id":2870,"href":"https:\/\/ea-marketplace.com\/en\/wp-json\/wp\/v2\/pages\/2866\/revisions\/2870"}],"wp:attachment":[{"href":"https:\/\/ea-marketplace.com\/en\/wp-json\/wp\/v2\/media?parent=2866"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}