diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index ea90a50..23eca8e 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -1,80 +1,170 @@ --- name: Compile +# Setting an environment variable with the value of a configuration variable. +env: + ARTIFACT_PREFIX: ${{ inputs.artifact_prefix || 'mt' }} + # yamllint disable-line rule:line-length + CHECKOUT_BRANCH: ${{ inputs.checkout_branch || github.head_ref || github.ref_name }} + INDI_OTHER_WORKDIR: ${{ vars.INDI_OTHER_WORKDIR || 'indicators-other' }} + REPOSITORY: EA31337/EA31337-indicators-other + SKIP_CLEANUP: ${{ inputs.skip_cleanup || false }} + # yamllint disable-line rule:truthy on: pull_request: branches: - 'master' - - 'dev*' + - '*dev*' paths-ignore: - '*.md' - '.git*' push: branches: - 'master' - - 'dev*' + - '*dev*' paths-ignore: - '*.md' - '.git*' + workflow_call: + inputs: + artifact_prefix: + default: mt + description: Artifact prefix. + required: false + type: string + checkout_branch: + default: ${{ github.head_ref || github.ref_name }} + description: Checkout branch + required: false + type: string + skip_cleanup: + default: false + description: Whether to skip a clean-up job. + required: false + type: boolean jobs: - GetList: - outputs: - filelist: ${{ steps.get-files.outputs.filelist }} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Set output with list of files - id: get-files - run: | - import glob, json, os - fghout = os.environ["GITHUB_OUTPUT"] - files = glob.glob("**/*.mq?", recursive=True) - filelist = "filelist={}".format(json.dumps(files)) - with open(fghout, "a") as fd: - fd.write(filelist) - shell: python - - name: Display outputs - run: echo "${{ toJson(steps.get-files.outputs) }}" - Compile: + mt4: + name: Installs platform (4) + uses: EA31337/EA-Tester/.github/workflows/platform-linux.yml@dev + with: + artifact_name: ${{ inputs.artifact_prefix || 'mt' }}4 + artifact_overwrite: true + skip_cleanup: true + version: 4 + + mt5: + name: Installs platform (5) + uses: EA31337/EA-Tester/.github/workflows/platform-linux.yml@dev + with: + artifact_name: ${{ inputs.artifact_prefix || 'mt' }}5 + artifact_overwrite: true + skip_cleanup: true + version: 5 + + compile-platform-indicators: defaults: run: shell: powershell - needs: [GetList] + name: Compile platform indicators + needs: [mt4, mt5] runs-on: windows-latest strategy: matrix: - file: ${{ fromJson(needs.GetList.outputs.filelist) }} + version: [4, 5] steps: - - uses: actions/checkout@v3 - - uses: actions/checkout@v3 + - uses: actions/download-artifact@v4 with: - path: Include/EA31337-classes - ref: v3.000-dev - repository: EA31337/EA31337-classes - - name: Compile (build 2361) - uses: fx31337/mql-compile-action@master + name: ${{ env.ARTIFACT_PREFIX }}${{ matrix.version }} + path: .${{ env.ARTIFACT_PREFIX }}${{ matrix.version }} + - name: Compile MQL + uses: fx31337/mql-compile-action@dev with: include: . init-platform: true - mt-version: 5.0.0.2361 - path: ${{ matrix.file }} + mt-path: .${{ env.ARTIFACT_PREFIX }}${{ matrix.version }} + # yamllint disable-line rule:line-length + path: .${{ env.ARTIFACT_PREFIX }}${{ matrix.version }}/**/MQL?/Indicators verbose: true - - name: Compile (build 2515) - if: endsWith(matrix.file, '.mq5') + - name: Copy MQL to the current location + run: >- + Copy-Item + -Path ".${{ env.ARTIFACT_PREFIX }}*\*\*\MQL?" + -Destination . + -Recurse + -Verbose + - name: List all source code files + run: '(Get-ChildItem -Recurse -Path "MQL?" -Include *.mq[45]).fullname' + - name: List compiled files + run: '(Get-ChildItem -Recurse -Path "MQL?" -Include *.ex[45]).fullname' + - name: Upload platform indicators + uses: actions/upload-artifact@v4 + with: + if-no-files-found: error + name: ${{ env.ARTIFACT_PREFIX }}-indicators-ex${{ matrix.version }} + path: MQL?/**/*.[me][qx][45h] + - if: ${{ failure() }} + uses: mxschmitt/action-tmate@v3 + timeout-minutes: 20 + + compile-indicators: + defaults: + run: + shell: powershell + name: Compile Indicators + needs: [compile-platform-indicators] + runs-on: windows-latest + strategy: + matrix: + version: [4, 5] + steps: + - uses: actions/checkout@v4 + with: + path: ${{ env.INDI_OTHER_WORKDIR }} + ref: ${{ env.CHECKOUT_BRANCH }} + repository: EA31337/EA31337-indicators-other + - uses: actions/checkout@v4 + with: + path: MQL${{ matrix.version}}/Include/EA31337-classes + ref: v3.000.1 + repository: EA31337/EA31337-classes + - uses: actions/download-artifact@v4 + with: + name: ${{ env.ARTIFACT_PREFIX }}${{ matrix.version }} + path: .${{ env.ARTIFACT_PREFIX }}${{ matrix.version }} + - uses: actions/download-artifact@v4 + with: + merge-multiple: true + pattern: ${{ env.ARTIFACT_PREFIX }}-indicators-ex? + - name: List all source code files + run: '(Get-ChildItem -Recurse -Path . -Include *.mq[45]).fullname' + - name: List compiled files + run: '(Get-ChildItem -Recurse -Path . -Include *.ex[45]).fullname' + - name: Compile uses: fx31337/mql-compile-action@master with: - include: . - init-platform: true - mt-version: 5.0.0.2515 - path: ${{ matrix.file }} + include: MQL${{ matrix.version }} + mt-path: .${{ env.ARTIFACT_PREFIX }}${{ matrix.version }} + path: ${{ env.INDI_OTHER_WORKDIR }}/**/*.mq${{ matrix.version }} verbose: true - name: List compiled files run: '(Get-ChildItem -Recurse -Path . -Include *.ex[45]).fullname' - run: Get-Location - name: Upload indicator artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 + with: + # yamllint disable-line rule:line-length + name: ${{ env.ARTIFACT_PREFIX }}-indicators-other-ex${{ matrix.version }} + path: ${{ env.INDI_OTHER_WORKDIR }}/**/*.ex[45] + timeout-minutes: 30 + + cleanup: + if: inputs.skip_cleanup != true + name: Clean-up + needs: [compile-indicators] + runs-on: ubuntu-latest + steps: + - uses: geekyeggo/delete-artifact@v5 with: - name: Indicators-other - path: '**/*.ex?' + name: ${{ env.ARTIFACT_PREFIX }}* diff --git a/Misc/ATR_MA_Trend.mq4 b/Misc/ATR_MA_Trend.mq4.todo similarity index 100% rename from Misc/ATR_MA_Trend.mq4 rename to Misc/ATR_MA_Trend.mq4.todo diff --git a/Oscillators/Elliott_Wave_Oscillator2.mq4 b/Oscillators/Multi/Elliott_Wave_Oscillator2.mq4 similarity index 100% rename from Oscillators/Elliott_Wave_Oscillator2.mq4 rename to Oscillators/Multi/Elliott_Wave_Oscillator2.mq4 diff --git a/Oscillators/Elliott_Wave_Oscillator2.mq5 b/Oscillators/Multi/Elliott_Wave_Oscillator2.mq5 similarity index 100% rename from Oscillators/Elliott_Wave_Oscillator2.mq5 rename to Oscillators/Multi/Elliott_Wave_Oscillator2.mq5 diff --git a/Oscillators/Multi/README.md b/Oscillators/Multi/README.md new file mode 100644 index 0000000..0205560 --- /dev/null +++ b/Oscillators/Multi/README.md @@ -0,0 +1,26 @@ +# Oscillator multi-value indicators + +Multi-value oscillators, often referred to as "multi-line" or "multi-buffer" +oscillators, are a variation of traditional oscillators used in technical +analysis. While traditional oscillators like the RSI or Stochastic oscillator +generate a single line that oscillates within a specific range, +multi-value oscillators plot multiple lines +or buffers on a histogram-like chart. + +These additional lines on the histogram provide traders and analysts with +more information and insights into the price movement and momentum of an +asset. Each line represents a different aspect of price behavior, allowing +for a more comprehensive analysis of market conditions. + +The interaction and relationship between these multiple lines can offer +valuable signals and indications of potential market trends, reversals, or +momentum shifts. Traders often look for crossovers, divergences, and +patterns among the lines to make more informed trading decisions. + +## TDI (Traders Dynamic Index) + +The Traders Dynamic Index (TDI) is a versatile trading indicator designed to +aid traders in analyzing market conditions related to trend direction, market +strength, and volatility. It combines RSI, Moving Averages, and volatility +bands to offer insights into trend direction, market strength, and volatility +which gives comprehensive overview of the market's behavior. diff --git a/Oscillators/SVE_Bollinger_Bands.mq4 b/Oscillators/Multi/SVE_Bollinger_Bands.mq4 similarity index 100% rename from Oscillators/SVE_Bollinger_Bands.mq4 rename to Oscillators/Multi/SVE_Bollinger_Bands.mq4 diff --git a/Oscillators/SVE_Bollinger_Bands.mq5 b/Oscillators/Multi/SVE_Bollinger_Bands.mq5 similarity index 100% rename from Oscillators/SVE_Bollinger_Bands.mq5 rename to Oscillators/Multi/SVE_Bollinger_Bands.mq5 diff --git a/Oscillators/SuperSlope.mq4 b/Oscillators/Multi/SuperSlope.mq4 similarity index 100% rename from Oscillators/SuperSlope.mq4 rename to Oscillators/Multi/SuperSlope.mq4 diff --git a/Oscillators/SuperSlope.mq5 b/Oscillators/Multi/SuperSlope.mq5.fixme similarity index 100% rename from Oscillators/SuperSlope.mq5 rename to Oscillators/Multi/SuperSlope.mq5.fixme diff --git a/Oscillators/TDI-RT-Clone.mq4 b/Oscillators/Multi/TDI-RT-Clone.mq4 similarity index 100% rename from Oscillators/TDI-RT-Clone.mq4 rename to Oscillators/Multi/TDI-RT-Clone.mq4 diff --git a/Oscillators/TDI-RT-Clone.mq5 b/Oscillators/Multi/TDI-RT-Clone.mq5 similarity index 100% rename from Oscillators/TDI-RT-Clone.mq5 rename to Oscillators/Multi/TDI-RT-Clone.mq5 diff --git a/Oscillators/Traders Dynamic Index.mq4 b/Oscillators/Multi/TDI.mq4 similarity index 97% rename from Oscillators/Traders Dynamic Index.mq4 rename to Oscillators/Multi/TDI.mq4 index 7900b8f..5bc9e9d 100644 --- a/Oscillators/Traders Dynamic Index.mq4 +++ b/Oscillators/Multi/TDI.mq4 @@ -92,12 +92,12 @@ #property indicator_separate_window extern int RSI_Period = 13; //8-25 -extern int RSI_Price = 0; //0-6 +extern ENUM_APPLIED_PRICE RSI_Price = PRICE_CLOSE; extern int Volatility_Band = 34; //20-40 extern int RSI_Price_Line = 2; -extern int RSI_Price_Type = 0; //0-3 +extern ENUM_MA_METHOD RSI_Price_Type = MODE_SMA; extern int Trade_Signal_Line = 7; -extern int Trade_Signal_Type = 0; //0-3 +extern ENUM_MA_METHOD Trade_Signal_Type = MODE_SMA; double RSIBuf[],UpZone[],MdZone[],DnZone[],MaBuf[],MbBuf[]; @@ -141,7 +141,7 @@ int start() ArrayResize(RSI,Volatility_Band); int counted_bars=IndicatorCounted(); int i; - int limit = Bars-counted_bars-1; + int limit = MathMax(0, Bars - counted_bars - Volatility_Band); for(i=limit; i>=0; i--) { RSIBuf[i] = (iRSI(NULL,0,RSI_Period,RSI_Price,i)); diff --git a/Oscillators/Traders Dynamic Index.mq5 b/Oscillators/Multi/TDI.mq5 similarity index 56% rename from Oscillators/Traders Dynamic Index.mq5 rename to Oscillators/Multi/TDI.mq5 index 45ad00a..72d7706 100644 --- a/Oscillators/Traders Dynamic Index.mq5 +++ b/Oscillators/Multi/TDI.mq5 @@ -28,32 +28,44 @@ #include #include +int BarsShrinked() { + static int _initial_bars = MathMax(0, ChartStatic::iBars(_Symbol, _Period) - 1000); + int _result = ChartStatic::iBars(_Symbol, _Period) - _initial_bars; + return _result; +} + // Defines macros. #define extern input -#define Bars fmin(10000, (ChartStatic::iBars(_Symbol, _Period))) +#define Bars BarsShrinked() #define Bid (SymbolInfoStatic::GetBid(_Symbol)) #define TimeDayOfWeek (DateTime::DateOfWeek()) // Includes the main file. -#include "Traders Dynamic Index.mq4" +#include "TDI.mq4" // Custom indicator initialization function. -void OnInit() { - init(); - if (!ArrayGetAsSeries(RSIBuf)) { - ArraySetAsSeries(RSIBuf, true); - ArraySetAsSeries(UpZone, true); - ArraySetAsSeries(MdZone, true); - ArraySetAsSeries(DnZone, true); - ArraySetAsSeries(MaBuf, true); - ArraySetAsSeries(MbBuf, true); - } -} +void OnInit() { init(); } // Custom indicator iteration function. -int OnCalculate(const int rates_total, const int prev_calculated, - const int begin, const double &price[]) { - IndicatorCounted(fmin(prev_calculated, Bars)); +int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) { ResetLastError(); - return start() >= 0 ? rates_total : 0; + + ArraySetAsSeries(RSIBuf, true); + ArraySetAsSeries(UpZone, true); + ArraySetAsSeries(MdZone, true); + ArraySetAsSeries(DnZone, true); + ArraySetAsSeries(MaBuf, true); + ArraySetAsSeries(MbBuf, true); + + int _result = start() >= 0 ? rates_total : 0; + + ArraySetAsSeries(RSIBuf, false); + ArraySetAsSeries(UpZone, false); + ArraySetAsSeries(MdZone, false); + ArraySetAsSeries(DnZone, false); + ArraySetAsSeries(MaBuf, false); + ArraySetAsSeries(MbBuf, false); + + IndicatorCounted(fmin(rates_total, Bars)); + return _result; } diff --git a/Oscillators/README.md b/Oscillators/README.md index b56bfad..13a7437 100644 --- a/Oscillators/README.md +++ b/Oscillators/README.md @@ -28,11 +28,3 @@ In summary, oscillators are a type of indicator used in technical analysis that measure price momentum and provide insights into overbought or oversold conditions. They are considered a subset of indicators due to their specific function and characteristics. - -## TDI (Traders Dynamic Index) - -The Traders Dynamic Index (TDI) is a versatile trading indicator designed to -aid traders in analyzing market conditions related to trend direction, market -strength, and volatility. It combines RSI, Moving Averages, and volatility -bands to offer insights into trend direction, market strength, and volatility -which gives comprehensive overview of the market's behavior. diff --git a/Price/SuperTrend.mq4 b/Price/SuperTrend.mq4 index b43dee1..c1181b8 100644 --- a/Price/SuperTrend.mq4 +++ b/Price/SuperTrend.mq4 @@ -5,13 +5,35 @@ * @fixme */ +#property indicator_chart_window +#property indicator_buffers 4 +#property indicator_plots 1 +#property indicator_label1 "SuperTrend" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrGreen +#property indicator_color2 clrRed +#property indicator_color3 clrDarkGray +#property indicator_style1 STYLE_SOLID +#property indicator_width1 2 + // Includes EA31337 framework. -//#include +// #include // Includes. -//#include "SuperTrend.mq5" +// #include "SuperTrend.mq5" // Custom indicator initialization function. void OnInit() { // @fixme } + +// Custom indicator iteration function. +int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], + const double &high[], const double &low[], const double &close[], const long &tick_volume[], + const long &volume[], const int &spread[]) { + int start = rates_total - prev_calculated; + + // @todo: Call OnCalculate() in .mq5 file. + + return (rates_total); +} diff --git a/enum.h b/enum.h index ff73a76..0488ff6 100644 --- a/enum.h +++ b/enum.h @@ -22,13 +22,13 @@ #ifndef ENUM_INDICATOR_OTHER_DEFINED // Defines enum with supported indicator list. enum ENUM_INDICATOR_OTHER { - INDI_OTHER_0_NONE = 0, // (None) - INDI_OTHER_MISC_ATR_MA_TREND, // Misc: ATR MA Trend - INDI_OTHER_OSC_SUPERSLOPE, // Oscillator: Super Slope - INDI_OTHER_OSC_TDI, // Oscillator: TDI (Traders Dynamic Index) - INDI_OTHER_OSC_TDI_RT_CLONE, // Oscillator: TDI-RT-Clone - INDI_OTHER_OSC_TMA_CG, // Oscillator: TMA CG - INDI_OTHER_PRICE_EWO2, // Oscillator: Elliott Wave Oscillator 2 + INDI_OTHER_0_NONE = 0, // (None) + INDI_OTHER_MISC_ATR_MA_TREND, // Misc: ATR MA Trend + INDI_OTHER_OSC_SUPERSLOPE, // Oscillator: Super Slope + INDI_OTHER_OSC_MULTI_EWO2, // Oscillator: Elliott Wave Oscillator 2 + INDI_OTHER_OSC_MULTI_TDI, // Oscillator: TDI (Traders Dynamic Index) + INDI_OTHER_OSC_MULTI_TDI_RT_CLONE, // Oscillator: TDI-RT-Clone + INDI_OTHER_OSC_MULTI_TMA_CG, // Oscillator: TMA CG INDI_OTHER_PRICE_MULTI_OHLC_HA_SMOOTHED, // Price/Range: SVE Bollinger Bands INDI_OTHER_PRICE_RANGE_SVE_BB, // Price/Range: SVE Bollinger Bands };