<?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: Arnold Holm</title>
    <description>The latest articles on DEV Community by Arnold Holm (@stratcorealpha).</description>
    <link>https://dev.to/stratcorealpha</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%2F4078355%2Fc2ecba14-1ac4-43ef-b437-2a38e810c2ca.png</url>
      <title>DEV Community: Arnold Holm</title>
      <link>https://dev.to/stratcorealpha</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/stratcorealpha"/>
    <language>en</language>
    <item>
      <title>Which loss limit leaves less room for your next trade?</title>
      <dc:creator>Arnold Holm</dc:creator>
      <pubDate>Sun, 01 Nov 2026 09:20:09 +0000</pubDate>
      <link>https://dev.to/stratcorealpha/which-loss-limit-leaves-less-room-for-your-next-trade-4d3o</link>
      <guid>https://dev.to/stratcorealpha/which-loss-limit-leaves-less-room-for-your-next-trade-4d3o</guid>
      <description>&lt;p&gt;In this invented example, 100 USD total room is tighter than 300 USD daily. If you track two fixed floors on one equity number, you compare your next loss to both gaps.&lt;/p&gt;

&lt;p&gt;A Reddit thread discusses daily drawdown or a consistency rule (&lt;a href="https://www.reddit.com/r/PropFirmTester/comments/1tf0r18/daily_drawdown_or_consistency_rule_which_haunts/" rel="noopener noreferrer"&gt;daily drawdown or consistency rule discussion&lt;/a&gt;). This piece does not answer consistency rules. It is only an arithmetic illustration motivated by that drawdown discussion.&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers
&lt;/h2&gt;

&lt;p&gt;Equity is the account value including open trades. Here it is 9,600 USD. The case sets a fixed total floor at 9,500 USD and a fixed daily floor at 9,300 USD on that same equity basis.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Equity USD&lt;/th&gt;
&lt;th&gt;Total floor USD&lt;/th&gt;
&lt;th&gt;Daily floor USD&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;9,600&lt;/td&gt;
&lt;td&gt;9,500&lt;/td&gt;
&lt;td&gt;9,300&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Total room is 100 USD. Daily room is 300 USD. A loss must stay above both floors at once, so the smaller positive room sets how far the next loss can go before it crosses a line.&lt;/p&gt;

&lt;p&gt;You can see it in two subtractions. 9,600 minus 9,500 leaves 100 USD. 9,600 minus 9,300 leaves 300 USD. Now subtract the next loss from equity first. Then compare that new equity with each floor. A 120 USD loss leaves 9,480 USD. That is below 9,500 USD and above 9,300 USD. So the daily gap alone would have missed the breach. The total gap decides here because it is smaller.&lt;/p&gt;

&lt;p&gt;300 USD daily room covers a 120 USD loss. 100 USD total room is exceeded at 9,480 USD, 20 USD below the total floor and 180 USD above the daily floor. I never use the larger buffer alone.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqrfmqzqrz1cqbqx81txt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqrfmqzqrz1cqbqx81txt.png" alt="Equity 9,600 USD with total floor 9,500 USD and daily floor 9,300 USD" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Python check
&lt;/h2&gt;

&lt;p&gt;This function does pure subtraction and returns both gaps plus a position tag. It places no trade and opens no broker connection. It only subtracts numbers you type in. Three arithmetic checks passed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;rooms&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;equity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total_floor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;daily_floor&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;total&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;equity&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;total_floor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;daily&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;equity&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;daily_floor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;position&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;equity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;equity&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;above&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;equity&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;at_floor_check_rule&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;below&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;rooms&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9300&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;total&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;daily&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="mi"&gt;9600&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;9480&lt;/span&gt;
&lt;span class="nf"&gt;assert &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;position&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9480&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9500&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;position&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9480&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9300&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;below&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;above&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Equality returns a tag that asks for the written rule. The code does not call that tag safe.&lt;/p&gt;

&lt;p&gt;I put the two floors side by side before I judge room. I take both numbers from written rules. I put them on the same equity basis. Then I subtract each floor from current equity. The smaller positive result is the tighter gap. That is the gap I check first in this invented case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cases near the total floor
&lt;/h2&gt;

&lt;p&gt;Start again from 9,600 USD and test three hypothetical losses against the 9,500 USD total floor. A 99 USD loss leaves 9,501 USD, above the floor. A 100 USD loss leaves 9,500 USD, exactly on the floor and allowed only if your firm wording permits equality. A 101 USD loss leaves 9,499 USD, below the floor. Equality is not automatically safe. Your written rules decide if touching the floor counts as a breach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your rules
&lt;/h2&gt;

&lt;p&gt;This case uses fixed floors only. Fixed means the floors stay at 9,500 USD and 9,300 USD in this case. They do not follow equity up or down. A trailing floor moves with the account under its own written rule and needs its own peak in the account. Do not reuse these fixed numbers for it.&lt;/p&gt;

&lt;p&gt;Room left is not allowed risk. Commissions, slippage and changing equity can shrink room before or during the next loss. This is no sizing instruction. Fees, floating P/L, resets and equality come from your actual written rules. I write both floors down first. Write both floors from your rules on the same equity basis and compare the smaller room.&lt;/p&gt;

&lt;p&gt;The optional &lt;a href="https://stratcorealpha.com/rule-guard?ref=devto" rel="noopener noreferrer"&gt;free Pre-Check&lt;/a&gt;, the free Prop Rule Guard, can help organise the written rules.&lt;/p&gt;

&lt;p&gt;This invented case is not firm terms, not live broker records and not a pass test.&lt;/p&gt;

</description>
      <category>trading</category>
      <category>python</category>
      <category>programming</category>
      <category>fintech</category>
    </item>
    <item>
      <title>Error 136: another retry is not a quote check</title>
      <dc:creator>Arnold Holm</dc:creator>
      <pubDate>Sat, 31 Oct 2026 08:33:34 +0000</pubDate>
      <link>https://dev.to/stratcorealpha/error-136-another-retry-is-not-a-quote-check-f6p</link>
      <guid>https://dev.to/stratcorealpha/error-136-another-retry-is-not-a-quote-check-f6p</guid>
      <description>&lt;p&gt;My native MT4 run passed three synthetic policy cases with zero order calls. If your EA keeps hitting off quotes, you still need a quote check first.&lt;/p&gt;

&lt;p&gt;This is a small policy check after error 136. A synthetic check with no orders cannot prove a broker cause and cannot show that retries fail.&lt;/p&gt;

&lt;h2&gt;
  
  
  The forum thread
&lt;/h2&gt;

&lt;p&gt;A trader asked why 10 to 15 repeated OrderSend attempts still return error 136. See the &lt;a href="https://www.mql5.com/en/forum/189947" rel="noopener noreferrer"&gt;MQL5 forum&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;James said 10 to 15 attempts still returned the same error. His helper read the chart price for the passed pair. A reply said that mix uses the wrong price when symbols differ. James fixed that line, but he trades only the chart symbol now. So that fix does not explain his failures. Without per attempt symbol, prices, quote time and error, the cause stays open.&lt;/p&gt;

&lt;p&gt;Many EAs assume this. Repeating the request will eventually solve off quotes. My rule says the opposite. A new attempt needs a usable quote and a still-valid signal.&lt;/p&gt;

&lt;h2&gt;
  
  
  What my policy check did
&lt;/h2&gt;

&lt;p&gt;I ran a native check in MT4 4.0.0.1491. It compiled with zero errors and zero warnings. It ran in the Strategy Tester on offline EURUSD H4 supplied history with fixed spread 20 points.&lt;/p&gt;

&lt;p&gt;Zero quote inputs returned NO_RETRY. Expired signal inputs returned NO_RETRY. Fresh inputs returned ELIGIBLE_ONCE, then NO_RETRY with alreadyConsidered at 1.&lt;/p&gt;

&lt;p&gt;Three chosen cases, not full coverage. The five second and one consideration limits are illustrative, not universal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;Bid&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;Ask&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;Bid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;NO_RETRY&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;quote_age_sec&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;quote_time&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;NO_RETRY&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;signal_expiry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;NO_RETRY&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;alreadyConsidered&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;NO_RETRY&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ELIGIBLE_ONCE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function does no waiting, no persistence, no network access, no orders and no duplicate checks. Your caller must keep its own count. Eligibility only allows one more review of all execution checks, never a trade by itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I check first
&lt;/h2&gt;

