Skip to content

Commit

Permalink
Adds Indi_Custom indicator
Browse files Browse the repository at this point in the history
  • Loading branch information
kenorb committed Jan 5, 2022
1 parent 66d435a commit a7f3334
Show file tree
Hide file tree
Showing 5 changed files with 276 additions and 0 deletions.
65 changes: 65 additions & 0 deletions .github/workflows/test-indicators-special.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
name: Test Indicators (Special)

# yamllint disable-line rule:truthy
on:
pull_request:
paths:
- 'Indicator**'
- 'Indicators/Special/**'
- '.github/workflows/test-indicators-special.yml'
push:
paths:
- 'Indicator**'
- 'Indicators/Special/**'
- '.github/workflows/test-indicators-special.yml'

jobs:

Compile:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- name: Compile
uses: fx31337/mql-compile-action@master
with:
init-platform: true
path: 'Indicators/Special/tests'
verbose: true
- name: Print compiled files
run: '(Get-ChildItem -Recurse -Path . -Include *.ex[45]).fullname'
shell: powershell
- name: Upload artifacts (MQL4)
uses: actions/upload-artifact@v2
with:
name: files-ex4
path: '**/*.ex4'
- name: Upload artifacts (MQL5)
uses: actions/upload-artifact@v2
with:
name: files-ex5
path: '**/*.ex5'

Indicators-Tests-MQL4:
defaults:
run:
shell: bash
working-directory: Indicators/tests
needs: Compile
runs-on: ubuntu-latest
strategy:
matrix:
test:
- Indi_Custom.test
steps:
- uses: actions/download-artifact@v2
with:
name: files-ex4
- name: Run ${{ matrix.test }}
uses: fx31337/mql-tester-action@master
with:
BtDays: 4-8
BtMonths: 1
BtYears: 2020
TestExpert: ${{ matrix.test }}
timeout-minutes: 10
118 changes: 118 additions & 0 deletions Indicators/Special/Indi_Custom.mqh
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
//+------------------------------------------------------------------+
//| Copyright 2016-2022, EA31337 Ltd |
//| https://github.com/EA31337 |
//+------------------------------------------------------------------+

