diff --git a/.github/workflows/test-exchange-account.yml b/.github/workflows/test-exchange-account.yml index d348e957e..05d73df32 100644 --- a/.github/workflows/test-exchange-account.yml +++ b/.github/workflows/test-exchange-account.yml @@ -3,6 +3,7 @@ name: Test Exchange/Account env: TEST_PATH: Exchange/Account/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -47,7 +48,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -62,7 +64,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-exchange-symbolinfo.yml b/.github/workflows/test-exchange-symbolinfo.yml index 4bb9ec81d..d9640c624 100644 --- a/.github/workflows/test-exchange-symbolinfo.yml +++ b/.github/workflows/test-exchange-symbolinfo.yml @@ -3,6 +3,7 @@ name: Test Exchange/SymbolInfo env: TEST_PATH: Exchange/SymbolInfo/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -45,7 +46,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -60,7 +62,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-exchange.yml b/.github/workflows/test-exchange.yml index 5e1260b36..eabe553a1 100644 --- a/.github/workflows/test-exchange.yml +++ b/.github/workflows/test-exchange.yml @@ -3,6 +3,7 @@ name: Test Exchange env: TEST_PATH: Exchange/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -47,7 +48,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -62,7 +64,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-indicator.yml b/.github/workflows/test-indicator.yml index c423bc459..1504084fb 100644 --- a/.github/workflows/test-indicator.yml +++ b/.github/workflows/test-indicator.yml @@ -3,6 +3,7 @@ name: Test Indicator env: TEST_PATH: Indicator/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -53,7 +54,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -68,7 +70,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-indicators-bitwise.yml b/.github/workflows/test-indicators-bitwise.yml index d0122bffa..e7356f1bb 100644 --- a/.github/workflows/test-indicators-bitwise.yml +++ b/.github/workflows/test-indicators-bitwise.yml @@ -3,6 +3,7 @@ name: Test Indicators (Bitwise) env: TEST_PATH: Indicators/Bitwise/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -48,7 +49,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -63,7 +65,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-indicators-ohlc.yml b/.github/workflows/test-indicators-ohlc.yml index 74728180a..07ebb0323 100644 --- a/.github/workflows/test-indicators-ohlc.yml +++ b/.github/workflows/test-indicators-ohlc.yml @@ -3,6 +3,7 @@ name: Test Indicators (OHLC) env: TEST_PATH: Indicators/OHLC/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -47,7 +48,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -62,7 +64,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-indicators-oscillator.yml b/.github/workflows/test-indicators-oscillator.yml index 67dfea524..73dd58bd6 100644 --- a/.github/workflows/test-indicators-oscillator.yml +++ b/.github/workflows/test-indicators-oscillator.yml @@ -3,6 +3,7 @@ name: Test Indicators (Oscillator) env: TEST_PATH: Indicators/Oscillator/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -50,7 +51,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -65,7 +67,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-indicators-price.yml b/.github/workflows/test-indicators-price.yml index fd4ded8ac..c5339ecfb 100644 --- a/.github/workflows/test-indicators-price.yml +++ b/.github/workflows/test-indicators-price.yml @@ -3,6 +3,7 @@ name: Test Indicators (Price) env: TEST_PATH: Indicators/Price/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -49,7 +50,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -64,7 +66,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-indicators-pricemulti.yml b/.github/workflows/test-indicators-pricemulti.yml index bbcbd8edd..549ecb6b8 100644 --- a/.github/workflows/test-indicators-pricemulti.yml +++ b/.github/workflows/test-indicators-pricemulti.yml @@ -3,6 +3,7 @@ name: Test Indicators (PriceMulti) env: TEST_PATH: Indicators/PriceMulti/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -47,7 +48,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -62,7 +64,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-indicators-pricerange.yml b/.github/workflows/test-indicators-pricerange.yml index bf4d58812..9e22cfcac 100644 --- a/.github/workflows/test-indicators-pricerange.yml +++ b/.github/workflows/test-indicators-pricerange.yml @@ -3,6 +3,7 @@ name: Test Indicators (PriceRange) env: TEST_PATH: Indicators/PriceRange/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -50,7 +51,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -65,7 +67,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-indicators-special.yml b/.github/workflows/test-indicators-special.yml index 2fed66ca6..817ca9aaf 100644 --- a/.github/workflows/test-indicators-special.yml +++ b/.github/workflows/test-indicators-special.yml @@ -3,6 +3,7 @@ name: Test Indicators (Special) env: TEST_PATH: Indicators/Special/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -48,7 +49,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -63,7 +65,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-indicators-tick.yml b/.github/workflows/test-indicators-tick.yml index d8cfe1da1..07f158ba7 100644 --- a/.github/workflows/test-indicators-tick.yml +++ b/.github/workflows/test-indicators-tick.yml @@ -3,6 +3,7 @@ name: Test Indicators (Tick) env: TEST_PATH: Indicators/Tick/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -38,7 +39,7 @@ jobs: strategy: matrix: test: - - Indi_Tick.test + - Indi_TickMt.test version: [5] max-parallel: 4 steps: @@ -47,7 +48,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -62,7 +64,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-indicators.yml b/.github/workflows/test-indicators.yml index 3c6c764be..1e1e7945f 100644 --- a/.github/workflows/test-indicators.yml +++ b/.github/workflows/test-indicators.yml @@ -3,6 +3,7 @@ name: Test Indicators env: TEST_PATH: Indicators/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -97,7 +98,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -112,7 +114,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-math.yml b/.github/workflows/test-math.yml index 6b9efd69b..f1dc64589 100644 --- a/.github/workflows/test-math.yml +++ b/.github/workflows/test-math.yml @@ -3,6 +3,7 @@ name: Test Math env: TEST_PATH: Math/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -47,7 +48,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -62,7 +64,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-platform-chart.yml b/.github/workflows/test-platform-chart.yml index 615611990..d85a9dded 100644 --- a/.github/workflows/test-platform-chart.yml +++ b/.github/workflows/test-platform-chart.yml @@ -3,6 +3,7 @@ name: Test Platform/Chart env: TEST_PATH: Platform/Chart/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -46,7 +47,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -61,7 +63,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-platform-chart3d.yml b/.github/workflows/test-platform-chart3d.yml index d1bae4e4a..05c3f4a87 100644 --- a/.github/workflows/test-platform-chart3d.yml +++ b/.github/workflows/test-platform-chart3d.yml @@ -3,6 +3,7 @@ name: Test Platform/Chart3D env: TEST_PATH: Platform/Chart3D/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -45,7 +46,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -61,7 +63,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 30 diff --git a/.github/workflows/test-platform-web.yml b/.github/workflows/test-platform-web.yml index 26748449a..afd4b9e57 100644 --- a/.github/workflows/test-platform-web.yml +++ b/.github/workflows/test-platform-web.yml @@ -3,6 +3,7 @@ name: Test Platform/Web env: TEST_PATH: Platform/Web/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -46,7 +47,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -61,7 +63,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-platform.yml b/.github/workflows/test-platform.yml index c45b67df1..37388ba03 100644 --- a/.github/workflows/test-platform.yml +++ b/.github/workflows/test-platform.yml @@ -3,6 +3,7 @@ name: Test Platform env: TEST_PATH: Platform/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -50,7 +51,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -65,7 +67,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-serializer.yml b/.github/workflows/test-serializer.yml index 14fd63593..a256229e8 100644 --- a/.github/workflows/test-serializer.yml +++ b/.github/workflows/test-serializer.yml @@ -3,6 +3,7 @@ name: Test Serializer env: TEST_PATH: Serializer/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -45,7 +46,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -60,7 +62,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-storage-cache.yml b/.github/workflows/test-storage-cache.yml index fd23eca52..c4649601d 100644 --- a/.github/workflows/test-storage-cache.yml +++ b/.github/workflows/test-storage-cache.yml @@ -3,6 +3,7 @@ name: Test Storage/Cache env: TEST_PATH: Storage/Cache/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -46,7 +47,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -61,7 +63,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-storage-dict-buffer.yml b/.github/workflows/test-storage-dict-buffer.yml index cba46092e..842a1ec5b 100644 --- a/.github/workflows/test-storage-dict-buffer.yml +++ b/.github/workflows/test-storage-dict-buffer.yml @@ -3,6 +3,7 @@ name: Test Storage/Dict/Buffer env: TEST_PATH: Storage/Dict/Buffer/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -50,7 +51,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -65,7 +67,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-storage-dict.yml b/.github/workflows/test-storage-dict.yml index 65beb558d..e9f62d7ae 100644 --- a/.github/workflows/test-storage-dict.yml +++ b/.github/workflows/test-storage-dict.yml @@ -3,6 +3,7 @@ name: Test Storage/Dict env: TEST_PATH: Storage/Dict/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -45,7 +46,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -60,7 +62,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-storage.yml b/.github/workflows/test-storage.yml index a23839cb4..2ee696439 100644 --- a/.github/workflows/test-storage.yml +++ b/.github/workflows/test-storage.yml @@ -3,6 +3,7 @@ name: Test Storage env: TEST_PATH: Storage/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -51,7 +52,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -66,7 +68,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-task.yml b/.github/workflows/test-task.yml index fb1be5be4..239753e58 100644 --- a/.github/workflows/test-task.yml +++ b/.github/workflows/test-task.yml @@ -3,6 +3,7 @@ name: Test Task env: TEST_PATH: Task/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -53,7 +54,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -68,7 +70,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test-tick.yml b/.github/workflows/test-tick.yml deleted file mode 100644 index 367ee78f6..000000000 --- a/.github/workflows/test-tick.yml +++ /dev/null @@ -1,70 +0,0 @@ ---- -name: Test Tick - -env: - TEST_PATH: Tick/tests - -# yamllint disable-line rule:truthy -on: - pull_request: - paths: - - .github/workflows/test-tick.yml - - Tick/**.h - push: - paths: - - .github/workflows/test-tick.yml - - Tick/**.h - -jobs: - - compile: - name: Compile - uses: ./.github/workflows/compile-mql.yml - with: - artifact_prefix: mt - path: Tick/tests - skip_cleanup: true - - test: - defaults: - run: - shell: bash - working-directory: ${{ env.TEST_PATH }} - name: Test - needs: compile - runs-on: ubuntu-latest - strategy: - matrix: - test: - - TickManager.test - version: [5] - max-parallel: 4 - steps: - - uses: actions/download-artifact@v4 - with: - name: files-ex${{ matrix.version }} - - name: List compiled files - run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} - uses: fx31337/mql-tester-action@master - with: - Login: ${{ secrets.MT5_LOGIN }} - Password: ${{ secrets.MT5_PASSWORD }} - Server: MetaQuotes-Demo - TestDeposit: 2000 - TestExpert: ${{ matrix.test }} - TestFromDate: ${{ matrix.year }}.01.01 - TestPeriod: M1 - TestSymbol: EURUSD - TestToDate: ${{ matrix.year }}.01.14 - # yamllint disable-line rule:line-length - UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} - Version: 5 - - if: ${{ failure() }} - uses: mxschmitt/action-tmate@v3 - timeout-minutes: 20 - - cleanup: - name: Clean-up - needs: [compile] - uses: ./.github/workflows/cleanup.yml diff --git a/.github/workflows/test-trade.yml b/.github/workflows/test-trade.yml index 5b6964b3c..2f16435b5 100644 --- a/.github/workflows/test-trade.yml +++ b/.github/workflows/test-trade.yml @@ -3,6 +3,7 @@ name: Test Trade env: TEST_PATH: Trade/tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -48,7 +49,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -63,7 +65,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 985a09334..a97047d2b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,6 +3,7 @@ name: Test env: TEST_PATH: tests + TEST_SKIP: ${{ secrets.MT5_LOGIN || false }} # yamllint disable-line rule:truthy on: @@ -57,7 +58,8 @@ jobs: name: files-ex${{ matrix.version }} - name: List compiled files run: find . -name '*.ex?' -type f -print - - name: Run ${{ matrix.test }} + - if: ${{ env.TEST_SKIP != true }} + name: Run ${{ matrix.test }} uses: fx31337/mql-tester-action@master with: Login: ${{ secrets.MT5_LOGIN }} @@ -72,7 +74,7 @@ jobs: # yamllint disable-line rule:line-length UrlExpert: file://${{ github.workspace }}/${{ env.TEST_PATH }}/${{ matrix.test }}.ex${{ matrix.version }} Version: 5 - - if: ${{ failure() }} + - if: ${{ failure() && runner.debug }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 20 diff --git a/Convert.basic.h b/Convert.basic.h index b985b961a..62fde0906 100644 --- a/Convert.basic.h +++ b/Convert.basic.h @@ -21,8 +21,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Includes. @@ -90,6 +90,14 @@ class ConvertBasic { static void StringToType(string _value, unsigned char& _out) { _out = (unsigned char)_value[0]; } static void StringToType(string _value, int64& _out) { _out = StringToInteger(_value); } static void StringToType(string _value, uint64& _out) { _out = StringToInteger(_value); } + +#ifndef __MQL__ + // @fixit + // Two specializations for C++'s "long". It is required until we refactor all "[unsigned] long"'s into "[u]int64"'s. + static void StringToType(string _value, long& _out) { _out = (long)StringToInteger(_value); } + static void StringToType(string _value, unsigned long& _out) { _out = (unsigned long)StringToInteger(_value); } +#endif + static void StringToType(string _value, short& _out) { _out = (short)StringToInteger(_value); } static void StringToType(string _value, unsigned short& _out) { _out = (unsigned short)StringToInteger(_value); } static void StringToType(string _value, float& _out) { _out = (float)StringToDouble(_value); } @@ -118,6 +126,14 @@ class ConvertBasic { static void BoolToType(bool _value, unsigned int& _out) { _out = (unsigned int)_value; } static void BoolToType(bool _value, int64& _out) { _out = (int64)_value; } static void BoolToType(bool _value, uint64& _out) { _out = (uint64)_value; } + +#ifndef __MQL__ + // @fixit + // Two specializations for C++'s "long". It is required until we refactor all "[unsigned] long"'s into "[u]int64"'s. + static void BoolToType(bool _value, long& _out) { _out = (long)_value; } + static void BoolToType(bool _value, unsigned long& _out) { _out = (unsigned long)_value; } +#endif + static void BoolToType(bool _value, short& _out) { _out = (short)_value; } static void BoolToType(bool _value, unsigned short& _out) { _out = (unsigned short)_value; } static void BoolToType(bool _value, float& _out) { _out = (float)_value; } @@ -140,6 +156,14 @@ class ConvertBasic { static void LongToType(int64 _value, unsigned int& _out) { _out = (unsigned int)_value; } static void LongToType(int64 _value, int64& _out) { _out = (int64)_value; } static void LongToType(int64 _value, uint64& _out) { _out = (uint64)_value; } + +#ifndef __MQL__ + // @fixit + // Two specializations for C++'s "long". It is required until we refactor all "[unsigned] long"'s into "[u]int64"'s. + static void LongToType(int64 _value, long& _out) { _out = (long)_value; } + static void LongToType(int64 _value, unsigned long& _out) { _out = (unsigned long)_value; } +#endif + static void LongToType(int64 _value, short& _out) { _out = (short)_value; } static void LongToType(int64 _value, unsigned short& _out) { _out = (unsigned short)_value; } static void LongToType(int64 _value, float& _out) { _out = (float)_value; } @@ -162,6 +186,14 @@ class ConvertBasic { static void DoubleToType(double _value, unsigned int& _out) { _out = (unsigned int)_value; } static void DoubleToType(double _value, int64& _out) { _out = (int64)_value; } static void DoubleToType(double _value, uint64& _out) { _out = (uint64)_value; } + +#ifndef __MQL__ + // @fixit + // Two specializations for C++'s "long". It is required until we refactor all "[unsigned] long"'s into "[u]int64"'s. + static void DoubleToType(double _value, long& _out) { _out = (long)_value; } + static void DoubleToType(double _value, unsigned long& _out) { _out = (unsigned long)_value; } +#endif + static void DoubleToType(double _value, short& _out) { _out = (short)_value; } static void DoubleToType(double _value, unsigned short& _out) { _out = (unsigned short)_value; } static void DoubleToType(double _value, float& _out) { _out = (float)_value; } @@ -195,6 +227,22 @@ class ConvertBasic { return _out; } +#ifndef __MQL__ + // @fixit + // Twop specialization for C++'s "long". It is required until we refactor all "[unsigned] long"'s into "[u]int64"'s. + template + static T Convert(long _value, T& _out) { + LongToType(_value, _out); + return _out; + } + + template + static T Convert(unsigned long _value, T& _out) { + LongToType(_value, _out); + return _out; + } +#endif + template static T Convert(double _value, T& _out) { DoubleToType(_value, _out); diff --git a/EA.mqh b/EA.mqh index 97f0f6471..b894673d4 100644 --- a/EA.mqh +++ b/EA.mqh @@ -26,16 +26,16 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Includes. -#include "Platform/Chart/Chart.struct.static.h" #include "EA.enum.h" #include "EA.struct.h" #include "Market.mqh" #include "Platform/Chart/Chart.h" +#include "Platform/Chart/Chart.struct.static.h" #include "Platform/Platform.h" #include "Platform/Terminal.h" #include "Refs.struct.h" @@ -97,7 +97,8 @@ class EA : public Taskable { */ void InitTask() { // Add and process init task. - TaskObject _taskobj_init(eparams.GetStruct(STRUCT_ENUM(EAParams, EA_PARAM_STRUCT_TASK_ENTRY)), + TaskEntry _task_entry(eparams.GetStruct(STRUCT_ENUM(EAParams, EA_PARAM_STRUCT_TASK_ENTRY))); + TaskObject _taskobj_init(_task_entry, THIS_PTR, THIS_PTR); estate.Set(STRUCT_ENUM(EAState, EA_STATE_FLAG_ON_INIT), true); _taskobj_init.Process(); @@ -162,7 +163,7 @@ class EA : public Taskable { */ template T Get(ENUM_TRADE_STATE _state, string _symbol = NULL) { - return trade.GetByKey(_symbol != NULL ? _symbol : _Symbol).Get(_state); + return trade.GetByKey(_symbol != "" ? _symbol : _Symbol) PTR_DEREF Get(_state); } /** @@ -281,8 +282,9 @@ class EA : public Taskable { } Trade *_trade = trade.GetByKey(_Symbol); Strategy *_strat = - strats.GetByKey(_signal PTR_DEREF Get(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_PROP_MAGIC_ID))).Ptr(); - _trade_allowed &= _trade.IsTradeAllowed(); + strats.GetByKey(_signal PTR_DEREF Get(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_PROP_MAGIC_ID))) + .Ptr(); + _trade_allowed &= _trade PTR_DEREF IsTradeAllowed(); if (_trade PTR_DEREF Get(TRADE_STATE_ORDERS_ACTIVE)) { float _sig_close = _signal PTR_DEREF GetSignalClose(); string _comment_close = @@ -293,16 +295,16 @@ class EA : public Taskable { if (_sig_close >= 0.5f) { // Close signal for buy order. _trade PTR_DEREF OrdersCloseViaProp2( - ORDER_MAGIC, _signal PTR_DEREF Get(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_PROP_MAGIC_ID)), ORDER_TYPE, - ORDER_TYPE_BUY, MATH_COND_EQ, ORDER_REASON_CLOSED_BY_SIGNAL, _comment_close); + ORDER_MAGIC, _signal PTR_DEREF Get(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_PROP_MAGIC_ID)), + ORDER_TYPE, ORDER_TYPE_BUY, MATH_COND_EQ, ORDER_REASON_CLOSED_BY_SIGNAL, _comment_close); // Buy orders closed. _strat PTR_DEREF OnOrderClose(ORDER_TYPE_BUY); } if (_sig_close <= -0.5f) { // Close signal for sell order. _trade PTR_DEREF OrdersCloseViaProp2( - ORDER_MAGIC, _signal PTR_DEREF Get(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_PROP_MAGIC_ID)), ORDER_TYPE, - ORDER_TYPE_SELL, MATH_COND_EQ, ORDER_REASON_CLOSED_BY_SIGNAL, _comment_close); + ORDER_MAGIC, _signal PTR_DEREF Get(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_PROP_MAGIC_ID)), + ORDER_TYPE, ORDER_TYPE_SELL, MATH_COND_EQ, ORDER_REASON_CLOSED_BY_SIGNAL, _comment_close); // Sell orders closed. _strat PTR_DEREF OnOrderClose(ORDER_TYPE_SELL); } @@ -312,14 +314,15 @@ class EA : public Taskable { if (_trade_allowed) { float _sig_open = _signal PTR_DEREF GetSignalOpen(); unsigned int _sig_f = eparams.Get(STRUCT_ENUM(EAParams, EA_PARAM_PROP_SIGNAL_FILTER)); - string _comment_open = _strat != NULL && _sig_open != 0.0f ? _strat PTR_DEREF GetOrderOpenComment() : __FUNCTION_LINE__; + string _comment_open = + _strat != NULL && _sig_open != 0.0f ? _strat PTR_DEREF GetOrderOpenComment() : __FUNCTION_LINE__; // Open orders on signals. // _trade_allowed &= _strat PTR_DEREF GetTrade() PTR_DEREF IsTradeAllowed(_sig_open != 0.0f); if (_sig_open != 0.0f && _trade_allowed) { if (_sig_open >= 0.5f) { // Open signal for buy. // When H1 or H4 signal filter is enabled, do not open minute-based orders on opposite or neutral signals. - if (GetSignalOpenFiltered(_signal, _sig_f) >= 0.5f) { + if (GetSignalOpenFiltered(PTR_TO_REF(_signal), _sig_f) >= 0.5f) { _strat PTR_DEREF Set(TRADE_PARAM_ORDER_COMMENT, _comment_open); // Buy order open. _result_local &= TradeRequest(ORDER_TYPE_BUY, _Symbol, _strat); @@ -334,7 +337,7 @@ class EA : public Taskable { if (_sig_open <= -0.5f) { // Open signal for sell. // When H1 or H4 signal filter is enabled, do not open minute-based orders on opposite or neutral signals. - if (GetSignalOpenFiltered(_signal, _sig_f) <= -0.5f) { + if (GetSignalOpenFiltered(PTR_TO_REF(_signal), _sig_f) <= -0.5f) { _strat PTR_DEREF Set(TRADE_PARAM_ORDER_COMMENT, _comment_open); // Sell order open. _result_local &= TradeRequest(ORDER_TYPE_SELL, _Symbol, _strat); @@ -398,11 +401,11 @@ class EA : public Taskable { // Check strategy's trade states. switch (_request.action) { case TRADE_ACTION_DEAL: - if (!_trade.IsTradeRecommended()) { + if (!_trade PTR_DEREF IsTradeRecommended()) { if (logger.GetLevel() > V_INFO) { - logger.Debug( - StringFormat("Trade not opened due to EA trading states (%d).", _trade.GetStates().GetStates()), - __FUNCTION_LINE__); + logger.Debug(StringFormat("Trade not opened due to EA trading states (%d).", + _trade PTR_DEREF GetStates().GetStates()), + __FUNCTION_LINE__); } return _result; } @@ -414,19 +417,19 @@ class EA : public Taskable { // Send the request. _result = _trade PTR_DEREF RequestSend(_request, _oparams); if (!_result) { // && _strade.IsTradeRecommended( - logger.Debug( - StringFormat("Error while sending a trade request! Entry: %s", - SerializerConverter::FromObject(MqlTradeRequestProxy(_request)).ToString()), - __FUNCTION_LINE__, StringFormat("Code: %d, Msg: %s", _LastError, Terminal::GetErrorText(_LastError))); - if (_trade.IsTradeRecommended()) { - logger.Debug( - StringFormat("Error while sending a trade request! Entry: %s", - SerializerConverter::FromObject(MqlTradeRequestProxy(_request)).ToString()), - __FUNCTION_LINE__, StringFormat("Code: %d, Msg: %s", _LastError, Terminal::GetErrorText(_LastError))); + MqlTradeRequestProxy _request_proxy(_request); + logger.Debug(StringFormat("Error while sending a trade request! Entry: %s", + C_STR(SerializerConverter::FromObject(_request_proxy).ToString())), + __FUNCTION_LINE__, + StringFormat("Code: %d, Msg: %s", _LastError, C_STR(Terminal::GetErrorText(_LastError)))); + if (_trade PTR_DEREF IsTradeRecommended()) { + logger.Debug(StringFormat("Error while sending a trade request! Entry: %s", + C_STR(SerializerConverter::FromObject(_request_proxy).ToString())), + __FUNCTION_LINE__, + StringFormat("Code: %d, Msg: %s", _LastError, C_STR(Terminal::GetErrorText(_LastError)))); } #ifdef __debug_ea__ - Print(__FUNCTION_LINE__ + - "(): " + SerializerConverter::FromObject(MqlTradeRequestProxy(_request)).ToString()); + Print(__FUNCTION_LINE__ + "(): " + SerializerConverter::FromObject(_request_proxy).ToString()); #endif } return _result; @@ -462,7 +465,8 @@ class EA : public Taskable { if (_strat PTR_DEREF TickFilter(_tick)) { _can_trade &= !_trade PTR_DEREF HasState(TRADE_STATE_MODE_DISABLED); _can_trade &= !_strat PTR_DEREF IsSuspended(); - TradeSignalEntry _sentry = GetStrategySignalEntry(_strat, _can_trade, _strat PTR_DEREF Get(STRAT_PARAM_SHIFT)); + TradeSignalEntry _sentry = + GetStrategySignalEntry(_strat, _can_trade, _strat PTR_DEREF Get(STRAT_PARAM_SHIFT)); if (_sentry.Get(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_PROP_SIGNALS)) > 0) { TradeSignal _signal(_sentry); if (_signal.GetSignalClose() != _signal.GetSignalOpen()) { @@ -544,7 +548,8 @@ class EA : public Taskable { } */ if (eparams.CheckFlagDataStore(EA_DATA_STORE_SYMBOL)) { - data_symbol.Add(SymbolInfo().GetEntryLast(), _timestamp); + SymbolInfoEntry _entry = SymbolInfo().GetEntryLast(); + data_symbol.Add(_entry, _timestamp); } if (eparams.CheckFlagDataStore(EA_DATA_STORE_TRADE)) { // @todo @@ -720,28 +725,30 @@ class EA : public Taskable { float _sig_open = _signal.GetSignalOpen(); ENUM_TIMEFRAMES _sig_tf = _signal.Get(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_PROP_TF)); if (ChartTf::TfToHours(_sig_tf) < 1 && bool(_sf & STRUCT_ENUM(EAParams, EA_PARAM_SIGNAL_FILTER_OPEN_M_IF_H))) { - for (DictStructIterator> _iter = GetStrategies().Begin(); _iter.IsValid(); ++_iter) { + for (DictStructIterator> _iter = GetStrategies() PTR_DEREF Begin(); _iter.IsValid(); + ++_iter) { Strategy *_strat = _iter.Value().Ptr(); ENUM_TIMEFRAMES _stf = _strat PTR_DEREF Get(STRAT_PARAM_TF); if (ChartTf::TfToHours(_stf) >= 1) { - TradeSignal *_hsignal0 = - tsm.GetSignalByCid(_strat PTR_DEREF Get(STRAT_PARAM_ID), (int)_stf, (int)ChartStatic::iTime(_Symbol, _stf)); - TradeSignal *_hsignal1 = - tsm.GetSignalByCid(_strat PTR_DEREF Get(STRAT_PARAM_ID), (int)_stf, (int)ChartStatic::iTime(_Symbol, _stf, 1)); - TradeSignal *_hsignal2 = - tsm.GetSignalByCid(_strat PTR_DEREF Get(STRAT_PARAM_ID), (int)_stf, (int)ChartStatic::iTime(_Symbol, _stf, 2)); + TradeSignal *_hsignal0 = tsm.GetSignalByCid(_strat PTR_DEREF Get(STRAT_PARAM_ID), (int)_stf, + (int)ChartStatic::iTime(_Symbol, _stf)); + TradeSignal *_hsignal1 = tsm.GetSignalByCid(_strat PTR_DEREF Get(STRAT_PARAM_ID), (int)_stf, + (int)ChartStatic::iTime(_Symbol, _stf, 1)); + TradeSignal *_hsignal2 = tsm.GetSignalByCid(_strat PTR_DEREF Get(STRAT_PARAM_ID), (int)_stf, + (int)ChartStatic::iTime(_Symbol, _stf, 2)); // Increase signal if confirmed by hourly signal. - if (_hsignal0 != NULL && _hsignal0.Get(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_PROP_TIME)) > 0) { - _sig_open += ((_sig_open > 0) == (_hsignal0.GetSignalOpen() > 0)) ? 1.0f : -1.0f; - _sig_open -= ((_sig_open < 0) == (_hsignal0.GetSignalOpen() < 0)) ? 1.0f : -1.0f; + if (_hsignal0 != NULL && + _hsignal0 PTR_DEREF Get(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_PROP_TIME)) > 0) { + _sig_open += ((_sig_open > 0) == (_hsignal0 PTR_DEREF GetSignalOpen() > 0)) ? 1.0f : -1.0f; + _sig_open -= ((_sig_open < 0) == (_hsignal0 PTR_DEREF GetSignalOpen() < 0)) ? 1.0f : -1.0f; } else if (_hsignal1 != NULL && - _hsignal1.Get(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_PROP_TIME)) > 0) { - _sig_open += ((_sig_open > 0) == (_hsignal1.GetSignalOpen() > 0)) ? 0.5f : -0.5f; - _sig_open -= ((_sig_open < 0) == (_hsignal1.GetSignalOpen() < 0)) ? 0.5f : -0.5f; + _hsignal1 PTR_DEREF Get(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_PROP_TIME)) > 0) { + _sig_open += ((_sig_open > 0) == (_hsignal1 PTR_DEREF GetSignalOpen() > 0)) ? 0.5f : -0.5f; + _sig_open -= ((_sig_open < 0) == (_hsignal1 PTR_DEREF GetSignalOpen() < 0)) ? 0.5f : -0.5f; } else if (_hsignal2 != NULL && - _hsignal2.Get(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_PROP_TIME)) > 0) { - _sig_open += ((_sig_open > 0) == (_hsignal2.GetSignalOpen() > 0)) ? 0.2f : -0.2f; - _sig_open -= ((_sig_open < 0) == (_hsignal2.GetSignalOpen() < 0)) ? 0.2f : -0.2f; + _hsignal2 PTR_DEREF Get(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_PROP_TIME)) > 0) { + _sig_open += ((_sig_open > 0) == (_hsignal2 PTR_DEREF GetSignalOpen() > 0)) ? 0.2f : -0.2f; + _sig_open -= ((_sig_open < 0) == (_hsignal2 PTR_DEREF GetSignalOpen() < 0)) ? 0.2f : -0.2f; } else { // Decrease signal by 0.1 if no hourly signal is found. _sig_open -= 0.1f; @@ -768,21 +775,21 @@ class EA : public Taskable { bool StrategyAdd(ENUM_TIMEFRAMES _tf, int64 _magic_no = 0, int _type = 0) { bool _result = true; _magic_no = _magic_no > 0 ? _magic_no : rand(); - Ref _strat = ((SClass *)NULL).Init(_tf, THIS_PTR); - _strat PTR_DEREF Ptr().Set(STRAT_PARAM_ID, _magic_no); - _strat PTR_DEREF Ptr().Set(TRADE_PARAM_MAGIC_NO, _magic_no); - _strat PTR_DEREF Ptr().Set(STRAT_PARAM_LOG_LEVEL, - (ENUM_LOG_LEVEL)eparams.Get(STRUCT_ENUM(EAParams, EA_PARAM_PROP_LOG_LEVEL))); - _strat PTR_DEREF Ptr().Set(STRAT_PARAM_TF, _tf); - _strat PTR_DEREF Ptr().Set(STRAT_PARAM_TYPE, _type); - _strat PTR_DEREF Ptr().OnInit(); + Ref _strat = new SClass(_tf, THIS_PTR); + _strat REF_DEREF Set(STRAT_PARAM_ID, _magic_no); + _strat REF_DEREF Set(TRADE_PARAM_MAGIC_NO, _magic_no); + _strat REF_DEREF Set(STRAT_PARAM_LOG_LEVEL, + (ENUM_LOG_LEVEL)eparams.Get(STRUCT_ENUM(EAParams, EA_PARAM_PROP_LOG_LEVEL))); + _strat REF_DEREF Set(STRAT_PARAM_TF, _tf); + _strat REF_DEREF Set(STRAT_PARAM_TYPE, _type); + _strat REF_DEREF OnInit(); if (!strats.KeyExists(_magic_no)) { _result &= strats.Set(_magic_no, _strat); } else { logger.Error("Strategy adding conflict!", __FUNCTION_LINE__); DebugBreak(); } - OnStrategyAdd(_strat PTR_DEREF Ptr()); + OnStrategyAdd(_strat.Ptr()); return _result; } @@ -820,14 +827,15 @@ class EA : public Taskable { bool _result = true; Trade *_trade = trade.GetByKey(_Symbol); // Load active trades. - _result &= _trade.OrdersLoadByMagic(_strat PTR_DEREF Get(STRAT_PARAM_ID)); + _result &= _trade PTR_DEREF OrdersLoadByMagic(_strat PTR_DEREF Get(STRAT_PARAM_ID)); // Load strategy-specific order parameters (e.g. conditions). // This is a temporary workaround for GH-705. // @todo: To move to Strategy class. Ref _order; - for (DictStructIterator> iter = _trade.GetOrdersActive().Begin(); iter.IsValid(); ++iter) { + for (DictStructIterator> iter = _trade PTR_DEREF GetOrdersActive() PTR_DEREF Begin(); + iter.IsValid(); ++iter) { _order = iter.Value(); - if (_order.IsSet() && _order.Ptr().IsOpen()) { + if (_order.IsSet() && _order REF_DEREF IsOpen()) { _strat PTR_DEREF OnOrderLoad(_order.Ptr()); } } @@ -847,8 +855,10 @@ class EA : public Taskable { ResetLastError(); for (DictObjectIterator titer = trade.Begin(); titer.IsValid(); ++titer) { Trade *_trade = titer.Value(); - if (_trade.Get(TRADE_STATE_ORDERS_ACTIVE) && !_trade.Get(TRADE_STATE_MARKET_CLOSED)) { - for (DictStructIterator> oiter = _trade.GetOrdersActive().Begin(); oiter.IsValid(); ++oiter) { + if (_trade PTR_DEREF Get(TRADE_STATE_ORDERS_ACTIVE) && + !_trade PTR_DEREF Get(TRADE_STATE_MARKET_CLOSED)) { + for (DictStructIterator> oiter = _trade PTR_DEREF GetOrdersActive() PTR_DEREF Begin(); + oiter.IsValid(); ++oiter) { bool _sl_valid = false, _tp_valid = false; double _sl_new = 0, _tp_new = 0; Order *_order = oiter.Value().Ptr(); @@ -895,7 +905,7 @@ class EA : public Taskable { if (_result) { _order PTR_DEREF Set(ORDER_PROP_TIME_LAST_UPDATE, TimeCurrent()); } else { - _trade.UpdateStates(true); + _trade PTR_DEREF UpdateStates(true); } } } @@ -1045,17 +1055,17 @@ class EA : public Taskable { // 1st (i:0) - Strategy's enum action to execute. // 2nd (i:1) - Strategy's argument to pass. TaskActionEntry _entry_strat = _entry; - _entry_strat PTR_DEREF ArgRemove(0); - for (DictStructIterator> iter_strat = strats.Begin(); iter_strat PTR_DEREF IsValid(); ++iter_strat) { - Strategy *_strat = iter_strat PTR_DEREF Value().Ptr(); + _entry_strat.ArgRemove(0); + for (DictStructIterator> iter_strat = strats.Begin(); iter_strat.IsValid(); ++iter_strat) { + Strategy *_strat = iter_strat.Value().Ptr(); _result &= _strat PTR_DEREF Run(_entry_strat); } return _result; } case EA_ACTION_TASKS_CLEAN: - tasks.GetTasks().Clear(); - return tasks.GetTasks().Size() == 0; + tasks.GetTasks() PTR_DEREF Clear(); + return tasks.GetTasks() PTR_DEREF Size() == 0; default: GetLogger() PTR_DEREF Error(StringFormat("Invalid EA action: %d!", _entry.GetId(), __FUNCTION_LINE__)); SetUserError(ERR_INVALID_PARAMETER); diff --git a/EA.struct.h b/EA.struct.h index 46eae797c..0efcb2a16 100644 --- a/EA.struct.h +++ b/EA.struct.h @@ -26,8 +26,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Includes. @@ -204,7 +204,9 @@ struct EAParams { } void SetTaskEntry(TaskEntry &_task_entry) { task_init = _task_entry; } // Printers. - string ToString(string _dlm = ",") { return StringFormat("%s v%s by %s (%s)", name, ver, author, desc); } + string ToString(string _dlm = ",") { + return StringFormat("%s v%s by %s (%s)", C_STR(name), C_STR(ver), C_STR(author), C_STR(desc)); + } }; /* Defines struct to store results for EA processing. */ diff --git a/Exchange/Account/AccountMt.h b/Exchange/Account/AccountMt.h index 7b71ebf3c..e21e936aa 100644 --- a/Exchange/Account/AccountMt.h +++ b/Exchange/Account/AccountMt.h @@ -21,8 +21,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Forward class declaration. @@ -286,7 +286,7 @@ class AccountMt : public AccountBase { return ::AccountFreeMarginMode(); #else // @todo: Not implemented yet. - return NULL_VALUE; + return (double)NULL_VALUE; #endif } static double GetAccountFreeMarginMode() { return AccountMt::AccountFreeMarginMode(); } diff --git a/Indicator/Indicator.h b/Indicator/Indicator.h index 87c6adcf6..fb8859785 100644 --- a/Indicator/Indicator.h +++ b/Indicator/Indicator.h @@ -21,8 +21,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Forward class declaration. @@ -51,17 +51,6 @@ struct IndicatorParams; #include "../Storage/ValueStorage.native.h" #include "../Task/TaskCondition.enum.h" -#ifndef __MQL4__ -// Defines global functions (for MQL4 backward compatibility). -bool IndicatorBuffers(int _count) { return Indicator::SetIndicatorBuffers(_count); } -int IndicatorCounted(int _value = 0) { - static int prev_calculated = 0; - // https://docs.mql4.com/customind/indicatorcounted - prev_calculated = _value > 0 ? _value : prev_calculated; - return prev_calculated; -} -#endif - #ifdef __MQL5__ // Defines global functions (for MQL5 forward compatibility). template T Get(STRUCT_ENUM(IndicatorParams, ENUM_INDI_PARAMS_PROP) _param) const { +#ifdef __MQL__ return iparams.Get(_param); +#else + return iparams.Get(_param); +#endif } /** @@ -213,7 +206,11 @@ class Indicator : public IndicatorData { */ template void Set(STRUCT_ENUM(IndicatorParams, ENUM_INDI_PARAMS_PROP) _param, T _value) { +#ifdef __MQL__ iparams.Set(_param, _value); +#else + iparams.Set(_param, _value); +#endif } /** @@ -508,7 +505,7 @@ class Indicator : public IndicatorData { int64 _arg1 = ArraySize(_args) > 0 ? DataParamEntry::ToInteger(_args[0]) : WRONG_VALUE; switch (_action) { case INDI_ACTION_CLEAR_CACHE: - _arg1 = _arg1 > 0 ? _arg1 : TimeCurrent(); + _arg1 = _arg1 > 0 ? _arg1 : (int64)TimeCurrent(); idata.Clear(_arg1); return true; default: @@ -757,3 +754,14 @@ class Indicator : public IndicatorData { return false; }; }; + +#ifndef __MQL4__ +// Defines global functions (for MQL4 backward compatibility). +bool IndicatorBuffers(int _count) { return Indicator::SetIndicatorBuffers(_count); } +int IndicatorCounted(int _value = 0) { + static int prev_calculated = 0; + // https://docs.mql4.com/customind/indicatorcounted + prev_calculated = _value > 0 ? _value : prev_calculated; + return prev_calculated; +} +#endif diff --git a/Indicator/Indicator.struct.h b/Indicator/Indicator.struct.h index ff3da54e5..c488930ce 100644 --- a/Indicator/Indicator.struct.h +++ b/Indicator/Indicator.struct.h @@ -26,8 +26,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Forward declaration. @@ -49,11 +49,12 @@ struct ChartParams; struct IndicatorParams { protected: void Init() {} + public: // @todo: Change it to protected. string custom_indi_name; // Name of the indicator passed to iCustom() method. string name; // Name of the indicator. int shift; // Shift (relative to the current bar, 0 - default). - uint bps; // A candle chart per number of seconds (e.g. for M1 is 60). + unsigned int bps; // A candle chart per number of seconds (e.g. for M1 is 60). unsigned int max_params; // Max supported input params. ENUM_INDICATOR_TYPE itype; // Indicator type (e.g. INDI_RSI). color indi_color; // Indicator color. @@ -65,6 +66,7 @@ struct IndicatorParams { enum ENUM_INDI_PARAMS_PROP { INDI_PARAMS_PROP_BPS, }; + public: /* Special methods */ // Constructor. @@ -131,7 +133,7 @@ struct IndicatorParams { void Set(STRUCT_ENUM(IndicatorParams, ENUM_INDI_PARAMS_PROP) _prop, T _value) { switch (_prop) { case INDI_PARAMS_PROP_BPS: - flags = (uint)_value; + bps = (unsigned int)_value; return; default: break; diff --git a/Indicator/IndicatorCandle.h b/Indicator/IndicatorCandle.h index 2e415cce1..c97d9a9d9 100644 --- a/Indicator/IndicatorCandle.h +++ b/Indicator/IndicatorCandle.h @@ -359,7 +359,7 @@ class IndicatorCandle : public Indicator { */ void OnDataSourceWillEmitEntries(ENUM_INDI_EMITTED_ENTRY_TYPE _type, int _num_entries) override { if (_type == INDI_EMITTED_ENTRY_TYPE_CANDLE) { - idata.Reserve(_num_entries); + THIS_ATTR idata.Reserve(_num_entries); } } diff --git a/Indicator/IndicatorData.h b/Indicator/IndicatorData.h index e08ab6799..181ce434f 100644 --- a/Indicator/IndicatorData.h +++ b/Indicator/IndicatorData.h @@ -1249,7 +1249,7 @@ class IndicatorData : public IndicatorBase { /** * Returns the indicator's struct value via timestamp. */ - // virtual IndicatorDataEntry GetEntry(datetime _dt) = nullptr; + // virtual IndicatorDataEntry GetEntry(datetime _dt) = 0; /** * Gets high price for a given, optional shift. @@ -1264,12 +1264,12 @@ class IndicatorData : public IndicatorBase { */ virtual void GetEntryAlter(IndicatorDataEntry& _entry, int _rel_shift) {} - // virtual ENUM_IDATA_VALUE_RANGE GetIDataValueRange() = nullptr; + // virtual ENUM_IDATA_VALUE_RANGE GetIDataValueRange() = 0; /** * Returns the indicator's entry value. */ - virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _abs_shift = 0) = nullptr; + virtual IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _abs_shift = 0) = 0; /** * Returns the shift of the maximum value over a specific number of periods depending on type. @@ -1338,7 +1338,7 @@ class IndicatorData : public IndicatorBase { * * When indicator values are not valid, returns empty signals. */ - virtual IndicatorSignal GetSignals(int _count = 3, int _shift = 0, int _mode1 = 0, int _mode2 = 0) = nullptr; + virtual IndicatorSignal GetSignals(int _count = 3, int _shift = 0, int _mode1 = 0, int _mode2 = 0) = 0; /** * Returns spread for the bar. @@ -1828,7 +1828,7 @@ class IndicatorData : public IndicatorBase { void EmitEntry(IndicatorDataEntry& _entry, ENUM_INDI_EMITTED_ENTRY_TYPE _type = INDI_EMITTED_ENTRY_TYPE_PARENT) { for (int i = 0; i < ArraySize(listeners); ++i) { if (listeners[i].ObjectExists()) { - listeners[i].Ptr().OnDataSourceEntry(_entry, _type); + listeners[i].Ptr() PTR_DEREF OnDataSourceEntry(_entry, _type); } } } @@ -1839,7 +1839,7 @@ class IndicatorData : public IndicatorBase { void WillEmitEntries(ENUM_INDI_EMITTED_ENTRY_TYPE _type, int _num_entries) { for (int i = 0; i < ArraySize(listeners); ++i) { if (listeners[i].ObjectExists()) { - listeners[i].Ptr().OnDataSourceWillEmitEntries(_type, _num_entries); + listeners[i].Ptr() PTR_DEREF OnDataSourceWillEmitEntries(_type, _num_entries); } } } @@ -2038,8 +2038,8 @@ int GetBarsFromStart(IndicatorData* _indi) { return _indi PTR_DEREF GetBars(); } #endif #ifdef EMSCRIPTEN -#include -#include + #include + #include EMSCRIPTEN_BINDINGS(IndicatorData) { emscripten::class_>("IndicatorData") diff --git a/Indicator/IndicatorTf.h b/Indicator/IndicatorTf.h index 8de961cde..30f038823 100644 --- a/Indicator/IndicatorTf.h +++ b/Indicator/IndicatorTf.h @@ -44,7 +44,8 @@ class IndicatorTf : public IndicatorCandle(ChartTf::TfToSeconds(GetTf()), THIS_PTR)); + THIS_ATTR history.SetItemProvider( + new ItemsHistoryTfCandleProvider(ChartTf::TfToSeconds(GetTf()), THIS_PTR)); } public: @@ -64,7 +65,7 @@ class IndicatorTf : public IndicatorCandle { static double iMA(string _symbol, ENUM_TIMEFRAMES _tf, unsigned int _ma_period, unsigned int _ma_shift, ENUM_MA_METHOD _ma_method, ENUM_APPLIED_PRICE _applied_price, int _shift = 0, IndicatorData *_obj = NULL) { -#ifdef __MQL__ -#ifdef __MQL4__ + #ifdef __MQL__ + #ifdef __MQL4__ return ::iMA(_symbol, _tf, _ma_period, _ma_shift, _ma_method, _applied_price, _shift); -#else // __MQL5__ + #else // __MQL5__ INDICATOR_BUILTIN_CALL_AND_RETURN(::iMA(_symbol, _tf, _ma_period, _ma_shift, _ma_method, _applied_price), 0, _shift); -#endif -#else // Non-MQL. + #endif + #else // Non-MQL. // @todo: Use Platform class. RUNTIME_ERROR( "Not implemented. Please use an On-Indicator mode and attach " "indicator via Platform::Add/AddWithDefaultBindings()."); return DBL_MAX; -#endif + #endif } /** @@ -162,16 +162,16 @@ class Indi_MA : public Indicator { */ static double iMAOnArray(ARRAY_REF(double, price), int total, int ma_period, int ma_shift, ENUM_MA_METHOD ma_method, int shift, IndiBufferCache *cache = NULL) { -#ifdef __MQL4__ + #ifdef __MQL4__ return ::iMAOnArray(price, total, ma_period, ma_shift, ma_method, shift); -#else + #else // We're reusing the same native array for each consecutive calculation. NativeValueStorage *_array_storage = Singleton>::Get(); _array_storage PTR_DEREF SetData(price); return iMAOnArray(PTR_TO_REF((ValueStorage *)_array_storage), total, ma_period, ma_shift, ma_method, shift, cache); -#endif + #endif } /** @@ -565,7 +565,7 @@ class Indi_MA : public Indicator { } static int LinearWeightedMAOnBuffer(const int rates_total, const int prev_calculated, const int begin, - const int period, const ARRAY_REF(double, price), ARRAY_REF(double, buffer), + const int period, ARRAY_REF(double, price), ARRAY_REF(double, buffer), int &weight_sum) { int i, k; @@ -849,14 +849,14 @@ class Indi_MA : public Indicator { } }; -#ifdef __MQL4__ + #ifdef __MQL4__ // MQL4 version of the method doesn't have last parameter. int LinearWeightedMAOnBuffer(const int rates_total, const int prev_calculated, const int begin, const int period, - const double &price[], double &buffer[]) { + double &price[], double &buffer[]) { int _weight_sum; return Indi_MA::LinearWeightedMAOnBuffer(rates_total, prev_calculated, begin, period, price, buffer, _weight_sum); } -#else // !__MQL__4 + #else // !__MQL__4 // Defines global functions (for MQL4 backward compability). double iMA(string _symbol, int _tf, int _ma_period, int _ma_shift, ENUM_MA_METHOD _ma_method, int _ap, int _shift) { ResetLastError(); @@ -868,6 +868,6 @@ double iMAOnArray(ARRAY_REF(double, _arr), int _total, int _period, int _ma_shif ResetLastError(); return Indi_MA::iMAOnArray(_arr, _total, _period, _ma_shift, _ma_method, _abs_shift, _cache); } -#endif // __MQL4__ + #endif // __MQL4__ #endif // INDI_MA_MQH diff --git a/Indicators/PriceRange/Indi_Envelopes.h b/Indicators/PriceRange/Indi_Envelopes.h index ed6fa936f..cddee7762 100644 --- a/Indicators/PriceRange/Indi_Envelopes.h +++ b/Indicators/PriceRange/Indi_Envelopes.h @@ -21,8 +21,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Includes. @@ -116,9 +116,9 @@ class Indi_Envelopes : public Indicator { // UPPER_LINE, 1 - LOWER_LINE int _shift = 0, IndicatorData *_obj = NULL) { #ifdef __MQL__ -#ifdef __MQL4__ + #ifdef __MQL4__ return ::iEnvelopes(_symbol, _tf, _ma_period, _ma_method, _ma_shift, _ap, _deviation, _mode, _shift); -#else // __MQL5__ + #else // __MQL5__ switch (_mode) { case LINE_UPPER: _mode = 0; @@ -130,7 +130,7 @@ class Indi_Envelopes : public Indicator { INDICATOR_BUILTIN_CALL_AND_RETURN(::iEnvelopes(_symbol, _tf, _ma_period, _ma_shift, _ma_method, _ap, _deviation), _mode, _shift); -#endif + #endif #else // Non-MQL. // @todo: Use Platform class. RUNTIME_ERROR( @@ -151,7 +151,7 @@ class Indi_Envelopes : public Indicator { _ma_method, _ma_shift, _deviation, _mode, _shift, _target PTR_DEREF GetCache()); } - static double iEnvelopesOnArray(CONST_ARRAY_REF(double, price), int total, int ma_period, ENUM_MA_METHOD ma_method, + static double iEnvelopesOnArray(ARRAY_REF(double, price), int total, int ma_period, ENUM_MA_METHOD ma_method, int ma_shift, double deviation, int mode, int shift, IndiBufferCache *_cache = NULL) { #ifdef __MQL4__ @@ -331,7 +331,7 @@ double iEnvelopes(string _symbol, int _tf, int _period, int _ma_method, int _ma_ return Indi_Envelopes::iEnvelopes(_symbol, (ENUM_TIMEFRAMES)_tf, _period, (ENUM_MA_METHOD)_ma_method, _ma_shift, (ENUM_APPLIED_PRICE)_ap, _deviation, _mode, _shift); } -double iEnvelopesOnArray(CONST_ARRAY_REF(double, _arr), int _total, int _ma_period, int _ma_method, int _ma_shift, +double iEnvelopesOnArray(ARRAY_REF(double, _arr), int _total, int _ma_period, int _ma_method, int _ma_shift, double _deviation, int _mode, int _shift) { ResetLastError(); return Indi_Envelopes::iEnvelopesOnArray(_arr, _total, _ma_period, (ENUM_MA_METHOD)_ma_method, _ma_shift, _deviation, diff --git a/Market.mqh b/Market.mqh index 441d7c580..94322431b 100644 --- a/Market.mqh +++ b/Market.mqh @@ -271,7 +271,7 @@ class Market : public SymbolInfo { case MARKET_COND_SPREAD_GT_20: return GetSpreadInPts() > 20; default: - logger.Error(StringFormat("Invalid market condition: %s!", EnumToString(_cond), __FUNCTION_LINE__)); + logger.Error(StringFormat("Invalid market condition: %s!", C_STR(EnumToString(_cond)), __FUNCTION_LINE__)); return false; } } diff --git a/Math/Matrix.h b/Math/Matrix.h index 898bddc94..1733501c6 100644 --- a/Math/Matrix.h +++ b/Math/Matrix.h @@ -25,30 +25,29 @@ #define MATRIX_MQH #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif - #ifdef __MQL5__ -#define MATRIX_USE_OPENCL + #define MATRIX_USE_OPENCL #endif #ifdef USE_MQL_MATH_STAT -#ifdef __MQL5__ -#include -#endif + #ifdef __MQL5__ + #include + #endif #endif // Includes. #include "Math.h" #ifdef MATRIX_USE_OPENCL -#include "OpenCL.h" + #include "OpenCL.h" -#resource "Matrix.matmul.cl" as string CLSource_Matrix_MatMul -#resource "Matrix.matmul.naive.cl" as string CLSource_Matrix_MatMul_Naive -#resource "Matrix.matmul.test.cl" as string CLSource_Matrix_MatMul_Test + #resource "Matrix.matmul.cl" as string CLSource_Matrix_MatMul + #resource "Matrix.matmul.naive.cl" as string CLSource_Matrix_MatMul_Naive + #resource "Matrix.matmul.test.cl" as string CLSource_Matrix_MatMul_Test #endif // MATRIX_USE_OPENCL #define MATRIX_DIMENSIONS 6 @@ -843,7 +842,7 @@ class Matrix { return; } - Initialize(_right.ptr_first_dimension.Clone()); + Initialize(_right.ptr_first_dimension PTR_DEREF Clone()); #ifdef MATRIX_USE_OPENCL InitializeOpenCL(); #endif @@ -2673,7 +2672,7 @@ unsigned long Matrix::version_counter = 0; #ifdef MATRIX_USE_OPENCL -#ifdef __MQL__ + #ifdef __MQL__ template Ref Matrix::cl_program_matmul; template @@ -2684,7 +2683,7 @@ template DictStruct> Matrix::cl_buffers_in_1; template DictStruct> Matrix::cl_buffers_out; -#else + #else template Ref Matrix::cl_program_matmul; template @@ -2695,7 +2694,7 @@ template DictStruct> Matrix::cl_buffers_in_1; template DictStruct> Matrix::cl_buffers_out; -#endif // __MQL__ + #endif // __MQL__ #endif // MATRIX_USE_OPENCL diff --git a/Platform/Chart/Chart.enum.h b/Platform/Chart/Chart.enum.h index e3f1d3bc8..36ef19255 100644 --- a/Platform/Chart/Chart.enum.h +++ b/Platform/Chart/Chart.enum.h @@ -26,8 +26,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif #ifndef __MQL__ @@ -43,7 +43,9 @@ enum ENUM_APPLIED_PRICE { PRICE_MEDIAN, // Median price (H+L)/2 PRICE_TYPICAL, // Typical price, (H+L+C)/3 PRICE_WEIGHTED, // Weighted close price (H+L+C+C)/4 - FINAL_APPLIED_PRICE_ENTRY + FINAL_APPLIED_PRICE_ENTRY, + __PRICE_ASK = 128, // Required, so PRICE_ASK define could work without throwing compilation error. + __PRICE_BID = 129, // Required, so PRICE_BID define could work without throwing compilation error. }; #endif @@ -126,9 +128,9 @@ enum ENUM_TIMEFRAMES { PERIOD_MN1 = 43200 // 1 month. }; -#ifdef EMSCRIPTEN -#include -#include + #ifdef EMSCRIPTEN + #include + #include EMSCRIPTEN_BINDINGS(ENUM_TIMEFRAMES) { emscripten::enum_("timeframes") @@ -165,7 +167,7 @@ EMSCRIPTEN_BINDINGS(ENUM_APPLIED_PRICE) { .value("weighted", PRICE_WEIGHTED); } -#endif + #endif #endif diff --git a/Platform/Chart/Chart.struct.static.h b/Platform/Chart/Chart.struct.static.h index efed99fa4..6c17ba9cc 100644 --- a/Platform/Chart/Chart.struct.static.h +++ b/Platform/Chart/Chart.struct.static.h @@ -26,8 +26,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Includes. @@ -311,7 +311,7 @@ struct ChartStatic { ARRAY(datetime, _arr); // ENUM_TIMEFRAMES _tf = MQL4::TFMigrate(_tf); // @todo: Improves performance by caching values. - return (_shift >= 0 && ::CopyTime(_symbol, _tf, _shift, 1, _arr) > 0) ? _arr[0] : 0; + return (_shift >= 0 && ::CopyTime(_symbol, _tf, _shift, 1, _arr) > 0) ? _arr[0] : (datetime)0; #endif } diff --git a/Platform/Order.enum.h b/Platform/Order.enum.h index ca53f9b69..b8c94d7fa 100644 --- a/Platform/Order.enum.h +++ b/Platform/Order.enum.h @@ -26,8 +26,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif /* Order actions. */ @@ -92,17 +92,17 @@ enum ENUM_ORDER_PROPERTY_CUSTOM { // Defines enumeration for order close reasons. enum ENUM_ORDER_REASON_CLOSE { - ORDER_REASON_CLOSED_ALL = 0, // Closed all - ORDER_REASON_CLOSED_BY_ACTION, // Closed by action - ORDER_REASON_CLOSED_BY_CONDITION, // Closed by condition - ORDER_REASON_CLOSED_BY_EXPIRE, // Closed by expiration - ORDER_REASON_CLOSED_BY_OPPOSITE, // Closed by opposite order - ORDER_REASON_CLOSED_BY_SIGNAL, // Closed by signal - ORDER_REASON_CLOSED_BY_SL, // Closed by stop loss - ORDER_REASON_CLOSED_BY_TEST, // Closed by test - ORDER_REASON_CLOSED_BY_TP, // Closed by take profit - ORDER_REASON_CLOSED_BY_USER, // Closed by user - ORDER_REASON_CLOSED_UNKNOWN, // Closed by unknown event + ORDER_REASON_CLOSED_ALL = 0, // Closed all + ORDER_REASON_CLOSED_BY_ACTION, // Closed by action + ORDER_REASON_CLOSED_BY_CONDITION, // Closed by condition + ORDER_REASON_CLOSED_BY_EXPIRE, // Closed by expiration + ORDER_REASON_CLOSED_BY_OPPOSITE, // Closed by opposite order + ORDER_REASON_CLOSED_BY_SIGNAL, // Closed by signal + ORDER_REASON_CLOSED_BY_SL, // Closed by stop loss + ORDER_REASON_CLOSED_BY_TEST, // Closed by test + ORDER_REASON_CLOSED_BY_TP, // Closed by take profit + ORDER_REASON_CLOSED_BY_USER, // Closed by user + ORDER_REASON_CLOSED_UNKNOWN, // Closed by unknown event }; #ifndef __MQL5__ @@ -209,7 +209,8 @@ enum ENUM_ORDER_PROPERTY_INTEGER { ORDER_MAGIC, // ID of an Expert Advisor that has placed the order. ORDER_REASON, // The reason or source for placing an order. ORDER_POSITION_ID, // Position identifier that is set to an order as soon as it is executed. - ORDER_POSITION_BY_ID // Identifier of an opposite position used for closing by order ORDER_TYPE_CLOSE_BY. + ORDER_POSITION_BY_ID, // Identifier of an opposite position used for closing by order ORDER_TYPE_CLOSE_BY. + __ORDER_REASON = 23, // Required, so ORDER_REASON define could work without throwing compilation error. }; /** @@ -219,9 +220,10 @@ enum ENUM_ORDER_PROPERTY_INTEGER { * @see: https://www.mql5.com/en/docs/constants/tradingconstants/orderproperties */ enum ENUM_ORDER_PROPERTY_STRING { - ORDER_COMMENT, // Order comment. - ORDER_EXTERNAL_ID, // Order identifier in an external trading system (on the Exchange). - ORDER_SYMBOL, // Symbol of the order. + ORDER_COMMENT, // Order comment. + ORDER_EXTERNAL_ID, // Order identifier in an external trading system (on the Exchange). + ORDER_SYMBOL, // Symbol of the order. + __ORDER_EXTERNAL_ID = 20 // Required, so ORDER_EXTERNAL_ID define could work without throwing compilation error. }; #endif @@ -249,7 +251,7 @@ enum ENUM_ORDER_TYPE { ORDER_TYPE_UNSET // A NULL value. }; #else -#define ORDER_TYPE_UNSET NULL + #define ORDER_TYPE_UNSET NULL #endif /* Positions */ diff --git a/Platform/Order.h b/Platform/Order.h index 026d0e7d4..88ccbf307 100644 --- a/Platform/Order.h +++ b/Platform/Order.h @@ -26,8 +26,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Forward declaration. @@ -35,55 +35,55 @@ class SymbolInfo; // Includes. #include "../Convert.basic.h" -#include "../Storage/Data.define.h" -#include "../Storage/Data.struct.h" -#include "../Platform/Deal.enum.h" +#include "../Exchange/SymbolInfo/SymbolInfo.h" #include "../Log.mqh" -#include "Order.define.h" -#include "Order.enum.h" -#include "Order.struct.h" +#include "../Platform/Deal.enum.h" #include "../Serializer/Serializer.define.h" #include "../Serializer/Serializer.h" #include "../Serializer/SerializerConverter.h" #include "../Serializer/SerializerJson.h" #include "../Std.h" +#include "../Storage/Data.define.h" +#include "../Storage/Data.struct.h" #include "../Storage/String.h" -#include "../Exchange/SymbolInfo/SymbolInfo.h" #include "../Task/TaskAction.enum.h" +#include "Order.define.h" +#include "Order.enum.h" +#include "Order.struct.h" #include "Terminal.define.h" /* Defines for backward compatibility. */ // Index in the order pool. #ifndef SELECT_BY_POS -#define SELECT_BY_POS 0 + #define SELECT_BY_POS 0 #endif // Index by the order ticket. #ifndef SELECT_BY_TICKET -#define SELECT_BY_TICKET 1 + #define SELECT_BY_TICKET 1 #endif #ifndef ORDER_EXTERNAL_ID -// Order identifier in an external trading system (on the Exchange). -// Note: Required for backward compatibility in MQL4. -// @see: https://www.mql5.com/en/docs/constants/tradingconstants/orderproperties#enum_order_property_string -#define ORDER_EXTERNAL_ID ((ENUM_ORDER_PROPERTY_STRING)20) + // Order identifier in an external trading system (on the Exchange). + // Note: Required for backward compatibility in MQL4. + // @see: https://www.mql5.com/en/docs/constants/tradingconstants/orderproperties#enum_order_property_string + #define ORDER_EXTERNAL_ID ((ENUM_ORDER_PROPERTY_STRING)20) #endif #ifndef ORDER_REASON -// The reason or source for placing an order. -// Note: Required for backward compatibility in MQL4. -// @see: https://www.mql5.com/en/docs/constants/tradingconstants/orderproperties -#define ORDER_REASON ((ENUM_ORDER_PROPERTY_INTEGER)23) + // The reason or source for placing an order. + // Note: Required for backward compatibility in MQL4. + // @see: https://www.mql5.com/en/docs/constants/tradingconstants/orderproperties + #define ORDER_REASON ((ENUM_ORDER_PROPERTY_INTEGER)23) #endif #ifndef __MQLBUILD__ -// Defines. -// Mode constants. -// @see: https://docs.mql4.com/trading/orderselect -#define MODE_TRADES 0 -#define MODE_HISTORY 1 + // Defines. + // Mode constants. + // @see: https://docs.mql4.com/trading/orderselect + #define MODE_TRADES 0 + #define MODE_HISTORY 1 #endif /** @@ -473,7 +473,7 @@ class Order : public SymbolInfo { #endif } datetime GetOpenTime() { - if (odata.Get(ORDER_PROP_TIME_OPENED) == 0) { + if (odata.Get(ORDER_PROP_TIME_OPENED) == (datetime)0) { OrderSelect(); odata.Set(ORDER_PROP_TIME_OPENED, Order::OrderOpenTime()); } @@ -931,11 +931,11 @@ class Order : public SymbolInfo { _request.action = TRADE_ACTION_DEAL; _request.comment = _comment != "" ? _comment : odata.GetReasonCloseText(); _request.deviation = orequest.deviation > 0 ? orequest.deviation : 40; - _request.magic = odata.Get(ORDER_MAGIC); + _request.magic = odata.Get(ORDER_MAGIC); _request.symbol = odata.Get(ORDER_SYMBOL); _request.type = NegateOrderType(odata.Get(ORDER_TYPE)); _request.type_filling = GetOrderFilling(odata.Get(ORDER_SYMBOL)); - _request.position = odata.Get(ORDER_PROP_TICKET); + _request.position = odata.Get(ORDER_PROP_TICKET); _request.price = SymbolInfo::GetCloseOffer(odata.Get(ORDER_TYPE)); _request.volume = odata.Get(ORDER_VOLUME_CURRENT); Order::OrderSend(_request, oresult, oresult_check); @@ -959,12 +959,12 @@ class Order : public SymbolInfo { if (OrderSelect()) { Refresh(true); if (!IsClosed()) { - ologger.Error( - StringFormat("Failed to send order request %u for position %d! Error: %d (%s)", oresult.request_id, - _request.position, fmax(oresult.retcode, oresult_check.retcode), oresult_check.comment), - __FUNCTION_LINE__); + ologger.Error(StringFormat("Failed to send order request %u for position %d! Error: %d (%s)", + oresult.request_id, _request.position, + fmax(oresult.retcode, oresult_check.retcode), C_STR(oresult_check.comment)), + __FUNCTION_LINE__); if (ologger.GetLevel() >= V_DEBUG) { - ologger.Debug(StringFormat("Failed request: %s", ToString()), __FUNCTION_LINE__); + ologger.Debug(StringFormat("Failed request: %s", C_STR(ToString())), __FUNCTION_LINE__); } } } @@ -1199,7 +1199,7 @@ class Order : public SymbolInfo { color _arrow_color = clrNONE // Color. ) { #ifdef __MQL4__ -#ifdef __debug__ + #ifdef __debug__ Print("Sending request:"); PrintFormat("Symbol: %s", _symbol); PrintFormat("Cmd: %d", _cmd); @@ -1211,7 +1211,7 @@ class Order : public SymbolInfo { PrintFormat("Comment: %s", _comment); PrintFormat("Magic: %d", _magic); PrintFormat("Expiration: %s", TimeToStr(_symbol, TIME_DATE | TIME_MINUTES | TIME_SECONDS)); -#endif + #endif return ::OrderSend(_symbol, _cmd, _volume, _price, (int)_deviation, _stoploss, _takeprofit, _comment, (unsigned int)_magic, _expiration, _arrow_color); @@ -1311,9 +1311,9 @@ class Order : public SymbolInfo { } } -#ifdef __debug__ + #ifdef __debug__ Print("Received result:\n", ToString(_result)); -#endif + #endif return _result.retcode == TRADE_RETCODE_DONE; #else @@ -1327,9 +1327,9 @@ class Order : public SymbolInfo { // - https://www.mql5.com/en/docs/trading/ordercheck // - https://www.mql5.com/en/docs/constants/errorswarnings/enum_trade_return_codes // - https://www.mql5.com/en/docs/constants/structures/mqltradecheckresult -#ifdef __debug__ + #ifdef __debug__ PrintFormat("%s: Error %d: %s", C_STR(__FUNCTION_LINE__), _result_check.retcode, C_STR(_result_check.comment)); -#endif + #endif _result.retcode = _result_check.retcode; return false; } @@ -1348,9 +1348,9 @@ class Order : public SymbolInfo { // Sends trade requests to a server. bool _success = ::OrderSend(_request, _result); -#ifdef __debug__ + #ifdef __debug__ Print("Received result:\n", ToString(_result)); -#endif + #endif return _success; // The function execution result is placed to structure MqlTradeResult, @@ -1404,9 +1404,9 @@ class Order : public SymbolInfo { // @see: https://www.mql5.com/en/docs/constants/errorswarnings/enum_trade_return_codes // In order to obtain information about the error, call the GetLastError() function. odata.Set(ORDER_PROP_LAST_ERROR, oresult.retcode); -#ifdef __debug_order__ + #ifdef __debug_order__ Print(__FUNCTION_LINE__ + "(): " + SerializerConverter::FromObject(orequest).ToString()); -#endif + #endif _result = -1; } } else { @@ -1595,10 +1595,10 @@ class Order : public SymbolInfo { selected_ticket_id = selected_ticket_type == ORDER_SELECT_TYPE_NONE ? 0 : _index; } else { -#ifdef __debug__ + #ifdef __debug__ PrintFormat("%s: Possible values for 'select' parameters are: SELECT_BY_POS or SELECT_BY_HISTORY.", __FUNCTION_LINE__); -#endif + #endif } _result = selected_ticket_type != ORDER_SELECT_TYPE_NONE; @@ -2004,14 +2004,14 @@ class Order : public SymbolInfo { _value = Order::OrderGetString(ORDER_SYMBOL); break; default: -/* -#ifdef ORDER_EXTERNAL_ID - if ((int)_prop_id == (int)ORDER_EXTERNAL_ID) { - _value = Order::OrderGetString(ORDER_EXTERNAL_ID); - break; - } -#endif -*/ + /* + #ifdef ORDER_EXTERNAL_ID + if ((int)_prop_id == (int)ORDER_EXTERNAL_ID) { + _value = Order::OrderGetString(ORDER_EXTERNAL_ID); + break; + } + #endif + */ _result = false; break; } @@ -2140,17 +2140,17 @@ class Order : public SymbolInfo { ResetLastError(); int64 _result = 0; #ifdef __MQL4__ -#ifdef __debug__ + #ifdef __debug__ Print("OrderGetInteger(", EnumToString(property_id), ")..."); -#endif + #endif switch (property_id) { -#ifndef __MQL__ + #ifndef __MQL__ // Note: In MT, the value conflicts with ORDER_TIME_SETUP. case ORDER_TICKET: // Order ticket. Unique number assigned to each order. _result = OrderStatic::Ticket(); break; -#endif + #endif case ORDER_TIME_SETUP: // Order setup time. // http://docs.mql4.com/trading/orderopentime @@ -2192,19 +2192,19 @@ class Order : public SymbolInfo { // Unique order number. _result = OrderStatic::MagicNumber(); break; -#ifdef ORDER_POSITION_ID + #ifdef ORDER_POSITION_ID case ORDER_POSITION_ID: // Position identifier. _result = OrderGetPositionID(); break; -#endif -#ifdef ORDER_POSITION_BY_ID + #endif + #ifdef ORDER_POSITION_BY_ID case ORDER_POSITION_BY_ID: // Identifier of an opposite position used for closing. // Not supported. SetUserError(ERR_INVALID_PARAMETER); break; -#endif + #endif default: // Unknown property. SetUserError(ERR_INVALID_PARAMETER); @@ -2212,11 +2212,11 @@ class Order : public SymbolInfo { int _last_error = GetLastError(); -#ifdef __debug__ + #ifdef __debug__ if (_last_error > 0) { Print("OrderGetInteger(", EnumToString(property_id), ") = ", _result, ", error = ", _last_error); } -#endif + #endif if (_last_error != ERR_SUCCESS) { SetUserError((unsigned short)_last_error); @@ -2254,9 +2254,9 @@ class Order : public SymbolInfo { ResetLastError(); double _result = WRONG_VALUE; #ifdef __MQL4__ -#ifdef __debug__ + #ifdef __debug__ Print("OrderGetDouble(", EnumToString(property_id), ")..."); -#endif + #endif switch (property_id) { case ORDER_VOLUME_INITIAL: _result = ::OrderLots(); @@ -2286,11 +2286,11 @@ class Order : public SymbolInfo { int _last_error = GetLastError(); -#ifdef __debug__ + #ifdef __debug__ if (_last_error > 0) { Print("OrderGetDouble(", EnumToString(property_id), ") = ", _result, ", error = ", _last_error); } -#endif + #endif if (_last_error != ERR_SUCCESS) { SetUserError((unsigned short)_last_error); @@ -2328,9 +2328,9 @@ class Order : public SymbolInfo { ResetLastError(); string _result; #ifdef __MQL4__ -#ifdef __debug__ + #ifdef __debug__ Print("OrderGetString(", EnumToString(property_id), ")..."); -#endif + #endif switch (property_id) { case ORDER_SYMBOL: _result = OrderStatic::Symbol(); @@ -2346,11 +2346,11 @@ class Order : public SymbolInfo { break; } int _last_error = GetLastError(); -#ifdef __debug__ + #ifdef __debug__ if (_last_error > 0) { Print("OrderGetString(", EnumToString(property_id), ") = ", _result, ", error = ", _last_error); } -#endif + #endif if (_last_error != ERR_SUCCESS) { SetUserError((unsigned short)_last_error); } @@ -2505,12 +2505,12 @@ class Order : public SymbolInfo { */ template static X OrderGetParam(int _prop_id, ENUM_ORDER_SELECT_TYPE _type, ENUM_ORDER_SELECT_DATA_TYPE _data_type, X &_out) { -#ifndef __MQL4__ + #ifndef __MQL4__ int64 _long; string _string; switch (selected_ticket_type) { case ORDER_SELECT_TYPE_NONE: - return NULL_VALUE; + return (X)NULL_VALUE; case ORDER_SELECT_TYPE_ACTIVE: case ORDER_SELECT_TYPE_HISTORY: @@ -2529,7 +2529,7 @@ class Order : public SymbolInfo { case DEAL_TYPE_SELL: return ConvertBasic::LongTo(ORDER_TYPE_SELL); default: - return NULL_VALUE; + return (X)NULL_VALUE; } break; case ORDER_STATE: @@ -2538,23 +2538,23 @@ class Order : public SymbolInfo { case ORDER_TIME_EXPIRATION: case ORDER_TIME_DONE: SetUserError(ERR_INVALID_PARAMETER); - return NULL_VALUE; + return (X)NULL_VALUE; case ORDER_TIME_SETUP_MSC: return OrderGetValue(DEAL_TIME_MSC, _type, _out); case ORDER_TIME_DONE_MSC: SetUserError(ERR_INVALID_PARAMETER); - return NULL_VALUE; + return (X)NULL_VALUE; case ORDER_TYPE_FILLING: case ORDER_TYPE_TIME: SetUserError(ERR_INVALID_PARAMETER); - return NULL_VALUE; + return (X)NULL_VALUE; case ORDER_MAGIC: return OrderGetValue(DEAL_MAGIC, _type, _out); case ORDER_POSITION_ID: return OrderGetValue(DEAL_POSITION_ID, _type, _out); case ORDER_POSITION_BY_ID: SetUserError(ERR_INVALID_PARAMETER); - return NULL_VALUE; + return (X)NULL_VALUE; default: if ((int)_prop_id == (int)ORDER_REASON) { switch ((int)OrderGetValue(DEAL_REASON, _type, _long)) { @@ -2573,7 +2573,7 @@ class Order : public SymbolInfo { case DEAL_REASON_SO: return ConvertBasic::LongTo(ORDER_REASON_SO); default: - return NULL_VALUE; + return (X)NULL_VALUE; } } } @@ -2584,31 +2584,31 @@ class Order : public SymbolInfo { return OrderGetValue(DEAL_VOLUME, _type, _out); case ORDER_VOLUME_CURRENT: SetUserError(ERR_INVALID_PARAMETER); - return NULL_VALUE; + return (X)NULL_VALUE; case ORDER_PRICE_OPEN: return OrderGetValue(DEAL_PRICE, _type, _out); case ORDER_SL: case ORDER_TP: SetUserError(ERR_INVALID_PARAMETER); - return NULL_VALUE; + return (X)NULL_VALUE; case ORDER_PRICE_CURRENT: return OrderGetValue(DEAL_PRICE, _type, _out); case ORDER_PRICE_STOPLIMIT: SetUserError(ERR_INVALID_PARAMETER); - return NULL_VALUE; + return (X)NULL_VALUE; } break; case ORDER_SELECT_DATA_TYPE_STRING: switch (_prop_id) { case ORDER_SYMBOL: case ORDER_COMMENT: - return NULL_VALUE; + return (X)NULL_VALUE; default: -#ifdef ORDER_EXTERNAL_ID + #ifdef ORDER_EXTERNAL_ID if ((int)_prop_id == (int)ORDER_EXTERNAL_ID) { - return NULL_VALUE; + return (X)NULL_VALUE; } -#endif + #endif } break; } @@ -2627,7 +2627,7 @@ class Order : public SymbolInfo { case POSITION_TYPE_SELL: return ConvertBasic::LongTo(ORDER_TYPE_SELL); default: - return NULL_VALUE; + return (X)NULL_VALUE; } break; case ORDER_STATE: @@ -2636,23 +2636,23 @@ class Order : public SymbolInfo { case ORDER_TIME_EXPIRATION: case ORDER_TIME_DONE: SetUserError(ERR_INVALID_PARAMETER); - return NULL_VALUE; + return (X)NULL_VALUE; case ORDER_TIME_SETUP_MSC: return OrderGetValue(POSITION_TIME_MSC, _type, _out); case ORDER_TIME_DONE_MSC: SetUserError(ERR_INVALID_PARAMETER); - return NULL_VALUE; + return (X)NULL_VALUE; case ORDER_TYPE_FILLING: case ORDER_TYPE_TIME: SetUserError(ERR_INVALID_PARAMETER); - return NULL_VALUE; + return (X)NULL_VALUE; case ORDER_MAGIC: return OrderGetValue(POSITION_MAGIC, _type, _out); case ORDER_POSITION_ID: return OrderGetValue(POSITION_IDENTIFIER, _type, _out); case ORDER_POSITION_BY_ID: SetUserError(ERR_INVALID_PARAMETER); - return NULL_VALUE; + return (X)NULL_VALUE; default: if ((int)_prop_id == (int)ORDER_REASON) { switch ((int)OrderGetValue(POSITION_REASON, _type, _long)) { @@ -2665,7 +2665,7 @@ class Order : public SymbolInfo { case POSITION_REASON_EXPERT: return ConvertBasic::LongTo(ORDER_REASON_EXPERT); default: - return NULL_VALUE; + return (X)NULL_VALUE; } } } @@ -2687,7 +2687,7 @@ class Order : public SymbolInfo { case ORDER_PRICE_STOPLIMIT: // @fixme SetUserError(ERR_INVALID_PARAMETER); - return NULL_VALUE; + return (X)NULL_VALUE; } break; case ORDER_SELECT_DATA_TYPE_STRING: @@ -2697,21 +2697,21 @@ class Order : public SymbolInfo { case ORDER_COMMENT: return OrderGetValue(POSITION_COMMENT, _type, _out); default: -#ifdef ORDER_EXTERNAL_ID + #ifdef ORDER_EXTERNAL_ID if ((int)_prop_id == (int)ORDER_EXTERNAL_ID) { return OrderGetValue(POSITION_EXTERNAL_ID, _type, _out); } -#endif + #endif } break; } break; } - return NULL_VALUE; -#else + return (X)NULL_VALUE; + #else return OrderGetValue(_prop_id, _type, _out); -#endif + #endif } #endif diff --git a/Platform/Order.struct.h b/Platform/Order.struct.h index 1b83a8010..7d5411688 100644 --- a/Platform/Order.struct.h +++ b/Platform/Order.struct.h @@ -26,8 +26,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Includes. @@ -473,7 +473,8 @@ struct OrderData { * Returns a comment with reason */ string GetCloseComment() { - string _result = StringFormat("%s (mn=%d,pips=%d)", GetReasonCloseText(), magic, Get(ORDER_PROP_PROFIT_PIPS)); + string _result = + StringFormat("%s (mn=%d,pips=%d)", C_STR(GetReasonCloseText()), magic, Get(ORDER_PROP_PROFIT_PIPS)); return _result; } @@ -511,9 +512,7 @@ struct OrderData { return "???"; } // Setters. - void IncCloseTries() { - close_tries++; - } + void IncCloseTries() { close_tries++; } template void Set(ENUM_ORDER_PROPERTY_CUSTOM _prop_name, T _value) { switch (_prop_name) { diff --git a/Platform/Platform.h b/Platform/Platform.h index 101208e38..3d5fbefa1 100644 --- a/Platform/Platform.h +++ b/Platform/Platform.h @@ -59,6 +59,7 @@ extern int Bars(CONST_REF_TO_SIMPLE(string) _symbol, ENUM_TIMEFRAMES _tf); #define PLATFORM_DEFAULT_INDICATOR_TF Indi_TfMt #else #include "../Indicators/Tick/Indi_TickProvider.h" + #include "../Indicators/Tick/Indi_TickRandom.h" #define PLATFORM_DEFAULT_INDICATOR_TICK Indi_TickRandom #define PLATFORM_DEFAULT_INDICATOR_TF IndicatorTfDummy #endif @@ -870,10 +871,10 @@ SymbolGetter::operator string() const { return Platform::GetSymbol(); } ENUM_TIMEFRAMES Period() { return Platform::GetPeriod(); } double Point() { return Platform::GetPoint(); } -#define _Point (Point()) + #define _Point (Point()) int Digits() { return Platform::GetDigits(); } -#define _Digits (Digits()) + #define _Digits (Digits()) datetime StructToTime(MqlDateTime &dt_struct) { tm ltm; diff --git a/Platform/Plot.h b/Platform/Plot.h index 7b36aa0ca..969d2b9c5 100644 --- a/Platform/Plot.h +++ b/Platform/Plot.h @@ -26,8 +26,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Class dependencies. @@ -44,45 +44,27 @@ class Plot; #include "Terminal.extern.h" #ifndef __MQL4__ -// Defines macros (for MQL4 backward compatibility). -#define SetIndexArrow(_index, _value) (PlotIndexSetInteger(_index, PLOT_ARROW, _value)) -#define SetIndexDrawBegin(_index, _value) (PlotIndexSetInteger(_index, PLOT_DRAW_BEGIN, _value)) -#define SetIndexEmptyValue(_index, _value) (PlotIndexSetDouble(_index, PLOT_EMPTY_VALUE, _value)) -#define SetIndexShift(_index, _value) (PlotIndexSetInteger(_index, PLOT_SHIFT, _value)) -#endif - -#ifndef __MQL4__ -// Defines global functions (for MQL4 backward compatibility). -bool ObjectCreate(string _name, ENUM_OBJECT _otype, int _swindow, datetime _t1, double _p1) { - return Plot::ObjectCreate(0, _name, _otype, _swindow, _t1, _p1); -} -bool ObjectCreate(string _name, ENUM_OBJECT _otype, int _swindow, datetime _t1, double _p1, datetime _t2, double _p2) { - return Plot::ObjectCreate(0, _name, _otype, _swindow, _t1, _p1, _t2, _p2); -} -bool ObjectDelete(string _name) { return Plot::ObjectDelete(_name); } -bool ObjectSet(string _name, int _prop_id, double _value) { return Plot::ObjectSet(_name, _prop_id, _value); } -int ObjectsTotal(int _type = EMPTY) { return Plot::ObjectsTotal(); } -string ObjectName(int _index) { return Plot::ObjectName(_index); } -void SetIndexLabel(int _index, string _text) { Plot::SetIndexLabel(_index, _text); } -void SetIndexStyle(int _index, int _type, int _style = EMPTY, int _width = EMPTY, color _clr = CLR_NONE) { - Plot::SetIndexStyle(_index, _type, _style, _width, _clr); -} + // Defines macros (for MQL4 backward compatibility). + #define SetIndexArrow(_index, _value) (PlotIndexSetInteger(_index, PLOT_ARROW, _value)) + #define SetIndexDrawBegin(_index, _value) (PlotIndexSetInteger(_index, PLOT_DRAW_BEGIN, _value)) + #define SetIndexEmptyValue(_index, _value) (PlotIndexSetDouble(_index, PLOT_EMPTY_VALUE, _value)) + #define SetIndexShift(_index, _value) (PlotIndexSetInteger(_index, PLOT_SHIFT, _value)) #endif #define WINDOW_MAIN 0 -#ifdef __MQL5__ -#define OBJPROP_TIME1 ((ENUM_OBJECT_PROPERTY_INTEGER)0) -#define OBJPROP_PRICE1 1 -#define OBJPROP_TIME2 2 -#define OBJPROP_PRICE2 3 -#define OBJPROP_TIME3 4 -#define OBJPROP_PRICE3 5 -#define OBJPROP_COLOR ((ENUM_OBJECT_PROPERTY_INTEGER)6) -#define OBJPROP_STYLE 7 -#define OBJPROP_WIDTH 8 -#define OBJPROP_BACK ((ENUM_OBJECT_PROPERTY_INTEGER)9) -#define OBJPROP_FIBOLEVELS 200 +#ifndef __MQL4__ + #define OBJPROP_TIME1 ((ENUM_OBJECT_PROPERTY_INTEGER)0) + #define OBJPROP_PRICE1 1 + #define OBJPROP_TIME2 2 + #define OBJPROP_PRICE2 3 + #define OBJPROP_TIME3 4 + #define OBJPROP_PRICE3 5 + #define OBJPROP_COLOR ((ENUM_OBJECT_PROPERTY_INTEGER)6) + #define OBJPROP_STYLE 7 + #define OBJPROP_WIDTH 8 + #define OBJPROP_BACK ((ENUM_OBJECT_PROPERTY_INTEGER)9) + #define OBJPROP_FIBOLEVELS 200 #endif /** @@ -371,3 +353,21 @@ class Plot : public Object { return true; } }; + +#ifndef __MQL4__ +// Defines global functions (for MQL4 backward compatibility). +bool ObjectCreate(string _name, ENUM_OBJECT _otype, int _swindow, datetime _t1, double _p1) { + return Plot::ObjectCreate(0, _name, _otype, _swindow, _t1, _p1); +} +bool ObjectCreate(string _name, ENUM_OBJECT _otype, int _swindow, datetime _t1, double _p1, datetime _t2, double _p2) { + return Plot::ObjectCreate(0, _name, _otype, _swindow, _t1, _p1, _t2, _p2); +} +bool ObjectDelete(string _name) { return Plot::ObjectDelete(_name); } +bool ObjectSet(string _name, int _prop_id, double _value) { return Plot::ObjectSet(_name, _prop_id, _value); } +int ObjectsTotal(int _type = EMPTY) { return Plot::ObjectsTotal(); } +string ObjectName(int _index) { return Plot::ObjectName(_index); } +void SetIndexLabel(int _index, string _text) { Plot::SetIndexLabel(_index, _text); } +void SetIndexStyle(int _index, int _type, int _style = EMPTY, int _width = EMPTY, color _clr = CLR_NONE) { + Plot::SetIndexStyle(_index, _type, _style, _width, _clr); +} +#endif diff --git a/Platform/Terminal.enum.h b/Platform/Terminal.enum.h index 7a6f481f1..7ee4e8726 100644 --- a/Platform/Terminal.enum.h +++ b/Platform/Terminal.enum.h @@ -26,8 +26,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Includes. @@ -319,7 +319,17 @@ enum ENUM_OBJECT_PROPERTY_INTEGER { OBJPROP_BORDER_COLOR }; -enum ENUM_OBJECT_PROPERTY_DOUBLE { OBJPROP_PRICE, OBJPROP_LEVELVALUE, OBJPROP_SCALE, OBJPROP_ANGLE, OBJPROP_DEVIATION }; +enum ENUM_OBJECT_PROPERTY_DOUBLE { + #ifndef __MQL__ + // In C++ we don't want enum values to conflict between MQL4/MQL5-style usage. + __ENUM_OBJECT_PROPERTY_DOUBLE_DUMMY = 100, + #endif + OBJPROP_PRICE, + OBJPROP_LEVELVALUE, + OBJPROP_SCALE, + OBJPROP_ANGLE, + OBJPROP_DEVIATION +}; enum ENUM_OBJECT_PROPERTY_STRING { OBJPROP_NAME, diff --git a/Serializer/Serializer.h b/Serializer/Serializer.h index c425520c5..359e0332d 100644 --- a/Serializer/Serializer.h +++ b/Serializer/Serializer.h @@ -21,8 +21,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Includes. @@ -461,7 +461,7 @@ class Serializer { * Returns next structure or structure by given key. */ template - X Struct(string key = "") { + X REF_CPP Struct(string key = "") { X value; PassStruct(THIS_REF, key, value); return value; diff --git a/Serializer/SerializerNodeParam.h b/Serializer/SerializerNodeParam.h index c4cd01498..1ae965e89 100644 --- a/Serializer/SerializerNodeParam.h +++ b/Serializer/SerializerNodeParam.h @@ -25,8 +25,8 @@ #define SERIALIZER_NODE_PARAM_H #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif #include "SerializerConversions.h" @@ -76,13 +76,18 @@ class SerializerNodeParam { /** * Returns new SerializerNodeParam object from given source value. */ - static SerializerNodeParam* FromBool(int64 value); + static SerializerNodeParam* FromBool(bool value); /** * Returns new SerializerNodeParam object from given source value. */ static SerializerNodeParam* FromLong(int64 value); + /** + * Returns new SerializerNodeParam object from given source value. + */ + static SerializerNodeParam* FromLong(uint64 value); + /** * Returns new SerializerNodeParam object from given source value. */ @@ -101,17 +106,17 @@ class SerializerNodeParam { /** * Returns new SerializerNodeParam object from given source value. */ - static SerializerNodeParam* FromValue(char value) { return FromLong(value); } + static SerializerNodeParam* FromValue(char value) { return FromLong((int64)value); } /** * Returns new SerializerNodeParam object from given source value. */ - static SerializerNodeParam* FromValue(color value) { return FromLong(value); } + static SerializerNodeParam* FromValue(color value) { return FromLong((int64)(unsigned int)value); } /** * Returns new SerializerNodeParam object from given source value. */ - static SerializerNodeParam* FromValue(datetime value) { return FromLong(value); } + static SerializerNodeParam* FromValue(datetime value) { return FromLong((int64)value); } /** * Returns new SerializerNodeParam object from given source value. @@ -121,7 +126,7 @@ class SerializerNodeParam { /** * Returns new SerializerNodeParam object from given source value. */ - static SerializerNodeParam* FromValue(int value) { return FromLong(value); } + static SerializerNodeParam* FromValue(int value) { return FromLong((int64)value); } /** * Returns new SerializerNodeParam object from given source value. @@ -131,32 +136,49 @@ class SerializerNodeParam { /** * Returns new SerializerNodeParam object from given source value. */ - static SerializerNodeParam* FromValue(short value) { return FromLong(value); } + static SerializerNodeParam* FromValue(uint64 value) { return FromLong(value); } + +#ifndef __MQL__ + + // @fixit + // Two specializations for C++'s "long". It is required until we refactor all "[unsigned] long"'s into "[u]int64"'s. /** * Returns new SerializerNodeParam object from given source value. */ - static SerializerNodeParam* FromValue(string& value) { return FromString(value); } + static SerializerNodeParam* FromValue(long value) { return FromLong((int64)value); } /** * Returns new SerializerNodeParam object from given source value. */ - static SerializerNodeParam* FromValue(unsigned char value) { return FromLong(value); } + static SerializerNodeParam* FromValue(unsigned long value) { return FromLong((uint64)value); } + +#endif /** * Returns new SerializerNodeParam object from given source value. */ - static SerializerNodeParam* FromValue(unsigned int value) { return FromLong(value); } + static SerializerNodeParam* FromValue(short value) { return FromLong((int64)value); } /** * Returns new SerializerNodeParam object from given source value. */ - static SerializerNodeParam* FromValue(uint64 value) { return FromLong(value); } + static SerializerNodeParam* FromValue(string& value) { return FromString(value); } /** * Returns new SerializerNodeParam object from given source value. */ - static SerializerNodeParam* FromValue(unsigned short value) { return FromLong(value); } + static SerializerNodeParam* FromValue(unsigned char value) { return FromLong((uint64)value); } + + /** + * Returns new SerializerNodeParam object from given source value. + */ + static SerializerNodeParam* FromValue(unsigned int value) { return FromLong((uint64)value); } + + /** + * Returns new SerializerNodeParam object from given source value. + */ + static SerializerNodeParam* FromValue(unsigned short value) { return FromLong((uint64)value); } /** * Returns stringified version of the value. Note "forceQuotesOnString" flag. @@ -303,7 +325,7 @@ class SerializerNodeParam { /** * Returns new SerializerNodeParam object from given source value. */ -SerializerNodeParam* SerializerNodeParam::FromBool(int64 value) { +SerializerNodeParam* SerializerNodeParam::FromBool(bool value) { SerializerNodeParam* param = new SerializerNodeParam(); PTR_ATTRIB(param, _type) = SerializerNodeParamBool; PTR_ATTRIB(param, _integral)._bool = value; @@ -320,6 +342,11 @@ SerializerNodeParam* SerializerNodeParam::FromLong(int64 value) { return param; } +/** + * Returns new SerializerNodeParam object from given source value. + */ +SerializerNodeParam* SerializerNodeParam::FromLong(uint64 value) { return FromLong((uint64)value); } + /** * Returns new SerializerNodeParam object from given source value. */ @@ -340,4 +367,4 @@ SerializerNodeParam* SerializerNodeParam::FromString(string& value) { return param; } -#endif // SERIALIZER_NODE_PARAM_H +#endif // SERIALIZER_NODE_PARAM_H diff --git a/Std.h b/Std.h index 3601b01bf..789ec31eb 100644 --- a/Std.h +++ b/Std.h @@ -64,6 +64,8 @@ #define int64 long #define uint64 unsigned long #define VOID_DATA(N) void*& N[] + #define CONST_CPP + #define REF_CPP #else #define GET_PTR(obj) (&obj) #define THIS_ATTR this-> @@ -76,16 +78,18 @@ #define REF_TO_PTR(PTR) (&(PTR)) #define MAKE_REF_FROM_PTR(TYPE, NAME, PTR) TYPE& NAME = PTR #define REF_DEREF .Ptr()-> - #define int64 long long - #define uint64 unsigned long long + #define int64 long long int + #define uint64 unsigned long long int #define VOID_DATA(N) void* N + #define CONST_CPP const + #define REF_CPP & #endif // Reference to simple type like bool, int, double, string. #ifdef __MQL__ -#define REF(X) X& + #define REF(X) X& #else -#define REF(X) (&X) + #define REF(X) (&X) #endif // Arrays and references to arrays. @@ -93,9 +97,9 @@ // Reference to object. #ifdef __MQL__ -#define REF_TO(T) T* + #define REF_TO(T) T* #else -#define REF_TO(T) T& + #define REF_TO(T) T& #endif // Const reference to object. @@ -109,9 +113,9 @@ // Returning type for methods that returns simple types as int, double, string. #ifdef __MQL__ -#define RETURN_REF_TO_SIMPLE(T) T + #define RETURN_REF_TO_SIMPLE(T) T #else -#define RETURN_REF_TO_SIMPLE(T) T& + #define RETURN_REF_TO_SIMPLE(T) T& #endif // Returning type for methods that returns simple contstant types as int, double, string. @@ -119,9 +123,9 @@ // Casts reference to object to given type. #ifdef __MQL__ -#define REF_CAST(T) (T*) + #define REF_CAST(T) (T*) #else -#define REF_CAST(T) (T&) + #define REF_CAST(T) (T&) #endif /** @@ -130,9 +134,9 @@ * Example: ARRAY_TYPE(int) items; ArrayPush(items, 1); */ #ifdef __MQL__ -#define ARRAY_TYPE(T) T[] + #define ARRAY_TYPE(T) T[] #else -#define ARRAY_TYPE(T) _cpp_array + #define ARRAY_TYPE(T) _cpp_array #endif /** @@ -142,9 +146,9 @@ * Example: ARRAY(int, items); ArrayPush(items, 1); */ #ifdef __MQL__ -#define ARRAY(T, N) T N[] + #define ARRAY(T, N) T N[] #else -#define ARRAY(T, N) ::_cpp_array N + #define ARRAY(T, N) ::_cpp_array N #endif /** @@ -154,9 +158,9 @@ * Example: void Append(ARRAY_REF(int, values)); */ #ifdef __MQL__ -#define ARRAY_REF(T, N) REF(T) N[] + #define ARRAY_REF(T, N) REF(T) N[] #else -#define ARRAY_REF(T, N) ARRAY_TYPE(T) & N + #define ARRAY_REF(T, N) ARRAY_TYPE(T) & N #endif /** @@ -166,9 +170,9 @@ * Example: void Append(CONST_ARRAY_REF(int, values)); */ #ifdef __MQL__ -#define CONST_ARRAY_REF(T, N) const T& N[] + #define CONST_ARRAY_REF(T, N) const T& N[] #else -#define CONST_ARRAY_REF(T, N) const _cpp_array& N + #define CONST_ARRAY_REF(T, N) const _cpp_array& N #endif /** @@ -188,9 +192,9 @@ * Example: void Append(FIXED_ARRAY_REF(int, values, 5)); */ #ifdef __MQL__ -#define FIXED_ARRAY_REF(T, N, S) ARRAY_REF(T, N) + #define FIXED_ARRAY_REF(T, N, S) ARRAY_REF(T, N) #else -#define FIXED_ARRAY_REF(T, N, S) T(&N)[S] + #define FIXED_ARRAY_REF(T, N, S) T(&N)[S] #endif /** @@ -201,9 +205,9 @@ * Example: void Append(FIXED_ARRAY_REF(int, values, 5)); */ #ifdef __MQL__ -#define CONST_FIXED_ARRAY_REF(T, N, S) const FIXED_ARRAY_REF(T, N, S) + #define CONST_FIXED_ARRAY_REF(T, N, S) const FIXED_ARRAY_REF(T, N, S) #else -#define CONST_FIXED_ARRAY_REF(T, N, S) const FIXED_ARRAY_REF(T, N, S) + #define CONST_FIXED_ARRAY_REF(T, N, S) const FIXED_ARRAY_REF(T, N, S) #endif // typename(T) diff --git a/Storage/Database.struct.h b/Storage/Database.struct.h index 9e380446c..8829a1fc0 100644 --- a/Storage/Database.struct.h +++ b/Storage/Database.struct.h @@ -26,8 +26,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Structs. @@ -104,11 +104,16 @@ struct DbSymbolInfoEntry : public SymbolInfoEntry { } // Methods. void DefineSchema() { - schema.columns.Push(DatabaseTableColumnEntry("bid", TYPE_DOUBLE)); - schema.columns.Push(DatabaseTableColumnEntry("ask", TYPE_DOUBLE)); - schema.columns.Push(DatabaseTableColumnEntry("last", TYPE_DOUBLE)); - schema.columns.Push(DatabaseTableColumnEntry("spread", TYPE_DOUBLE)); - schema.columns.Push(DatabaseTableColumnEntry("volume", TYPE_INT)); + DatabaseTableColumnEntry _col1("bid", TYPE_DOUBLE); + DatabaseTableColumnEntry _col2("ask", TYPE_DOUBLE); + DatabaseTableColumnEntry _col3("last", TYPE_DOUBLE); + DatabaseTableColumnEntry _col4("spread", TYPE_DOUBLE); + DatabaseTableColumnEntry _col5("volume", TYPE_INT); + schema.columns.Push(_col1); + schema.columns.Push(_col2); + schema.columns.Push(_col3); + schema.columns.Push(_col4); + schema.columns.Push(_col5); } }; #endif diff --git a/Storage/Dict/Buffer/BufferStruct.h b/Storage/Dict/Buffer/BufferStruct.h index 81cfb9ef0..ee296d7ff 100644 --- a/Storage/Dict/Buffer/BufferStruct.h +++ b/Storage/Dict/Buffer/BufferStruct.h @@ -21,8 +21,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Flag for Database.struct.h so BufferStruct structure will be supported by it. @@ -94,10 +94,10 @@ class BufferStruct : public DictStruct { for (DictStructIterator iter(THIS_ATTR Begin()); iter.IsValid(); ++iter) { int64 _time = iter.Key(); if (_older && _time < _dt) { - Unset(iter.Key()); + THIS_ATTR Unset(iter.Key()); continue; } else if (!_older && _time > _dt) { - Unset(iter.Key()); + THIS_ATTR Unset(iter.Key()); continue; } min = _time < min ? _time : min; diff --git a/Storage/Dict/Buffer/BufferTick.h b/Storage/Dict/Buffer/BufferTick.h index d5ea9baf5..620ee6223 100644 --- a/Storage/Dict/Buffer/BufferTick.h +++ b/Storage/Dict/Buffer/BufferTick.h @@ -21,8 +21,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Includes. @@ -77,7 +77,7 @@ class BufferTickValueStorage : ValueStorage { /** * Returns number of values available to fetch (size of the values buffer). */ - int Size() override { return (int)THIS_ATTR buffer_tick.Size(); } + int Size() override { return (int)THIS_ATTR buffer_tick PTR_DEREF Size(); } }; /** diff --git a/Storage/Dict/Dict.h b/Storage/Dict/Dict.h index c7979ec29..438d2334a 100644 --- a/Storage/Dict/Dict.h +++ b/Storage/Dict/Dict.h @@ -21,8 +21,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif #include "../../Convert.basic.h" @@ -71,10 +71,10 @@ class Dict : public DictBase { Dict(const Dict& right) { Clear(); Resize(right.GetSlotCount()); - for (unsigned int i = 0; i < (unsigned int)ArraySize(right._DictSlots_ref.DictSlots); ++i) { - THIS_ATTR _DictSlots_ref.DictSlots[i] = right._DictSlots_ref.DictSlots[i]; + for (unsigned int i = 0; i < (unsigned int)ArraySize(right._DictSlots_ref PTR_DEREF DictSlots); ++i) { + THIS_ATTR _DictSlots_ref PTR_DEREF DictSlots[i] = right._DictSlots_ref PTR_DEREF DictSlots[i]; } - THIS_ATTR _DictSlots_ref._num_used = right._DictSlots_ref._num_used; + THIS_ATTR _DictSlots_ref PTR_DEREF _num_used = right._DictSlots_ref PTR_DEREF _num_used; THIS_ATTR _current_id = right._current_id; THIS_ATTR _mode = right._mode; } @@ -82,22 +82,23 @@ class Dict : public DictBase { void operator=(const Dict& right) { Clear(); Resize(right.GetSlotCount()); - for (unsigned int i = 0; i < (unsigned int)ArraySize(right._DictSlots_ref.DictSlots); ++i) { - THIS_ATTR _DictSlots_ref.DictSlots[i] = right._DictSlots_ref.DictSlots[i]; + for (unsigned int i = 0; i < (unsigned int)ArraySize(right._DictSlots_ref PTR_DEREF DictSlots); ++i) { + THIS_ATTR _DictSlots_ref PTR_DEREF DictSlots[i] = right._DictSlots_ref PTR_DEREF DictSlots[i]; } - THIS_ATTR _DictSlots_ref._num_used = right._DictSlots_ref._num_used; + THIS_ATTR _DictSlots_ref PTR_DEREF _num_used = right._DictSlots_ref PTR_DEREF _num_used; THIS_ATTR _current_id = right._current_id; THIS_ATTR _mode = right._mode; } void Clear() { - _DictSlots_ref = new DictSlotsRef(); + THIS_ATTR _DictSlots_ref = new DictSlotsRef(); - for (unsigned int i = 0; i < (unsigned int)ArraySize(THIS_ATTR _DictSlots_ref.DictSlots); ++i) { - if (THIS_ATTR _DictSlots_ref.DictSlots[i].IsUsed()) THIS_ATTR _DictSlots_ref.DictSlots[i].SetFlags(0); + for (unsigned int i = 0; i < (unsigned int)ArraySize(THIS_ATTR _DictSlots_ref PTR_DEREF DictSlots); ++i) { + if (THIS_ATTR _DictSlots_ref PTR_DEREF DictSlots[i].IsUsed()) + THIS_ATTR _DictSlots_ref PTR_DEREF DictSlots[i].SetFlags(0); } - THIS_ATTR _DictSlots_ref._num_used = 0; + THIS_ATTR _DictSlots_ref PTR_DEREF _num_used = 0; } /** @@ -355,8 +356,8 @@ class Dict : public DictBase { * Expands array of DictSlots by given percentage value. */ bool GrowUp(int percent = DICT_GROW_UP_PERCENT_DEFAULT) { - return Resize( - MathMax(10, (int)((float)ArraySize(THIS_ATTR _DictSlots_ref.DictSlots) * ((float)(percent + 100) / 100.0f)))); + return Resize(MathMax( + 10, (int)((float)ArraySize(THIS_ATTR _DictSlots_ref PTR_DEREF DictSlots) * ((float)(percent + 100) / 100.0f)))); } public: @@ -364,7 +365,7 @@ class Dict : public DictBase { * Ensures that there is at least given number of slots in dict. */ bool Reserve(int _size) { - if (_size <= ArraySize(THIS_ATTR _DictSlots_ref.DictSlots)) { + if (_size <= ArraySize(THIS_ATTR _DictSlots_ref PTR_DEREF DictSlots)) { return true; } return Resize(_size); @@ -375,7 +376,8 @@ class Dict : public DictBase { * Shrinks or expands array of DictSlots. */ bool Resize(int new_size) { - if (new_size <= MathMin(THIS_ATTR _DictSlots_ref._num_used, ArraySize(THIS_ATTR _DictSlots_ref.DictSlots))) { + if (new_size <= MathMin(THIS_ATTR _DictSlots_ref PTR_DEREF _num_used, + ArraySize(THIS_ATTR _DictSlots_ref PTR_DEREF DictSlots))) { // We already use minimum number of slots possible. return true; } @@ -393,19 +395,19 @@ class Dict : public DictBase { new_DictSlots PTR_DEREF _num_used = 0; // Copies entire array of DictSlots into new array of DictSlots. Hashes will be rehashed. - for (i = 0; i < ArraySize(THIS_ATTR _DictSlots_ref.DictSlots); ++i) { - if (!THIS_ATTR _DictSlots_ref.DictSlots[i].IsUsed()) continue; + for (i = 0; i < ArraySize(THIS_ATTR _DictSlots_ref PTR_DEREF DictSlots); ++i) { + if (!THIS_ATTR _DictSlots_ref PTR_DEREF DictSlots[i].IsUsed()) continue; - if (THIS_ATTR _DictSlots_ref.DictSlots[i].HasKey()) { - if (!InsertInto(new_DictSlots, THIS_ATTR _DictSlots_ref.DictSlots[i].key, - THIS_ATTR _DictSlots_ref.DictSlots[i].value, false)) + if (THIS_ATTR _DictSlots_ref PTR_DEREF DictSlots[i].HasKey()) { + if (!InsertInto(new_DictSlots, THIS_ATTR _DictSlots_ref PTR_DEREF DictSlots[i].key, + THIS_ATTR _DictSlots_ref PTR_DEREF DictSlots[i].value, false)) return false; } else { - if (!InsertInto(new_DictSlots, THIS_ATTR _DictSlots_ref.DictSlots[i].value)) return false; + if (!InsertInto(new_DictSlots, THIS_ATTR _DictSlots_ref PTR_DEREF DictSlots[i].value)) return false; } } // Freeing old DictSlots array. - ArrayFree(THIS_ATTR _DictSlots_ref.DictSlots); + ArrayFree(THIS_ATTR _DictSlots_ref PTR_DEREF DictSlots); delete THIS_ATTR _DictSlots_ref; diff --git a/Storage/Dict/DictIteratorBase.h b/Storage/Dict/DictIteratorBase.h index eddf34e56..f996289e5 100644 --- a/Storage/Dict/DictIteratorBase.h +++ b/Storage/Dict/DictIteratorBase.h @@ -21,8 +21,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Forward class declaration. @@ -113,7 +113,7 @@ class DictIteratorBase { return _index; } - V Value() { + V REF_CPP Value() { CheckValidity(); return _dict PTR_DEREF GetSlot(_slotIdx) PTR_DEREF value; } diff --git a/Storage/Dict/DictStruct.h b/Storage/Dict/DictStruct.h index e406278aa..c4a4efa3a 100644 --- a/Storage/Dict/DictStruct.h +++ b/Storage/Dict/DictStruct.h @@ -122,6 +122,18 @@ class DictStruct : public DictBase { return true; } +#ifndef __MQL__ + + /** + * Inserts value using hashless key. + */ + bool Push(const V& value) { + if (!InsertInto(THIS_ATTR _DictSlots_ref, value)) return false; + return true; + } + +#endif + /** * Inserts value using hashless key. */ @@ -367,7 +379,7 @@ class DictStruct : public DictBase { /** * Inserts hashless value into given array of DictSlots. */ - bool InsertInto(DictSlotsRef*& dictSlotsRef, V& value) { + bool InsertInto(DictSlotsRef*& dictSlotsRef, CONST_CPP V& value) { if (THIS_ATTR _mode == DictModeUnknown) THIS_ATTR _mode = DictModeList; else if (THIS_ATTR _mode != DictModeList) { diff --git a/Storage/ItemsHistory.h b/Storage/ItemsHistory.h index 08cc1f37a..85b16383c 100644 --- a/Storage/ItemsHistory.h +++ b/Storage/ItemsHistory.h @@ -29,14 +29,15 @@ #pragma once #endif -#include "../Refs.mqh" -#include "../Storage/Dict/DictStruct.h" - /** * Direction used by ItemsHistoryItemProvider's methods. */ enum ENUM_ITEMS_HISTORY_DIRECTION { ITEMS_HISTORY_DIRECTION_FORWARD, ITEMS_HISTORY_DIRECTION_BACKWARD }; +#include "../Indicator/IndicatorData.h" +#include "../Refs.mqh" +#include "../Storage/Dict/DictStruct.h" + /** * Forward declaration. */ diff --git a/Storage/ValueStorage.indicator.h b/Storage/ValueStorage.indicator.h index 4b36b561f..c6e4d6346 100644 --- a/Storage/ValueStorage.indicator.h +++ b/Storage/ValueStorage.indicator.h @@ -26,8 +26,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Forward declarations. @@ -66,13 +66,13 @@ class IndicatorBufferValueStorage : public HistoryValueStorage { }; // clang-format off -#include "../Indicator/IndicatorData.h" +#include "../Indicator/IndicatorBase.h" // clang-format on #ifndef __MQL__ template C IndicatorBufferValueStorage::Fetch(int _rel_shift) { IndicatorBase* _indi = THIS_ATTR indi_candle.Ptr(); - return _indi PTR_DEREF GetValue(mode, THIS_ATTR RealShift(_rel_shift)); + return _indi PTR_DEREF template GetValue(mode, THIS_ATTR RealShift(_rel_shift)); } #endif diff --git a/Storage/ValueStorage.native.h b/Storage/ValueStorage.native.h index 84686630d..6a61b80f1 100644 --- a/Storage/ValueStorage.native.h +++ b/Storage/ValueStorage.native.h @@ -25,8 +25,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Includes. @@ -55,7 +55,7 @@ class NativeValueStorage : public ValueStorage { /** * Initializes array with given one. */ - void SetData(CONST_ARRAY_REF(C, _arr)) { + void SetData(ARRAY_REF(C, _arr)) { bool _was_series = ArrayGetAsSeries(_arr); ArraySetAsSeries(_arr, false); ArraySetAsSeries(_values, false); diff --git a/Strategy.mqh b/Strategy.mqh index efd10014f..4f51cc261 100644 --- a/Strategy.mqh +++ b/Strategy.mqh @@ -44,44 +44,44 @@ class Trade; // Defines. // Primary inputs. #ifdef __input__ -#define INPUT input -#ifndef __MQL4__ -#define INPUT_GROUP(name) input group #name + #define INPUT input + #ifndef __MQL4__ + #define INPUT_GROUP(name) input group #name + #else + #define INPUT_GROUP(name) static input string; // #name + #endif #else -#define INPUT_GROUP(name) static input string; // #name -#endif -#else -#define INPUT static -#define INPUT_GROUP(name) static string + #define INPUT static + #define INPUT_GROUP(name) static string #endif // Secondary inputs. #ifdef __input2__ -#define INPUT2 input -#ifndef __MQL4__ -#define INPUT2_GROUP(name) input group #name -#else -#define INPUT2_GROUP(name) static input string; // #name -#endif + #define INPUT2 input + #ifndef __MQL4__ + #define INPUT2_GROUP(name) input group #name + #else + #define INPUT2_GROUP(name) static input string; // #name + #endif #else -#define INPUT2 static -#define INPUT2_GROUP(name) static string + #define INPUT2 static + #define INPUT2_GROUP(name) static string #endif // Tertiary inputs. #ifdef __input3__ -#define INPUT3 input -#ifndef __MQL4__ -#define INPUT3_GROUP(name) input group #name + #define INPUT3 input + #ifndef __MQL4__ + #define INPUT3_GROUP(name) input group #name + #else + #define INPUT3_GROUP(name) static input string; // #name + #endif #else -#define INPUT3_GROUP(name) static input string; // #name -#endif -#else -#define INPUT3 static -#define INPUT3_GROUP(name) static string + #define INPUT3 static + #define INPUT3_GROUP(name) static string #endif #ifdef __optimize__ -#define OINPUT input + #define OINPUT input #else -#define OINPUT static + #define OINPUT static #endif /** @@ -340,7 +340,8 @@ class Strategy : public Taskable { // return StringFormat("%s%s[%s];s:%gp%s", _prefix != "" ? _prefix + ": " : "", name, trade REF_DEREF // chart.TfToString(), GetCurrSpread(), _suffix != "" ? "| " + _suffix : ""); - return StringFormat("%s%s[%s]%s", _prefix, name, trade REF_DEREF GetSource() PTR_DEREF GetSymbolTf(), _suffix); + return StringFormat("%s%s[%s]%s", C_STR(_prefix), C_STR(name), + C_STR(trade REF_DEREF GetSource() PTR_DEREF GetSymbolTf()), C_STR(_suffix)); } /** @@ -348,7 +349,8 @@ class Strategy : public Taskable { */ string GetOrderCloseComment(string _prefix = "", string _suffix = "") { // @todo: Add spread. - return StringFormat("%s%s[%s]%s", _prefix, name, trade REF_DEREF GetSource() PTR_DEREF GetSymbolTf(), _suffix); + return StringFormat("%s%s[%s]%s", C_STR(_prefix), C_STR(name), + C_STR(trade REF_DEREF GetSource() PTR_DEREF GetSymbolTf()), C_STR(_suffix)); } /** @@ -655,7 +657,7 @@ class Strategy : public Taskable { /** * Prints strategy's details. */ - string const ToString() override { return StringFormat("%s: %s", GetName(), sparams.ToString()); } + string const ToString() override { return StringFormat("%s: %s", C_STR(GetName()), C_STR(sparams.ToString())); } /* Virtual methods */ @@ -669,21 +671,22 @@ class Strategy : public Taskable { */ virtual void OnInit() { // Link log instances. - logger.Link(trade.Ptr().GetLogger()); - trade.Ptr().GetLogger().SetLevel((ENUM_LOG_LEVEL)sparams.Get(STRAT_PARAM_LOG_LEVEL)); + logger.Link(trade REF_DEREF GetLogger()); + trade REF_DEREF GetLogger() PTR_DEREF SetLevel((ENUM_LOG_LEVEL)sparams.Get(STRAT_PARAM_LOG_LEVEL)); // Sets strategy stops. SetStops(THIS_PTR, THIS_PTR); // trade.SetStrategy(&this); // @fixme // Sets strategy's trade spread limit. - trade.Ptr().Set(TRADE_PARAM_MAX_SPREAD, sparams.Get(STRAT_PARAM_MAX_SPREAD)); + trade REF_DEREF Set(TRADE_PARAM_MAX_SPREAD, sparams.Get(STRAT_PARAM_MAX_SPREAD)); // Load active trades. if (Get(STRAT_PARAM_ID) > 0) { - trade.Ptr().OrdersLoadByMagic(Get(STRAT_PARAM_ID)); + trade REF_DEREF OrdersLoadByMagic(Get(STRAT_PARAM_ID)); } Ref _order; - for (DictStructIterator> iter = trade.Ptr().GetOrdersActive().Begin(); iter.IsValid(); ++iter) { + for (DictStructIterator> iter = trade REF_DEREF GetOrdersActive() PTR_DEREF Begin(); + iter.IsValid(); ++iter) { _order = iter.Value(); - if (_order.IsSet() && _order.Ptr().IsOpen()) { + if (_order.IsSet() && _order REF_DEREF IsOpen()) { Strategy::OnOrderLoad(_order.Ptr()); } } @@ -700,25 +703,26 @@ class Strategy : public Taskable { ENUM_TIMEFRAMES _stf = Get(STRAT_PARAM_TF); unsigned int _stf_secs = ChartTf::TfToSeconds(_stf); if (sparams.order_close_time != 0) { - long _close_time_arg = sparams.order_close_time > 0 ? sparams.order_close_time * 60 - : (int)round(-sparams.order_close_time * _stf_secs); - _order.Set(ORDER_PARAM_COND_CLOSE, ORDER_COND_LIFETIME_GT_ARG, _index); - _order.Set(ORDER_PARAM_COND_CLOSE_ARG_VALUE, _close_time_arg, _index); + long _close_time_arg = sparams.order_close_time > 0 + ? sparams.order_close_time * 60 + : (long)MathRound((long)-sparams.order_close_time * (long)_stf_secs); + _order PTR_DEREF Set(ORDER_PARAM_COND_CLOSE, ORDER_COND_LIFETIME_GT_ARG, _index); + _order PTR_DEREF Set(ORDER_PARAM_COND_CLOSE_ARG_VALUE, _close_time_arg, _index); _index++; } if (sparams.order_close_loss != 0.0f) { float _loss_limit = sparams.order_close_loss; - _order.Set(ORDER_PARAM_COND_CLOSE, ORDER_COND_IN_LOSS, _index); - _order.Set(ORDER_PARAM_COND_CLOSE_ARG_VALUE, _loss_limit, _index); + _order PTR_DEREF Set(ORDER_PARAM_COND_CLOSE, ORDER_COND_IN_LOSS, _index); + _order PTR_DEREF Set(ORDER_PARAM_COND_CLOSE_ARG_VALUE, _loss_limit, _index); _index++; } if (sparams.order_close_profit != 0.0f) { float _profit_limit = sparams.order_close_profit; - _order.Set(ORDER_PARAM_COND_CLOSE, ORDER_COND_IN_PROFIT, _index); - _order.Set(ORDER_PARAM_COND_CLOSE_ARG_VALUE, _profit_limit, _index); + _order PTR_DEREF Set(ORDER_PARAM_COND_CLOSE, ORDER_COND_IN_PROFIT, _index); + _order PTR_DEREF Set(ORDER_PARAM_COND_CLOSE_ARG_VALUE, _profit_limit, _index); _index++; } - _order.Set(ORDER_PARAM_UPDATE_FREQ, _stf_secs); + _order PTR_DEREF Set(ORDER_PARAM_UPDATE_FREQ, _stf_secs); SetStops(GetPointer(this), GetPointer(this)); // trade REF_DEREF SetStrategy(&this); // @fixme } @@ -894,7 +898,7 @@ class Strategy : public Taskable { * @result bool * Returns true when trade should be opened, otherwise false. */ - virtual bool SignalOpen(ENUM_ORDER_TYPE _cmd, int _method = 0, float _level = 0.0f, int _shift = 0) = NULL; + virtual bool SignalOpen(ENUM_ORDER_TYPE _cmd, int _method = 0, float _level = 0.0f, int _shift = 0) = 0; /** * Returns strength of strategy's open signal. @@ -1004,17 +1008,17 @@ class Strategy : public Taskable { if (METHOD(_method, 0)) if (IsTrend(_cmd)) _result *= 1.1f; if (METHOD(_method, 1)) - if (trade.Ptr().GetTrendOp(18, _stf)) _result *= 1.1f; + if (trade REF_DEREF GetTrendOp(18, _stf)) _result *= 1.1f; if (METHOD(_method, 2)) - if (!trade.Ptr().HasOrderBetter(_cmd)) _result *= 1.1f; + if (!trade REF_DEREF HasOrderBetter(_cmd)) _result *= 1.1f; if (METHOD(_method, 3)) - if (trade.Ptr().IsPeak(_cmd, _shift)) _result *= 1.1f; + if (trade REF_DEREF IsPeak(_cmd, _shift)) _result *= 1.1f; if (METHOD(_method, 4)) - if (trade.Ptr().IsPivot(_cmd, _shift)) _result *= 1.1f; + if (trade REF_DEREF IsPivot(_cmd, _shift)) _result *= 1.1f; if (METHOD(_method, 5)) - if (trade.Ptr().HasOrderOppositeType(_cmd)) _result *= 1.1f; + if (trade REF_DEREF HasOrderOppositeType(_cmd)) _result *= 1.1f; if (METHOD(_method, 6)) - if (trade.Ptr().HasBarOrder(_cmd, _shift)) _result *= 1.1f; + if (trade REF_DEREF HasBarOrder(_cmd, _shift)) _result *= 1.1f; // if (METHOD(_method, 0)) if (Trade().IsTrend(_cmd)) _result *= 1.1; // if (METHOD(_method, 1)) if (Trade().IsPivot(_cmd)) _result *= 1.1; // if (METHOD(_method, 2)) if (Trade().IsPeakHours(_cmd)) _result *= 1.1; @@ -1062,9 +1066,9 @@ class Strategy : public Taskable { if (METHOD(_method, 3)) _result |= _result || iOpen(Symbol(), PERIOD_CURRENT, _shift) > iHigh(Symbol(), PERIOD_CURRENT, _shift + 1) || iOpen(Symbol(), PERIOD_CURRENT, _shift) < iLow(Symbol(), PERIOD_CURRENT, _shift + 1); // 8 - if (METHOD(_method, 4)) _result |= _result || trade REF_DEREF IsPeak(_cmd, _shift); // 16 - if (METHOD(_method, 5)) _result |= _result || trade REF_DEREF HasOrderBetter(_cmd); // 32 - if (METHOD(_method, 6)) _result |= _result || trade REF_DEREF CalcActiveProfitInValue() > 0.0f; // 64 + if (METHOD(_method, 4)) _result |= _result || trade REF_DEREF IsPeak(_cmd, _shift); // 16 + if (METHOD(_method, 5)) _result |= _result || trade REF_DEREF HasOrderBetter(_cmd); // 32 + if (METHOD(_method, 6)) _result |= _result || trade REF_DEREF CalcActiveProfitInValue() > 0.0f; // 64 /* if (METHOD(_method, 6)) _result |= diff --git a/Strategy.struct.h b/Strategy.struct.h index 5df14b88f..178197aed 100644 --- a/Strategy.struct.h +++ b/Strategy.struct.h @@ -26,8 +26,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Includes. @@ -445,9 +445,10 @@ struct StgEntry { unsigned short signals; StgStatsPeriod stats_period[FINAL_ENUM_STRATEGY_STATS_PERIOD]; string ToCSV() { - return StringFormat("%s,%s,%s,%s", stats_period[(int)EA_STATS_DAILY].ToCSV(), - stats_period[(int)EA_STATS_WEEKLY].ToCSV(), stats_period[(int)EA_STATS_MONTHLY].ToCSV(), - stats_period[(int)EA_STATS_TOTAL].ToCSV()); + return StringFormat("%s,%s,%s,%s", C_STR(stats_period[(int)EA_STATS_DAILY].ToCSV()), + C_STR(stats_period[(int)EA_STATS_WEEKLY].ToCSV()), + C_STR(stats_period[(int)EA_STATS_MONTHLY].ToCSV()), + C_STR(stats_period[(int)EA_STATS_TOTAL].ToCSV())); } // Struct setters. void SetStats(StgStatsPeriod &_stats, ENUM_STRATEGY_STATS_PERIOD _period) { stats_period[(int)_period] = _stats; } diff --git a/SummaryReport.mqh b/SummaryReport.mqh index 405ab6482..d1a68aae2 100644 --- a/SummaryReport.mqh +++ b/SummaryReport.mqh @@ -21,8 +21,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif #include "Convert.mqh" @@ -307,17 +307,19 @@ class SummaryReport { string output = ""; _currency = _currency != "" ? _currency : AccountInfoString(ACCOUNT_CURRENCY); output += StringFormat("Currency pair symbol: %s", _Symbol) + sep; - output += StringFormat("Initial deposit: %.2f %s", GetInitDeposit(), _currency) + sep; - output += StringFormat("Total net profit: %.2f %s", summary_profit, _currency) + sep; - output += StringFormat("Gross profit: %.2f %s", gross_profit, _currency) + sep; - output += StringFormat("Gross loss: %.2f %s", gross_loss, _currency) + sep; - output += StringFormat("Absolute drawdown: %.2f %s", abs_dd, _currency) + sep; output += - StringFormat("Maximal drawdown: %.1f %s (%.1f%%)", max_dd, _currency, max_dd_pct) + - sep; + StringFormat("Initial deposit: %.2f %s", GetInitDeposit(), C_STR(_currency)) + sep; output += - StringFormat("Relative drawdown: (%.1f%%) %.1f %s", rel_dd_pct, rel_dd, _currency) + - sep; + StringFormat("Total net profit: %.2f %s", summary_profit, C_STR(_currency)) + sep; + output += StringFormat("Gross profit: %.2f %s", gross_profit, C_STR(_currency)) + sep; + output += StringFormat("Gross loss: %.2f %s", gross_loss, C_STR(_currency)) + sep; + output += StringFormat("Absolute drawdown: %.2f %s", abs_dd, C_STR(_currency)) + sep; + output += StringFormat("Maximal drawdown: %.1f %s (%.1f%%)", max_dd, C_STR(_currency), + max_dd_pct) + + sep; + output += StringFormat("Relative drawdown: (%.1f%%) %.1f %s", rel_dd_pct, rel_dd, + C_STR(_currency)) + + sep; output += StringFormat("Profit factor: %.2f", profit_factor) + sep; output += StringFormat("Expected payoff: %.2f", expected_payoff) + sep; output += StringFormat("Trades total %d", summary_trades) + sep; diff --git a/Task/Task.h b/Task/Task.h index f6e2b483e..548df0483 100644 --- a/Task/Task.h +++ b/Task/Task.h @@ -26,16 +26,14 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Includes. -#include "../Storage/Dict/DictStruct.h" -#include "../Refs.mqh" #include "../Platform/Terminal.define.h" +#include "../Refs.mqh" #include "../Storage/Dict/DictStruct.h" -#include "../Platform/Terminal.define.h" #include "Task.enum.h" #include "Task.struct.h" #include "TaskAction.h" @@ -318,8 +316,8 @@ class Task : public Taskable { }; #ifdef EMSCRIPTEN -#include -#include + #include + #include EMSCRIPTEN_BINDINGS(Task) { emscripten::class_("Task").smart_ptr>("Ref").constructor(emscripten::optional_override([]() { diff --git a/Task/TaskObject.h b/Task/TaskObject.h index 9f93a0265..942f6b7d7 100644 --- a/Task/TaskObject.h +++ b/Task/TaskObject.h @@ -26,16 +26,16 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Prevents processing this includes file for the second time. #ifndef TASK_OBJECT_H -#define TASK_OBJECT_H + #define TASK_OBJECT_H -// Includes. -#include "Task.h" + // Includes. + #include "Task.h" template class TaskObject : public Task { @@ -54,7 +54,8 @@ class TaskObject : public Task { /** * Class constructor with task entry as argument. */ - TaskObject(TaskEntry &_tentry, TA *_obja = nullptr, TC *_objc = nullptr) : Task(_tentry), obja(_obja), objc(_objc) {} + TaskObject(TaskEntry &_tentry, TA *_obja = nullptr, TC *_objc = nullptr) + : Task(_tentry), obja(_obja), objc(_objc) {} /** * Class deconstructor. diff --git a/Trade.mqh b/Trade.mqh index 0446da64b..4ada25cb4 100644 --- a/Trade.mqh +++ b/Trade.mqh @@ -107,18 +107,10 @@ class Trade : public Taskable { /** * Class deconstructor. */ - void ~Trade() {} + ~Trade() {} /* Getters simple */ - /** - * Gets an account parameter value of double type. - */ - template - T Get(ENUM_ACCOUNT_INFO_DOUBLE _param) { - return account.Get(_param); - } - /** * Gets a trade state value. */ @@ -213,7 +205,8 @@ class Trade : public Taskable { MqlTradeRequest _request = {(ENUM_TRADE_REQUEST_ACTIONS)0}; _request.action = TRADE_ACTION_DEAL; _request.comment = _comment; - _request.deviation = tparams.Get(TRADE_PARAM_SLIPPAGE); // The maximal price deviation, specified in points. + _request.deviation = + tparams.Get(TRADE_PARAM_SLIPPAGE); // The maximal price deviation, specified in points. _request.magic = _magic > 0 ? _magic : tparams.Get(TRADE_PARAM_MAGIC_NO); _request.symbol = GetSource() PTR_DEREF GetSymbol(); _request.price = GetSource() PTR_DEREF GetOpenOffer(_type); @@ -794,7 +787,8 @@ HistorySelect(0, TimeCurrent()); // Select history for access. break; case TRADE_ACTION_DEAL: if (!IsTradeRecommended(true)) { - logger.Debug("Trade not opened due to trading states.", __FUNCTION_LINE__, (string)tstates.GetStates()); + logger.Debug("Trade not opened due to trading states.", __FUNCTION_LINE__, + IntegerToString(tstates.GetStates())); return _result; } else if (account.GetAccountFreeMarginCheck(_request.type, _request.volume) == 0) { logger.Error("No free margin to open a new trade!", __FUNCTION_LINE__); @@ -830,8 +824,8 @@ HistorySelect(0, TimeCurrent()); // Select history for access. if (_order PTR_DEREF IsOpen()) { // @todo: _order.IsPending()? _result &= orders_active.Set(_order PTR_DEREF Get(ORDER_PROP_TICKET), _order_ref); - logger.Link(_order.GetLogger()); - _order PTR_DEREF GetLogger().SetLevel((ENUM_LOG_LEVEL)tparams.Get(TRADE_PARAM_LOG_LEVEL)); + logger.Link(_order PTR_DEREF GetLogger()); + _order PTR_DEREF GetLogger() PTR_DEREF SetLevel((ENUM_LOG_LEVEL)tparams.Get(TRADE_PARAM_LOG_LEVEL)); } else { _result &= orders_history.Set(_order PTR_DEREF Get(ORDER_PROP_TICKET), _order_ref); } @@ -895,11 +889,12 @@ HistorySelect(0, TimeCurrent()); // Select history for access. OrderMoveToHistory(_order.Ptr()); order_last = _order; } else { - logger.Error(StringFormat("Failed to close the order: %d! Error: %d (%s)", - _order REF_DEREF Get(ORDER_PROP_TICKET), - _order REF_DEREF Get(ORDER_PROP_LAST_ERROR), - Terminal::GetErrorText(_order REF_DEREF Get(ORDER_PROP_LAST_ERROR))), - __FUNCTION_LINE__); + logger.Error( + StringFormat("Failed to close the order: %d! Error: %d (%s)", + _order REF_DEREF Get(ORDER_PROP_TICKET), + _order REF_DEREF Get(ORDER_PROP_LAST_ERROR), + C_STR(Terminal::GetErrorText(_order REF_DEREF Get(ORDER_PROP_LAST_ERROR)))), + __FUNCTION_LINE__); continue; } } else { @@ -936,7 +931,7 @@ HistorySelect(0, TimeCurrent()); // Select history for access. StringFormat("Failed to close the order: %d! Error: %d (%s)", _order REF_DEREF Get(ORDER_PROP_TICKET), _order REF_DEREF Get(ORDER_PROP_LAST_ERROR), - Terminal::GetErrorText(_order REF_DEREF Get(ORDER_PROP_LAST_ERROR))), + C_STR(Terminal::GetErrorText(_order REF_DEREF Get(ORDER_PROP_LAST_ERROR)))), __FUNCTION_LINE__); continue; } @@ -1396,7 +1391,7 @@ HistorySelect(0, TimeCurrent()); // Select history for access. * @return * Returns Buy operation for bullish, Sell for bearish, otherwise NULL for neutral market trend. */ - ENUM_ORDER_TYPE GetTrendOp(int method, ENUM_TIMEFRAMES _tf = NULL, bool simple = false) { + ENUM_ORDER_TYPE GetTrendOp(int method, ENUM_TIMEFRAMES _tf = (ENUM_TIMEFRAMES)0, bool simple = false) { double _curr_trend = GetTrend(method, _tf, simple); return _curr_trend == 0 ? (ENUM_ORDER_TYPE)(ORDER_TYPE_BUY + ORDER_TYPE_SELL) : (_curr_trend > 0 ? ORDER_TYPE_BUY : ORDER_TYPE_SELL); @@ -1864,52 +1859,60 @@ HistorySelect(0, TimeCurrent()); // Select history for access. return tparams.IsLimitGe(tstats); case TRADE_COND_IS_PEAK: if (Get(TRADE_STATE_ORDERS_ACTIVE) && orders_active.Size() > 0) { - ENUM_ORDER_TYPE _order_types1[] = {ORDER_TYPE_BUY, ORDER_TYPE_SELL}; + ARRAY(ENUM_ORDER_TYPE, _order_types1); + ArrayPush(_order_types1, ORDER_TYPE_BUY); + ArrayPush(_order_types1, ORDER_TYPE_SELL); ENUM_ORDER_TYPE _order_type_profitable1 = - _oquery_ref.Ptr() - .FindPropBySum( + _oquery_ref.Ptr() PTR_DEREF + FindPropBySum( _order_types1, ORDER_PROP_PROFIT, ORDER_TYPE); return IsPeak(_order_type_profitable1); } case TRADE_COND_IS_PIVOT: if (Get(TRADE_STATE_ORDERS_ACTIVE) && orders_active.Size() > 0) { - ENUM_ORDER_TYPE _order_types2[] = {ORDER_TYPE_BUY, ORDER_TYPE_SELL}; + ARRAY(ENUM_ORDER_TYPE, _order_types2); + ArrayPush(_order_types2, ORDER_TYPE_BUY); + ArrayPush(_order_types2, ORDER_TYPE_SELL); ENUM_ORDER_TYPE _order_type_profitable2 = - _oquery_ref.Ptr() - .FindPropBySum( + _oquery_ref.Ptr() PTR_DEREF + FindPropBySum( _order_types2, ORDER_PROP_PROFIT, ORDER_TYPE); return IsPivot(_order_type_profitable2); } case TRADE_COND_ORDERS_PROFIT_DBL_LOSS: if (Get(TRADE_STATE_ORDERS_ACTIVE) && orders_active.Size() > 1) { float _profit_buys = - _oquery_ref.Ptr() - .CalcSumByPropWithCond(ORDER_PROP_PROFIT_PIPS, ORDER_TYPE, ORDER_TYPE_BUY); + _oquery_ref.Ptr() PTR_DEREF CalcSumByPropWithCond(ORDER_PROP_PROFIT_PIPS, + ORDER_TYPE, ORDER_TYPE_BUY); float _profit_sells = - _oquery_ref.Ptr() - .CalcSumByPropWithCond(ORDER_PROP_PROFIT_PIPS, ORDER_TYPE, ORDER_TYPE_SELL); + _oquery_ref.Ptr() PTR_DEREF CalcSumByPropWithCond(ORDER_PROP_PROFIT_PIPS, + ORDER_TYPE, ORDER_TYPE_SELL); return (((_profit_buys > 1) && (_profit_sells < -1) && (_profit_buys > -(_profit_sells * 2))) || ((_profit_sells > 1) && (_profit_buys < -1) && (_profit_sells > -(_profit_buys * 2)))); } break; case TRADE_COND_ORDERS_IN_TREND: if (Get(TRADE_STATE_ORDERS_ACTIVE)) { - ENUM_ORDER_TYPE _order_types3[] = {ORDER_TYPE_BUY, ORDER_TYPE_SELL}; + ARRAY(ENUM_ORDER_TYPE, _order_types3); + ArrayPush(_order_types3, ORDER_TYPE_BUY); + ArrayPush(_order_types3, ORDER_TYPE_SELL); ENUM_ORDER_TYPE _order_type_profit1 = - _oquery_ref.Ptr() - .FindPropBySum( + _oquery_ref.Ptr() PTR_DEREF + FindPropBySum( _order_types3, ORDER_PROP_PROFIT, ORDER_TYPE); return _order_type_profit1 == GetTrendOp(18, PERIOD_D1); } break; case TRADE_COND_ORDERS_IN_TREND_NOT: if (Get(TRADE_STATE_ORDERS_ACTIVE)) { - ENUM_ORDER_TYPE _order_types4[] = {ORDER_TYPE_BUY, ORDER_TYPE_SELL}; + ARRAY(ENUM_ORDER_TYPE, _order_types4); + ArrayPush(_order_types4, ORDER_TYPE_BUY); + ArrayPush(_order_types4, ORDER_TYPE_SELL); ENUM_ORDER_TYPE _order_type_profit2 = - _oquery_ref.Ptr() - .FindPropBySum( + _oquery_ref.Ptr() PTR_DEREF + FindPropBySum( _order_types4, ORDER_PROP_PROFIT, ORDER_TYPE); return _order_type_profit2 != GetTrendOp(18, PERIOD_D1); } diff --git a/Trade.struct.h b/Trade.struct.h index 8f8ac43fd..fa3fad96e 100644 --- a/Trade.struct.h +++ b/Trade.struct.h @@ -26,8 +26,8 @@ */ #ifndef __MQL__ -// Allows the preprocessor to include a header file when it is needed. -#pragma once + // Allows the preprocessor to include a header file when it is needed. + #pragma once #endif // Forward declarations. @@ -211,10 +211,10 @@ struct TradeParams { } bool IsLimitGe(TradeStats &_stats) { // @todo: Improve code performance. - for (ENUM_TRADE_STAT_TYPE t = 0; t < FINAL_ENUM_TRADE_STAT_TYPE; t++) { - for (ENUM_TRADE_STAT_PERIOD p = 0; p < FINAL_ENUM_TRADE_STAT_PERIOD; p++) { - unsigned int _stat_value = _stats.GetOrderStats(t, p); - if (_stat_value > 0 && IsLimitGe(t, p, _stat_value)) { + for (/*ENUM_TRADE_STAT_TYPE*/ int t = 0; t < FINAL_ENUM_TRADE_STAT_TYPE; t++) { + for (/*ENUM_TRADE_STAT_PERIOD*/ int p = 0; p < FINAL_ENUM_TRADE_STAT_PERIOD; p++) { + unsigned int _stat_value = _stats.GetOrderStats((ENUM_TRADE_STAT_TYPE)t, (ENUM_TRADE_STAT_PERIOD)p); + if (_stat_value > 0 && IsLimitGe((ENUM_TRADE_STAT_TYPE)t, (ENUM_TRADE_STAT_PERIOD)p, _stat_value)) { return true; } } diff --git a/tests/AccountTest.cpp b/tests/AccountTest.cpp index 4fb5082c8..4ee0054ba 100644 --- a/tests/AccountTest.cpp +++ b/tests/AccountTest.cpp @@ -35,7 +35,7 @@ typedef unsigned long ulong; typedef unsigned short ushort; // Includes. -#include "../Account/Account.h" +#include "../Exchange/Account/Account.h" int main(int argc, char **argv) { // Initialize class. diff --git a/tests/ObjectTest.cpp b/tests/ObjectTest.cpp index 200b014a7..ac78bc4ac 100644 --- a/tests/ObjectTest.cpp +++ b/tests/ObjectTest.cpp @@ -35,7 +35,7 @@ typedef unsigned long ulong; typedef unsigned short ushort; // Includes. -#include "../Object.mqh" +#include "../Storage/Object.h" // Variables. Object *obj; diff --git a/tests/SymbolInfoTest.cpp b/tests/SymbolInfoTest.cpp index 9603626e8..f3dd50e37 100644 --- a/tests/SymbolInfoTest.cpp +++ b/tests/SymbolInfoTest.cpp @@ -35,7 +35,7 @@ typedef unsigned long ulong; typedef unsigned short ushort; // Includes. -#include "../SymbolInfo.mqh" +#include "../Exchange/SymbolInfo/SymbolInfo.h" int main(int argc, char **argv) { SymbolInfo *si = new SymbolInfo(); diff --git a/tests/TerminalTest.cpp b/tests/TerminalTest.cpp index 7471e025b..ec9c8fcef 100644 --- a/tests/TerminalTest.cpp +++ b/tests/TerminalTest.cpp @@ -25,7 +25,7 @@ */ // Includes. -#include "../Terminal.mqh" +#include "../Platform/Terminal.h" // Variables. Terminal *terminal;