&lt;p&gt;I check the quote and the still-valid signal before considering another attempt. If the quote is missing or unusable, I stop. If the symbol is wrong, I stop. If the signal or count is spent, I stop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check your next result
&lt;/h2&gt;

&lt;p&gt;On your next off quotes result, write request symbol, Bid and Ask, quote time, signal expiry, captured error 136 and attempt count in one line. Missing or disordered prices mean no further review of that attempt.&lt;/p&gt;

&lt;p&gt;Confirm the price read uses the order symbol. Compare now with expiry and read your kept count. If any check fails, keep the record and wait for a fresh idea.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this check does not show
&lt;/h2&gt;

&lt;p&gt;Three chosen cases, zero order calls. Error 136 was not reproduced or fixed. No broker, execution or profit claim.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stratcorealpha.com/fix/mt4-error-136-off-quotes" rel="noopener noreferrer"&gt;Original website article with tester proof&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>mql4</category>
      <category>debugging</category>
      <category>programming</category>
    </item>
    <item>
      <title>MT4 OrderModify error 1: skip a stop update that changes nothing</title>
      <dc:creator>Arnold Holm</dc:creator>
      <pubDate>Wed, 28 Oct 2026 14:39:34 +0000</pubDate>
      <link>https://dev.to/stratcorealpha/mt4-ordermodify-error-1-skip-a-stop-update-that-changes-nothing-o2l</link>
      <guid>https://dev.to/stratcorealpha/mt4-ordermodify-error-1-skip-a-stop-update-that-changes-nothing-o2l</guid>
      <description>&lt;p&gt;Your trailing stop can skip an unchanged update: my native MT4 test returned error 1 for the same stop, then error 0 after a real change. If you see error 1 on every tick, check stored and requested values before you change code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5l2u851eem86p1d91v8n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5l2u851eem86p1d91v8n.png" alt="Native MT4 tester: same stop returns error 1, changed stop returns error 0 and stored stop matches. Zero account orders." width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What the error means
&lt;/h2&gt;

&lt;p&gt;A trader asked: "Why does OrderModify keep reporting error 1 when I change the stop value?" A follow-up asked if an unchanged stop would also block a take-profit change. Those are different requests.&lt;/p&gt;

&lt;p&gt;An unchanged intended request can be skipped before the call.&lt;/p&gt;

&lt;p&gt;I compare the complete intended change before calling OrderModify.&lt;/p&gt;

&lt;p&gt;The official MQL4 reference calls error 1 ERR_NO_RESULT. Passing unchanged values can produce it. It does not say every field must change. A new take profit can still matter while the stop stays put. Open price and expiration can change only for pending orders.&lt;/p&gt;

&lt;p&gt;I ran the unchanged-stop case in the native MT4 Strategy Tester on EURUSD H4. It opened one simulated BUY 0.10 at 1.2054 with stop 1.1934. It called OrderModify with the same open price, stop and target. It returned false with immediate error 1. It then moved the requested stop to 1.1944. That call returned true with immediate error 0, and a fresh selection read back 1.1944. The position closed inside the tester at 1.2034 with zero account orders.&lt;/p&gt;

&lt;p&gt;A trailing rule can print the same valid target on many ticks. The candle low can stay flat, or rounding to the symbol increment can erase a tiny move. Logging error 1 each time hides what matters: stored value, requested value, and whether they differ.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three checks before you edit
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Stored target already matches
&lt;/h3&gt;

&lt;p&gt;Read the order again and compare stored and intended values at symbol precision. Do not trust a rounded chart label.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stop-only test hides a target change
&lt;/h3&gt;

&lt;p&gt;Compare take profit too. An unchanged stop does not mean the whole request is unchanged. My native run covered only the stop path. Test a target-only change separately.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stale error looks current
&lt;/h3&gt;

&lt;p&gt;Check the return value. Clear the error before the call and read GetLastError right after a fail, before another call replaces it. Keep request and result together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compare both fields, then validate the rest
&lt;/h2&gt;

&lt;p&gt;The helper below expects valid prices on the symbol increment. Zero can mean no stop or target. A false result means do not call. It never means remove protection.&lt;/p&gt;

