Skip to content

Commit

Permalink
Initial Meta RSI strategy logic
Browse files Browse the repository at this point in the history
  • Loading branch information
kenorb committed Sep 27, 2023
1 parent 372b408 commit 0f93b24
Showing 1 changed file with 89 additions and 94 deletions.
183 changes: 89 additions & 94 deletions Stg_Meta_RSI.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@

// User input params.
INPUT2_GROUP("Meta RSI strategy: main params");
INPUT2 ENUM_STRATEGY Meta_RSI_Strategy = STRAT_STOCHASTIC; // Strategy to filter by rsi
INPUT2 ENUM_STRATEGY Meta_RSI_Strategy_RSI_Neutral = STRAT_BANDS; // Strategy for RSI at neutral range (40-60)
INPUT2 ENUM_STRATEGY Meta_RSI_Strategy_RSI_Peak = STRAT_FORCE; // Strategy for RSI at peak range (0-20,80-100)
INPUT2 ENUM_STRATEGY Meta_RSI_Strategy_RSI_Trend = STRAT_AC; // Strategy for RSI at trend range (20-40,60-80)
INPUT2_GROUP("Meta RSI strategy: common params");
INPUT2 float Meta_RSI_LotSize = 0; // Lot size
INPUT2 int Meta_RSI_SignalOpenMethod = 0; // Signal open method
Expand All @@ -29,8 +31,8 @@ INPUT2 float Meta_RSI_OrderCloseLoss = 200; // Order close loss
INPUT2 float Meta_RSI_OrderCloseProfit = 200; // Order close profit
INPUT2 int Meta_RSI_OrderCloseTime = 2880; // Order close time in mins (>0) or bars (<0)
INPUT_GROUP("Meta RSI strategy: RSI oscillator params");
INPUT int Meta_RSI_RSI_Period = 16; // Period
INPUT ENUM_APPLIED_PRICE Meta_RSI_RSI_Applied_Price = PRICE_WEIGHTED; // Applied Price
INPUT int Meta_RSI_RSI_Period = 14; // Period
INPUT ENUM_APPLIED_PRICE Meta_RSI_RSI_Applied_Price = PRICE_TYPICAL; // Applied Price
INPUT int Meta_RSI_RSI_Shift = 0; // Shift
INPUT ENUM_IDATA_SOURCE_TYPE Meta_RSI_RSI_SourceType = IDATA_BUILTIN; // Source type

