Skip to content

Commit c6c1390

Browse files
committed
merge PR #35: Update MQL cross compiler
2 parents 0658688 + 1e16aec commit c6c1390

File tree

18 files changed

+274
-61
lines changed

18 files changed

+274
-61
lines changed

.gitattributes

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717

1818
# set content encodings
1919
* encoding=UTF-8
20-
/mql*/ encoding=CP1252
21-
*.md encoding=UTF-8
20+
*.mqh encoding=CP1252
21+
*.mq4 encoding=CP1252
22+
*.mq5 encoding=CP1252
23+
*.tpl encoding=CP1252
2224

2325

2426
# checkout with Windows line-endings (not yet supported by EGit)

.github/workflows/compile-mql.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ on:
1010
push:
1111
branches:
1212
- master
13-
- feature/mql-cross-compiler
1413

1514
pull_request:
1615
branches:

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11

2-
# MQL framework for MetaTrader 4
2+
[![Build Status](https://img.shields.io/badge/Build_status-passed-green?style=flat&logo=GitHub&color=%234cc61e)](https://github.com/rosasurfer/mt4-mql-framework/actions#)
33

4-
[<img src="https://api.gitsponsors.com/api/badge/img?id=98562802" height="40">](https://api.gitsponsors.com/api/badge/link?p=siJPuuNmHD8NWqtbPUP8QmW+l+2mKhgfeqSIS08CnLbsL5nZJbABhLRdacm1hbCtLxj9mHUpslsnxaCPgb3JQm38C12lPDiZl8dMpzn1Exw=)
4+
5+
## MQL application framework for MetaTrader 4
56

67
-----
78

8-
### MetaQuotes support
9+
### MetaQuotes terminal support
10+
11+
###### July 2025:
12+
- MetaQuotes stops supporting terminals older than build 1440.
913

1014
###### December 2024:
1115
- MetaQuotes stops supporting terminals older than build 1420.

bin/.mqlcrc renamed to bin/.mqlcrc.dist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copy this file to "/.mqlcrc" and adjust the settings to your system.
2+
# Copy this file to "~/.mqlcrc" and adjust the settings to your system.
33
# ----------------------------------------------------------------------------------------------------
44
# Configuration for the MQL compiler script. Compiler locations may also be specified via environment.
55
# Environment settings have higher priority than settings in this file.

bin/mqlc

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
#
77
# Configuration via environment and config file.
88
#
9-
# @see "/bin/.mqlcrc" for an example
9+
# @see "/bin/.mqlcrc.dist" for an example
1010
# @see https://www.metatrader5.com/en/metaeditor/help/beginning/integration_ide#compiler
1111
#
1212
#
1313
# TODO:
1414
# - colored output
1515
# - implement download tracker
16-
# - option --rc/--norc
16+
# - option --rc/--no-rc
1717
# - option --clean
1818
# - option --syntax
1919
# - option --info
@@ -50,21 +50,21 @@ Usage: mqlc [options] [--] SOURCES...
5050
mqlc [options] /compile:(FILE|DIR)... [/include:DIR]... [/log[:FILE]]
5151
5252
Arguments:
53-
SOURCES One or more MQL files or source directories to compile. Supports wildcards.
54-
55-
Options:
56-
-h --help This screen.
57-
/compile:FILE Source file to compile. Doesn't support wildcards.
58-
/compile:DIR Source directory to compile. Recompiles new and modified sources (not in subdirectories).
59-
/include:DIR Include directory for the following sources (default: "<data-dir>/MQL4" or "<data-dir>/MQL5").
60-
/log Writes output to "<source-file.log>" (default: no logfile on success, logfile on errors/warnings).
61-
/log:FILE Writes output to the specified logfile.
62-
-v=VERSION MQL version of the following MQL4 sources: either "mql40" or "mql45". May appear multiple times.
63-
-v= --version= Empty version argument: auto-detect the version of the following MQL4 sources (default).
64-
-s --syntax Syntax check only, no compilation.
65-
-w --warn2error Treat compiler warnings as errors, affects the exit status.
66-
--[no]color Enforce or disable colored output (default: auto).
67-
--rc=FILE --norc Use the specified configuration file, or no file at all (default: see configuration section).
53+
SOURCES One or more MQL files or source directories to compile. Supports wildcards.
54+
55+
Options:
56+
-h, --help This screen.
57+
/compile:FILE Source file to compile. Doesn't support wildcards.
58+
/compile:DIR Source directory to compile. Recompiles new and modified sources (not in subdirectories).
59+
/include:DIR Include directory for the following sources (default: "<data-dir>/MQL4" or "<data-dir>/MQL5").
60+
/log Writes output to "<source-file.log>" (default: no logfile on success, logfile on errors/warnings).
61+
/log:FILE Writes output to the specified logfile.
62+
-v=VERSION MQL version of the following MQL4 sources: either "mql40" or "mql45". Can appear multiple times.
63+
-v=, --version= Empty version argument: auto-detect the version of the following MQL4 sources (default).
64+
-s, --syntax Syntax check only, no compilation.
65+
-w, --warn2error Treat compiler warnings as errors, affects the exit status.
66+
--color, --no-color Enforce or disable colored output (default: auto).
67+
--rc=FILE, --no-rc Use the specified configuration file, or no file at all (default: see configuration section).
6868
6969
The script exits with 0 (success) or the number of errors of the last failing compilation.
7070
@@ -625,7 +625,7 @@ function fail() {
625625
#
626626
# @param $@ - any number of arguments
627627
#
628-
function stderr () {
628+
function stderr() {
629629
echo "$@" >&2
630630
}
631631

@@ -979,12 +979,12 @@ while (("$#")); do
979979
continue;;
980980

981981
-v|--version)
982-
syntaxError "missing version argument: $1";;
982+
syntaxError "Missing version argument: $1";;
983983

984984
-v=*|--version=*)
985985
version="${1#*=}"
986986
version="${version,,}"
987-
[[ -n "$version" && "$version" != mql4[05] ]] && syntaxError "invalid version argument in \"$1\" (expecting \"mql40\" or \"mql45\")"
987+
[[ -n "$version" && "$version" != mql4[05] ]] && syntaxError "Invalid version argument in \"$1\" (expecting \"mql40\" or \"mql45\")"
988988
if ((firstVersion < 0)); then
989989
for i in "${!srcFileVersions[@]}"; do
990990
srcFileVersions[i]="$version" # the first --version affects previous sources if no more sources follow
@@ -994,13 +994,13 @@ while (("$#")); do
994994
shift; continue;;
995995

996996
-*)
997-
syntaxError "unrecognized option \"$1\" (use the -- delimiter if source arguments start with a hyphen)";;
997+
syntaxError "Unrecognized option \"$1\" (use the -- delimiter if source arguments start with a hyphen)";;
998998

999999
/inc|/include|/inc[=:]*|/include[=:]*)
10001000
[[ "$1" == /include* ]] && include="${1:9}" || include="${1:5}"
10011001
include="$(sanitizeName "$include")"
1002-
[[ -z "$include" ]] && syntaxError "missing argument: $1"
1003-
[[ -d "$include" ]] || syntaxError "include directory not found: \"$include\""
1002+
[[ -z "$include" ]] && syntaxError "Missing argument: $1"
1003+
[[ -d "$include" ]] || syntaxError "Include directory not found: \"$include\""
10041004
if ((firstInclude < 0)); then
10051005
for i in "${!srcFileIncludes[@]}"; do
10061006
srcFileIncludes[i]="$include" # the first /include affects previous sources if no more sources follow
@@ -1010,18 +1010,18 @@ while (("$#")); do
10101010
shift; continue;;
10111011

10121012
/log|/log[=:]*)
1013-
[[ "$log" -eq 1 ]] && syntaxError "multiple /log options"
1013+
[[ "$log" -eq 1 ]] && syntaxError "Multiple /log options"
10141014
log=1
10151015
if [[ ${#1} -gt 4 ]]; then
10161016
customLog="$(sanitizeName "${1:5}")"
1017-
[[ -z "$customLog" ]] && syntaxError "missing argument: $1"
1017+
[[ -z "$customLog" ]] && syntaxError "Missing argument: $1"
10181018
customLog="$(cygpath -w "$customLog")"
10191019
fi
10201020
shift; continue;;
10211021

10221022
/compile[=:]*)
10231023
srcArg="$(sanitizeName "${1:9}")"
1024-
[[ -z "$srcArg" ]] && syntaxError "missing argument: $1";;
1024+
[[ -z "$srcArg" ]] && syntaxError "Missing argument: $1";;
10251025
# processing continues after the case block
10261026
esac
10271027
fi
@@ -1038,14 +1038,14 @@ while (("$#")); do
10381038
done < <(find "$srcArg" -maxdepth 1 -type f -iname '*.mq[45]')
10391039
elif [[ -f "$srcArg" ]]; then
10401040
ext="$(fileExtension "$srcArg")"
1041-
[[ "${ext,,}" != mq[45] ]] && syntaxError "cannot compile file \"$srcArg\""
1041+
[[ "${ext,,}" != mq[45] ]] && syntaxError "Cannot compile file \"$srcArg\""
10421042
srcFileNames+=("$srcArg")
10431043
srcFileVersions+=("${version:-}")
10441044
srcFileIncludes+=("${include:-}")
10451045
else
10461046
srcArg="$1"
10471047
[[ "$srcArg" =~ ^[[:space:]]*$ ]] && srcArg="\"$srcArg\""
1048-
syntaxError "file or directory not found: $srcArg"
1048+
syntaxError "File or directory not found: $srcArg"
10491049
fi
10501050

10511051
if ((firstVersion > 0)); then

mql40/include/rsf/functions/ObjectCreateRegister.mqh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ bool ObjectCreateRegister(string name, int type, int window=0, datetime time1=NU
5252
// OBJ_ARROW - Arrows. Uses 1 coordinate pair.
5353
// OBJ_LABEL - Text label. Uses 1 coordinate pair in pixels.
5454

55+
// @todo: delete an existing object
56+
5557
// create the object
5658
bool success = ObjectCreate(name, type, window, time1, price1, time2, price2, time3, price3);
5759
if (!success) return(!catch("ObjectCreateRegister(2) name=\""+ name +"\", type="+ ObjectTypeToStr(type, F_ERR_INVALID_PARAMETER) +", window="+ window, intOr(GetLastError(), ERR_RUNTIME_ERROR)));

mql40/include/rsf/stdfunctions.mqh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,7 @@ string FindStandardSymbol(string symbol, bool strict = false) {
931931
else if (StrEndsWith(_symbol, "_AVG")) _symbol = StrLeft(_symbol, -4);
932932
else if (StrEndsWith(_symbol, "^" )) _symbol = StrLeft(_symbol, -1);
933933
else if (StrEndsWith(_symbol, "." )) _symbol = StrLeft(_symbol, -1);
934+
else if (StrEndsWith(_symbol, ".a" )) _symbol = StrLeft(_symbol, -2);
934935
else if (StrEndsWith(_symbol, ".m" )) _symbol = StrLeft(_symbol, -2);
935936
else if (StrEndsWith(_symbol, ".pro")) _symbol = StrLeft(_symbol, -4);
936937
else if (StrEndsWith(_symbol, ".r" )) _symbol = StrLeft(_symbol, -2);

mql40/indicators/ChartInfos.mq4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1941,7 +1941,7 @@ bool UpdateStopoutLevel() {
19411941
positions.showMfe = positions.showMfe || config.dData[line][I_MFE_ENABLED];
19421942

19431943
// track the first (top-most) virtual position
1944-
if (isVirtual && !isVirtualPosition) {
1944+
if (!isVirtualPosition && isVirtual && (customLongPosition || customShortPosition)) {
19451945
isVirtualPosition = true;
19461946
virtualTotalPosition = customTotalPosition;
19471947
virtualLongPosition = customLongPosition;

mql40/indicators/ZigZag.mq4

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -89,25 +89,25 @@ extern int Donchian.Crossing.Width = 1;
8989
extern color Donchian.Crossing.Color = CLR_NONE;
9090

9191
extern string ___c__________________________ = "=== ZigZag projections ===";
92-
extern bool TrackZigZagBalance = false; // whether to track ZigZag balances
93-
extern datetime TrackZigZagBalance.Since = 0; // mark ZigZag balances since this time
94-
extern bool ProjectNextBalance = false; // whether to project zero-balance levels
92+
extern bool TrackZigZagBalance = false; // whether to track ZigZag balances
93+
extern datetime TrackZigZagBalance.Since = 0; // mark ZigZag balances since this time
94+
extern bool ProjectNextBalance = false; // whether to project zero-balance levels
9595

9696
extern string ___d__________________________ = "=== Display settings ===";
9797
extern bool ShowChartLegend = true;
98-
extern int MaxBarsBack = 10000; // max. values to calculate (-1: all available)
98+
extern int MaxBarsBack = 10000; // max. values to calculate (-1: all available)
9999

100100
extern string ___e__________________________ = "=== Signaling ===";
101-
extern bool Signal.onReversal = false; // signal ZigZag reversals (first Donchian channel crossing)
101+
extern bool Signal.onReversal = false; // signal ZigZag reversals (first Donchian channel crossing)
102102
extern string Signal.onReversal.Types = "sound* | alert | mail | sms";
103103

104-
extern bool Signal.onBreakout = false; // signal ZigZag breakouts
104+
extern bool Signal.onBreakout = false; // signal ZigZag breakouts
105105
extern string Signal.onBreakout.Types = "sound* | alert | mail | sms";
106106

107107
extern string Signal.Sound.Up = "Signal Up.wav";
108108
extern string Signal.Sound.Down = "Signal Down.wav";
109109

110-
extern bool Sound.onChannelWidening = false; // signal Donchian channel widenings
110+
extern bool Sound.onChannelWidening = false; // signal Donchian channel widenings
111111
extern string Sound.onNewChannelHigh = "Price Advance.wav";
112112
extern string Sound.onNewChannelLow = "Price Decline.wav";
113113

@@ -162,8 +162,8 @@ int framework_buffers = 4; // buffers manage
162162
#property indicator_color7 CLR_NONE // offset of last ZigZag reversal to previous ZigZag semaphore
163163
#property indicator_color8 CLR_NONE // trend (combined buffers MODE_KNOWN_TREND and MODE_UNKNOWN_TREND)
164164

165-
double semaphoreOpen []; // ZigZag semaphore open prices (yields a vertical line segment if open != close)
166-
double semaphoreClose[]; // ZigZag semaphore close prices (yields a vertical line segment if open != close)
165+
double semaphoreOpen []; // semaphore open prices
166+
double semaphoreClose[]; // semaphore close prices (yields a vertical line segment if open != close)
167167
double upperBand []; // upper channel band
168168
double lowerBand []; // lower channel band
169169
double upperCross []; // upper channel band crossings
@@ -485,6 +485,7 @@ int onTick() {
485485
unknownTrend [startbar] = 0;
486486
combinedTrend [startbar] = 0;
487487
}
488+
488489
for (int bar=startbar; bar >= 0; bar--) {
489490
// recalculate Donchian channel
490491
if (bar > 0) {
@@ -650,7 +651,7 @@ int onTick() {
650651
if (balance > -HalfPoint) fontColor = C'45,181,45';
651652
else if (prevBalanceReset) fontColor = Blue;
652653
else fontColor = Red;
653-
string name = shortName + ifString(eventType==EVENT_REVERSAL_UP, ".reversal-up.", ".reversal-down.") + TimeToStr(eventTime);
654+
string name = shortName + ifString(eventType==EVENT_REVERSAL_UP, ".up.", ".down.") + TimeToStr(eventTime);
654655
ObjectCreateRegister(name, OBJ_TEXT, 0, eventTime, eventPrice-markerOffset);
655656
ObjectSetText(name, NumberToStr(balance/pUnit, ",'R."+ pDigits), fontSize, fontName, fontColor);
656657

@@ -730,7 +731,7 @@ double CalculateMarkerOffset() {
730731

731732

732733
/**
733-
* Whether a bar crossing both channel bands crossed the upper band first. The returned result is only a "best guess".
734+
* Whether a bar crossing both channel bands crossed the upper band first. The result is just a "best guess".
734735
*
735736
* @param int bar - bar offset
736737
*
@@ -771,7 +772,7 @@ bool IsUpperCrossFirst(int bar) {
771772

772773

773774
/**
774-
* Whether a bar crossing both channel bands crossed the upper band last. The returned result is only a "best guess".
775+
* Whether a bar crossing both channel bands crossed the upper band last. The result is just a "best guess".
775776
*
776777
* @param int bar - bar offset
777778
*

mql40/scripts/CloseOrders.mq4

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,14 @@ int onInit() {
8484
ArrayPushInt(closeTypes, OP_BUYSTOP );
8585
ArrayPushInt(closeTypes, OP_SELLSTOP );
8686
}
87-
else if (sValue == "l" ) ArrayPushInt(closeTypes, OP_BUY);
88-
else if (sValue == "long" ) ArrayPushInt(closeTypes, OP_BUY);
89-
else if (sValue == "s" ) ArrayPushInt(closeTypes, OP_SELL);
90-
else if (sValue == "short") ArrayPushInt(closeTypes, OP_SELL);
91-
else if (sValue == "bl" ) ArrayPushInt(closeTypes, OP_BUYLIMIT);
92-
else if (sValue == "bs" ) ArrayPushInt(closeTypes, OP_BUYSTOP);
87+
else if (sValue == "l" ) ArrayPushInt(closeTypes, OP_BUY);
88+
else if (sValue == "long" ) ArrayPushInt(closeTypes, OP_BUY);
89+
else if (sValue == "s" ) ArrayPushInt(closeTypes, OP_SELL);
90+
else if (sValue == "short") ArrayPushInt(closeTypes, OP_SELL);
91+
else if (sValue == "bl" || sValue == "b-l") ArrayPushInt(closeTypes, OP_BUYLIMIT);
92+
else if (sValue == "bs" || sValue == "b-s") ArrayPushInt(closeTypes, OP_BUYSTOP);
93+
else if (sValue == "sl" || sValue == "s-l") ArrayPushInt(closeTypes, OP_SELLLIMIT);
94+
else if (sValue == "ss" || sValue == "s-s") ArrayPushInt(closeTypes, OP_SELLSTOP);
9395
else {
9496
int type = StrToOperationType(sValue);
9597
if (type < OP_BUY || type > OP_SELLSTOP) return(catch("onInit(1) invalid input parameter Close.OrderTypes: "+ DoubleQuoteStr(Close.OrderTypes), ERR_INVALID_INPUT_PARAMETER));

0 commit comments

Comments
 (0)