&lt;p&gt;Use the order symbol increment, select the right ticket, and keep the market open price. Then run your own distance, freeze, direction and account checks. A different price is not automatically an allowed price. The helper does not choose a stop, round a price, select an order or send a request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bool StopPairChanged(double currentSL,double currentTP,
                     double targetSL,double targetTP,double tickSize)
{
   if(!MathIsValidNumber(tickSize) || tickSize&amp;lt;=0) return false;
   if(!MathIsValidNumber(currentSL) || !MathIsValidNumber(currentTP) ||
      !MathIsValidNumber(targetSL) || !MathIsValidNumber(targetTP)) return false;
   return MathAbs(currentSL-targetSL)&amp;gt;tickSize*0.5 ||
          MathAbs(currentTP-targetTP)&amp;gt;tickSize*0.5;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The picture shows the real tester run. Its single-price check uses Point for this supplied EURUSD dataset. The two-field helper is for review only. It did not run in that test case. Do not read the picture as a test of every helper branch.&lt;/p&gt;

&lt;h2&gt;
  
  
  How you know it is fixed
&lt;/h2&gt;

&lt;p&gt;Unchanged call must return false with immediate error 1, then skip. Changed call must return true with immediate error 0, and a fresh selection must show 1.1944.&lt;/p&gt;

&lt;h3&gt;
  
  
  Your five-minute source check
&lt;/h3&gt;

&lt;p&gt;Find OrderModify in your trailing branch. Print the selected ticket, current stop and target, intended stop and target, symbol increment and immediate result. Check that a target-only update is not lost behind a stop-only equality test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does error 1 mean the trailing stop is broken?
&lt;/h3&gt;

&lt;p&gt;It can mean that this call requested no change. Inspect the current and intended values before changing your trading logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Must both stop loss and take profit change?
&lt;/h3&gt;

&lt;p&gt;No. One genuine parameter change can make the request meaningful. The unchanged-value condition concerns the request as a whole.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does a true comparison guarantee a successful modification?
&lt;/h3&gt;

&lt;p&gt;No. Stop distances, freeze rules, order state and server conditions still matter. Check the actual function result and stored order values.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.mql5.com/en/forum/152744" rel="noopener noreferrer"&gt;Original OrderModify error 1 question with stop and target follow-up&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stratcorealpha.com/fix/mt4-ordermodify-error-1" rel="noopener noreferrer"&gt;Original article and free EA check&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Native MT4 offline/default tester test case on supplied EURUSD H4 history, fixed 20-point spread, zero account orders sent. No broker acceptance, live execution or strategy performance is established.&lt;/p&gt;

</description>
      <category>trading</category>
      <category>mql4</category>
      <category>debugging</category>
      <category>programming</category>
    </item>
    <item>
      <title>A 100 USD counter example: when your reset starts an hour too early</title>
      <dc:creator>Arnold Holm</dc:creator>
      <pubDate>Tue, 27 Oct 2026 11:58:44 +0000</pubDate>
      <link>https://dev.to/stratcorealpha/a-100-usd-counter-example-when-your-reset-starts-an-hour-too-early-2lp5</link>
      <guid>https://dev.to/stratcorealpha/a-100-usd-counter-example-when-your-reset-starts-an-hour-too-early-2lp5</guid>
      <description>&lt;p&gt;On 25 October, a hardcoded 22:00 UTC reset could have erased a hypothetical 100 USD daily loss from your counter one hour early. That code would have started the next rule day one hour early on 25 October 2026.&lt;/p&gt;

&lt;p&gt;Eight original offline clock checks from 25 October 2026 passed. This is a clock check about rule dates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the written reset rule
&lt;/h2&gt;

&lt;p&gt;The question is simple. How is the limit calculated? The &lt;a href="https://academy.ftmo.com/lesson/maximum-daily-loss/" rel="noopener noreferrer"&gt;FTMO Academy lesson&lt;/a&gt; discusses that question. The &lt;a href="https://ftmo.com/en/trading-objectives/" rel="noopener noreferrer"&gt;current trading objectives&lt;/a&gt; describe a recalculation at midnight, 00:00 CE(S)T. CE(S)T means Central European time with its summer change. I use the IANA timezone Europe/Prague for the mappings below. A named timezone carries the change between UTC plus two hours in summer and UTC plus one hour in winter. A fixed offset misses that change.&lt;/p&gt;

&lt;p&gt;The local rule date matters. It is not always the date on a broker server, your laptop or an unlabelled UTC log.&lt;/p&gt;

&lt;p&gt;Many counters rest on one idea. A daily reset always happens at the same UTC hour. On 25 October the same local midnight maps to a different UTC hour. That shift is the point of this example.&lt;/p&gt;

&lt;h2&gt;
  
  
  The disputed half hour
&lt;/h2&gt;

&lt;p&gt;At 22:30 UTC on 25 October 2026, the Prague clock read 23:30 with an offset of plus one hour. That was still 25 October. A program that changed its daily counter at 22:00 UTC had already moved to 26 October 2026. It was thirty minutes before the correct local boundary.&lt;/p&gt;

&lt;p&gt;In the hypothetical 100 USD example, that program would show a fresh daily counter while the written rule still belonged to the old day. The loss stayed live under the challenge rule. The program had started the next day too soon.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8biyt7o0gzzw5rc8tru6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8biyt7o0gzzw5rc8tru6.png" alt="Three exact UTC-to-Prague mappings from the offline clock checks" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These are three of the saved timestamp cases.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;24 October, 22:00 UTC becomes 25 October, 00:00 at UTC+02.&lt;/li&gt;
&lt;li&gt;25 October, 22:30 UTC becomes 25 October, 23:30 at UTC+01.&lt;/li&gt;
&lt;li&gt;25 October, 23:00 UTC becomes 26 October, 00:00 at UTC+01.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The saved set holds seven timestamp cases plus one check for the elapsed time between those local midnights. That local day lasted 25 hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a 24-hour timer gives the wrong answer
&lt;/h2&gt;

&lt;p&gt;A common shortcut is to save the prior reset and add 24 hours. Another is to hardcode 22:00 UTC because that matched the prior summer midnight. Both hide the same idea. They assume the UTC span between local midnights never changes.&lt;/p&gt;

&lt;p&gt;On 25 October 2026 it changed. The next Prague midnight was at 23:00 UTC. I would calculate the next midnight in the written rule timezone first, then convert that instant to UTC for storage and comparison. I would not silently rename an uncertain server timestamp as UTC.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check your counter before you rely on it
&lt;/h2&gt;

&lt;p&gt;Use these four steps. They take about five minutes.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find the timezone and reset wording for your exact challenge product.&lt;/li&gt;
&lt;li&gt;Convert the next local midnight to UTC with a timezone database that includes daylight saving rules.&lt;/li&gt;
&lt;li&gt;Compare that instant with the firm's dashboard countdown. If they disagree, fix the rule or timestamp source before you trust the local counter.&lt;/li&gt;
&lt;li&gt;Test one instant just before the boundary and one exactly on it. The first must keep the old local date. The second must start the new one.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For this example, 25 October 2026 at 22:59:59 UTC was still the old rule day. At 23:00:00 UTC, the Prague date changed to 26 October 2026. That one-second boundary in a repeatable clock check tells you more than a glance at a clock face.&lt;/p&gt;

&lt;p&gt;Your own check is the next reset instant and the dashboard countdown. The optional &lt;a href="https://stratcorealpha.com/rule-guard?ref=devto" rel="noopener noreferrer"&gt;free Pre-Check&lt;/a&gt;, the free Prop Rule Guard, can help organise the written rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this check does not show
&lt;/h2&gt;

&lt;p&gt;This clock check from 25 October 2026 shows these mappings only. It does not show breach detection, broker server mapping, live fills or profit. It does not set a loss percent shared by every challenge. It does not show remaining loss allowance under a limit, which also needs exact equity, the account value including open trades, plus open positions, fees and product rules. Check the rule text for your exact product.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stratcorealpha.com/guides/challenge-reset-dst-utc-2026-10-25.html" rel="noopener noreferrer"&gt;Original website article with clock proof&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>trading</category>
      <category>python</category>
      <category>programming</category>
      <category>fintech</category>
    </item>
    <item>
      <title>MT4 error 4107: log the exact price before changing it</title>
      <dc:creator>Arnold Holm</dc:creator>
      <pubDate>Mon, 26 Oct 2026 11:35:11 +0000</pubDate>
      <link>https://dev.to/stratcorealpha/mt4-error-4107-log-the-exact-price-before-changing-it-b1j</link>
      <guid>https://dev.to/stratcorealpha/mt4-error-4107-log-the-exact-price-before-changing-it-b1j</guid>
      <description>&lt;p&gt;Your entry can look valid and still fail. My MT4 test returned error 4107 for an over-precise entry, then accepted current Ask.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkh89tfiq7ktzbgvharol.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkh89tfiq7ktzbgvharol.png" alt="Native MT4 tester: fractional-point entry fails with 4107, current Ask succeeds and stored entry matches. Zero account orders." width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What the error means
&lt;/h2&gt;

&lt;p&gt;A trader testing XAUUSD reported an invalid price of 2347.42500000. The number looked close to the market. The trader had checked for negative inputs and tried normalization, but the error remained. Without the source and symbol settings, that report does not establish which argument was wrong. A plausible-looking number is not enough to diagnose an OrderSend call.&lt;/p&gt;

&lt;p&gt;I start by keeping three things together: the exact request, the function return value, and the error captured immediately after the call. The request includes entry, stop loss and take profit. Looking only at the entry price can miss a problem in a calculated stop or target. Printing fewer decimal places can also hide the input that the function actually received.&lt;/p&gt;

&lt;p&gt;The official MQL4 error table lists 4107 as ERR_INVALID_PRICE_PARAM. It separately lists 129 as ERR_INVALID_PRICE and 130 as ERR_INVALID_STOPS. Those numbers should not be swapped in a log or folded into one guessed explanation. The OrderSend reference describes price-thread and precision conditions for 129, and stop-distance conditions for 130. Record the number that your own terminal returned.&lt;/p&gt;

&lt;p&gt;I built a small native MT4 Strategy Tester test case to isolate an over-precise entry. On supplied EURUSD H4 history, it first submitted a simulated BUY at Ask plus 0.1234567 of one point. The deliberately altered price returned ticket -1 and error 4107. The next simulated BUY used the current Ask without that extra fraction. It returned a positive ticket and error 0. A fresh order selection confirmed that the stored entry matched Ask within half a point.&lt;/p&gt;

&lt;p&gt;The simulated position was then closed inside the tester. No order went to an account. The screenshot is the actual tester output from this run, not a mock trading result. The test case uses one EURUSD dataset and a fixed 20-point spread. It does not reproduce the trader's XAUUSD setup, inspect that person's source, or establish a universal rounding rule for gold.&lt;/p&gt;

&lt;p&gt;I diagnose the exact request before adding another retry. A retry with the same invalid input adds no new information. A retry after silently rounding a pending entry can change the trading rule. Keep the original value in the record, identify the field that fails validation, and decide whether a corrected candidate still satisfies the intended rule.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three code paths to check
&lt;/h2&gt;

&lt;h3&gt;
  
  
  An entry calculation adds unsupported precision
&lt;/h3&gt;

&lt;p&gt;In the native test case, adding a fractional point to Ask was enough to produce 4107. For a market BUY, use the current Ask for the actual order symbol. For a market SELL, use current Bid. A calculated pending entry has a different validation path and must retain the intended distance and direction after alignment.&lt;/p&gt;

&lt;h3&gt;
  
  
  A calculated stop or target is the bad input
&lt;/h3&gt;

&lt;p&gt;Record stop loss and take profit alongside the entry. Check that every nonzero value is finite, has the intended sign and sits on the permitted price increment. Zero can mean no stop or target. Do not reject zero indiscriminately or silently replace a requested protective stop with zero.&lt;/p&gt;

&lt;h3&gt;
  
  
  Decimal formatting is mistaken for a valid price grid
&lt;/h3&gt;

&lt;p&gt;Digits controls decimal precision. A symbol can also have a tradable price increment that needs separate handling. Rounding to a number of decimal places does not by itself prove that a calculated price is on that grid. Read the symbol specifications and keep point, tick increment and pip conventions distinct.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep the failing input and immediate error in one record
&lt;/h2&gt;

&lt;p&gt;The excerpt is deliberately invalid and belongs only in a tester. Its purpose is to show the input that caused this local failure. It is not an EA entry routine. The full test case refuses to initialize outside IsTesting, checks the successful order by ticket, reads back its open price, closes the simulated position and requires every expected result before printing PASS.&lt;/p&gt;

&lt;p&gt;The change in this test case was to stop altering a valid terminal quote. It was not a general instruction to round every value. For a real EA, first select the correct symbol and request type. Read fresh prices for that symbol. Validate calculated pending prices and stops against their own requirements. If alignment moves a level, check that the resulting request still represents the rule you intended to trade.&lt;/p&gt;

&lt;p&gt;ResetLastError before the attempt and capture GetLastError immediately afterward. Other calls can change the saved error. Treat a failed ticket as a failed attempt, not as an open position. If the request is accepted, select the returned ticket and read the stored values. That gives you evidence of what happened instead of relying on a success message alone.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Native tester test case only. OnInit rejects !IsTesting().
double badPrice = Ask + Point * 0.1234567;
ResetLastError();
int ticket = OrderSend(Symbol(), OP_BUY, 0.1, badPrice,
                       10, 0, 0, "FIX26 invalid", 260026, 0, clrNONE);
int error = GetLastError();
// Observed in this test case: ticket = -1, error = 4107.
// A separate call using current Ask returned a positive ticket and error 0.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Native MT4 offline tester, supplied EURUSD H4 history, 3 May 2021, fixed 20-point spread. One invalid entry and one accepted simulated entry. No XAUUSD diagnosis, broker execution, latency or strategy performance claim.&lt;/p&gt;

&lt;h2&gt;
  
  
  How you know it is fixed
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Negative case: preserve the deliberately invalid input
&lt;/h3&gt;

&lt;p&gt;Run the supplied test case only in the Strategy Tester. Its fractional-point entry must fail with ticket -1 and captured error 4107 in the documented environment. An unexpected result is a failed test, not permission to change the expected number.&lt;/p&gt;

&lt;h3&gt;
  
  
  Positive case: read back the accepted simulated entry
&lt;/h3&gt;

&lt;p&gt;The current-Ask call must return a positive ticket and error 0. Select that ticket again and compare its stored entry with the requested Ask. Close the simulated position and keep the complete result log.&lt;/p&gt;

&lt;h3&gt;
  
  
  Your five-minute source check
&lt;/h3&gt;

&lt;p&gt;Find the failing OrderSend. Print its symbol, operation, entry, stop, target, Digits, Point, symbol price increment, Bid and Ask. Keep enough precision to expose the actual arguments. Check all three price fields before changing rounding or retry behaviour.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does 4107 prove that my broker rejected the order?
&lt;/h3&gt;

&lt;p&gt;The number alone does not establish a broker-side rejection. Keep the exact request and local return value. This offline test case reproduced 4107 without sending any account order.&lt;/p&gt;

&lt;h3&gt;
  
  
  Will NormalizeDouble fix every invalid-price report?
&lt;/h3&gt;

&lt;p&gt;No. Decimal precision, the symbol price increment, request direction and stop distances are separate checks. The right correction depends on the actual failing field and intended rule.&lt;/p&gt;

&lt;h3&gt;
  
  
  Did this test solve the original XAUUSD report?
&lt;/h3&gt;

&lt;p&gt;No. The original report did not include enough source and symbol details. This is an independently reproduced EURUSD precision failure with an explicit before-and-after check.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.mql5.com/en/forum/467796" rel="noopener noreferrer"&gt;Original XAUUSD invalid-price question, unresolved source details&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.mql4.com/constants/errorswarnings/errorcodes" rel="noopener noreferrer"&gt;Official MQL4 runtime error codes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.mql4.com/trading/ordersend" rel="noopener noreferrer"&gt;Official MQL4 OrderSend parameters and return values&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stratcorealpha.com/fix/mt4-error-4107-invalid-price-parameter" rel="noopener noreferrer"&gt;Original article and free EA check&lt;/a&gt;&lt;/p&gt;

</description>
      <category>trading</category>
      <category>programming</category>
      <category>debugging</category>
    </item>
    <item>
      <title>Alpaca partial fills: count 7 shares, not 10</title>
      <dc:creator>Arnold Holm</dc:creator>
      <pubDate>Sat, 24 Oct 2026 14:41:25 +0000</pubDate>
      <link>https://dev.to/stratcorealpha/alpaca-partial-fills-do-not-add-3-and-7-188g</link>
      <guid>https://dev.to/stratcorealpha/alpaca-partial-fills-do-not-add-3-and-7-188g</guid>
      <description>&lt;p&gt;Your bot should count 7 filled shares after totals of 3 and 7, not 10. In my small local check, adding both totals overstated the order by three shares. That is enough to give you the wrong view of how much of an order remains open.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://dev.to/sergei_b/a-good-price-is-not-yet-a-trade-1mab"&gt;A Good Price Is Not Yet a Trade&lt;/a&gt;, Sergei B asks: "Which orders went into the count?" His post separates orders with some filled volume from orders with none. That distinction also matters when you read a bot's filled quantity. A good fill price says little if the quantity beside it has been counted twice.&lt;/p&gt;

&lt;p&gt;This example uses invented quantities. It does not use Sergei's trading records or claim to repeat his measurement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two messages do not mean two new trades
&lt;/h2&gt;

&lt;p&gt;Suppose you ask your bot to buy seven shares. The first message says three have filled. A later message says seven have filled in total. The later seven includes the first three. Only four more shares have filled between those messages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.alpaca.markets/us/docs/websocket-streaming" rel="noopener noreferrer"&gt;Alpaca's trade-update documentation&lt;/a&gt; distinguishes the quantity of an individual execution, &lt;code&gt;qty&lt;/code&gt;, from the order's total filled quantity, &lt;code&gt;filled_qty&lt;/code&gt;. Check which field your bot stores before changing the calculation. Adding new executions and reading order totals are different ways to answer the same narrow quantity question.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Message&lt;/th&gt;
&lt;th&gt;Shares in this execution&lt;/th&gt;
&lt;th&gt;Total shares filled for the order&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;First partial fill&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Final fill&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You can add the two distinct executions: three plus four makes seven. Or you can read the latest authoritative order total: seven. Adding the two order totals gives ten, which counts the first three twice.&lt;/p&gt;

&lt;p&gt;I keep an order's running filled quantity separate from each individual execution. I would stop on an unexplained lower total rather than quietly change the number shown to the trader.&lt;/p&gt;

&lt;h2&gt;
  
  
  What my local check found
&lt;/h2&gt;

&lt;p&gt;I ran six checks with invented inputs. The first sequence reported three, then seven, and kept seven as the order total. Repeating seven added zero. A second order kept its own quantity. A lower total, a negative quantity and a non-number each stopped the calculation without changing the first order's seven shares.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2x30rekzygngla7g7u3u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2x30rekzygngla7g7u3u.png" alt="Actual local check: seven shares counted correctly; adding the two reported totals gives ten. Six checks passed." width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The picture comes from the output of that local run. The bar marked ten shows the incorrect addition of the two reported totals. It is not an order sent to a broker. You can reproduce the core calculation with Python's standard library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;decimal&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Decimal&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Reconcile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;observe_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;totals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filled_qty&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Decimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filled_qty&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_finite&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;Reconcile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;invalid filled quantity&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;previous&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;totals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Decimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;previous&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;Reconcile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lower total: reconcile before changing state&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;totals&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;previous&lt;/span&gt;

&lt;span class="n"&gt;totals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;observe_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;totals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;order-A&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;observe_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;totals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;order-A&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;7&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;observe_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;totals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;order-A&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;7&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;totals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;order-A&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Check one order in your own history
&lt;/h2&gt;

&lt;p&gt;Compare one order's latest filled total with the sum of its distinct executions, keeping the order identifier the same. Do this on exported history or demo data before changing a running bot. Keep the message order and any execution identifiers with the values, so a repeated message cannot look like a new trade.&lt;/p&gt;

&lt;p&gt;Also compare the filled amount with what you originally requested. Seven filled shares out of a seven-share request leaves none open in this example. Three filled out of seven leaves four. Do not mark the whole requested quantity as completed just because one part filled at a good price.&lt;/p&gt;

&lt;p&gt;If a later message shows six after seven, investigate. It may be old information, a correction or a mapping mistake. This short check cannot choose between those explanations. Keeping the larger value forever would hide a real correction; trusting whichever message arrives last would hide a delayed one.&lt;/p&gt;

&lt;p&gt;This is a check of one order's quantities, not your account's position or a trading result. The code has no lasting storage, reconnect handling or full account comparison, and restarting it loses the dictionary. The six local checks do not establish that a live bot is ready.&lt;/p&gt;

&lt;p&gt;If your bot's order history disagrees with its dashboard, the &lt;a href="https://stratcorealpha.com/bot-fix?ref=devto" rel="noopener noreferrer"&gt;bot repair page&lt;/a&gt; gives you a place to describe the expected and actual behaviour. Keep account identifiers and access details out of public comments.&lt;/p&gt;

</description>
      <category>python</category>
      <category>debugging</category>
      <category>trading</category>
      <category>algotrading</category>
    </item>
    <item>
      <title>MT5 error 10004: a requote is not a reason to retry forever</title>
      <dc:creator>Arnold Holm</dc:creator>
      <pubDate>Fri, 23 Oct 2026 07:59:07 +0000</pubDate>
      <link>https://dev.to/stratcorealpha/mt5-error-10004-a-requote-is-not-a-reason-to-retry-forever-5275</link>
      <guid>https://dev.to/stratcorealpha/mt5-error-10004-a-requote-is-not-a-reason-to-retry-forever-5275</guid>
      <description>&lt;p&gt;Your EA needs a stop condition after a requote. My policy example compiled with 0 errors; it sends no orders and proves no broker-side repair.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxirq5iej8cwq0zzwspae.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxirq5iej8cwq0zzwspae.png" alt="Native compiler result: 0 errors and 0 warnings. Compile-only. No script execution or broker request." width="799" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What the error means
&lt;/h2&gt;

&lt;p&gt;A trader asked why a USDJPY buy request returned 10004 when the requested price and the server ask differed by only 0.001. That price difference alone does not establish the cause. The official MT5 server-return table names 10004 as TRADE_RETCODE_REQUOTE. Keep that server result alongside the exact request and quote instead of treating every rejected request as the same error.&lt;/p&gt;

&lt;p&gt;A requote does not mean a position was opened. The table gives other codes for an order placed, a request completed and a request partly completed. The next decision depends on the actual result and account state. Do not let a generic retry branch treat those outcomes as interchangeable.&lt;/p&gt;

&lt;p&gt;I separate receiving a requote from deciding whether an entry is still worth considering. A new quote can make an old signal stale or put the spread and price outside its limits. A loop that keeps resending until something succeeds can enter long after the original conditions disappeared.&lt;/p&gt;

&lt;p&gt;The helper below only answers a local policy question: may this requote be reconsidered under the caller's stated limits? It rejects other return codes, an invalid signal, an exhausted attempt budget, an old quote, an invalid or excessive spread, and a price outside the allowed limit. A true result is permission to inspect the situation again. It is not permission to submit a trade blindly. The caller must supply current values and still check its order and position state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three code paths to check
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The request and its server result were not preserved together.
&lt;/h3&gt;

&lt;p&gt;Keep the requested price, bid, ask, execution mode, deviation, timestamps and full MqlTradeResult. A screenshot of one price difference cannot explain the whole request.&lt;/p&gt;

&lt;h3&gt;
  
  
  The retry branch ignores the original entry conditions.
&lt;/h3&gt;

&lt;p&gt;Recheck the signal, quote age, spread and price limit before considering another request. Stop once the retry budget is used.&lt;/p&gt;

&lt;h3&gt;
  
  
  Several trade outcomes share one generic error branch.
&lt;/h3&gt;

&lt;p&gt;Keep a requote separate from placed, completed and partly completed outcomes. Check orders and positions before any new submission to avoid duplicate intent.&lt;/p&gt;

&lt;h2&gt;
  
  
  A bounded local policy, with no order submission
&lt;/h2&gt;

&lt;p&gt;I compiled RequotePolicy.mq5 with native MetaEditor on 23 October 2026. The compiler reported 0 errors and 0 warnings. The image renders that actual compiler result. Its OnStart only prints a label; it does not call this helper. I did not execute the script.&lt;/p&gt;

&lt;p&gt;The limits are explicit inputs, not recommended trading settings. Quote age is supplied in milliseconds and spread in points. The caller is responsible for measuring them correctly and keeping attempt counts current. This example does not obtain quotes, change deviation or filling mode, wait for a new event, inspect positions, or retry an order.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bool MayReconsider(const uint retcode,const bool signal_valid,
                  const int attempts,const int max_attempts,
                  const long quote_age_ms,const long max_age_ms,
                  const double spread_points,const double max_spread_points,
                  const bool inside_price_limit)
{
 if(retcode!=TRADE_RETCODE_REQUOTE || !signal_valid) return false;
 if(max_attempts&amp;lt;=0 || attempts&amp;lt;0 || attempts&amp;gt;=max_attempts) return false;
 if(max_age_ms&amp;lt;0 || quote_age_ms&amp;lt;0 || quote_age_ms&amp;gt;max_age_ms) return false;
 if(!MathIsValidNumber(spread_points) || !MathIsValidNumber(max_spread_points)) return false;
 if(spread_points&amp;lt;0 || max_spread_points&amp;lt;0 || spread_points&amp;gt;max_spread_points) return false;
 return inside_price_limit;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compile-only proof. No runtime branch tests, reproduced server 10004, broker request, automatic retry or successful trade.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checks on your own source
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Keep the failed request intact
&lt;/h3&gt;

&lt;p&gt;Save the full request, result.retcode and result.comment, requested price, observed bid/ask, symbol execution mode and timestamp. Do not overwrite the first failure with the result of a later attempt.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test refusal before any order path
&lt;/h3&gt;

&lt;p&gt;On a separate demo test, cover a false signal, exhausted attempts, old quote, excessive spread and a price outside the limit. None may reach an order-send branch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Your five-minute source check
&lt;/h3&gt;

&lt;p&gt;Find the branch handling 10004. Trace its maximum attempts, its signal-validity check and the exact condition that prevents a new request. If one is missing, an automatic retry can outlive the original entry.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does increasing deviation always fix error 10004?
&lt;/h3&gt;

&lt;p&gt;No universal repair follows from this code alone. Preserve the actual request, execution mode and server result before changing a setting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does a true helper result mean I should send an order?
&lt;/h3&gt;

&lt;p&gt;No. It only passes this local policy. The caller still needs current inputs, order and position checks, and a separate submission decision.&lt;/p&gt;

&lt;h3&gt;
  
  
  Was a broker requote reproduced and fixed in this proof?
&lt;/h3&gt;

&lt;p&gt;No. Only compilation is evidenced. The script was not executed and no broker request was made.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.mql5.com/en/forum/444587" rel="noopener noreferrer"&gt;Original USDJPY requote question&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.mql5.com/en/docs/constants/errorswarnings/enum_trade_return_codes" rel="noopener noreferrer"&gt;Official MT5 trade server return codes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stratcorealpha.com/fix/mt5-error-10004-requote" rel="noopener noreferrer"&gt;Original article&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mql5</category>
      <category>metatrader</category>
      <category>debugging</category>
      <category>programming</category>
    </item>
    <item>
      <title>MQL5 error 4806: keep missing indicator data out of your signal</title>
      <dc:creator>Arnold Holm</dc:creator>
      <pubDate>Thu, 22 Oct 2026 07:35:19 +0000</pubDate>
      <link>https://dev.to/stratcorealpha/mql5-error-4806-keep-missing-indicator-data-out-of-your-signal-k30</link>
      <guid>https://dev.to/stratcorealpha/mql5-error-4806-keep-missing-indicator-data-out-of-your-signal-k30</guid>
      <description>&lt;p&gt;My guarded indicator reader compiled with 0 errors, but that proves no working signal on your account.&lt;/p&gt;

&lt;p&gt;A trader reported repeated 4806 failures while reading indicator values across multiple currency pairs. The official runtime table names 4806 as requested indicator data not found. That describes missing data at the call. It does not identify one universal repair for every program.&lt;/p&gt;

&lt;p&gt;I keep missing data out of the trading decision. For this small original example, the intended sample is one completed-bar value from buffer zero of an existing moving-average handle. The code first rejects an invalid handle or fewer than two calculated values. It then requests exactly one value starting at shift one. Only a complete copy with a finite, non-empty sample can update the caller's output.&lt;/p&gt;

&lt;p&gt;The readiness check is useful but does not guarantee that the next call succeeds. The copy result is checked again. A failed read leaves the caller's output untouched. The caller still has to respect the false result and skip its decision. Treating that untouched old output as a new signal would defeat the whole guard.&lt;/p&gt;

&lt;p&gt;These choices are specific to this example. A different indicator may expose a different buffer number, require a longer warm-up period or use different empty-value semantics. A multi-symbol program also needs to identify which handle and symbol failed. Keep a bounded retry on a later event rather than adding an endless loop that blocks the program. The compiled helper alone does not implement handle creation, retries or signal generation.&lt;/p&gt;

&lt;p&gt;A handle exists before the requested values are ready.&lt;br&gt;
Record the handle, calculated count, requested shift and count at the failure. A handle number alone is not evidence that a sample exists.&lt;/p&gt;

&lt;p&gt;The requested buffer does not match the indicator.&lt;br&gt;
Check the actual indicator interface. This example uses moving-average buffer zero. Do not apply that number blindly to a custom indicator.&lt;/p&gt;

&lt;p&gt;A failed copy was turned into an ordinary number.&lt;br&gt;
Check the returned copy count before reading the array. Keep a missing sample separate from a legitimate zero or a previous value.&lt;/p&gt;

&lt;p&gt;A one-value reader that refuses an incomplete copy&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;TryClosedMA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="n"&gt;INVALID_HANDLE&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;BarsCalculated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
 &lt;span class="n"&gt;ResetLastError&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CopyBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;MathIsValidNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="n"&gt;EMPTY_VALUE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I compiled BufferReader.mq5 with native MetaEditor on 22 October 2026. It produced zero errors and zero warnings. Its OnStart only prints a label and never calls TryClosedMA. I did not run the script. The image below renders the actual compiler result.&lt;/p&gt;

&lt;p&gt;This is a source-level example, not an observed cure for error 4806. There is no reproduced error-to-recovery sequence, indicator output, strategy run or broker request in this proof. Before using it, test the caller's false-result path and the chosen indicator's actual data behaviour on demo.&lt;/p&gt;

&lt;p&gt;Compile-only proof. No reproduced runtime 4806, indicator readiness check, retry sequence, strategy validation or order submission.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnw65svhmerd79xi4khvk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnw65svhmerd79xi4khvk.png" alt="Native MetaEditor compiler output: 0 errors and 0 warnings. Compile-only proof." width="800" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Preserve the failing request&lt;br&gt;
Record symbol, timeframe, indicator parameters, handle, buffer number, shift, count and the copy result. Reset the error before the call and capture it immediately after a failure.&lt;/p&gt;

&lt;p&gt;Test the no-data branch&lt;br&gt;
On demo, a missing sample must skip the trading decision. The previous output must not become a new signal merely because the read failed.&lt;/p&gt;

&lt;p&gt;Your five-minute source check&lt;br&gt;
Find the CopyBuffer call that failed. Compare its requested buffer, shift and count with the indicator interface, then find the branch that prevents use of an incomplete copy.&lt;/p&gt;

&lt;p&gt;Does BarsCalculated alone remove error 4806?&lt;br&gt;
No. The subsequent copy can still fail or return an incomplete sample. Check its result as well.&lt;/p&gt;

&lt;p&gt;Did this proof reproduce and repair a runtime error?&lt;br&gt;
No. It proves only that this original defensive reader compiles. A real indicator and caller still require runtime tests.&lt;/p&gt;

&lt;p&gt;Sources: &lt;a href="https://www.mql5.com/en/docs/series/copybuffer" rel="noopener noreferrer"&gt;CopyBuffer&lt;/a&gt;, &lt;a href="https://www.mql5.com/en/docs/series/barscalculated" rel="noopener noreferrer"&gt;BarsCalculated&lt;/a&gt;, &lt;a href="https://www.mql5.com/en/docs/constants/errorswarnings/errorcodes" rel="noopener noreferrer"&gt;runtime error codes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stratcorealpha.com/fix/mql5-error-4806-copybuffer-data-not-found" rel="noopener noreferrer"&gt;Original version with compiler proof&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>mql5</category>
      <category>trading</category>
      <category>programming</category>
      <category>debugging</category>
    </item>
    <item>
      <title>Why can your $100,000 challenge dashboard turn green with no data?</title>
      <dc:creator>Arnold Holm</dc:creator>
      <pubDate>Tue, 20 Oct 2026 21:04:07 +0000</pubDate>
      <link>https://dev.to/stratcorealpha/why-can-your-100000-challenge-dashboard-turn-green-with-no-data-57b9</link>
      <guid>https://dev.to/stratcorealpha/why-can-your-100000-challenge-dashboard-turn-green-with-no-data-57b9</guid>
      <description>&lt;p&gt;Your $100,000 example account can show unknown against a $2,000 daily loss limit: 7 invented checks kept missing data separate from a clean recorded path.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fii8ha9rghi3n6hoc01bn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fii8ha9rghi3n6hoc01bn.png" alt="Seven invented checks: gaps stay unknown and recorded crossings stay visible." width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two recorded equity values can sit above a challenge loss floor while the recording between them is missing. A green badge is too strong a conclusion. In these checks, an empty recording and a NaN both returned unknown, while a recorded crossing stayed a crossing even when another value was missing.&lt;/p&gt;

&lt;p&gt;This is a small Python check for a dashboard or exported journal. It does not determine whether a real account passed a firm's rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem is the label
&lt;/h2&gt;

&lt;p&gt;Suppose the fixed floor is 98,000. The first and last recorded values are both 100,000. If the middle value is absent, the data does not tell us whether the path crossed the floor.&lt;/p&gt;

&lt;p&gt;A developer might already handle that gap but still miss two other cases. An empty list can pass an &lt;code&gt;all(...)&lt;/code&gt; check. A NaN can make a numeric comparison false without raising an exception. Both can quietly end up with a reassuring label.&lt;/p&gt;

&lt;p&gt;There is also a precedence question. A recording of &lt;code&gt;100000 -&amp;gt; 97000 -&amp;gt; missing&lt;/code&gt; contains both a crossing and a gap. Returning only &lt;code&gt;unknown&lt;/code&gt; throws away the crossing we actually observed.&lt;/p&gt;

&lt;p&gt;I keep a recorded crossing visible even when the recording also has gaps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three states, with crossing checked first
&lt;/h2&gt;

&lt;p&gt;The accepted data is deliberately small: a list of numbers or &lt;code&gt;None&lt;/code&gt;, a fixed finite floor, and an inclusive boundary. A value equal to the floor counts as a crossing in this example. The function does not accept arbitrary strings or read an account. NaN means that a stored entry is not a valid number.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;isfinite&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;floor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;98_000&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="nf"&gt;isfinite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;floor&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;crossing recorded&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;isfinite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unknown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;no crossing in recorded values&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;cases&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;100_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;99_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100_000&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;no crossing in recorded values&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;100_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;97_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100_000&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;crossing recorded&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;100_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;98_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100_000&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;crossing recorded&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;100_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100_000&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unknown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;([],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unknown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;100_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nan&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;100_000&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unknown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;100_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;97_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;crossing recorded&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cases&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;7 synthetic checks passed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final label is intentionally narrow: &lt;strong&gt;no crossing in recorded values&lt;/strong&gt;. It does not say that nothing happened between samples. Adding more samples does not by itself prove continuous coverage either.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would show beside the badge
&lt;/h2&gt;

&lt;p&gt;A trader needs to know what the software saw. Beside the status, show the last recorded time, which recording period is covered, and whether there are known gaps. Keep the fixed-floor assumption visible. If a crossing exists, retain its recorded time and value even if collection later fails.&lt;/p&gt;

&lt;p&gt;The $2,000 loss limit in this invented example is measured from a starting value of $100,000. That produces the fixed $98,000 floor. A reading of $97,000 is $1,000 below that floor. This is a deliberately chosen test case, with a made-up rule, rather than a result from a trading account.&lt;/p&gt;

&lt;p&gt;For a real challenge, first map the firm's actual rule. Does it use balance or equity? Is the floor fixed or trailing? What happens at the daily reset, and which timezone defines it? Fees, open positions and the firm's own measurement feed can change the calculation. None of those rules is tested by this short program.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try this before trusting the colour
&lt;/h2&gt;

&lt;p&gt;Delete every value from a test export. Then replace one middle value with NaN. Finally put a known below-floor value before a missing value. Does the dashboard distinguish those three cases, or does it turn one of them green?&lt;/p&gt;

&lt;p&gt;This is one small check for the broader &lt;a href="https://www.reddit.com/r/proptrading/comments/1wi2xyn/how_do_you_know_your_ready_to_take_on_a_prop_firm/" rel="noopener noreferrer"&gt;question of challenge readiness&lt;/a&gt;. Seven invented cases test these labels and their precedence. They do not establish a profitable strategy, complete account history or a pass verdict.&lt;/p&gt;

&lt;p&gt;For a starting point on the account rules themselves, use the free &lt;a href="https://stratcorealpha.com/rule-guard?ref=devto-unknown-equity" rel="noopener noreferrer"&gt;Challenge Pre-Check&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>debugging</category>
      <category>algotrading</category>
      <category>fintech</category>
    </item>
    <item>
      <title>MQL array out of range: check 3 values before reading a buffer</title>
      <dc:creator>Arnold Holm</dc:creator>
      <pubDate>Mon, 19 Oct 2026 15:59:44 +0000</pubDate>
      <link>https://dev.to/stratcorealpha/mql-array-out-of-range-check-3-values-before-reading-a-buffer-52jh</link>
      <guid>https://dev.to/stratcorealpha/mql-array-out-of-range-check-3-values-before-reading-a-buffer-52jh</guid>
      <description>&lt;h1&gt;
  
  
  MQL array out of range: check 3 values before reading a buffer
&lt;/h1&gt;

&lt;p&gt;Your indicator cannot read a value that is absent from its array. My native MT5 run passed six array-read checks without executing an invalid read. I check the returned count and array size before reading an indicator value.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fprdy96p8owpyr5uevi9d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fprdy96p8owpyr5uevi9d.png" alt="Six fixed native MT5 checks passed; zero orders. Chart is terminal background." width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What the array error means
&lt;/h2&gt;

&lt;p&gt;An array holds a sequence of values. Its size tells you how many elements exist. With three elements, the valid indices are zero, one and two. Three is the size, but it is already outside the array. A loop that includes the size as its final index can therefore reach a value that does not exist.&lt;/p&gt;

&lt;p&gt;A forum author converting an MT4 indicator to MT5 reported an array error and posted code that copied indicator values and then read element zero. The posted code also attempted more buffer bindings than its declared buffer count. These are separate places to inspect. The discussion does not establish that a single guard repairs that whole indicator.&lt;/p&gt;

&lt;p&gt;For a copied indicator value, keep the return count from CopyBuffer. Requesting one element is an intention. The return value tells you how many elements were actually copied, or reports failure. An empty or failed result must stay out of the array access. An allocated array alone does not establish that its old values belong to the latest successful request.&lt;/p&gt;

&lt;p&gt;The helper below receives the actual array, the count from the current copy and the index you intend to read. It rejects a non-positive count, a negative index, an index at or beyond the copied count and an index at or beyond the physical array size. Only then does it read the element. Keep these inputs tied to the same operation. Passing a count from an earlier copy would change what this check means.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three places to inspect
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The copy result was ignored.
&lt;/h3&gt;

&lt;p&gt;Save the return count from the current CopyBuffer call. Keep zero and negative results out of the read. Record the handle, buffer and requested shift separately so the failed request can be investigated.&lt;/p&gt;

&lt;h3&gt;
  
  
  The loop reached the size itself.
&lt;/h3&gt;

&lt;p&gt;For a three-element ordinary array, the final valid index is two. Check the upper bound before entering the read. Also check a lower bound when an offset subtracts from the loop index.&lt;/p&gt;

&lt;h3&gt;
  
  
  The buffer setup was assumed to succeed.
&lt;/h3&gt;

&lt;p&gt;Keep the declared buffer count, binding indices and SetIndexBuffer return values together. Read direction and which candle a position refers to need their own checks after the binding. The guard here checks bounds, not trading meaning.&lt;/p&gt;

&lt;h2&gt;
  
  
  The local bounds guard
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bool SafeRead(const double &amp;amp;values[],int copied,int index,double &amp;amp;out)
{
   if(copied&amp;lt;=0 || index&amp;lt;0 || index&amp;gt;=copied || index&amp;gt;=ArraySize(values)) return false;
   out=values[index];
   return true;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Six fixed cases in native MT5
&lt;/h2&gt;

&lt;p&gt;I compiled and ran my original read-only script in an isolated MT5 terminal on 19 October 2026. The empty-array input was blocked. A negative index was blocked. The last valid index in a three-value array returned 30. An index equal to the size was blocked. An index outside a shorter copied count was blocked even though the array itself was larger. A negative copy-result input was blocked.&lt;/p&gt;

&lt;p&gt;All six comparisons passed. The runtime log and screenshot retain those outcomes. No invalid element was deliberately accessed. The value 30 is a fixed input used to check the helper, rather than a market price or trading result. The chart behind the text is terminal background.&lt;/p&gt;

&lt;p&gt;This is a small boundary you can test before investigating the rest of an indicator. In your own program, preserve the original input and error line first. A bounds check should stop the unavailable read; it should not quietly turn missing data into an entry signal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check your own error line
&lt;/h2&gt;

&lt;p&gt;Find the array access named by your Journal error. Log its requested index, actual array size and copy return count before that line.&lt;/p&gt;

&lt;p&gt;Six fixed local inputs, zero orders and no real CopyBuffer call; no third-party indicator repaired, candle order established or live feed tested.&lt;/p&gt;

&lt;p&gt;DEMO0: send the problem and try a free compiled demo first. R49: one authorised, reproducible MT4/MT5 defect in readable source up to 500 lines, with three agreed cases. 49 USD fixed. Delivery within 48 hours after source review and funding.&lt;/p&gt;

&lt;p&gt;Native runtime log: &lt;a href="https://stratcorealpha.com/proof/fix/FIX-20-runtime.txt" rel="noopener noreferrer"&gt;https://stratcorealpha.com/proof/fix/FIX-20-runtime.txt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Original page: &lt;a href="https://stratcorealpha.com/fix/mql-array-out-of-range" rel="noopener noreferrer"&gt;https://stratcorealpha.com/fix/mql-array-out-of-range&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Send your rule sheet or trading program for the &lt;a href="https://stratcorealpha.com/challenge-check?ref=devto" rel="noopener noreferrer"&gt;free Challenge Pre-Check&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>mql5</category>
      <category>debugging</category>
      <category>testing</category>
      <category>algotrading</category>
    </item>
    <item>
      <title>MT5 filling flags are not your order filling policy</title>
      <dc:creator>Arnold Holm</dc:creator>
      <pubDate>Sun, 18 Oct 2026 13:38:13 +0000</pubDate>
      <link>https://dev.to/stratcorealpha/mt5-filling-flags-are-not-your-order-filling-policy-4712</link>
      <guid>https://dev.to/stratcorealpha/mt5-filling-flags-are-not-your-order-filling-policy-4712</guid>
      <description>&lt;p&gt;Your EA can put the wrong filling policy into a perfectly valid integer. My MT5 run passed 6 local filling-value checks and sent zero orders. The useful detail was a collision: the symbol capability flags were 3, and ORDER_FILLING_BOC was also 3. Those equal numbers describe different things.&lt;/p&gt;

&lt;p&gt;A trader's original error report showed a large negative filling value beside an invalid-request result. The author later reported success after explicitly choosing IOC. That gives us a concrete debugging question: where did the value come from before the request was sent? Copying the final setting into another bot skips that question.&lt;/p&gt;

&lt;h2&gt;
  
  
  The conversion I would look for first
&lt;/h2&gt;

&lt;p&gt;This is the tempting assignment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;request.type_filling =
    (ENUM_ORDER_TYPE_FILLING)SymbolInfoInteger(symbol, SYMBOL_FILLING_MODE);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It compiles because an explicit cast permits the conversion. But SYMBOL_FILLING_MODE describes capabilities through flags. The request field expects one named policy. A cast changes the type the compiler sees. It has not translated a set of capabilities into a permitted policy for this order.&lt;/p&gt;

&lt;p&gt;In my native run, the symbol flags were 3. The named order values were FOK 0, IOC 1, RETURN 2 and BOC 3. A raw cast would therefore make that particular capability mask look like BOC. BOC is a passive filling policy, with its own order-type and symbol conditions. A market order has not become eligible for it because both values print as 3.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate integer validity from permission
&lt;/h2&gt;

&lt;p&gt;I wrote and ran this small guard before considering policy selection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;string FillingState(long raw)
{
   if(raw==(long)ORDER_FILLING_FOK || raw==(long)ORDER_FILLING_IOC ||
      raw==(long)ORDER_FILLING_RETURN || raw==(long)ORDER_FILLING_BOC)
      return "KNOWN_ENUM_CHECK_CONTEXT";
   return "INVALID_ENUM_NO_REQUEST";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output deliberately has two meanings. A value outside the named constants stops here. A known constant still needs the execution mode, order type and symbol capabilities checked. I keep those states separate because a boolean named ValidFilling can quietly grow into permission to send.&lt;/p&gt;

&lt;p&gt;Two inputs, -370154256 and 999, returned INVALID_ENUM_NO_REQUEST. Each of the four named constants returned KNOWN_ENUM_CHECK_CONTEXT. All six comparisons passed in MT5 build 6230. The program also read the current EURUSD symbol capabilities and execution mode separately, so the log preserved the numbers that could otherwise get mixed together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check the caller as well as the helper
&lt;/h2&gt;

&lt;p&gt;A useful early guard can still be defeated by its caller. Search for every assignment to type_filling, rather than inspecting only the last line before OrderSend. Check whether a structure was initialised, whether a helper overwrote the value, and whether a default branch reuses a stale request.&lt;/p&gt;

&lt;p&gt;Then follow the known-enum path. The official filling-policy table matters here. RETURN is unavailable for Market Execution. BOC has its own supported order types. Knowing a constant exists says nothing about whether this particular request should use it. I do not choose IOC simply because it fixed another trader's example.&lt;/p&gt;

&lt;p&gt;My five-minute check is this: open one failed request log and write down its symbol, order type, type_filling, symbol flags, execution mode and actual returned code. Trace where type_filling was assigned. If a raw mask was cast directly into it, separate the capability read from the named choice before another test.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.mql5.com/en/forum/381657" rel="noopener noreferrer"&gt;original question&lt;/a&gt;, &lt;a href="https://www.mql5.com/en/docs/constants/tradingconstants/orderproperties#enum_order_type_filling" rel="noopener noreferrer"&gt;official policy table&lt;/a&gt; and &lt;a href="https://stratcorealpha.com/proof/fix/FIX-17-runtime.txt" rel="noopener noreferrer"&gt;native output&lt;/a&gt; let you check the example. The screenshot below shows the actual local run.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo9prsnx1zsekrpc3g4el.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo9prsnx1zsekrpc3g4el.png" alt="Native MT5 output showing six local checks, separate flags and enum values, and zero orders" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have a small reproducible trading-bot defect, the &lt;a href="https://stratcorealpha.com/developers?ref=devto" rel="noopener noreferrer"&gt;free bug check&lt;/a&gt; is a way to start with the failing case.&lt;/p&gt;

&lt;p&gt;This run checked local integer handling, sent no requests and did not reproduce server error 10013 or validate a complete order.&lt;/p&gt;

</description>
      <category>mql5</category>
      <category>debugging</category>
      <category>tutorial</category>
      <category>algotrading</category>
    </item>
    <item>
      <title>MT5 return code 10006: keep the result before retrying</title>
      <dc:creator>Arnold Holm</dc:creator>
      <pubDate>Sat, 17 Oct 2026 14:00:29 +0000</pubDate>
      <link>https://dev.to/stratcorealpha/mt5-return-code-10006-keep-the-result-before-retrying-1g0d</link>
      <guid>https://dev.to/stratcorealpha/mt5-return-code-10006-keep-the-result-before-retrying-1g0d</guid>
      <description>&lt;p&gt;Your bot can receive a result without a fill. My MT5 run passed 3 synthetic return-code checks and sent zero orders. I keep rejection, placement and completion separate before considering another request.&lt;/p&gt;

&lt;p&gt;A trader asked &lt;a href="https://www.mql5.com/en/forum/429496" rel="noopener noreferrer"&gt;how to check a failed Python order and send it again&lt;/a&gt;. The thread reported return code 10006. The journal did not give the trader a useful cause. The request included a market order, stop loss and take profit.&lt;/p&gt;

&lt;p&gt;The useful next step is to retain the request and returned result together. An error number alone cannot tell you whether changing a price, stop distance or filling mode addresses this particular failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before: one label hides three states
&lt;/h2&gt;

&lt;p&gt;This reduced logging pattern loses the distinction a retry decision needs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Print("order result received");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Receiving a result and filling a trade are different events. A log that collapses them leaves the next attempt without a clear starting state.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.mql5.com/en/docs/python_metatrader5/mt5ordersend_py" rel="noopener noreferrer"&gt;official Python order_send reference&lt;/a&gt; returns a trade-result structure. Its request field contains the submitted request. The example expands both structures with &lt;code&gt;_asdict()&lt;/code&gt;. Keep that detail rather than reducing the result to one short string.&lt;/p&gt;

&lt;h2&gt;
  
  
  After: preserve distinct local states
&lt;/h2&gt;

&lt;p&gt;I used this small original classifier in a native MT5 script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;string Classify(uint code) {
 if(code==TRADE_RETCODE_REJECT) return "REJECTED_REASON_UNKNOWN";
 if(code==TRADE_RETCODE_DONE) return "COMPLETED_RECONCILE_DEAL";
 if(code==TRADE_RETCODE_PLACED) return "PLACED_NOT_FILLED";
 return "UNCLASSIFIED_RECONCILE";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The classifier takes a number and returns a label. It does not send an order or choose a retry. The unknown branch matters too. A new code must remain visible instead of falling through to a success label.&lt;/p&gt;

&lt;h2&gt;
  
  
  The native result
&lt;/h2&gt;

&lt;p&gt;The script supplied three fixed inputs. The &lt;a href="https://stratcorealpha.com/proof/fix/FIX-15-runtime.txt" rel="noopener noreferrer"&gt;runtime receipt&lt;/a&gt; retained these outputs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Synthetic input&lt;/th&gt;
&lt;th&gt;Local classification&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;10006&lt;/td&gt;
&lt;td&gt;REJECTED_REASON_UNKNOWN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10009&lt;/td&gt;
&lt;td&gt;COMPLETED_RECONCILE_DEAL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10008&lt;/td&gt;
&lt;td&gt;PLACED_NOT_FILLED&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All three comparisons passed. The native run recorded &lt;code&gt;orders_sent=0&lt;/code&gt; and &lt;code&gt;server_reject_reproduced=false&lt;/code&gt;. The EURUSD chart was the capture surface. It was not a trade in this test.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc5hs0vsk862jycmlf1j4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc5hs0vsk862jycmlf1j4.png" alt="Native MT5 capture of three synthetic classifier checks and zero orders" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The result supports one narrow claim: the local classifier kept those three chosen values separate. It establishes no broker cause, server rejection or complete execution state machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep the receipt before choosing another attempt
&lt;/h2&gt;

&lt;p&gt;For one real failed request, retain the original symbol, volume, order type, requested prices and timestamp. Keep the returned code, comment, order and deal fields beside it. If an external return code is present, retain that too. A local attempt identifier helps join later order and deal records without confusing a trading intent with a new submission.&lt;/p&gt;

&lt;p&gt;Then compare the relevant order, deal and position state for the operation you requested. A placed order and a completed request need different handling. Even completion needs reconciliation with the corresponding account record.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.mql5.com/en/docs/trading/ordersend" rel="noopener noreferrer"&gt;official OrderSend reference&lt;/a&gt; explains why a true function return alone does not establish a completed market trade. A retry loop should not turn missing information into a second entry.&lt;/p&gt;

&lt;p&gt;Open one rejected request and compare its returned code, comment, order and deal fields with its original request and timestamp. If your log saved only a label, improve that receipt first. If the reason is missing, keep it unknown.&lt;/p&gt;

&lt;p&gt;The original native proof and its boundaries are on the &lt;a href="https://stratcorealpha.com/fix/mt5-error-10006-request-rejected" rel="noopener noreferrer"&gt;FIX-15 page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If your first receipt loses these fields, check that logging change with one rejected, one placed and one completed example before enabling any automatic retry.&lt;/p&gt;

&lt;p&gt;For a bounded source review, &lt;a href="https://stratcorealpha.com/developers?ref=devto" rel="noopener noreferrer"&gt;Free EA Code Check&lt;/a&gt; begins with readable code and one expected result.&lt;/p&gt;

</description>
      <category>mql5</category>
      <category>debugging</category>
      <category>tutorial</category>
      <category>algotrading</category>
    </item>
  </channel>
</rss>
