Trade Stats Multicurrency
- Утилиты
-
Vsevolod Morozov
Narm - Версия: 1.32
- Активации: 5
1. Overview
Trade Stats is a non-trading analytics Expert Advisor for MetaTrader 5. It reads the account's closed-deal history, groups every trade by its Magic Number, and renders a compact live statistics table directly on the chart. Its purpose is to answer one question: which Expert Advisor on this account is actually making money, and how much each one costs to run?
It places no orders, modifies nothing, and never touches positions. It only reads history and draws chart labels.
2. What it does not do
- No trading, no money management, no signals — it cannot open or close anything.
- No writes to the account, no external network calls, no file uploads.
- Only chart objects are created, all with the prefix ByMagic_ , and all of them are removed in OnDeinit .
3. How it works
- History selection — on each refresh the EA calls HistorySelect(from, to) for the period defined by the period inputs (current month, current week, today, last N days, or custom dates). Server time is used.
- Deal filtering — only balance-bearing market deals are counted ( DEAL_TYPE_BUY / DEAL_TYPE_SELL ). Balance operations are ignored. Optional filters: exact Magic number, symbol name, and "hide manual trades" (magic = 0).
- Exit deals define a "trade" — a row counter is incremented only for deals that reduce a position: DEAL_ENTRY_OUT , DEAL_ENTRY_OUT_BY , DEAL_ENTRY_INOUT . Entry deals do not inflate the trade count.
- Cost accumulation — commission, broker fees, swap and (optionally) an estimated spread are accumulated for all deals, including entries, because brokers book these costs on entry deals.
- Net result per deal — profit + commission + fee + swap + spread estimate , where each component is included only if the corresponding switch is enabled. This same value feeds wins/losses, gross profit/loss, P/L, best/worst trade.
- Expert name resolution (highest priority first):
- explicit user map from InpExpertNames ( magic=Name; );
- the most frequently repeated "meaningful" comment of the entry deals for that magic (voting mechanism);
- the last meaningful comment;
- otherwise the row is shown as — . Broker technical comments are filtered out: strings starting with [ , sl , tp , so: , from # , by # , and comments containing cancelled , canceled , partial , split , timeout , deleted , as well as comments made only of digits and punctuation.
- Sorting — by Magic ascending (manual trades always last), or by net P/L, Profit Factor, trade count or Winrate, ascending/descending; ties are resolved by Magic for a stable order.
- Rendering — a lightweight label grid is redrawn: column widths are measured with TextSetFont / TextGetSize from the header and the visible cells, so the table auto-sizes to the content in either language.
4. Panel layout
Five information lines above the table:
| Line | Example (English) |
|---|---|
| Title | TRADE STATS — BY MAGIC NUMBER |
| Period | Period: 2026.10.01 → 2026.10.28 |
| Counters | Magic groups: 4 Closed trades: 187 |
| Costs | Costs: commission -42.10 swap -3.55 spread* -18.40 |
| Status | Updated: 13:20:57 * spread is estimated from ticks |
Then the table header, rows, and the TOTAL row. If the number of groups exceeds InpMaxRows , the remainder is reported as ... and N more Magic .
Columns: Magic | Expert | Trades | W | L | Winrate | [Comm.] | [Swap] | [Spread*] | P/L | PF
Comm. , Swap and Spread* appear only when their switches are on. Numeric columns are right-aligned, the expert name is left-aligned and truncated with .. when it exceeds the column width (hard cap 320 px). Colour coding is applied per cell: profit/positive → clrLime , loss/negative → clrOrangeRed , neutral → clrSilver ; the magic of manual trades is shown in silver, program magic numbers in cyan.
5. Metrics and formulas
- Trades — number of position-closing deals in the period.
- W / L — closed deals with net result > 0 and < 0; zero-result deals are counted separately (not shown as a column, exported in CSV).
- Winrate — wins / (wins + losses + zeros) × 100 .
- Gross profit / gross loss — sums of positive and absolute negative net results.
- P/L — net result of all deals of the group, including the enabled cost components.
- PF (Profit Factor) — grossProfit / grossLoss ; when there are no losses but there is profit, it is capped at 99.99 ; otherwise `0.
- Best / worst trade, average trade, last deal time — computed and exported to CSV (not shown on the panel).
- TOTAL row — sums across all groups plus a portfolio-level Winrate and Profit Factor.
6. Inputs
| Input | Default | Meaning |
|---|---|---|
| InpPeriodMode | PERIOD_CURRENT_MONTH | Current month / current week / today / last N days / custom dates |
| InpLastDays | 30 | Number of days for the "last N days" mode |
| InpCustomFrom , InpCustomTo | 2025.01.01 , 2025.12.31 | Custom date range (end date is extended to 23:59:59) |
| InpMagicFilter | 0 | Analyse a single magic number (0 = all) |
| InpShowManual | true | Include manual trades (magic = 0) |
| InpSymbolFilter | "" | Analyse one symbol only ("" = all) |
| InpShowCommission | true | Show the commission column and include commission + fees in P/L |
| InpShowSwap | true | Show the swap column and include swap in P/L |
| InpShowSpread | false | Show the spread column and subtract an estimated spread from P/L |
| InpSpreadMaxCalc | 300 | Maximum number of new spread estimations per refresh (0..5000) |
| InpLanguage | LANG_ENGLISH | Panel and journal language: English (default) or Russian |
| InpShowComment | true | Derive expert names from deal comments |
| InpCommentLen | 20 | Maximum length of a derived expert name |
| InpExpertNames | "" | Explicit name map, e.g. 20261012=GoldScalperPro;1=ScalperProM30 |
| InpSortMode | STATS_SORT_MAGIC | Magic / net P/L / Profit Factor / trades / Winrate |
| InpSortDesc | true | Descending order (ignored for "by Magic", which is always ascending) |
| InpRefreshSec | 5 | Minimum interval between recalculations, seconds (1..3600) |
| InpPanelX , InpPanelY | 10 , 20 | Panel offset in pixels |
| InpTextColor , InpBgColor , InpHeaderColor | clrWhite , C'15,15,25' , clrGold | Colours |
| InpFontSize , InpFontName | 9 , Consolas | Font (size 6..30); a monospaced font keeps the columns aligned |
| InpMaxRows | 30 | Maximum visible rows (0 = all) |
| InpExportCSV | false | Write a CSV snapshot on every refresh |
| InpCSVFileName | stats_by_magic.csv | CSV name, created in the terminal's MQL5\Files sandbox |
Invalid inputs (period bounds, font size, comment length, refresh interval, spread budget) abort initialisation with INIT_PARAMETERS_INCORRECT and a journal message.
7. Spread estimation
MT5 does not store the spread in a deal, so when InpShowSpread is enabled the EA estimates it: it copies ticks ±5 seconds around the deal time with CopyTicksRange , takes the tick nearest to the execution moment, and computes
spread_cost = 0.5 × (ask − bid) × volume × contract_size
The value is stored as a negative contribution to the result and cached per deal ticket in a ticket-sorted array with binary search, so a deal is estimated once. Estimations are throttled by InpSpreadMaxCalc per refresh; if no ticks exist for that moment, nothing is cached and the deal is retried on a later refresh. The panel and journal explicitly mark this value as an estimate ( spread* ).
8. CSV export
FILE_WRITE | FILE_CSV | FILE_ANSI , ; delimiter, one row per magic group, always in English:
Magic;Expert;Trades;Wins;Losses;Zeros;Winrate;Commission;Swap;Spread;NetProfit; GrossProfit;GrossLoss;ProfitFactor;BestTrade;WorstTrade;AvgTrade;LastDeal
The file is written to the terminal data folder ( MQL5\Files\... ), so it can be read by other tools or services.
9. Localization
All runtime text (panel and journal messages) is resolved through the T(ENUM_TXT) helper from a compile-time table of English or another strings. English is the default; switching InpLanguage changes the panel on the next refresh without restarting the EA. The labels in the EA properties dialog are static English strings (MQL5 cannot localize input captions at runtime).
10. Performance notes
- Recalculation is throttled by InpRefreshSec and driven by both a 1-second timer and OnTick , so the panel stays alive without ticks; the first calculation runs in OnInit .
- One HistorySelect plus one linear pass over the deals of the period per refresh; grouping is a short linear scan, sorting is insertion sort (the number of groups is small).
- Chart labels are created once and only updated afterwards; stale row/column objects are deleted by HideUnusedRows , and the background is recreated if it disappears (e.g. after a template change).
11. Limitations and assumptions
- Only closed deals inside the selected period are analysed; open positions and floating P/L are not included.
- Trade counts follow the broker's deal structure: partial closes appear as several exits, and DEAL_ENTRY_INOUT (netting reversals) is treated as an exit.
- Results are shown in the account deposit currency; no currency conversion is performed.
- Commission is reported exactly as the broker records it; if a broker books commission on entry deals only, that behaviour is preserved.
- Spread is an estimate by design and is not identical to the broker's actual mark-up.
- Expert names are heuristics based on comments; use InpExpertNames for exact labelling.
- The EA is an indicator/analytics tool: it is intended to be attached to any chart and left running.
12. Compatibility and validation
- MetaTrader 5, MQL5; compiled with 0 errors and 0 warnings on compiler build 6230.
- The published binary is compiled for X64 Regular so it is accepted by the MQL5 Market (AVX2/AVX512 builds are rejected there).
- Verify on a demo account or in the Strategy Tester's visual mode that the panel fits the chart, that column widths are correct in both languages, and that exported CSV values match the account history.
13. Risk disclaimer
Trade Stats only reports historical statistics. Past performance of an Expert Advisor does not guarantee future results, and spread estimates and comment-derived names may differ from broker reality. Always validate any decision based on these numbers against your own records.
