<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Omais Ali</title>
    <description>The latest articles on DEV Community by Omais Ali (@omaisali).</description>
    <link>https://dev.to/omaisali</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4173524%2F25bad014-e6df-4e8d-ad5f-db874f3b23fc.png</url>
      <title>DEV Community: Omais Ali</title>
      <link>https://dev.to/omaisali</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/omaisali"/>
    <language>en</language>
    <item>
      <title>Adding Useful Logging to an MQL5 Expert Advisor</title>
      <dc:creator>Omais Ali</dc:creator>
      <pubDate>Sat, 10 Oct 2026 10:32:05 +0000</pubDate>
      <link>https://dev.to/omaisali/adding-useful-logging-to-an-mql5-expert-advisor-a18</link>
      <guid>https://dev.to/omaisali/adding-useful-logging-to-an-mql5-expert-advisor-a18</guid>
      <description>&lt;p&gt;When a client tells me their EA "did something weird last night," the first thing I ask for is the log. Too often there is nothing useful in it. The Experts tab shows that the EA loaded, maybe a few lines from the terminal about orders, and that is all. Without a record of what the EA saw and decided, debugging turns into guessing.&lt;/p&gt;

&lt;p&gt;Here is how I add logging to the EAs I build, so that a strange trade can be explained in a few minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to log
&lt;/h2&gt;

&lt;p&gt;I log decisions, not ticks. Printing every tick floods the journal and hides the lines that matter. The events worth a line are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Startup: EA version, symbol, timeframe, account type, key input values, and the broker's digits, point and volume step for the symbol.&lt;/li&gt;
&lt;li&gt;Signals: when an entry or exit condition becomes true, with the values that triggered it, such as the indicator readings and the bar time.&lt;/li&gt;
&lt;li&gt;Skipped trades: when a signal fires but a filter blocks it, with the reason. Spread too wide, outside session hours, daily limit reached, position already open.&lt;/li&gt;
&lt;li&gt;Every trade request and its result, including the return code.&lt;/li&gt;
&lt;li&gt;State changes: a breakeven move, a trailing stop update, a daily lock switching on or off.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The skipped trade lines are the ones people forget, and they answer the most common question I get: "Why didn't it take that trade?"&lt;/p&gt;

&lt;h2&gt;
  
  
  Print vs FileWrite
&lt;/h2&gt;

&lt;p&gt;Print writes to the Experts tab and to the terminal's daily log in the MQL5/Logs folder. It is quick to add and fine for development. The downside is that it mixes your lines with everything else the terminal writes, and the format is not easy to load into a spreadsheet.&lt;/p&gt;

&lt;p&gt;For live accounts I also write to my own file with FileOpen and FileWrite. That gives me one file per EA and per symbol, a consistent column layout, and something I can open in a spreadsheet or search with a script. I keep Print for the important lines too, so they still show up in the terminal while I am watching.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int g_log = INVALID_HANDLE;

bool LogOpen()
{
   MqlDateTime d;
   TimeToStruct(TimeCurrent(), d);
   string name = StringFormat("MyEA_%s_%04d%02d%02d.csv",
                              _Symbol, d.year, d.mon, d.day);
   g_log = FileOpen(name, FILE_WRITE | FILE_READ | FILE_CSV |
                    FILE_SHARE_READ | FILE_ANSI, ';');
   if(g_log == INVALID_HANDLE) return false;
   FileSeek(g_log, 0, SEEK_END);      // append, do not overwrite
   return true;
}