/*
* This file is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

// Prevents processing the same indicator file twice.
#ifndef INDI_CUSTOM_MQH
#define INDI_CUSTOM_MQH

// Defines
#ifndef INDI_CUSTOM_PATH
#ifdef __MQL4__
#define INDI_CUSTOM_PATH "RSI"
#else
#define INDI_CUSTOM_PATH "Examples\\RSI"
#endif
#endif

// Includes.
#include "../../Indicator.mqh"

// Structs.

// Defines struct to store indicator parameter values.
struct IndiCustomParams : public IndicatorParams {
DataParamEntry iargs[];
// Struct constructors.
IndiCustomParams(string _filepath = INDI_CUSTOM_PATH, int _shift = 0) : IndicatorParams(INDI_CUSTOM, 1, TYPE_DOUBLE) {
custom_indi_name = _filepath;
SetDataSourceType(IDATA_ICUSTOM);
}
IndiCustomParams(IndiCustomParams &_params, ENUM_TIMEFRAMES _tf) {
THIS_REF = _params;
tf = _tf;
}
// Getters.
DataParamEntry GetParam(int _index) const { return iargs[_index - 1]; }
int GetParamsSize() const { return ArraySize(iargs); }
// Setters.
void AddParam(DataParamEntry &_entry) {
int _size = GetParamsSize();
ArrayResize(iargs, _size + 1);
iargs[_size] = _entry;
}
void SetParam(DataParamEntry &_entry, int _index) {
if (_index >= GetParamsSize()) {
ArrayResize(iargs, _index + 1);
}
iargs[_index + 1] = _entry;
}
void SetParams(DataParamEntry &_entries[]) {
for (int i = 0; i < ArraySize(_entries); i++) {
iargs[i] = _entries[i];
}
}
};

/**
* Implements indicator class.
*/
class Indi_Custom : public Indicator<IndiCustomParams> {
public:
/**
* Class constructor.
*/
Indi_Custom(IndiCustomParams &_p, IndicatorBase *_indi_src = NULL) : Indicator<IndiCustomParams>(_p, _indi_src) {}
Indi_Custom(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : Indicator(INDI_CUSTOM, _tf){};

/**
* Returns the indicator's value.
*/
IndicatorDataEntryValue GetEntryValue(int _mode = 0, int _shift = -1) {
double _value = EMPTY_VALUE;
int _ishift = _shift >= 0 ? _shift : iparams.GetShift();
switch (iparams.idstype) {
case IDATA_ICUSTOM:
switch (iparams.GetParamsSize()) {
case 0:
_value = iCustom(istate.handle, Get<string>(CHART_PARAM_SYMBOL), Get<ENUM_TIMEFRAMES>(CHART_PARAM_TF),
iparams.custom_indi_name, _mode, _ishift);
break;
case 1:
_value = iCustom(istate.handle, Get<string>(CHART_PARAM_SYMBOL), Get<ENUM_TIMEFRAMES>(CHART_PARAM_TF),
iparams.custom_indi_name, iparams.GetParam(1).ToValue<double>(), _mode, _ishift);
break;
case 2:
_value = iCustom(istate.handle, Get<string>(CHART_PARAM_SYMBOL), Get<ENUM_TIMEFRAMES>(CHART_PARAM_TF),
iparams.custom_indi_name, iparams.GetParam(1).ToValue<double>(),
iparams.GetParam(2).ToValue<double>(), _mode, _ishift);
break;
}
break;
default:
SetUserError(ERR_INVALID_PARAMETER);
_value = EMPTY_VALUE;
break;
}
return _value;
}
};

#endif // INDI_CUSTOM_MQH
1 change: 1 addition & 0 deletions Indicators/Special/indicators.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@
*/

// Special indicators.
#include "Indi_Custom.mqh"
#include "Indi_Math.mqh"
27 changes: 27 additions & 0 deletions Indicators/Special/tests/Indi_Custom.test.mq4
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//+------------------------------------------------------------------+
//| EA31337 framework |
//| Copyright 2016-2022, EA31337 Ltd |
//| https://github.com/EA31337 |
//+------------------------------------------------------------------+

/*
* This file is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/**
* @file
* Test functionality of Indi_Custom indicator class.
*/

#include "Indi_Custom.test.mq5"
65 changes: 65 additions & 0 deletions Indicators/Special/tests/Indi_Custom.test.mq5
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//+------------------------------------------------------------------+
//| EA31337 framework |
//| Copyright 2016-2022, EA31337 Ltd |
//| https://github.com/EA31337 |
//+------------------------------------------------------------------+

/*
* This file is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

// Includes.
#include "../../../Test.mqh"
#include "../Indi_Custom.mqh"

/**
* @file
* Test functionality of Indi_Custom indicator class.
*/

Indi_Custom indi(PERIOD_CURRENT);

/**
* Implements Init event handler.
*/
int OnInit() {
bool _result = true;
assertTrueOrFail(indi.IsValid(), "Error on IsValid!");
// assertTrueOrFail(indi.IsValidEntry(), "Error on IsValidEntry!");
// Overrides indicator params.
DataParamEntry _iparam_rsi_period = 12;
IndiCustomParams _iparams(INDI_CUSTOM_PATH);
_iparams.AddParam(_iparam_rsi_period);
indi.SetParams(_iparams);
return (_result && _LastError == ERR_NO_ERROR ? INIT_SUCCEEDED : INIT_FAILED);
}

/**
* Implements Tick event handler.
*/
void OnTick() {
static MqlTick _tick_last;
MqlTick _tick_new = SymbolInfoStatic::GetTick(_Symbol);
if (_tick_new.time % 60 < _tick_last.time % 60) {
// Process ticks each minute.
if (_tick_new.time % 3600 < _tick_last.time % 3600) {
// Print indicator values every hour.
Print(indi.ToString());
if (indi.Get<bool>(STRUCT_ENUM(IndicatorState, INDICATOR_STATE_PROP_IS_READY))) {
assertTrueOrExit(indi.GetEntry().IsValid(), "Invalid entry!");
}
}
}
_tick_last = _tick_new;
}

0 comments on commit a7f3334

Please sign in to comment.