Expand All @@ -52,7 +54,7 @@ struct Stg_Meta_RSI_Params_Defaults : StgParams {

class Stg_Meta_RSI : public Strategy {
protected:
Ref<Strategy> strat;
DictStruct<long, Ref<Strategy>> strats;

public:
Stg_Meta_RSI(StgParams &_sparams, TradeParams &_tparams, ChartParams &_cparams, string _name = "")
Expand All @@ -73,7 +75,9 @@ class Stg_Meta_RSI : public Strategy {
* Event on strategy's init.
*/
void OnInit() {
SetStrategy(Meta_RSI_Strategy);
StrategyAdd(Meta_RSI_Strategy_RSI_Neutral, 0);
StrategyAdd(Meta_RSI_Strategy_RSI_Peak, 1);
StrategyAdd(Meta_RSI_Strategy_RSI_Trend, 2);
// Initialize indicators.
{
IndiRSIParams _indi_params(::Meta_RSI_RSI_Period, ::Meta_RSI_RSI_Applied_Price, ::Meta_RSI_RSI_Shift);
Expand All @@ -86,7 +90,7 @@ class Stg_Meta_RSI : public Strategy {
/**
* Sets strategy.
*/
bool SetStrategy(ENUM_STRATEGY _sid) {
bool StrategyAdd(ENUM_STRATEGY _sid, long _index) {
bool _result = true;
long _magic_no = Get<long>(STRAT_PARAM_ID);
ENUM_TIMEFRAMES _tf = Get<ENUM_TIMEFRAMES>(STRAT_PARAM_TF);
Expand All @@ -95,166 +99,166 @@ class Stg_Meta_RSI : public Strategy {
case STRAT_NONE:
break;
case STRAT_AC:
_result &= StrategyAdd<Stg_AC>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_AC>(_tf, _magic_no, _sid, _index);
break;
case STRAT_AD:
_result &= StrategyAdd<Stg_AD>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_AD>(_tf, _magic_no, _sid, _index);
break;
case STRAT_ADX:
_result &= StrategyAdd<Stg_ADX>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_ADX>(_tf, _magic_no, _sid, _index);
break;
case STRAT_AMA:
_result &= StrategyAdd<Stg_AMA>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_AMA>(_tf, _magic_no, _sid, _index);
break;
case STRAT_ARROWS:
_result &= StrategyAdd<Stg_Arrows>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Arrows>(_tf, _magic_no, _sid, _index);
break;
case STRAT_ASI:
_result &= StrategyAdd<Stg_ASI>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_ASI>(_tf, _magic_no, _sid, _index);
break;
case STRAT_ATR:
_result &= StrategyAdd<Stg_ATR>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_ATR>(_tf, _magic_no, _sid, _index);
break;
case STRAT_ALLIGATOR:
_result &= StrategyAdd<Stg_Alligator>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Alligator>(_tf, _magic_no, _sid, _index);
break;
case STRAT_AWESOME:
_result &= StrategyAdd<Stg_Awesome>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Awesome>(_tf, _magic_no, _sid, _index);
break;
case STRAT_BWMFI:
_result &= StrategyAdd<Stg_BWMFI>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_BWMFI>(_tf, _magic_no, _sid, _index);
break;
case STRAT_BANDS:
_result &= StrategyAdd<Stg_Bands>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Bands>(_tf, _magic_no, _sid, _index);
break;
case STRAT_BEARS_POWER:
_result &= StrategyAdd<Stg_BearsPower>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_BearsPower>(_tf, _magic_no, _sid, _index);
break;
case STRAT_BULLS_POWER:
_result &= StrategyAdd<Stg_BullsPower>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_BullsPower>(_tf, _magic_no, _sid, _index);
break;
case STRAT_CCI:
_result &= StrategyAdd<Stg_CCI>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_CCI>(_tf, _magic_no, _sid, _index);
break;
case STRAT_CHAIKIN:
_result &= StrategyAdd<Stg_Chaikin>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Chaikin>(_tf, _magic_no, _sid, _index);
break;
case STRAT_DEMA:
_result &= StrategyAdd<Stg_DEMA>(_tf, _magic_no, _sid);
break;
case STRAT_DEMARKER:
_result &= StrategyAdd<Stg_DeMarker>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_DEMA>(_tf, _magic_no, _sid, _index);
break;
case STRAT_DPO:
_result &= StrategyAdd<Stg_DPO>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_DPO>(_tf, _magic_no, _sid, _index);
break;
case STRAT_DEMARKER:
_result &= StrategyAdd<Stg_DeMarker>(_tf, _magic_no, _sid, _index);
break;
case STRAT_ENVELOPES:
_result &= StrategyAdd<Stg_Envelopes>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Envelopes>(_tf, _magic_no, _sid, _index);
break;
case STRAT_FORCE:
_result &= StrategyAdd<Stg_Force>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Force>(_tf, _magic_no, _sid, _index);
break;
case STRAT_FRACTALS:
_result &= StrategyAdd<Stg_Fractals>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Fractals>(_tf, _magic_no, _sid, _index);
break;
case STRAT_GATOR:
_result &= StrategyAdd<Stg_Gator>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Gator>(_tf, _magic_no, _sid, _index);
break;
case STRAT_HEIKEN_ASHI:
_result &= StrategyAdd<Stg_HeikenAshi>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_HeikenAshi>(_tf, _magic_no, _sid, _index);
break;
case STRAT_ICHIMOKU:
_result &= StrategyAdd<Stg_Ichimoku>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Ichimoku>(_tf, _magic_no, _sid, _index);
break;
case STRAT_INDICATOR:
_result &= StrategyAdd<Stg_Indicator>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Indicator>(_tf, _magic_no, _sid, _index);
break;
case STRAT_MA:
_result &= StrategyAdd<Stg_MA>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_MA>(_tf, _magic_no, _sid, _index);
break;
case STRAT_MA_BREAKOUT:
_result &= StrategyAdd<Stg_MA_Breakout>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_MA_Breakout>(_tf, _magic_no, _sid, _index);
break;
case STRAT_MA_CROSS_PIVOT:
_result &= StrategyAdd<Stg_MA_Cross_Pivot>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_MA_Cross_Pivot>(_tf, _magic_no, _sid, _index);
break;
case STRAT_MA_CROSS_SHIFT:
_result &= StrategyAdd<Stg_MA_Cross_Shift>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_MA_Cross_Shift>(_tf, _magic_no, _sid, _index);
break;
case STRAT_MA_CROSS_SUP_RES:
_result &= StrategyAdd<Stg_MA_Cross_Sup_Res>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_MA_Cross_Sup_Res>(_tf, _magic_no, _sid, _index);
break;
case STRAT_MA_TREND:
_result &= StrategyAdd<Stg_MA_Trend>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_MA_Trend>(_tf, _magic_no, _sid, _index);
break;
case STRAT_MACD:
_result &= StrategyAdd<Stg_MACD>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_MACD>(_tf, _magic_no, _sid, _index);
break;
case STRAT_MFI:
_result &= StrategyAdd<Stg_MFI>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_MFI>(_tf, _magic_no, _sid, _index);
break;
case STRAT_MOMENTUM:
_result &= StrategyAdd<Stg_Momentum>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Momentum>(_tf, _magic_no, _sid, _index);
break;
case STRAT_OBV:
_result &= StrategyAdd<Stg_OBV>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_OBV>(_tf, _magic_no, _sid, _index);
break;
case STRAT_OSCILLATOR:
_result &= StrategyAdd<Stg_Oscillator>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Oscillator>(_tf, _magic_no, _sid, _index);
break;
case STRAT_OSCILLATOR_DIVERGENCE:
_result &= StrategyAdd<Stg_Oscillator_Divergence>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Oscillator_Divergence>(_tf, _magic_no, _sid, _index);
break;
case STRAT_OSCILLATOR_MULTI:
_result &= StrategyAdd<Stg_Oscillator_Multi>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Oscillator_Multi>(_tf, _magic_no, _sid, _index);
break;
case STRAT_OSCILLATOR_CROSS:
_result &= StrategyAdd<Stg_Oscillator_Cross>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Oscillator_Cross>(_tf, _magic_no, _sid, _index);
break;
case STRAT_OSCILLATOR_CROSS_SHIFT:
_result &= StrategyAdd<Stg_Oscillator_Cross_Shift>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Oscillator_Cross_Shift>(_tf, _magic_no, _sid, _index);
break;
case STRAT_OSCILLATOR_CROSS_ZERO:
_result &= StrategyAdd<Stg_Oscillator_Cross_Zero>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Oscillator_Cross_Zero>(_tf, _magic_no, _sid, _index);
break;
case STRAT_OSCILLATOR_RANGE:
_result &= StrategyAdd<Stg_Oscillator_Range>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Oscillator_Range>(_tf, _magic_no, _sid, _index);
break;
case STRAT_OSCILLATOR_TREND:
_result &= StrategyAdd<Stg_Oscillator_Trend>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Oscillator_Trend>(_tf, _magic_no, _sid, _index);
break;
case STRAT_OSMA:
_result &= StrategyAdd<Stg_OsMA>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_OsMA>(_tf, _magic_no, _sid, _index);
break;
case STRAT_PATTERN:
_result &= StrategyAdd<Stg_Pattern>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Pattern>(_tf, _magic_no, _sid, _index);
break;
case STRAT_PINBAR:
_result &= StrategyAdd<Stg_Pinbar>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Pinbar>(_tf, _magic_no, _sid, _index);
break;
case STRAT_PIVOT:
_result &= StrategyAdd<Stg_Pivot>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Pivot>(_tf, _magic_no, _sid, _index);
break;
case STRAT_RSI:
_result &= StrategyAdd<Stg_RSI>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_RSI>(_tf, _magic_no, _sid, _index);
break;
case STRAT_RVI:
_result &= StrategyAdd<Stg_RVI>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_RVI>(_tf, _magic_no, _sid, _index);
break;
case STRAT_SAR:
_result &= StrategyAdd<Stg_SAR>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_SAR>(_tf, _magic_no, _sid, _index);
break;
case STRAT_STDDEV:
_result &= StrategyAdd<Stg_StdDev>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_StdDev>(_tf, _magic_no, _sid, _index);
break;
case STRAT_STOCHASTIC:
_result &= StrategyAdd<Stg_Stochastic>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_Stochastic>(_tf, _magic_no, _sid, _index);
break;
case STRAT_WPR:
_result &= StrategyAdd<Stg_WPR>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_WPR>(_tf, _magic_no, _sid, _index);
break;
case STRAT_ZIGZAG:
_result &= StrategyAdd<Stg_ZigZag>(_tf, _magic_no, _sid);
_result &= StrategyAdd<Stg_ZigZag>(_tf, _magic_no, _sid, _index);
break;
default:
logger.Warning(StringFormat("Unknown strategy: %d", _sid), __FUNCTION_LINE__, GetName());
Expand All @@ -275,15 +279,15 @@ class Stg_Meta_RSI : public Strategy {
* Returns true if the strategy has been initialized correctly, otherwise false.
*/
template <typename SClass>
bool StrategyAdd(ENUM_TIMEFRAMES _tf, long _magic_no = 0, int _type = 0) {
bool StrategyAdd(ENUM_TIMEFRAMES _tf, long _magic_no = 0, int _type = 0, long _index = 0) {
bool _result = true;
_magic_no = _magic_no > 0 ? _magic_no : rand();
Ref<Strategy> _strat = ((SClass *)NULL).Init(_tf);
_strat.Ptr().Set<long>(STRAT_PARAM_ID, _magic_no);
_strat.Ptr().Set<ENUM_TIMEFRAMES>(STRAT_PARAM_TF, _tf);
_strat.Ptr().Set<int>(STRAT_PARAM_TYPE, _type);
_strat.Ptr().OnInit();
strat = _strat;
strats.Set(_index, _strat);
return _result;
}

Expand All @@ -292,46 +296,37 @@ class Stg_Meta_RSI : public Strategy {
*/
bool SignalOpen(ENUM_ORDER_TYPE _cmd, int _method, float _level = 0.0f, int _shift = 0) {
bool _result = true;
if (!strat.IsSet()) {
// Returns false when strategy is not set.
return false;
}
IndicatorBase *_indi = GetIndicator();
// uint _ishift = _indi.GetShift();
uint _ishift = _shift;
switch (_cmd) {
case ORDER_TYPE_BUY:
_result &= _indi[_shift][0] >= 50 - _level && _indi[_shift + 1][0] >= 50 - _level;
break;
case ORDER_TYPE_SELL:
_result &= _indi[_shift][0] <= 50 + _level && _indi[_shift + 1][0] <= 50 + _level;
break;
IndicatorBase *_indi = GetIndicator();
Ref<Strategy> _strat_ref;
if (_indi[_ishift][0] <= 20 || _indi[_ishift][0] >= 80) {
// RSI value is at peak range (0-20 or 80-100).
_strat_ref = strats.GetByKey(1);
} else if (_indi[_ishift][0] < 40 || _indi[_ishift][0] > 60) {
// RSI value is at trend range (20-40 or 60-80).
_strat_ref = strats.GetByKey(2);
} else if (_indi[_ishift][0] > 40 && _indi[_ishift][0] < 60) {
// RSI value is at neutral range (40-60).
_strat_ref = strats.GetByKey(0);
}
_level = _level == 0.0f ? strat.Ptr().Get<float>(STRAT_PARAM_SOL) : _level;
_method = _method == 0 ? strat.Ptr().Get<int>(STRAT_PARAM_SOM) : _method;
_shift = _shift == 0 ? strat.Ptr().Get<int>(STRAT_PARAM_SHIFT) : _shift;
_result &= strat.Ptr().SignalOpen(_cmd, _method, _level, _shift);
if (!_strat_ref.IsSet()) {
// Returns false when strategy is not set.
return false;
}
_level = _level == 0.0f ? _strat_ref.Ptr().Get<float>(STRAT_PARAM_SOL) : _level;
_method = _method == 0 ? _strat_ref.Ptr().Get<int>(STRAT_PARAM_SOM) : _method;
_shift = _shift == 0 ? _strat_ref.Ptr().Get<int>(STRAT_PARAM_SHIFT) : _shift;
_result &= _strat_ref.Ptr().SignalOpen(_cmd, _method, _level, _shift);
return _result;
}

/**
* Check strategy's closing signal.
*/
bool SignalClose(ENUM_ORDER_TYPE _cmd, int _method, float _level = 0.0f, int _shift = 0) {
bool _result = true;
if (!strat.IsSet()) {
// Returns false when strategy is not set.
return false;
}
IndicatorBase *_indi = GetIndicator();
switch (_cmd) {
case ORDER_TYPE_BUY:
_result &= _indi[_shift][0] <= 50 + _level && _indi[_shift + 1][0] <= 50 + _level;
break;
case ORDER_TYPE_SELL:
_result &= _indi[_shift][0] >= 50 - _level && _indi[_shift + 1][0] >= 50 - _level;
break;
}
bool _result = false;
_result = SignalOpen(Order::NegateOrderType(_cmd), _method, _level, _shift);
return _result;
}
};
Expand Down

0 comments on commit 0f93b24

Please sign in to comment.