Skip to content

Commit

Permalink
Strategy: Adds StrategyPriceStop struct logic
Browse files Browse the repository at this point in the history
  • Loading branch information
kenorb committed Jun 20, 2021
1 parent 0a9131f commit e535306
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 2 deletions.
28 changes: 26 additions & 2 deletions Strategy.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -1162,8 +1162,32 @@ class Strategy : public Object {
* Returns current stop loss value when _mode is ORDER_TYPE_SL
* and profit take when _mode is ORDER_TYPE_TP.
*/
virtual float PriceStop(ENUM_ORDER_TYPE _cmd, ENUM_ORDER_TYPE_VALUE _mode, int _method = 0,
float _level = 0.0f) = NULL;
virtual float PriceStop(ENUM_ORDER_TYPE _cmd, ENUM_ORDER_TYPE_VALUE _mode, int _method = 0, float _level = 0.0f) {
double _result = 0;
float _trade_dist = trade.GetTradeDistanceInValue();
int _count = (int)fmax(fabs(_level), fabs(_method));
int _direction = Order::OrderDirection(_cmd, _mode);
Chart *_chart = trade.GetChart();
Indicator *_indi = GetIndicator();
StrategyPriceStop _psm(_method);
_psm.SetChartParams(_chart.GetParams());
if (Object::IsValid(_indi)) {
int _ishift = _direction > 0 ? _indi.GetHighest<double>(_count) : _indi.GetLowest<double>(_count);
_psm.SetIndicatorPriceValue(_indi.GetValuePrice<float>(_ishift, 0, PRICE_CLOSE));
/*
//IndicatorDataEntry _data[];
if (_indi.CopyEntries(_data, 3, 0)) {
_psm.SetIndicatorDataEntry(_data);
_psm.SetIndicatorParams(_indi.GetParams());
}
*/
_result = _psm.GetValue(_ishift, _direction, _trade_dist);
} else {
int _pshift = _direction > 0 ? _chart.GetHighest(_count) : _chart.GetLowest(_count);
_result = _psm.GetValue(_pshift, _direction, _trade_dist);
}
return (float)_result;
}

/**
* Gets trend strength value.
Expand Down
3 changes: 3 additions & 0 deletions Strategy.struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
// Includes.
#include "Serializer.mqh"
#include "Strategy.enum.h"
#include "Strategy.struct.pricestop.h"
#include "Task.struct.h"

// Forward class declaration.
Expand Down Expand Up @@ -129,6 +130,7 @@ struct StgParams {
}
// Deconstructor.
~StgParams() {}

// Getters.
template <typename T>
T Get(ENUM_STRATEGY_PARAM _param) {
Expand Down Expand Up @@ -171,6 +173,7 @@ struct StgParams {
SetUserError(ERR_INVALID_PARAMETER);
return WRONG_VALUE;
}
bool HasIndicator(int _id = 0) { return GetIndicator(_id) != NULL; }
bool IsBoosted() { return is_boosted; }
bool IsEnabled() { return is_enabled; }
bool IsSuspended() { return is_suspended; }
Expand Down
147 changes: 147 additions & 0 deletions Strategy.struct.pricestop.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
//+------------------------------------------------------------------+
//| EA31337 framework |
//| Copyright 2016-2021, 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
* Includes Indicator's signal structs.
*/

#ifndef __MQL__
// Allows the preprocessor to include a header file when it is needed.
#pragma once
#endif

// Forward declaration.
struct ChartParams;
struct IndicatorDataEntry;
struct IndicatorParams;

// Includes.
#include "Chart.struct.h"

/* Structure for strategy price stops. */
struct StrategyPriceStop {
/* Define enumeration for strategy price stops. */
enum ENUM_STRATEGY_PRICE_STOP {
STRATEGY_PRICE_STOP_NONE = 0 << 0, // (None)
STRATEGY_PRICE_STOP_INDI_PEAK = 1 << 0, // Indicator value peak.
STRATEGY_PRICE_STOP_INDI_PRICE = 1 << 1, // Indicator value.
STRATEGY_PRICE_STOP_PRICE = 1 << 2, // Price value.
STRATEGY_PRICE_STOP_PRICE_PEAK = 1 << 3, // Price value peak.
STRATEGY_PRICE_STOP_PRICE_PP = 1 << 4, // Price value of Pivot res/sup.
STRATEGY_PRICE_STOP_VALUE_ADD_PRICE_DIFF = 1 << 5, // Add price difference.
STRATEGY_PRICE_STOP_VALUE_ADD_RANGE = 1 << 6, // Add candle range to the trail value.
// STRATEGY_PRICE_STOP_INDI_CHG_PCT = 1 << 0, // Indicator value change (%).
};

float ivalue; // Indicator price value.
unsigned int method; // Store price stop methods (@see: ENUM_STRATEGY_PRICE_STOP).
// unsigned int mode[2]; // Indicator modes to use.
ChartParams cparams;
// IndicatorDataEntry idata[];
// IndicatorParams iparams;

/* Constructors */
void StrategyPriceStop(int _method = 0, float _ivalue = 0) : method(_method), ivalue(_ivalue) {}
// Main methods.
// Calculate price stop value.
float GetValue(int _shift = 0, int _direction = -1, float _min_trade_dist = 0.0f) {
float _result = ivalue, _trail = _min_trade_dist;
BarOHLC _ohlc0 = Chart::GetOHLC(cparams.tf.GetTf(), 0, cparams.symbol);
BarOHLC _ohlc1 = Chart::GetOHLC(cparams.tf.GetTf(), _shift, cparams.symbol);
if (CheckMethod(STRATEGY_PRICE_STOP_INDI_PRICE)) {
_result = ivalue;
}
if (CheckMethod(STRATEGY_PRICE_STOP_PRICE)) {
// Use price as a base line for the stop value.
float _price;
ENUM_APPLIED_PRICE _ap = PRICE_WEIGHTED;
if (CheckMethod(STRATEGY_PRICE_STOP_PRICE_PEAK)) {
// On peak, use low or high prices instead.
_ap = _direction > 0 ? PRICE_HIGH : PRICE_LOW;
}
_price = (float)ChartStatic::iPrice(_ap, cparams.symbol, cparams.tf.GetTf(), _shift);
_result = _direction > 0 ? fmax(_price, _result) : fmin(_price, _result);
}
if (CheckMethod(STRATEGY_PRICE_STOP_PRICE_PP)) {
float _pp, _r1, _r2, _r3, _r4, _s1, _s2, _s3, _s4;
float _prices[4];
_prices[0] = _ohlc0.GetClose();
_prices[1] = _direction > 0 ? _ohlc0.GetHigh() : _ohlc0.GetLow();
_prices[2] = _direction > 0 ? _ohlc1.GetHigh() : _ohlc1.GetLow();
_prices[3] = _ohlc1.GetOpen();
BarOHLC _ohlc_pp(_prices, _ohlc0.GetTime());
_ohlc_pp.GetPivots(PP_CLASSIC, _pp, _r1, _r2, _r3, _r4, _s1, _s2, _s3, _s4);
_result = _direction > 0 ? fmax(_r1, _result) : fmin(_s1, _result);
}
if (CheckMethod(STRATEGY_PRICE_STOP_VALUE_ADD_PRICE_DIFF)) {
_trail += fabs(_ohlc0.GetPivot() - _ohlc1.GetPivot());
}
if (CheckMethod(STRATEGY_PRICE_STOP_VALUE_ADD_RANGE)) {
_trail += _ohlc1.GetRange();
}
_result = _result > 0 ? (_direction > 0 ? _result + _trail : _result - _trail) : 0;
return _result;
}
/* Setters */
void SetChartParams(ChartParams &_cparams) { cparams = _cparams; }
void SetIndicatorPriceValue(float _ivalue) { ivalue = _ivalue; }
/*
void SetIndicatorDataEntry(IndicatorDataEntry &_data[]) {
int _asize = ArraySize(idata);
for (int i = 0; i < _asize; i++) {
idata[i] = _data[i];
}
}
void SetIndicatorParams(IndicatorParams &_iparams, int _m1 = 0, int _m2 = 0) {
iparams = _iparams;
mode[0] = _m1;
mode[1] = _m2;
}
*/
/* Flag getters */
bool CheckMethod(unsigned int _flags) { return (method & _flags) != 0; }
bool CheckMethodsXor(unsigned int _flags) { return (method ^ _flags) != 0; }
bool CheckMethodAll(unsigned int _flags) { return (method & _flags) == _flags; }
bool CheckMethodXorAll(unsigned int _flags) { return (method ^ _flags) == _flags; }
unsigned int GetMethod() { return method; }
/* Flag setters */
void AddMethod(unsigned int _flags) { method |= _flags; }
void RemoveMethod(unsigned int _flags) { method &= ~_flags; }
void SetMethod(ENUM_STRATEGY_PRICE_STOP _flag, bool _value = true) {
if (_value) {
AddMethod(_flag);
} else {
RemoveMethod(_flag);
}
}
void SetMethod(unsigned int _flags) { method = _flags; }
/* Serializers */
SerializerNodeType Serialize(Serializer &_s) {
int _size = sizeof(int) * 8;
for (int i = 0; i < _size; i++) {
int _value = CheckMethod(1 << i) ? 1 : 0;
_s.Pass(this, (string)(i + 1), _value, SERIALIZER_FIELD_FLAG_DYNAMIC | SERIALIZER_FIELD_FLAG_FEATURE);
}
return SerializerNodeObject;
}
};

0 comments on commit e535306

Please sign in to comment.