void Log(string event, string detail)
{
   string t = TimeToString(TimeCurrent(), TIME_DATE | TIME_SECONDS);
   if(g_log != INVALID_HANDLE)
   {
      FileWrite(g_log, t, _Symbol, event, detail);
      FileFlush(g_log);
   }
   Print(event, " | ", detail);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;FileFlush after each write matters. If the terminal crashes or the VPS reboots, unflushed lines are lost, and those are usually the lines you needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Log rotation
&lt;/h2&gt;

&lt;p&gt;A busy EA can write a lot over a few months. I put the date in the file name, as above, and open a new file when the server date changes. On startup the EA can delete files older than a set number of days from its own folder. Files live in the terminal's MQL5/Files sandbox, so the EA can only touch its own files, which keeps this safe.&lt;/p&gt;

&lt;h2&gt;
  
  
  Logging order results and retcodes
&lt;/h2&gt;

&lt;p&gt;The single most useful line in any EA log is the trade result. A request that returns true from OrderSend is not the same as a filled order. I log the requested price and volume next to what came back.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#include &amp;lt;Trade/Trade.mqh&amp;gt;
CTrade trade;

void LogResult(string action)
{
   Log(action, StringFormat(
       "retcode=%u (%s) req_price=%.5f fill_price=%.5f vol=%.2f deal=%I64u",
       trade.ResultRetcode(), trade.ResultRetcodeDescription(),
       trade.RequestPrice(), trade.ResultPrice(),
       trade.ResultVolume(), trade.ResultDeal()));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that line in place, requotes, invalid stops, market closed errors and partial fills stop being mysteries. You can also measure slippage directly by comparing the requested and filled price.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading logs: live vs backtest
&lt;/h2&gt;

&lt;p&gt;In the Strategy Tester, Print output goes to the tester journal, and files are written to the tester agent's own Files folder rather than the terminal's. That catches people out the first time they look for their log after a test.&lt;/p&gt;

&lt;p&gt;My routine when live behaviour differs from a backtest is simple. I run the tester over the same days, with the same inputs, and log in the same format. Then I put the two files side by side and find the first line where they disagree. Usually it is a signal that fired on a different bar, a filter that blocked a trade live because of spread, or a retcode the tester never produced. Once you know the first point of divergence, the cause is rarely far away.&lt;/p&gt;

&lt;p&gt;Good logging takes an hour to add and saves days later. I treat it as part of the EA, not an extra.&lt;/p&gt;

&lt;p&gt;I build custom MT5 Expert Advisors at &lt;a href="https://customtradingbots.com/?utm_source=devto&amp;amp;utm_campaign=logging" rel="noopener noreferrer"&gt;Custom Trading Bots&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>mql5</category>
      <category>trading</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>What to Send a Developer Before They Build Your Trading Bot</title>
      <dc:creator>Omais Ali</dc:creator>
      <pubDate>Fri, 09 Oct 2026 14:10:17 +0000</pubDate>
      <link>https://dev.to/omaisali/what-to-send-a-developer-before-they-build-your-trading-bot-12ca</link>
      <guid>https://dev.to/omaisali/what-to-send-a-developer-before-they-build-your-trading-bot-12ca</guid>
      <description>&lt;p&gt;Most custom trading bot projects that go wrong don't fail in the code. They fail in the brief. The trader knows the strategy by feel, the developer guesses at the gaps, and the finished bot does something slightly different from what the trader meant.&lt;/p&gt;

&lt;p&gt;Here's the one-page spec I ask every client for before building an MT5 Expert Advisor. If you fill this in, any competent developer can quote accurately and build what you actually want.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Market and timeframe
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Which symbols (for example EURUSD, XAUUSD, US30)?&lt;/li&gt;
&lt;li&gt;Which timeframe are signals calculated on?&lt;/li&gt;
&lt;li&gt;Which broker and account type (hedging or netting)?&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  2. Entry rules
&lt;/h2&gt;

&lt;p&gt;Write each condition as a plain sentence:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;"Go long when the 20 EMA closes above the 50 EMA on the H1 chart."&lt;/li&gt;
&lt;li&gt;"Only if RSI(14) is below 70 at that close."&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Say whether the signal is checked at bar close or on every tick. This one detail causes more backtest-versus-live surprises than anything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Exit rules
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Stop loss: fixed pips, ATR-based, or below the last swing?&lt;/li&gt;
&lt;li&gt;Take profit: fixed, ATR-based, or none?&lt;/li&gt;
&lt;li&gt;Trailing stop and breakeven: when do they activate, and by how much?&lt;/li&gt;
&lt;li&gt;Time exit: close after a maximum number of bars?&lt;/li&gt;
&lt;li&gt;Opposite signal: does it close the trade, reverse it, or do nothing?&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  4. Position sizing and risk
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Fixed lot size, or a percentage of the account per trade?&lt;/li&gt;
&lt;li&gt;Maximum number of open trades at once, and per symbol?&lt;/li&gt;
&lt;li&gt;Daily and weekly maximum loss before the bot stops trading?&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  5. Filters
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Trading hours or sessions to allow or avoid.&lt;/li&gt;
&lt;li&gt;Maximum spread allowed for an entry.&lt;/li&gt;
&lt;li&gt;News avoidance, if any.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  6. What "done" looks like
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Backtest period and the results you expect to roughly reproduce.&lt;/li&gt;
&lt;li&gt;Inputs you want to be able to change without touching the code.&lt;/li&gt;
&lt;li&gt;Whether you need alerts (Telegram, email, push) for entries and exits.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  A tip that saves money
&lt;/h2&gt;

&lt;p&gt;If you can, send screenshots of three or four past trades marked up with exactly where you would have entered and exited, and why. Developers can test their logic against those examples, and you'll catch misunderstandings before a single line is written.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;A clear spec means a fixed, honest quote, a faster build, and a bot that behaves the way you trade on your best day.&lt;/p&gt;

&lt;p&gt;I build custom MT5 Expert Advisors with this process, plus a proper risk and execution layer in every build. If you've got your rules written down and want them automated, have a look at &lt;a href="https://customtradingbots.com/?utm_source=devto" rel="noopener noreferrer"&gt;CustomTradingBots.com&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>automation</category>
      <category>beginners</category>
      <category>trading</category>
    </item>
  </channel>
</rss>
