backup all works even x121 ...
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,504 @@
|
||||
///////////////////////////////////////////////////////
|
||||
// SaherElm IT Center MQL5 Indicator
|
||||
// -------------------------------------------
|
||||
// Name: XMGTD
|
||||
// Description: Mega Trend ...
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XMGTD Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
#define ShortName "XMGTD"
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
// Inputs ...
|
||||
|
||||
//
|
||||
input group "Market";
|
||||
input int length = 14; // Length
|
||||
input double coeff = 2.0; // Coefficient
|
||||
input double multiplier = 3.0; // Multiplier
|
||||
input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To
|
||||
|
||||
//
|
||||
input group "Presentation";
|
||||
input bool show = true; // Show
|
||||
input bool showSTR = false; // Show STR
|
||||
input bool showHTD = false; // Show HTR
|
||||
input bool showATSL = false; // Show ATSL
|
||||
|
||||
//
|
||||
// Buffers ...
|
||||
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 13
|
||||
#property indicator_plots 6
|
||||
|
||||
//
|
||||
#define mainBufferIndex 0
|
||||
double mainBuffer[];
|
||||
|
||||
//
|
||||
#define mainBufferColorIndex 1
|
||||
double mainBufferColor[];
|
||||
|
||||
//
|
||||
#define hideColorIDX 0
|
||||
#define bullColorIDX 1
|
||||
#define bearColorIDX 2
|
||||
|
||||
//
|
||||
#property indicator_label1 "XMGTD"
|
||||
#property indicator_type1 DRAW_COLOR_LINE
|
||||
#property indicator_color1 CLR_NONE, clrGreen, clrDarkRed
|
||||
#property indicator_style1 STYLE_DOT
|
||||
#property indicator_width1 1
|
||||
|
||||
//
|
||||
#define atslBufferIndex 2
|
||||
#define atslBufferPlotIndex 1
|
||||
double atslBuffer[];
|
||||
|
||||
//
|
||||
#define atslBufferColorIndex 3
|
||||
double atslBufferColor[];
|
||||
|
||||
//
|
||||
#property indicator_label2 "XATSL"
|
||||
#property indicator_type2 DRAW_COLOR_LINE
|
||||
#property indicator_color2 CLR_NONE, clrGreen, clrDarkRed
|
||||
#property indicator_style2 STYLE_DOT
|
||||
#property indicator_width2 1
|
||||
|
||||
//
|
||||
#define htdBufferIndex 4
|
||||
#define htdBufferPlotIndex 2
|
||||
double htdBuffer[];
|
||||
|
||||
//
|
||||
#define htdBufferColorIndex 5
|
||||
double htdBufferColor[];
|
||||
|
||||
//
|
||||
#property indicator_label3 "XHTD"
|
||||
#property indicator_type3 DRAW_COLOR_LINE
|
||||
#property indicator_color3 CLR_NONE, clrGreen, clrDarkRed
|
||||
#property indicator_style3 STYLE_DOT
|
||||
#property indicator_width3 1
|
||||
|
||||
//
|
||||
#define hlBufferIndex 6
|
||||
double hlBuffer[];
|
||||
|
||||
//
|
||||
#define wmaBufferIndex 7
|
||||
double wmaBuffer[];
|
||||
|
||||
//
|
||||
#define tmpBufferIndex 8
|
||||
double tmpBuffer[];
|
||||
|
||||
//
|
||||
#define diffBufferIndex 9
|
||||
double diffBuffer[];
|
||||
|
||||
//
|
||||
#define upBufferIndex 10
|
||||
double upBuffer[];
|
||||
|
||||
//
|
||||
#define downBufferIndex 11
|
||||
double downBuffer[];
|
||||
|
||||
//
|
||||
#define directionBufferIndex 12
|
||||
double directionBuffer[];
|
||||
|
||||
//
|
||||
// Variables ...
|
||||
|
||||
//
|
||||
int maPeriod;
|
||||
double kpi;
|
||||
|
||||
//
|
||||
// Event Handlers ...
|
||||
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
maPeriod = int(length < 1 ? 1 : length);
|
||||
double n1 = 2.0 * double(maPeriod - 1);
|
||||
kpi = 2.0 / (n1 + 1);
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
}
|
||||
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
const int rates_total, // Total Bars on Chart ...
|
||||
const int prev_calculated, // Total Calculated Bars on Charts ...
|
||||
const datetime &time[], // History of Open Time ...
|
||||
const double &open[], // History of Open Price ...
|
||||
const double &high[], // History of High Price ...
|
||||
const double &low[], // History of Low Price ...
|
||||
const double &close[], // History of Close Price ...
|
||||
const long &tick_volume[], // History of Tick Volumes on Bar ...
|
||||
const long &volume[], // History of Trade Volumes ...
|
||||
const int &spread[] // History of Spread Price ...
|
||||
)
|
||||
{
|
||||
//
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
|
||||
//
|
||||
if (rates_total < maPeriod)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
int limit = rates_total - prev_calculated;
|
||||
if (limit > 1)
|
||||
{
|
||||
//
|
||||
limit = rates_total - 2;
|
||||
|
||||
//
|
||||
ArrayInitialize(atslBuffer, EMPTY_VALUE);
|
||||
ArrayInitialize(hlBuffer, 0);
|
||||
ArrayInitialize(diffBuffer, 0);
|
||||
ArrayInitialize(wmaBuffer, 0);
|
||||
ArrayInitialize(tmpBuffer, 0);
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = limit; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
hlBuffer[i] = high[i] - low[i];
|
||||
|
||||
//
|
||||
double href = 0;
|
||||
double lref = 0;
|
||||
|
||||
//
|
||||
double sma = MAOnArray(hlBuffer, 0, maPeriod, 0, MODE_SMA, i);
|
||||
double hiLo = fmin(hlBuffer[i], sma);
|
||||
|
||||
//
|
||||
href = (low[i] <= high[i + 1] ? high[i] - close[i + 1] : (hlBuffer[i] - close[i + 1] + high[i + 1]) / 2);
|
||||
lref = (high[i] >= low[i + 1] ? close[i + 1] - low[i] : (close[i + 1] - low[i + 1] + hlBuffer[i]) / 2);
|
||||
|
||||
//
|
||||
diffBuffer[i] = fmax(hiLo, fmax(href, lref));
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = limit; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
if (i == rates_total - 2)
|
||||
{
|
||||
wmaBuffer[i] = MAOnArray(diffBuffer, 0, maPeriod, 0, MODE_EMA, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
wmaBuffer[i] = (diffBuffer[i] - wmaBuffer[i + 1]) * kpi + wmaBuffer[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = limit; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
double loss = wmaBuffer[i] * coeff;
|
||||
if (close[i] > tmpBuffer[i + 1] && close[i + 1] > tmpBuffer[i + 1])
|
||||
{
|
||||
//
|
||||
tmpBuffer[i] = fmax(tmpBuffer[i + 1], close[i] - loss);
|
||||
|
||||
//
|
||||
atslBuffer[i] = tmpBuffer[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
if (close[i] < tmpBuffer[i + 1] && close[i + 1] < tmpBuffer[i + 1])
|
||||
{
|
||||
//
|
||||
tmpBuffer[i] = fmin(tmpBuffer[i + 1], close[i] + loss);
|
||||
|
||||
//
|
||||
atslBuffer[i] = tmpBuffer[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
if (close[i] > tmpBuffer[i + 1])
|
||||
{
|
||||
//
|
||||
tmpBuffer[i] = close[i] - loss;
|
||||
|
||||
//
|
||||
atslBuffer[i] = tmpBuffer[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
tmpBuffer[i] = close[i] + loss;
|
||||
|
||||
//
|
||||
atslBuffer[i] = tmpBuffer[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Define Color Buffer ...
|
||||
double clrValue = !showATSL
|
||||
? hideColorIDX
|
||||
: atslBuffer[i] > close[i]
|
||||
? bearColorIDX
|
||||
: bullColorIDX;
|
||||
atslBufferColor[i] = clrValue;
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
|
||||
//
|
||||
// Custom Functions ...
|
||||
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = length >= 2 &&
|
||||
coeff > 0;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
|
||||
//
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
// Main ...
|
||||
ENUM_DRAW_TYPE mainDrawType = show ? DRAW_COLOR_LINE : DRAW_NONE;
|
||||
|
||||
//
|
||||
ArraySetAsSeries(mainBuffer, true);
|
||||
ArraySetAsSeries(mainBufferColor, true);
|
||||
PlotIndexSetInteger(mainBufferIndex, PLOT_SHOW_DATA, show);
|
||||
SetIndexBuffer(mainBufferIndex, mainBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(mainBufferIndex, PLOT_DRAW_TYPE, mainDrawType);
|
||||
SetIndexBuffer(mainBufferColorIndex, mainBufferColor, INDICATOR_COLOR_INDEX);
|
||||
|
||||
//
|
||||
// XATSL ...
|
||||
ENUM_DRAW_TYPE atslDrawType = showATSL ? DRAW_COLOR_LINE : DRAW_NONE;
|
||||
|
||||
//
|
||||
ArraySetAsSeries(atslBuffer, true);
|
||||
ArraySetAsSeries(atslBufferColor, true);
|
||||
SetIndexBuffer(atslBufferIndex, atslBuffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(atslBufferColorIndex, atslBufferColor, INDICATOR_COLOR_INDEX);
|
||||
PlotIndexSetInteger(atslBufferPlotIndex, PLOT_SHOW_DATA, showATSL);
|
||||
PlotIndexSetInteger(atslBufferPlotIndex, PLOT_DRAW_TYPE, atslDrawType);
|
||||
|
||||
//
|
||||
// XHTD ...
|
||||
ENUM_DRAW_TYPE htdDrawType = showHTD ? DRAW_COLOR_LINE : DRAW_NONE;
|
||||
|
||||
//
|
||||
SetIndexBuffer(htdBufferIndex, htdBuffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(htdBufferColorIndex, htdBufferColor, INDICATOR_COLOR_INDEX);
|
||||
PlotIndexSetInteger(htdBufferPlotIndex, PLOT_SHOW_DATA, showHTD);
|
||||
PlotIndexSetInteger(htdBufferPlotIndex, PLOT_DRAW_TYPE, htdDrawType);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(hlBuffer, true);
|
||||
SetIndexBuffer(hlBufferIndex, hlBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(wmaBuffer, true);
|
||||
SetIndexBuffer(wmaBufferIndex, wmaBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(tmpBuffer, true);
|
||||
SetIndexBuffer(tmpBufferIndex, tmpBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(diffBuffer, true);
|
||||
SetIndexBuffer(diffBufferIndex, diffBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
SetIndexBuffer(upBufferIndex, upBuffer, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(downBufferIndex, downBuffer, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(directionBufferIndex, directionBuffer, INDICATOR_CALCULATIONS);
|
||||
}
|
||||
|
||||
//
|
||||
// Hull Handler ...
|
||||
double workHull[][2];
|
||||
double iHull(
|
||||
double price,
|
||||
double period,
|
||||
int r,
|
||||
int bars,
|
||||
int instanceNo = 0 //
|
||||
)
|
||||
{
|
||||
//
|
||||
if (ArrayRange(workHull, 0) != bars)
|
||||
{
|
||||
ArrayResize(workHull, bars);
|
||||
}
|
||||
|
||||
//
|
||||
int HmaPeriod = (int)MathMax(period, 2);
|
||||
int HalfPeriod = (int)MathFloor(HmaPeriod / 2);
|
||||
int HullPeriod = (int)MathFloor(MathSqrt(HmaPeriod));
|
||||
double hma, hmw, weight;
|
||||
instanceNo *= 2;
|
||||
|
||||
//
|
||||
workHull[r][instanceNo] = price;
|
||||
|
||||
//
|
||||
hmw = HalfPeriod;
|
||||
hma = hmw * price;
|
||||
for (int k = 1; k < HalfPeriod && (r - k) >= 0; k++)
|
||||
{
|
||||
//
|
||||
weight = HalfPeriod - k;
|
||||
hmw += weight;
|
||||
hma += weight * workHull[r - k][instanceNo];
|
||||
}
|
||||
workHull[r][instanceNo + 1] = 2.0 * hma / hmw;
|
||||
|
||||
//
|
||||
hmw = HmaPeriod;
|
||||
hma = hmw * price;
|
||||
for (int k = 1; k < period && (r - k) >= 0; k++)
|
||||
{
|
||||
//
|
||||
weight = HmaPeriod - k;
|
||||
hmw += weight;
|
||||
hma += weight * workHull[r - k][instanceNo];
|
||||
}
|
||||
workHull[r][instanceNo + 1] -= hma / hmw;
|
||||
|
||||
//
|
||||
hmw = HullPeriod;
|
||||
hma = hmw * workHull[r][instanceNo + 1];
|
||||
for (int k = 1; k < HullPeriod && (r - k) >= 0; k++)
|
||||
{
|
||||
//
|
||||
weight = HullPeriod - k;
|
||||
hmw += weight;
|
||||
hma += weight * workHull[r - k][1 + instanceNo];
|
||||
}
|
||||
|
||||
//
|
||||
return (hma / hmw);
|
||||
}
|
||||
|
||||
//
|
||||
double getPrice(ENUM_APPLIED_PRICE price, const double &open[], const double &close[], const double &high[], const double &low[], int i, int bars)
|
||||
{
|
||||
switch (price)
|
||||
{
|
||||
case PRICE_CLOSE:
|
||||
return (close[i]);
|
||||
case PRICE_OPEN:
|
||||
return (open[i]);
|
||||
case PRICE_HIGH:
|
||||
return (high[i]);
|
||||
case PRICE_LOW:
|
||||
return (low[i]);
|
||||
case PRICE_MEDIAN:
|
||||
return ((high[i] + low[i]) / 2.0);
|
||||
case PRICE_TYPICAL:
|
||||
return ((high[i] + low[i] + close[i]) / 3.0);
|
||||
case PRICE_WEIGHTED:
|
||||
return ((high[i] + low[i] + close[i] + close[i]) / 4.0);
|
||||
// case PRICE_AVERAGE: return((high[i]+low[i]+close[i]+open[i])/4.0);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
//
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,444 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Class Library
|
||||
// --------------------------------------
|
||||
// Name: XSCXEMRNGStrategy
|
||||
// Description: provides all based classes for use ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
/// Imports ...
|
||||
#include "../Helpers/x-saherelm.xtm.helper.mq5"
|
||||
#include "../Helpers/x-saherelm.xstr.helper.mq5"
|
||||
#include "../Classes/x-saherelm.xstrategy.class.mq5"
|
||||
|
||||
//
|
||||
string XEMRNGStartegyToken = "XEMRNG";
|
||||
|
||||
//
|
||||
class XSCXEMRNGStrategy : public XSCBaseStrategy
|
||||
{
|
||||
//
|
||||
// Public ...
|
||||
public:
|
||||
//
|
||||
// Constructor(s) ...
|
||||
void XSCXEMRNGStrategy(
|
||||
//
|
||||
// Base ...
|
||||
string _symbol, // Trading Symbol
|
||||
ENUM_TIMEFRAMES _period, // Trading TimeFrame
|
||||
double _volume, // Voluem
|
||||
double _r2r, // Risk/Reward Ratio
|
||||
int _slippage, // Trader Slippage
|
||||
long _magicNumber, // Trader Magic Number
|
||||
bool _useTPSLAsPoint = false, // Converts TP and SL by Provided Points
|
||||
bool _forceMaxTPSLAsPoint = false, // Force Max TP and SL by Provided Points
|
||||
double _tpPoint = 0, // TP As Point
|
||||
double _slPoint = 0, // SL As Point
|
||||
bool _allowLong = true,
|
||||
bool _allowShort = true,
|
||||
int _maxAllowedLongs = 0,
|
||||
int _maxAllowedShorts = 0 //
|
||||
) : XSCBaseStrategy(_symbol,
|
||||
_period,
|
||||
_volume,
|
||||
_r2r,
|
||||
_slippage,
|
||||
_magicNumber,
|
||||
_useTPSLAsPoint,
|
||||
_forceMaxTPSLAsPoint,
|
||||
_tpPoint,
|
||||
_slPoint,
|
||||
_allowLong,
|
||||
_allowShort,
|
||||
_maxAllowedLongs,
|
||||
_maxAllowedShorts //
|
||||
)
|
||||
{
|
||||
//
|
||||
ConfigureRequirements();
|
||||
|
||||
//
|
||||
SetAlertPrefix(GetTag());
|
||||
}
|
||||
|
||||
//
|
||||
// Deconstructor ...
|
||||
void ~XSCXEMRNGStrategy()
|
||||
{
|
||||
delete mTMHelper;
|
||||
delete mSTRHelper;
|
||||
}
|
||||
|
||||
//
|
||||
// Getter / Setter (s) ...
|
||||
|
||||
//
|
||||
// Overrides ...
|
||||
|
||||
//
|
||||
// Customize Strategy Identifier ...
|
||||
string GetTag() override
|
||||
{
|
||||
return XEMRNGStartegyToken;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Conditions For Signal ...
|
||||
bool HasSignal(
|
||||
XSignal &signal //
|
||||
) override
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
signal.Clean();
|
||||
|
||||
//
|
||||
double sl = 0;
|
||||
double tp = 0;
|
||||
double risk = 0;
|
||||
double entry = 0;
|
||||
double reward = 0;
|
||||
double r2r = R2R();
|
||||
ENUM_POSITION_TYPE type = POSITION_TYPE_BUY;
|
||||
ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET;
|
||||
|
||||
//
|
||||
int start = 0;
|
||||
int count = 5;
|
||||
|
||||
//
|
||||
double tms[];
|
||||
ArraySetAsSeries(tms, true);
|
||||
mTMHelper.CopyMain(
|
||||
start,
|
||||
count,
|
||||
tms //
|
||||
);
|
||||
|
||||
//
|
||||
XSTRConditions strConditions;
|
||||
result = mSTRHelper.GetConditions(
|
||||
strConditions,
|
||||
start,
|
||||
count //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
XOHCL cBar;
|
||||
result = cBar.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
1 //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double hh5 = cBar.FindHighest(
|
||||
5,
|
||||
MODE_HIGH //
|
||||
);
|
||||
double ll5 = cBar.FindLowest(
|
||||
5,
|
||||
MODE_LOW //
|
||||
);
|
||||
|
||||
//
|
||||
XOHCL pBar;
|
||||
result = cBar.GetPreviousBar(pBar);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool hasLong = false;
|
||||
bool hasShort = false;
|
||||
|
||||
//
|
||||
XOHCL tmpHSW[];
|
||||
XOHCL tmpLSW[];
|
||||
|
||||
//
|
||||
bool useHammer = true;
|
||||
bool useMorningStar = false;
|
||||
bool useBullishEngulfing = true;
|
||||
bool useBullishMaurubozu = true;
|
||||
|
||||
//
|
||||
bool useShootingStar = true;
|
||||
bool useEveningStar = false;
|
||||
bool useBearishEngulfing = true;
|
||||
bool useBearishMaurubozu = true;
|
||||
|
||||
//
|
||||
// Long ...
|
||||
|
||||
//
|
||||
bool isHammer = !useHammer
|
||||
? false
|
||||
: cBar.IsHammer();
|
||||
bool isMorningStar = !useMorningStar
|
||||
? false
|
||||
: cBar.IsMorningStar();
|
||||
bool isBullishMarubozu = !useBullishEngulfing
|
||||
? false
|
||||
: cBar.IsBullishMarubozu();
|
||||
bool isBullishEngulfing = !useBullishMaurubozu
|
||||
? false
|
||||
: cBar.IsBullishEngulfing();
|
||||
|
||||
//
|
||||
bool isBullishTrend = cBar.HasBullishTrend(
|
||||
tmpHSW,
|
||||
tmpLSW,
|
||||
true //
|
||||
);
|
||||
|
||||
//
|
||||
// Find Swing Low Above of EMA ...
|
||||
// Find Swing High Above of EMA ...
|
||||
// Fins Swing Low Below of EMA ...
|
||||
// Detect Bullish Pattern ...
|
||||
hasLong =
|
||||
//
|
||||
cBar.IsBullish()
|
||||
//
|
||||
&&
|
||||
//
|
||||
isBullishTrend
|
||||
//
|
||||
&&
|
||||
//
|
||||
cBar.close > tms[1]
|
||||
//
|
||||
&&
|
||||
//
|
||||
ll5 < tms[1]
|
||||
//
|
||||
&&
|
||||
//
|
||||
strConditions.isTrendSwitchedToBullish
|
||||
//
|
||||
&&
|
||||
//
|
||||
(
|
||||
//
|
||||
isHammer
|
||||
//
|
||||
||
|
||||
//
|
||||
isMorningStar
|
||||
//
|
||||
||
|
||||
//
|
||||
isBullishMarubozu
|
||||
//
|
||||
||
|
||||
//
|
||||
isBullishEngulfing
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
if (hasLong)
|
||||
{
|
||||
//
|
||||
type = POSITION_TYPE_BUY;
|
||||
|
||||
//
|
||||
sl = tmpLSW[ArraySize(tmpLSW) - 1].low;
|
||||
}
|
||||
|
||||
//
|
||||
// Short ...
|
||||
bool isShootingStar = !useShootingStar
|
||||
? false
|
||||
: cBar.IsShootingStar();
|
||||
bool isEveningStar = !useEveningStar
|
||||
? false
|
||||
: cBar.IsEveningStar();
|
||||
bool isBearishEngulfing = !useBearishEngulfing
|
||||
? false
|
||||
: cBar.IsBearishEngulfing();
|
||||
bool isBearishMaurubozu = !useBearishMaurubozu
|
||||
? false
|
||||
: cBar.IsBearishMarubozu();
|
||||
|
||||
//
|
||||
bool isBearishTrend = cBar.HasBearishTrend(
|
||||
tmpHSW,
|
||||
tmpLSW,
|
||||
true //
|
||||
);
|
||||
|
||||
//
|
||||
hasShort =
|
||||
//
|
||||
cBar.IsBearish()
|
||||
//
|
||||
&&
|
||||
//
|
||||
isBearishTrend
|
||||
//
|
||||
&&
|
||||
//
|
||||
cBar.close < tms[1]
|
||||
//
|
||||
&&
|
||||
//
|
||||
hh5 > tms[1]
|
||||
//
|
||||
&&
|
||||
//
|
||||
strConditions.isTrendSwitchedToBearish
|
||||
//
|
||||
&&
|
||||
//
|
||||
(
|
||||
//
|
||||
isShootingStar
|
||||
//
|
||||
||
|
||||
//
|
||||
isEveningStar
|
||||
//
|
||||
||
|
||||
//
|
||||
isBearishEngulfing
|
||||
//
|
||||
||
|
||||
//
|
||||
isBearishMaurubozu
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
if (hasShort)
|
||||
{
|
||||
//
|
||||
type = POSITION_TYPE_SELL;
|
||||
|
||||
//
|
||||
sl = tmpHSW[ArraySize(tmpHSW) - 1].high;
|
||||
}
|
||||
|
||||
//
|
||||
result = hasLong || hasShort;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
entry = GetEntry(mSymbol, type);
|
||||
CalculateTPSLByPrice(
|
||||
sl,
|
||||
tp,
|
||||
type,
|
||||
entry,
|
||||
r2r //
|
||||
);
|
||||
|
||||
//
|
||||
result = signal.Prepare(
|
||||
mSymbol,
|
||||
GetTag(),
|
||||
mPeriod,
|
||||
type,
|
||||
mode,
|
||||
entry,
|
||||
mVolume,
|
||||
sl,
|
||||
tp //
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Protected ...
|
||||
protected:
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
XTMInputs mTMInputs; // Tren Magic Inputs ...
|
||||
XSCXTMHelper *mTMHelper; // Trend Magic Helper Class ...
|
||||
|
||||
//
|
||||
XSTRInputs mSTRInputs; // Super Trend Inputs ...
|
||||
XSCXSTRHelper *mSTRHelper; // Super Trend Helper Class ...
|
||||
|
||||
//
|
||||
// Private ...
|
||||
private:
|
||||
//
|
||||
|
||||
//
|
||||
// Set Default TM Inputs ...
|
||||
void ConfigureRequirements()
|
||||
{
|
||||
//
|
||||
mTMInputs.maShift = 0;
|
||||
mTMInputs.maPeriod = 100;
|
||||
mTMInputs.maMethod = MODE_EMA;
|
||||
mTMInputs.maAppliedTo = PRICE_CLOSE;
|
||||
|
||||
//
|
||||
mTMInputs.showLine = true;
|
||||
|
||||
//
|
||||
mTMHelper = new XSCXTMHelper();
|
||||
|
||||
//
|
||||
mTMHelper.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
mTMInputs //
|
||||
);
|
||||
|
||||
//
|
||||
mSTRInputs.length = 14;
|
||||
mSTRInputs.multiplier = 3.5;
|
||||
mSTRInputs.appliedTo = PRICE_CLOSE;
|
||||
|
||||
//
|
||||
mSTRInputs.showTrends = true;
|
||||
mSTRInputs.fillTrends = false;
|
||||
|
||||
//
|
||||
mSTRHelper = new XSCXSTRHelper();
|
||||
mSTRHelper.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
mSTRInputs //
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
@@ -0,0 +1,823 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Class Library
|
||||
// --------------------------------------
|
||||
// Name: XSCXOBVGStrategy
|
||||
// Description: provides all based classes for use ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
/// Imports ...
|
||||
#include "../Helpers/x-saherelm.xosc.helper.mq5"
|
||||
#include "../Classes/x-saherelm.xstrategy.class.mq5"
|
||||
|
||||
//
|
||||
string XOBVGStartegyToken = "XOBVG";
|
||||
|
||||
//
|
||||
class XSCXOBVGStrategy : public XSCBaseStrategy
|
||||
{
|
||||
//
|
||||
// Public ...
|
||||
public:
|
||||
//
|
||||
// Constructor(s) ...
|
||||
void XSCXOBVGStrategy(
|
||||
//
|
||||
// Base ...
|
||||
string _symbol, // Trading Symbol
|
||||
ENUM_TIMEFRAMES _period, // Trading TimeFrame
|
||||
ENUM_TIMEFRAMES _analyzingPeriod, // Analyzing Period
|
||||
double _volume, // Voluem
|
||||
double _r2r, // Risk/Reward Ratio
|
||||
int _slippage, // Trader Slippage
|
||||
long _magicNumber, // Trader Magic Number
|
||||
bool _useTPSLAsPoint = false, // Converts TP and SL by Provided Points
|
||||
bool _forceMaxTPSLAsPoint = false, // Force Max TP and SL by Provided Points
|
||||
double _tpPoint = 0, // TP As Point
|
||||
double _slPoint = 0, // SL As Point
|
||||
bool _allowLong = true,
|
||||
bool _allowShort = true,
|
||||
int _maxAllowedLongs = 0,
|
||||
int _maxAllowedShorts = 0 //
|
||||
) : XSCBaseStrategy(_symbol,
|
||||
_period,
|
||||
_volume,
|
||||
_r2r,
|
||||
_slippage,
|
||||
_magicNumber,
|
||||
_useTPSLAsPoint,
|
||||
_forceMaxTPSLAsPoint,
|
||||
_tpPoint,
|
||||
_slPoint,
|
||||
_allowLong,
|
||||
_allowShort,
|
||||
_maxAllowedLongs,
|
||||
_maxAllowedShorts //
|
||||
)
|
||||
{
|
||||
//
|
||||
mAnalyzingPeriod = _analyzingPeriod;
|
||||
|
||||
//
|
||||
SetAlertPrefix(GetTag());
|
||||
|
||||
//
|
||||
PrepareRequirements();
|
||||
|
||||
//
|
||||
fvgUpper = 0;
|
||||
fvgLower = 0;
|
||||
isFVGTouched = false;
|
||||
|
||||
//
|
||||
oBar.Clean();
|
||||
oBullishOrderBlock.Clean();
|
||||
oBearishOrderBlock.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Deconstructor ...
|
||||
void ~XSCXOBVGStrategy()
|
||||
{
|
||||
delete oscHelper;
|
||||
}
|
||||
|
||||
//
|
||||
// Getter / Setter (s) ...
|
||||
|
||||
//
|
||||
ENUM_TIMEFRAMES AnalyzingPeriod()
|
||||
{
|
||||
return mAnalyzingPeriod;
|
||||
}
|
||||
|
||||
//
|
||||
void AnalyzingPeriod(ENUM_TIMEFRAMES value)
|
||||
{
|
||||
mAnalyzingPeriod = value;
|
||||
}
|
||||
|
||||
//
|
||||
// Overrides ...
|
||||
|
||||
//
|
||||
// Customize Strategy Identifier ...
|
||||
string GetTag() override
|
||||
{
|
||||
return XOBVGStartegyToken;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Conditions For Signal ...
|
||||
bool HasSignal(
|
||||
XSignal &signal //
|
||||
) override
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
signal.Clean();
|
||||
|
||||
//
|
||||
double sl = 0;
|
||||
double tp = 0;
|
||||
double risk = 0;
|
||||
double entry = 0;
|
||||
double reward = 0;
|
||||
double r2r = R2R();
|
||||
ENUM_POSITION_TYPE type = POSITION_TYPE_BUY;
|
||||
ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET;
|
||||
|
||||
//
|
||||
bool hasLong = false;
|
||||
bool hasShort = false;
|
||||
|
||||
//
|
||||
// For Trend ...
|
||||
XOHCL tmpHSW[];
|
||||
XOHCL tmpLSW[];
|
||||
|
||||
//
|
||||
// For Verifications ...
|
||||
|
||||
//
|
||||
bool useHammer = true;
|
||||
bool useMorningStar = false;
|
||||
bool useBullishEngulfing = true;
|
||||
bool useBullishMaurubozu = true;
|
||||
|
||||
//
|
||||
bool useShootingStar = true;
|
||||
bool useEveningStar = false;
|
||||
bool useBearishEngulfing = true;
|
||||
bool useBearishMaurubozu = true;
|
||||
|
||||
//
|
||||
// Bar On Trading Period ...
|
||||
XOHCL cBar;
|
||||
result = cBar.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
1 //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// 3 Bar LL and HH ...
|
||||
double ll3 = cBar.FindLowest(
|
||||
3,
|
||||
MODE_LOW //
|
||||
);
|
||||
double hh3 = cBar.FindHighest(
|
||||
3,
|
||||
MODE_HIGH //
|
||||
);
|
||||
|
||||
//
|
||||
double atr = oscHelper.GetATR(1);
|
||||
|
||||
//
|
||||
// Check OB Finder Bar ...
|
||||
result = oBar.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
// Init OB Finder Bar ...
|
||||
result = oBar.Init(
|
||||
mSymbol,
|
||||
mAnalyzingPeriod,
|
||||
1 //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
bool hasBullishOrderBlock = oBullishOrderBlock.IsValid();
|
||||
bool hasBearishOrderBlock = oBearishOrderBlock.IsValid();
|
||||
|
||||
//
|
||||
// Here we Have to Check Order Block Age ...
|
||||
|
||||
//
|
||||
if (hasBullishOrderBlock)
|
||||
{
|
||||
//
|
||||
int age = oBullishOrderBlock.Index();
|
||||
result = age <= 26;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
oBar.Clean();
|
||||
oBullishOrderBlock.Clean();
|
||||
fvgUpper = 0;
|
||||
fvgLower = 0;
|
||||
fvgTouchDate = NULL;
|
||||
isFVGTouched = false;
|
||||
|
||||
//
|
||||
RemoveDraws();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (hasBearishOrderBlock)
|
||||
{
|
||||
//
|
||||
int age = oBearishOrderBlock.Index();
|
||||
result = age <= 26;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
oBar.Clean();
|
||||
oBearishOrderBlock.Clean();
|
||||
fvgUpper = 0;
|
||||
fvgLower = 0;
|
||||
fvgTouchDate = NULL;
|
||||
isFVGTouched = false;
|
||||
|
||||
//
|
||||
RemoveDraws();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
hasBullishOrderBlock = oBullishOrderBlock.IsValid();
|
||||
hasBearishOrderBlock = oBearishOrderBlock.IsValid();
|
||||
result =
|
||||
//
|
||||
hasBullishOrderBlock
|
||||
//
|
||||
||
|
||||
//
|
||||
hasBearishOrderBlock
|
||||
//
|
||||
;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
// Detect Order Blocks ...
|
||||
hasBullishOrderBlock = oBar.HasBullishOrderBlock(oBullishOrderBlock);
|
||||
hasBearishOrderBlock = oBar.HasBearishOrderBlock(oBearishOrderBlock);
|
||||
|
||||
//
|
||||
// Check OB Detected ...
|
||||
result =
|
||||
//
|
||||
hasBullishOrderBlock
|
||||
//
|
||||
||
|
||||
//
|
||||
hasBearishOrderBlock
|
||||
//
|
||||
;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
oBar.Clean();
|
||||
oBullishOrderBlock.Clean();
|
||||
oBearishOrderBlock.Clean();
|
||||
|
||||
//
|
||||
fvgUpper = 0;
|
||||
fvgLower = 0;
|
||||
fvgTouchDate = NULL;
|
||||
isFVGTouched = false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Long ...
|
||||
if (hasBullishOrderBlock)
|
||||
{
|
||||
//
|
||||
DrawBullishOrderBlock(
|
||||
oBullishOrderBlock,
|
||||
ChartID() //
|
||||
);
|
||||
|
||||
//
|
||||
// Detect an FVG Inside Order Block in Trading Period ...
|
||||
result = FindBullishFVGInsideOrderBlock();
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
oBar.Clean();
|
||||
oBullishOrderBlock.Clean();
|
||||
fvgUpper = 0;
|
||||
fvgLower = 0;
|
||||
fvgTouchDate = NULL;
|
||||
isFVGTouched = false;
|
||||
|
||||
//
|
||||
RemoveDraws();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Now We Have to Waits Until Price reached the FVG ...
|
||||
if (!isFVGTouched)
|
||||
{
|
||||
//
|
||||
isFVGTouched = ll3 < fvgUpper;
|
||||
fvgTouchDate = TimeCurrent();
|
||||
}
|
||||
|
||||
//
|
||||
result = isFVGTouched;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Now we Have to Wait for Pressure ...
|
||||
|
||||
//
|
||||
bool isHammer = !useHammer
|
||||
? false
|
||||
: cBar.IsHammer();
|
||||
bool isMorningStar = !useMorningStar
|
||||
? false
|
||||
: cBar.IsMorningStar();
|
||||
bool isBullishMarubozu = !useBullishEngulfing
|
||||
? false
|
||||
: cBar.IsBullishMarubozu();
|
||||
bool isBullishEngulfing = !useBullishMaurubozu
|
||||
? false
|
||||
: cBar.IsBullishEngulfing();
|
||||
|
||||
//
|
||||
bool isBullishTrend = oBar.HasBullishTrend(
|
||||
tmpHSW,
|
||||
tmpLSW,
|
||||
false //
|
||||
);
|
||||
|
||||
//
|
||||
hasLong =
|
||||
//
|
||||
true // isBullishTrend
|
||||
//
|
||||
&&
|
||||
//
|
||||
(
|
||||
//
|
||||
isHammer
|
||||
//
|
||||
||
|
||||
//
|
||||
isMorningStar
|
||||
//
|
||||
||
|
||||
//
|
||||
isBullishMarubozu
|
||||
//
|
||||
||
|
||||
//
|
||||
isBullishEngulfing
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
result = hasLong;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
// Check FVG Touch Date ...
|
||||
int cTimeSec = (int)TimeCurrent();
|
||||
int tTimeSec = (int)fvgTouchDate;
|
||||
int periodSec = PeriodSeconds(mPeriod);
|
||||
int touchAge = (cTimeSec - tTimeSec) / periodSec;
|
||||
if (touchAge >= 10)
|
||||
{
|
||||
//
|
||||
oBar.Clean();
|
||||
oBullishOrderBlock.Clean();
|
||||
fvgUpper = 0;
|
||||
fvgLower = 0;
|
||||
fvgTouchDate = NULL;
|
||||
isFVGTouched = false;
|
||||
|
||||
//
|
||||
RemoveDraws();
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
type = POSITION_TYPE_BUY;
|
||||
sl = cBar.low - atr;
|
||||
}
|
||||
|
||||
//
|
||||
// Short ...
|
||||
if (hasBearishOrderBlock)
|
||||
{
|
||||
//
|
||||
DrawBearishOrderBlock(
|
||||
oBearishOrderBlock,
|
||||
ChartID() //
|
||||
);
|
||||
|
||||
//
|
||||
// Detect an FVG Inside Order Block in Trading Period ...
|
||||
result = FindBearishFVGInsideOrderBlock();
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
oBar.Clean();
|
||||
oBearishOrderBlock.Clean();
|
||||
fvgUpper = 0;
|
||||
fvgLower = 0;
|
||||
fvgTouchDate = NULL;
|
||||
isFVGTouched = false;
|
||||
|
||||
//
|
||||
RemoveDraws();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Now We Have to Waits Until Price reached the FVG ...
|
||||
if (!isFVGTouched)
|
||||
{
|
||||
//
|
||||
isFVGTouched = hh3 > fvgLower;
|
||||
fvgTouchDate = TimeCurrent();
|
||||
}
|
||||
|
||||
//
|
||||
result = isFVGTouched;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Now we Have to Wait for Pressure ...
|
||||
|
||||
//
|
||||
// Short ...
|
||||
bool isShootingStar = !useShootingStar
|
||||
? false
|
||||
: cBar.IsShootingStar();
|
||||
bool isEveningStar = !useEveningStar
|
||||
? false
|
||||
: cBar.IsEveningStar();
|
||||
bool isBearishEngulfing = !useBearishEngulfing
|
||||
? false
|
||||
: cBar.IsBearishEngulfing();
|
||||
bool isBearishMaurubozu = !useBearishMaurubozu
|
||||
? false
|
||||
: cBar.IsBearishMarubozu();
|
||||
|
||||
//
|
||||
bool isBearishTrend = oBar.HasBearishTrend(
|
||||
tmpHSW,
|
||||
tmpLSW,
|
||||
false //
|
||||
);
|
||||
|
||||
//
|
||||
hasShort =
|
||||
//
|
||||
true // isBearishTrend
|
||||
//
|
||||
&&
|
||||
//
|
||||
(
|
||||
//
|
||||
isShootingStar
|
||||
//
|
||||
||
|
||||
//
|
||||
isEveningStar
|
||||
//
|
||||
||
|
||||
//
|
||||
isBearishEngulfing
|
||||
//
|
||||
||
|
||||
//
|
||||
isBearishMaurubozu
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
result = hasShort;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
// Check FVG Touch Date ...
|
||||
int cTimeSec = (int)TimeCurrent();
|
||||
int tTimeSec = (int)fvgTouchDate;
|
||||
int periodSec = PeriodSeconds(mPeriod);
|
||||
int touchAge = (cTimeSec - tTimeSec) / periodSec;
|
||||
if (touchAge >= 10)
|
||||
{
|
||||
//
|
||||
oBar.Clean();
|
||||
oBearishOrderBlock.Clean();
|
||||
fvgUpper = 0;
|
||||
fvgLower = 0;
|
||||
fvgTouchDate = NULL;
|
||||
isFVGTouched = false;
|
||||
|
||||
//
|
||||
RemoveDraws();
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
type = POSITION_TYPE_SELL;
|
||||
sl = cBar.high + atr;
|
||||
}
|
||||
|
||||
//
|
||||
result = hasLong || hasShort;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
entry = GetEntry(mSymbol, type);
|
||||
CalculateTPSLByPrice(
|
||||
sl,
|
||||
tp,
|
||||
type,
|
||||
entry,
|
||||
r2r //
|
||||
);
|
||||
|
||||
//
|
||||
result = signal.Prepare(
|
||||
mSymbol,
|
||||
GetTag(),
|
||||
mPeriod,
|
||||
type,
|
||||
mode,
|
||||
entry,
|
||||
mVolume,
|
||||
sl,
|
||||
tp //
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Protected ...
|
||||
protected:
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
ENUM_TIMEFRAMES mAnalyzingPeriod; // Analyzing Period
|
||||
|
||||
//
|
||||
XOSCInputs oscInputs;
|
||||
XSCXOSCHelper *oscHelper;
|
||||
|
||||
//
|
||||
// Private ...
|
||||
private:
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
XOHCL oBar;
|
||||
XOHCL oBullishOrderBlock;
|
||||
XOHCL oBearishOrderBlock;
|
||||
|
||||
//
|
||||
double fvgUpper;
|
||||
double fvgLower;
|
||||
bool isFVGTouched;
|
||||
datetime fvgTouchDate;
|
||||
|
||||
//
|
||||
void PrepareRequirements()
|
||||
{
|
||||
//
|
||||
oscInputs.Default();
|
||||
oscHelper = new XSCXOSCHelper();
|
||||
oscHelper.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
oscInputs //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
bool FindBullishFVGInsideOrderBlock()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = oBullishOrderBlock.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int totalBars = iBars(
|
||||
mSymbol,
|
||||
mPeriod //
|
||||
);
|
||||
int maxAllowed = totalBars / 10;
|
||||
|
||||
//
|
||||
for (int i = 0; i < maxAllowed; i++)
|
||||
{
|
||||
//
|
||||
XOHCL iBar;
|
||||
result = iBar.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
i //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
result = iBar.HasBullishFVG(
|
||||
fvgUpper,
|
||||
fvgLower //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Check FVG has Correlation by OB ...
|
||||
result =
|
||||
//
|
||||
// Full Inside ...
|
||||
(fvgUpper <= oBullishOrderBlock.high &&
|
||||
fvgLower >= oBullishOrderBlock.low)
|
||||
//
|
||||
||
|
||||
//
|
||||
(fvgUpper > oBullishOrderBlock.high &&
|
||||
fvgLower >= oBullishOrderBlock.low &&
|
||||
fvgLower <= oBullishOrderBlock.high)
|
||||
//
|
||||
||
|
||||
//
|
||||
(fvgUpper > oBullishOrderBlock.low &&
|
||||
fvgUpper <= oBullishOrderBlock.high &&
|
||||
fvgLower < oBullishOrderBlock.low)
|
||||
//
|
||||
;
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
DrawBullishFVG(
|
||||
iBar,
|
||||
fvgUpper,
|
||||
fvgLower,
|
||||
ChartID() //
|
||||
);
|
||||
|
||||
//
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool FindBearishFVGInsideOrderBlock()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = oBearishOrderBlock.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int totalBars = iBars(
|
||||
mSymbol,
|
||||
mPeriod //
|
||||
);
|
||||
int maxAllowed = totalBars / 10;
|
||||
|
||||
//
|
||||
for (int i = 0; i < maxAllowed; i++)
|
||||
{
|
||||
//
|
||||
XOHCL iBar;
|
||||
result = iBar.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
i //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
result = iBar.HasBearishFVG(
|
||||
fvgUpper,
|
||||
fvgLower //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Check FVG has Correlation by OB ...
|
||||
result =
|
||||
//
|
||||
// Full Inside ...
|
||||
(fvgUpper <= oBearishOrderBlock.high &&
|
||||
fvgLower >= oBearishOrderBlock.low)
|
||||
//
|
||||
||
|
||||
//
|
||||
(fvgUpper > oBearishOrderBlock.high &&
|
||||
fvgLower >= oBearishOrderBlock.low &&
|
||||
fvgLower <= oBearishOrderBlock.high)
|
||||
//
|
||||
||
|
||||
//
|
||||
(fvgUpper > oBearishOrderBlock.low &&
|
||||
fvgUpper <= oBearishOrderBlock.high &&
|
||||
fvgLower < oBearishOrderBlock.low)
|
||||
//
|
||||
;
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
DrawBearishFVG(
|
||||
iBar,
|
||||
fvgUpper,
|
||||
fvgLower,
|
||||
ChartID() //
|
||||
);
|
||||
|
||||
//
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
@@ -0,0 +1,742 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Class Library
|
||||
// --------------------------------------
|
||||
// Name: XSCXPVFMCStrategy
|
||||
// Description: provides all based classes for use ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../Helpers/x-saherelm.xhk.helper.mq5"
|
||||
#include "../Helpers/x-saherelm.xmc.helper.mq5"
|
||||
#include "../Helpers/x-saherelm.xtd.helper.mq5"
|
||||
#include "../Helpers/x-saherelm.xpv.helper.mq5"
|
||||
#include "../Helpers/x-saherelm.xvlm.helper.mq5"
|
||||
#include "../Helpers/x-saherelm.xosc.helper.mq5"
|
||||
#include "../Classes/x-saherelm.xstrategy.class.mq5"
|
||||
|
||||
//
|
||||
string XPVFMCStartegyToken = "XPVFMC";
|
||||
|
||||
//
|
||||
class XSCXPVFMCStrategy : public XSCBaseStrategy
|
||||
{
|
||||
//
|
||||
// Public ...
|
||||
public:
|
||||
//
|
||||
// Constructor(s) ...
|
||||
void XSCXPVFMCStrategy(
|
||||
//
|
||||
// Base ...
|
||||
string _symbol, // Trading Symbol
|
||||
ENUM_TIMEFRAMES _period, // Trading TimeFrame
|
||||
double _volume, // Voluem
|
||||
double _r2r, // Risk/Reward Ratio
|
||||
int _slippage, // Trader Slippage
|
||||
long _magicNumber, // Trader Magic Number
|
||||
bool _useTPSLAsPoint = false, // Converts TP and SL by Provided Points
|
||||
bool _forceMaxTPSLAsPoint = false, // Force Max TP and SL by Provided Points
|
||||
double _tpPoint = 0, // TP As Point
|
||||
double _slPoint = 0, // SL As Point
|
||||
bool _allowLong = true,
|
||||
bool _allowShort = true,
|
||||
int _maxAllowedLongs = 0,
|
||||
int _maxAllowedShorts = 0 //
|
||||
) : XSCBaseStrategy(_symbol,
|
||||
_period,
|
||||
_volume,
|
||||
_r2r,
|
||||
_slippage,
|
||||
_magicNumber,
|
||||
_useTPSLAsPoint,
|
||||
_forceMaxTPSLAsPoint,
|
||||
_tpPoint,
|
||||
_slPoint,
|
||||
_allowLong,
|
||||
_allowShort,
|
||||
_maxAllowedLongs,
|
||||
_maxAllowedShorts //
|
||||
)
|
||||
{
|
||||
//
|
||||
SetAlertPrefix(GetTag());
|
||||
|
||||
//
|
||||
PrepareRequirements();
|
||||
}
|
||||
|
||||
//
|
||||
// Deconstructor ...
|
||||
void ~XSCXPVFMCStrategy()
|
||||
{
|
||||
//
|
||||
delete mcHelper;
|
||||
delete pvHelper;
|
||||
delete tdHelper;
|
||||
delete hkHelper;
|
||||
delete oscHelper;
|
||||
delete vlmHelper;
|
||||
}
|
||||
|
||||
//
|
||||
// Getter / Setter (s) ...
|
||||
|
||||
//
|
||||
// Overrides ...
|
||||
|
||||
//
|
||||
// Customize Strategy Identifier ...
|
||||
string GetTag() override
|
||||
{
|
||||
return XPVFMCStartegyToken;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Conditions For Signal ...
|
||||
bool HasSignal(
|
||||
XSignal &signal //
|
||||
) override
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
signal.Clean();
|
||||
|
||||
//
|
||||
double sl = 0;
|
||||
double tp = 0;
|
||||
double risk = 0;
|
||||
double entry = 0;
|
||||
double reward = 0;
|
||||
double r2r = R2R();
|
||||
ENUM_POSITION_TYPE type = POSITION_TYPE_BUY;
|
||||
ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET;
|
||||
|
||||
//
|
||||
bool hasLong = false;
|
||||
bool hasShort = false;
|
||||
|
||||
//
|
||||
// XMC ...
|
||||
XMCConditions mcConditions;
|
||||
result = mcHelper.GetConditions(mcConditions);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// XPV ...
|
||||
XPVConditions pvConditions;
|
||||
result = pvHelper.GetConditions(pvConditions);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// XTD ...
|
||||
XTDConditions tdConditions;
|
||||
result = tdHelper.GetConditions(tdConditions);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// XHK ...
|
||||
XHKConditions hkConditions;
|
||||
result = hkHelper.GetConditions(hkConditions);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// XVLM ...
|
||||
XVLMConditions vlmConditions;
|
||||
result = vlmHelper.GetConditions(vlmConditions);
|
||||
|
||||
//
|
||||
double atr = oscHelper.GetATR(1);
|
||||
|
||||
//
|
||||
double rsis[];
|
||||
ArraySetAsSeries(rsis, true);
|
||||
oscHelper.CopyRSI(
|
||||
0,
|
||||
3,
|
||||
rsis //
|
||||
);
|
||||
|
||||
//
|
||||
double points = GetPoints(mSymbol);
|
||||
|
||||
//
|
||||
int zIndex = 0;
|
||||
int cIndex = zIndex + 1;
|
||||
int pIndex = cIndex + 1;
|
||||
int ppIndex = pIndex + 1;
|
||||
|
||||
//
|
||||
// For Trend ...
|
||||
XOHCL tmpHSW[];
|
||||
XOHCL tmpLSW[];
|
||||
|
||||
//
|
||||
// For Verifications ...
|
||||
|
||||
//
|
||||
// Bar On Trading Period ...
|
||||
XOHCL cBar;
|
||||
result = cBar.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
cIndex //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// //
|
||||
// // Find Lowest Low and Highest High ...
|
||||
// double hh3 = cBar.FindHighest(
|
||||
// 3,
|
||||
// MODE_HIGH //
|
||||
// );
|
||||
// double ll3 = cBar.FindLowest(
|
||||
// 3,
|
||||
// MODE_LOW //
|
||||
// );
|
||||
|
||||
//
|
||||
XOHCL pBar;
|
||||
result = cBar.GetPreviousBar(pBar);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool hasBullishPattern = HasBullishPattern(cBar);
|
||||
bool isBullishTrend = cBar.HasBullishTrend(
|
||||
tmpHSW,
|
||||
tmpLSW,
|
||||
true //
|
||||
);
|
||||
|
||||
//
|
||||
bool hasBearishPattern = HasBearishPattern(cBar);
|
||||
|
||||
//
|
||||
bool isBearishTrend = cBar.HasBearishTrend(
|
||||
tmpHSW,
|
||||
tmpLSW,
|
||||
false //
|
||||
);
|
||||
|
||||
//
|
||||
// Check Support Exists or Find ...
|
||||
bool hasSupport = support.IsValid();
|
||||
if (!hasSupport)
|
||||
{
|
||||
//
|
||||
hasSupport =
|
||||
//
|
||||
cBar.HasSupport(support)
|
||||
//
|
||||
&&
|
||||
//
|
||||
MathAbs(pvConditions.fib3s[cIndex] - support.high) <= 10 * points
|
||||
//
|
||||
;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Resistance Exists or Find ...
|
||||
bool hasResistance = resistance.IsValid();
|
||||
if (!hasResistance)
|
||||
{
|
||||
//
|
||||
hasResistance =
|
||||
//
|
||||
cBar.HasResistance(resistance)
|
||||
//
|
||||
&&
|
||||
//
|
||||
MathAbs(pvConditions.fib3s[cIndex] - resistance.low) <= 10 * points
|
||||
//
|
||||
;
|
||||
}
|
||||
|
||||
//
|
||||
if (hasSupport)
|
||||
{
|
||||
//
|
||||
DrawSupport(
|
||||
support,
|
||||
ChartID() //
|
||||
);
|
||||
|
||||
//
|
||||
supportTime = cBar.time;
|
||||
|
||||
//
|
||||
// Check Price is Around Support ...
|
||||
double priceDiff = MathMin(
|
||||
MathAbs(cBar.low - support.high),
|
||||
MathAbs(cBar.high - support.high)) /
|
||||
points;
|
||||
result =
|
||||
//
|
||||
priceDiff <= 50
|
||||
//
|
||||
;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
CheckSupportValidation();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
if (result && !isSupportTested)
|
||||
{
|
||||
isSupportTested = true;
|
||||
}
|
||||
|
||||
//
|
||||
// Long ...
|
||||
hasLong =
|
||||
//
|
||||
(
|
||||
//
|
||||
isBullishTrend
|
||||
//
|
||||
||
|
||||
//
|
||||
hasBullishPattern
|
||||
//
|
||||
)
|
||||
//
|
||||
&&
|
||||
//
|
||||
(
|
||||
//
|
||||
(tdConditions.isSwitchedToBullish &&
|
||||
hkConditions.isSMHKBullish)
|
||||
//
|
||||
||
|
||||
//
|
||||
(hkConditions.isSMHKSwitchedToBullish &&
|
||||
tdConditions.isBullish)
|
||||
//
|
||||
||
|
||||
//
|
||||
(mcConditions.isFastCrossedOverSlow &&
|
||||
mcConditions.isSlowOverVerifier)
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
if (hasLong)
|
||||
{
|
||||
//
|
||||
type = POSITION_TYPE_BUY;
|
||||
XOHCL swingLow;
|
||||
bool hasSwing = cBar.FindLastSwingLow(swingLow);
|
||||
if (!hasSwing)
|
||||
{
|
||||
sl = support.high - (50 * points);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
DrawSwingLow(swingLow, ChartID());
|
||||
sl = swingLow.low - atr;
|
||||
RemoveSwingLow(swingLow);
|
||||
swingLow.Clean();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// //
|
||||
// if (hasResistance)
|
||||
// {
|
||||
// //
|
||||
// DrawResistance(
|
||||
// support,
|
||||
// ChartID() //
|
||||
// );
|
||||
|
||||
// //
|
||||
// supportTime = cBar.time;
|
||||
|
||||
// //
|
||||
// // Check Price is Around Support ...
|
||||
// double priceDiff = MathMin(
|
||||
// MathAbs(cBar.low - support.high),
|
||||
// MathAbs(cBar.high - support.high)) /
|
||||
// points;
|
||||
// result =
|
||||
// //
|
||||
// priceDiff <= 50
|
||||
// //
|
||||
// ;
|
||||
// if (!result)
|
||||
// {
|
||||
// //
|
||||
// CheckResistanceValidation();
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// //
|
||||
// if (result && !isResistanceTested)
|
||||
// {
|
||||
// isResistanceTested = true;
|
||||
// }
|
||||
// }
|
||||
|
||||
//
|
||||
result = hasLong || hasShort;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
CheckSupportValidation();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
if (hasSupport)
|
||||
{
|
||||
//
|
||||
isSupportTested = false;
|
||||
supportTime = NULL;
|
||||
RemoveSupport(support);
|
||||
support.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
if (hasResistance)
|
||||
{
|
||||
//
|
||||
isResistanceTested = false;
|
||||
resistanceTime = NULL;
|
||||
RemoveResistance(resistance);
|
||||
resistance.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
entry = GetEntry(mSymbol, type);
|
||||
CalculateTPSLByPrice(
|
||||
sl,
|
||||
tp,
|
||||
type,
|
||||
entry,
|
||||
r2r //
|
||||
);
|
||||
|
||||
//
|
||||
result = signal.Prepare(
|
||||
mSymbol,
|
||||
GetTag(),
|
||||
mPeriod,
|
||||
type,
|
||||
mode,
|
||||
entry,
|
||||
mVolume,
|
||||
sl,
|
||||
tp //
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Protected ...
|
||||
protected:
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
XOHCL support;
|
||||
XOHCL resistance;
|
||||
|
||||
//
|
||||
// XMC ...
|
||||
XMCInputs mcInputs;
|
||||
XSCXMCHelper *mcHelper;
|
||||
|
||||
//
|
||||
XTDInputs tdInputs;
|
||||
XSCXTDHelper *tdHelper;
|
||||
|
||||
//
|
||||
// XPV ...
|
||||
XPVInputs pvInputs;
|
||||
XSCXPVHelper *pvHelper;
|
||||
|
||||
//
|
||||
// XOSC ...
|
||||
XOSCInputs oscInputs;
|
||||
XSCXOSCHelper *oscHelper;
|
||||
|
||||
//
|
||||
// XVLM ...
|
||||
XVLMInputs vlmInputs;
|
||||
XSCXVLMHelper *vlmHelper;
|
||||
|
||||
//
|
||||
// XHK ...
|
||||
XHKInputs hkInputs;
|
||||
XSCXHKHelper *hkHelper;
|
||||
|
||||
//
|
||||
// Private ...
|
||||
private:
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
void PrepareRequirements()
|
||||
{
|
||||
//
|
||||
support.Clean();
|
||||
supportTime = NULL;
|
||||
isSupportTested = false;
|
||||
|
||||
//
|
||||
resistance.Clean();
|
||||
resistanceTime = NULL;
|
||||
isResistanceTested = false;
|
||||
|
||||
//
|
||||
// Prepare XTD ...
|
||||
tdInputs.Default();
|
||||
|
||||
//
|
||||
tdHelper = new XSCXTDHelper();
|
||||
tdHelper.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
tdInputs //
|
||||
);
|
||||
|
||||
//
|
||||
// Preparing XHK ...
|
||||
hkInputs.Default();
|
||||
hkInputs.smoothingLength = 14;
|
||||
|
||||
//
|
||||
hkInputs.drawHikenAshi = false;
|
||||
hkInputs.drawSmoothedHikenAshi = true;
|
||||
|
||||
//
|
||||
hkHelper = new XSCXHKHelper();
|
||||
hkHelper.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
hkInputs //
|
||||
);
|
||||
|
||||
//
|
||||
// Preparing XMC ...
|
||||
mcInputs.Default();
|
||||
|
||||
//
|
||||
mcInputs.showSar = false;
|
||||
mcInputs.showFastMa = true;
|
||||
mcInputs.showSlowMa = true;
|
||||
mcInputs.showVerifierMa = true;
|
||||
|
||||
//
|
||||
mcHelper = new XSCXMCHelper();
|
||||
mcHelper.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
mcInputs //
|
||||
);
|
||||
|
||||
//
|
||||
// Preparing XPV ...
|
||||
pvInputs.Default();
|
||||
|
||||
//
|
||||
pvInputs.showPeaksAndVales = true;
|
||||
pvInputs.showLevels = false;
|
||||
pvInputs.showConsolidations = false;
|
||||
pvInputs.showFibo1Levels = false;
|
||||
pvInputs.showFibo2Levels = false;
|
||||
pvInputs.showFibo3Levels = true;
|
||||
pvInputs.showFibo4Levels = false;
|
||||
pvInputs.showFibo5Levels = false;
|
||||
|
||||
//
|
||||
pvHelper = new XSCXPVHelper();
|
||||
pvHelper.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
pvInputs //
|
||||
);
|
||||
|
||||
//
|
||||
// Preparing XOSC ...
|
||||
oscInputs.Default();
|
||||
oscHelper = new XSCXOSCHelper();
|
||||
oscHelper.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
oscInputs //
|
||||
);
|
||||
|
||||
//
|
||||
// Preparing XVLM ...
|
||||
vlmInputs.Default();
|
||||
vlmHelper = new XSCXVLMHelper();
|
||||
vlmHelper.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
vlmInputs //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
bool isSupportTested;
|
||||
datetime supportTime;
|
||||
void CheckSupportValidation()
|
||||
{
|
||||
//
|
||||
if (!isSupportTested)
|
||||
{
|
||||
//
|
||||
if (support.IsValid() && IsValid(supportTime))
|
||||
{
|
||||
//
|
||||
int age = (int)(((int)(TimeToSeconds(TimeCurrent()) - TimeToSeconds(supportTime))) / PeriodSeconds(mPeriod));
|
||||
if (age >= 50)
|
||||
{
|
||||
//
|
||||
isSupportTested = false;
|
||||
supportTime = NULL;
|
||||
RemoveSupport(support);
|
||||
support.Clean();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
XOHCL cBar;
|
||||
bool isInited = cBar.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
1 //
|
||||
);
|
||||
if (!isInited)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
double points = GetPoints(mSymbol);
|
||||
|
||||
//
|
||||
// Find Price Distance ...
|
||||
double highDiff = MathAbs(cBar.high - support.high);
|
||||
double lowDiff = MathAbs(cBar.low - support.high);
|
||||
|
||||
//
|
||||
bool isBreaked = MathMax(highDiff, lowDiff) >= 100 * points;
|
||||
if (!isBreaked)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
isSupportTested = false;
|
||||
RemoveSupport(support);
|
||||
supportTime = NULL;
|
||||
support.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
bool isResistanceTested;
|
||||
datetime resistanceTime;
|
||||
void CheckResistanceValidation()
|
||||
{
|
||||
//
|
||||
if (!isResistanceTested)
|
||||
{
|
||||
//
|
||||
if (resistance.IsValid() && IsValid(resistanceTime))
|
||||
{
|
||||
//
|
||||
int age = (int)(((int)(TimeToSeconds(TimeCurrent()) - TimeToSeconds(resistanceTime))) / PeriodSeconds(mPeriod));
|
||||
if (age >= 50)
|
||||
{
|
||||
//
|
||||
isResistanceTested = false;
|
||||
resistanceTime = NULL;
|
||||
RemoveResistance(resistance);
|
||||
resistance.Clean();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
XOHCL cBar;
|
||||
bool isInited = cBar.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
1 //
|
||||
);
|
||||
if (!isInited)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
double points = GetPoints(mSymbol);
|
||||
|
||||
//
|
||||
// Find Price Distance ...
|
||||
double highDiff = MathAbs(cBar.high - resistance.low);
|
||||
double lowDiff = MathAbs(cBar.low - resistance.low);
|
||||
|
||||
//
|
||||
bool isBreaked = MathMax(highDiff, lowDiff) >= 100 * points;
|
||||
if (!isBreaked)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
isResistanceTested = false;
|
||||
RemoveResistance(resistance);
|
||||
resistanceTime = NULL;
|
||||
resistance.Clean();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
@@ -0,0 +1,723 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Class Library
|
||||
// --------------------------------------
|
||||
// Name: XSCXSRBRStrategy
|
||||
// Description: provides all based classes for use ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
/// Imports ...
|
||||
#include "../Classes/x-saherelm.xstrategy.class.mq5"
|
||||
|
||||
//
|
||||
string XSRBRStartegyToken = "XSRBR";
|
||||
|
||||
//
|
||||
class XSCXSRBRStrategy : public XSCBaseStrategy
|
||||
{
|
||||
//
|
||||
// Public ...
|
||||
public:
|
||||
//
|
||||
// Constructor(s) ...
|
||||
void XSCXSRBRStrategy(
|
||||
//
|
||||
// Base ...
|
||||
string _symbol, // Trading Symbol
|
||||
ENUM_TIMEFRAMES _period, // Trading TimeFrame
|
||||
ENUM_TIMEFRAMES _analyzingPeriod, // Analyzing Timeframe
|
||||
double _volume, // Voluem
|
||||
double _r2r, // Risk/Reward Ratio
|
||||
int _slippage, // Trader Slippage
|
||||
long _magicNumber, // Trader Magic Number
|
||||
bool _useTPSLAsPoint = false, // Converts TP and SL by Provided Points
|
||||
bool _forceMaxTPSLAsPoint = false, // Force Max TP and SL by Provided Points
|
||||
double _tpPoint = 0, // TP As Point
|
||||
double _slPoint = 0, // SL As Point
|
||||
bool _allowLong = true,
|
||||
bool _allowShort = true,
|
||||
int _maxAllowedLongs = 0,
|
||||
int _maxAllowedShorts = 0,
|
||||
ENUM_X_SIGNALLING_DIRECTION _signallingDirection = X_SIGNALLING_TREND_DIRECTION // Signalling in Which Direction
|
||||
) : XSCBaseStrategy(_symbol,
|
||||
_period,
|
||||
_volume,
|
||||
_r2r,
|
||||
_slippage,
|
||||
_magicNumber,
|
||||
_useTPSLAsPoint,
|
||||
_forceMaxTPSLAsPoint,
|
||||
_tpPoint,
|
||||
_slPoint,
|
||||
_allowLong,
|
||||
_allowShort,
|
||||
_maxAllowedLongs,
|
||||
_maxAllowedShorts //
|
||||
)
|
||||
{
|
||||
//
|
||||
mAnalyzingPeriod = _analyzingPeriod;
|
||||
mSignallingDirection = _signallingDirection;
|
||||
|
||||
//
|
||||
SetAlertPrefix(GetTag());
|
||||
}
|
||||
|
||||
//
|
||||
// Getter / Setter (s) ...
|
||||
|
||||
//
|
||||
ENUM_X_SIGNALLING_DIRECTION SignallingDirection()
|
||||
{
|
||||
return mSignallingDirection;
|
||||
}
|
||||
|
||||
//
|
||||
void SignallingDirection(ENUM_X_SIGNALLING_DIRECTION value)
|
||||
{
|
||||
mSignallingDirection = value;
|
||||
}
|
||||
|
||||
//
|
||||
// Overrides ...
|
||||
|
||||
//
|
||||
// Customize Strategy Identifier ...
|
||||
string GetTag() override
|
||||
{
|
||||
return XSRBRStartegyToken;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Conditions For Signal ...
|
||||
bool HasSignal(
|
||||
XSignal &signal //
|
||||
) override
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
double _threshold = 5;
|
||||
double threshold = GetPoints(mSymbol) * _threshold;
|
||||
|
||||
//
|
||||
signal.Clean();
|
||||
|
||||
//
|
||||
double sl = 0;
|
||||
double tp = 0;
|
||||
double risk = 0;
|
||||
double entry = 0;
|
||||
double reward = 0;
|
||||
double r2r = R2R();
|
||||
ENUM_POSITION_TYPE type = POSITION_TYPE_BUY;
|
||||
ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET;
|
||||
|
||||
//
|
||||
// Check Signalling Direction ...
|
||||
result = mSignallingDirection != X_SIGNALLING_NONE;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Conditions Exists ...
|
||||
result = HasRequirements();
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
// Prepare Conditions ...
|
||||
result = PrepareRequirements();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Implement Signalling Conditions ...
|
||||
XOHCL cBar;
|
||||
result = cBar.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
1 //
|
||||
);
|
||||
|
||||
//
|
||||
// Check Analyzing Period Contains a Trend or not ...
|
||||
|
||||
//
|
||||
// Detecting Trend ...
|
||||
bool isInBullishTrend = false;
|
||||
bool isInBearishTrend = false;
|
||||
|
||||
//
|
||||
// Verify Pressure for Signals ...
|
||||
bool verifyPressure = true;
|
||||
bool checkTrensByMethod2 = false;
|
||||
|
||||
//
|
||||
bool checkHammer = false;
|
||||
bool checkMorningStar = false;
|
||||
bool checkBullishEngulfing = true;
|
||||
|
||||
//
|
||||
bool checkShootingStar = false;
|
||||
bool checkEveningStar = false;
|
||||
bool checkBearishEngulfing = true;
|
||||
|
||||
//
|
||||
isInBullishTrend = bar.HasBullishTrend(
|
||||
highSwingBars,
|
||||
lowSwingBars,
|
||||
checkTrensByMethod2 //
|
||||
);
|
||||
if (!isInBullishTrend)
|
||||
{
|
||||
//
|
||||
isInBearishTrend = bar.HasBearishTrend(
|
||||
highSwingBars,
|
||||
lowSwingBars,
|
||||
checkTrensByMethod2 //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Only Looks For Signals if aTrend Detected ...
|
||||
result = isInBullishTrend || isInBearishTrend;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
ResetRequirements();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
if (isInBullishTrend)
|
||||
{
|
||||
//
|
||||
DrawBullishTrend(
|
||||
cBar,
|
||||
highSwingBars,
|
||||
lowSwingBars,
|
||||
ChartID(),
|
||||
true,
|
||||
true //
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
DrawBearishTrend(
|
||||
cBar,
|
||||
highSwingBars,
|
||||
lowSwingBars,
|
||||
ChartID(),
|
||||
true,
|
||||
true //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Here We have to Decide Trend or Reversal Act ...
|
||||
|
||||
//
|
||||
// Check Trend Direction Signal ...
|
||||
if (mSignallingDirection == X_SIGNALLING_BOTH_DIRECTIONS ||
|
||||
mSignallingDirection == X_SIGNALLING_TREND_DIRECTION)
|
||||
{
|
||||
//
|
||||
if (isInBullishTrend)
|
||||
{
|
||||
//
|
||||
// Find Long Signals ...
|
||||
// since we are in Bullish Trend and
|
||||
// we must do Trend Trading ...
|
||||
|
||||
//
|
||||
// In Trend Trading we must Waits for :
|
||||
// - Support Rejection;
|
||||
|
||||
//
|
||||
// Support Rejecting Hppens when Price Go Down of Support area and
|
||||
// Go Up or
|
||||
// Price Recive a Candlestic Pattern ...
|
||||
|
||||
//
|
||||
// this Moving Up Make us Ready for Reciving a
|
||||
// Candlestick Pattern which Prove us Buyers Pressure ...
|
||||
// - Hammer;
|
||||
// - Morning Star;
|
||||
// - Bullish Engulfing;
|
||||
|
||||
//
|
||||
XOHCL tmpSWH[];
|
||||
XOHCL tmpSWL[];
|
||||
|
||||
//
|
||||
bool isSupportRejected = IsSupportRejected(support, verifyPressure, checkHammer, checkMorningStar, checkBullishEngulfing);
|
||||
bool isResistanceBreaked = IsResistanceBreaked(resistance, verifyPressure, checkHammer, checkMorningStar, checkBullishEngulfing);
|
||||
|
||||
//
|
||||
bool isBullishTrend = cBar.HasBullishTrend(
|
||||
tmpSWH,
|
||||
tmpSWL,
|
||||
true //
|
||||
);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
isBullishTrend
|
||||
//
|
||||
&&
|
||||
//
|
||||
(
|
||||
//
|
||||
isSupportRejected
|
||||
//
|
||||
||
|
||||
//
|
||||
isResistanceBreaked
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
type = POSITION_TYPE_BUY;
|
||||
|
||||
//
|
||||
if (isSupportRejected)
|
||||
{
|
||||
//
|
||||
sl = support.low - threshold;
|
||||
RemoveSupport(support);
|
||||
support.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
if (isResistanceBreaked)
|
||||
{
|
||||
//
|
||||
sl = resistance.low - threshold;
|
||||
RemoveResistance(resistance);
|
||||
resistance.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
RemoveDraws(XTLSBullishTrendToken);
|
||||
RemoveDraws(XTLSBearishTrendToken);
|
||||
}
|
||||
}
|
||||
else if (isInBearishTrend)
|
||||
{
|
||||
//
|
||||
// Find Short Signals ...
|
||||
// since we are in Bearish Trend and
|
||||
// we must do Trend Trading ...
|
||||
|
||||
//
|
||||
XOHCL tmpSWH[];
|
||||
XOHCL tmpSWL[];
|
||||
|
||||
//
|
||||
bool isSupportBreaked = IsSupportBreaked(support, verifyPressure, checkShootingStar, checkEveningStar, checkBearishEngulfing);
|
||||
bool isResistanceRejected = IsResistanceRejected(resistance, verifyPressure, checkShootingStar, checkEveningStar, checkBearishEngulfing);
|
||||
|
||||
//
|
||||
bool isBearishTrend = cBar.HasBearishTrend(
|
||||
tmpSWH,
|
||||
tmpSWL,
|
||||
true //
|
||||
);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
isBearishTrend
|
||||
//
|
||||
&&
|
||||
//
|
||||
(
|
||||
//
|
||||
isSupportBreaked
|
||||
//
|
||||
||
|
||||
//
|
||||
isResistanceRejected
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
type = POSITION_TYPE_SELL;
|
||||
|
||||
//
|
||||
if (isSupportBreaked)
|
||||
{
|
||||
//
|
||||
sl = support.high + threshold;
|
||||
RemoveSupport(support);
|
||||
support.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
if (isResistanceRejected)
|
||||
{
|
||||
//
|
||||
sl = resistance.high + threshold;
|
||||
RemoveResistance(resistance);
|
||||
resistance.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
RemoveDraws(XTLSBullishTrendToken);
|
||||
RemoveDraws(XTLSBearishTrendToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Trend Reversal Direction Signal ...
|
||||
if (!result &&
|
||||
(mSignallingDirection == X_SIGNALLING_BOTH_DIRECTIONS ||
|
||||
mSignallingDirection == X_SIGNALIING_TREND_REVERSAL_DIRECTION))
|
||||
{
|
||||
//
|
||||
if (isInBullishTrend)
|
||||
{
|
||||
//
|
||||
// Find Short Signals ...
|
||||
// since we are in Bullish Trend and
|
||||
// we must do Trend Reversal Trading ...
|
||||
|
||||
//
|
||||
XOHCL tmpSWH[];
|
||||
XOHCL tmpSWL[];
|
||||
|
||||
//
|
||||
bool isSupportBreaked = IsSupportBreaked(support, verifyPressure, checkShootingStar, checkEveningStar, checkBearishEngulfing);
|
||||
bool isResistanceRejected = IsResistanceRejected(resistance, verifyPressure, checkShootingStar, checkEveningStar, checkBearishEngulfing);
|
||||
|
||||
//
|
||||
bool isBearishTrend = cBar.HasBearishTrend(
|
||||
tmpSWH,
|
||||
tmpSWL,
|
||||
true //
|
||||
);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
true // isBearishTrend
|
||||
//
|
||||
&&
|
||||
//
|
||||
(
|
||||
//
|
||||
isSupportBreaked
|
||||
//
|
||||
||
|
||||
//
|
||||
isResistanceRejected
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
type = POSITION_TYPE_SELL;
|
||||
|
||||
//
|
||||
if (isSupportBreaked)
|
||||
{
|
||||
//
|
||||
sl = support.high + threshold;
|
||||
RemoveSupport(support);
|
||||
support.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
if (isResistanceRejected)
|
||||
{
|
||||
//
|
||||
sl = resistance.high + threshold;
|
||||
RemoveResistance(resistance);
|
||||
resistance.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
RemoveDraws(XTLSBullishTrendToken);
|
||||
RemoveDraws(XTLSBearishTrendToken);
|
||||
}
|
||||
}
|
||||
else if (isInBearishTrend)
|
||||
{
|
||||
//
|
||||
// Find Long Signals ...
|
||||
// since we are in Bearish Trend and
|
||||
// we must do Trend Reversal Trading ...
|
||||
|
||||
//
|
||||
XOHCL tmpSWH[];
|
||||
XOHCL tmpSWL[];
|
||||
|
||||
//
|
||||
bool isSupportRejected = IsSupportRejected(support, verifyPressure, checkHammer, checkMorningStar, checkBullishEngulfing);
|
||||
bool isResistanceBreaked = IsResistanceBreaked(resistance, verifyPressure, checkHammer, checkMorningStar, checkBullishEngulfing);
|
||||
|
||||
//
|
||||
bool isBullishTrend = cBar.HasBullishTrend(
|
||||
tmpSWH,
|
||||
tmpSWL,
|
||||
true //
|
||||
);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
true // isBullishTrend
|
||||
//
|
||||
&&
|
||||
//
|
||||
(
|
||||
//
|
||||
isSupportRejected
|
||||
//
|
||||
||
|
||||
//
|
||||
isResistanceBreaked
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
type = POSITION_TYPE_BUY;
|
||||
|
||||
//
|
||||
if (isSupportRejected)
|
||||
{
|
||||
//
|
||||
sl = support.low - threshold;
|
||||
RemoveSupport(support);
|
||||
support.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
if (isResistanceBreaked)
|
||||
{
|
||||
//
|
||||
sl = resistance.low - threshold;
|
||||
RemoveResistance(resistance);
|
||||
resistance.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
RemoveDraws(XTLSBullishTrendToken);
|
||||
RemoveDraws(XTLSBearishTrendToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Make Sure Signal Exists ...
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
RemoveDraws(XTLSBullishTrendToken);
|
||||
RemoveDraws(XTLSBearishTrendToken);
|
||||
|
||||
//
|
||||
ResetRequirements();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
entry = GetEntry(mSymbol, type);
|
||||
CalculateTPSLByPrice(
|
||||
sl,
|
||||
tp,
|
||||
type,
|
||||
entry,
|
||||
r2r //
|
||||
);
|
||||
|
||||
//
|
||||
result = signal.Prepare(
|
||||
mSymbol,
|
||||
GetTag(),
|
||||
mPeriod,
|
||||
type,
|
||||
mode,
|
||||
entry,
|
||||
mVolume,
|
||||
sl,
|
||||
tp //
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Protected ...
|
||||
protected:
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
ENUM_TIMEFRAMES mAnalyzingPeriod; // Analyzing Period
|
||||
ENUM_X_SIGNALLING_DIRECTION mSignallingDirection; // Signalling Direction
|
||||
|
||||
//
|
||||
XOHCL bar;
|
||||
|
||||
//
|
||||
// Pivots ...
|
||||
XOHCL support;
|
||||
XOHCL resistance;
|
||||
|
||||
//
|
||||
XOHCL lowSwingBars[];
|
||||
XOHCL highSwingBars[];
|
||||
|
||||
//
|
||||
// Private ...
|
||||
private:
|
||||
//
|
||||
|
||||
//
|
||||
// Check Requirements Exists or not ...
|
||||
bool HasRequirements()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
bar.IsValid() &&
|
||||
support.IsValid() &&
|
||||
resistance.IsValid()
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare Requirements ...
|
||||
bool PrepareRequirements()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (support.IsValid())
|
||||
{
|
||||
RemoveSupport(support);
|
||||
}
|
||||
|
||||
//
|
||||
// Finding Analyzing Bar ...
|
||||
result = bar.Init(
|
||||
mSymbol,
|
||||
mAnalyzingPeriod,
|
||||
1 //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Find Support Bar based on Analyzing Bar ...
|
||||
result = bar.HasSupport(
|
||||
support //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
DrawSupport(support, ChartID(), 5);
|
||||
|
||||
//
|
||||
if (resistance.IsValid())
|
||||
{
|
||||
RemoveResistance(resistance);
|
||||
}
|
||||
|
||||
//
|
||||
// Find Resistance Bar based on Analyzing Bar ...
|
||||
result = bar.HasResistance(
|
||||
resistance //
|
||||
);
|
||||
|
||||
//
|
||||
DrawResistance(resistance, ChartID(), 5);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Reset Reqirements ...
|
||||
void ResetRequirements()
|
||||
{
|
||||
//
|
||||
if (IsSupportBreaked(support, false))
|
||||
{
|
||||
//
|
||||
RemoveSupport(support);
|
||||
support.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
if (IsResistanceBreaked(resistance, false))
|
||||
{
|
||||
//
|
||||
RemoveResistance(resistance);
|
||||
resistance.Clean();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
@@ -0,0 +1,446 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Class Library
|
||||
// --------------------------------------
|
||||
// Name: XSCXEMRNGStrategy
|
||||
// Description: provides all based classes for use ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// TODO: Complete this ...
|
||||
|
||||
//
|
||||
/// Imports ...
|
||||
#include "../Helpers/x-saherelm.xtm.helper.mq5"
|
||||
#include "../Helpers/x-saherelm.xstr.helper.mq5"
|
||||
#include "../Classes/x-saherelm.xstrategy.class.mq5"
|
||||
|
||||
//
|
||||
string XEMRNGStartegyToken = "XEMRNG";
|
||||
|
||||
//
|
||||
class XSCXEMRNGStrategy : public XSCBaseStrategy
|
||||
{
|
||||
//
|
||||
// Public ...
|
||||
public:
|
||||
//
|
||||
// Constructor(s) ...
|
||||
void XSCXEMRNGStrategy(
|
||||
//
|
||||
// Base ...
|
||||
string _symbol, // Trading Symbol
|
||||
ENUM_TIMEFRAMES _period, // Trading TimeFrame
|
||||
double _volume, // Voluem
|
||||
double _r2r, // Risk/Reward Ratio
|
||||
int _slippage, // Trader Slippage
|
||||
long _magicNumber, // Trader Magic Number
|
||||
bool _useTPSLAsPoint = false, // Converts TP and SL by Provided Points
|
||||
bool _forceMaxTPSLAsPoint = false, // Force Max TP and SL by Provided Points
|
||||
double _tpPoint = 0, // TP As Point
|
||||
double _slPoint = 0, // SL As Point
|
||||
bool _allowLong = true,
|
||||
bool _allowShort = true,
|
||||
int _maxAllowedLongs = 0,
|
||||
int _maxAllowedShorts = 0 //
|
||||
) : XSCBaseStrategy(_symbol,
|
||||
_period,
|
||||
_volume,
|
||||
_r2r,
|
||||
_slippage,
|
||||
_magicNumber,
|
||||
_useTPSLAsPoint,
|
||||
_forceMaxTPSLAsPoint,
|
||||
_tpPoint,
|
||||
_slPoint,
|
||||
_allowLong,
|
||||
_allowShort,
|
||||
_maxAllowedLongs,
|
||||
_maxAllowedShorts //
|
||||
)
|
||||
{
|
||||
//
|
||||
ConfigureRequirements();
|
||||
|
||||
//
|
||||
SetAlertPrefix(GetTag());
|
||||
}
|
||||
|
||||
//
|
||||
// Deconstructor ...
|
||||
void ~XSCXEMRNGStrategy()
|
||||
{
|
||||
delete mTMHelper;
|
||||
}
|
||||
|
||||
//
|
||||
// Getter / Setter (s) ...
|
||||
|
||||
//
|
||||
// Overrides ...
|
||||
|
||||
//
|
||||
// Customize Strategy Identifier ...
|
||||
string GetTag() override
|
||||
{
|
||||
return XEMRNGStartegyToken;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Conditions For Signal ...
|
||||
bool HasSignal(
|
||||
XSignal &signal //
|
||||
) override
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
signal.Clean();
|
||||
|
||||
//
|
||||
double sl = 0;
|
||||
double tp = 0;
|
||||
double risk = 0;
|
||||
double entry = 0;
|
||||
double reward = 0;
|
||||
double r2r = R2R();
|
||||
ENUM_POSITION_TYPE type = POSITION_TYPE_BUY;
|
||||
ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET;
|
||||
|
||||
//
|
||||
int start = 0;
|
||||
int count = 5;
|
||||
|
||||
//
|
||||
double tms[];
|
||||
ArraySetAsSeries(tms, true);
|
||||
mTMHelper.CopyMain(
|
||||
start,
|
||||
count,
|
||||
tms //
|
||||
);
|
||||
|
||||
//
|
||||
XSTRConditions strConditions;
|
||||
result = mSTRHelper.GetConditions(
|
||||
strConditions,
|
||||
start,
|
||||
count //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
XOHCL cBar;
|
||||
result = cBar.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
1 //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double hh5 = cBar.FindHighest(
|
||||
5,
|
||||
MODE_HIGH //
|
||||
);
|
||||
double ll5 = cBar.FindLowest(
|
||||
5,
|
||||
MODE_LOW //
|
||||
);
|
||||
|
||||
//
|
||||
XOHCL pBar;
|
||||
result = cBar.GetPreviousBar(pBar);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool hasLong = false;
|
||||
bool hasShort = false;
|
||||
|
||||
//
|
||||
XOHCL tmpHSW[];
|
||||
XOHCL tmpLSW[];
|
||||
|
||||
//
|
||||
bool useHammer = true;
|
||||
bool useMorningStar = false;
|
||||
bool useBullishEngulfing = true;
|
||||
bool useBullishMaurubozu = true;
|
||||
|
||||
//
|
||||
bool useShootingStar = true;
|
||||
bool useEveningStar = false;
|
||||
bool useBearishEngulfing = true;
|
||||
bool useBearishMaurubozu = true;
|
||||
|
||||
//
|
||||
// Long ...
|
||||
|
||||
//
|
||||
bool isHammer = !useHammer
|
||||
? false
|
||||
: cBar.IsHammer();
|
||||
bool isMorningStar = !useMorningStar
|
||||
? false
|
||||
: cBar.IsMorningStar();
|
||||
bool isBullishMarubozu = !useBullishEngulfing
|
||||
? false
|
||||
: cBar.IsBullishMarubozu();
|
||||
bool isBullishEngulfing = !useBullishMaurubozu
|
||||
? false
|
||||
: cBar.IsBullishEngulfing();
|
||||
|
||||
//
|
||||
bool isBullishTrend = cBar.HasBullishTrend(
|
||||
tmpHSW,
|
||||
tmpLSW,
|
||||
true //
|
||||
);
|
||||
|
||||
//
|
||||
// Find Swing Low Above of EMA ...
|
||||
// Find Swing High Above of EMA ...
|
||||
// Fins Swing Low Below of EMA ...
|
||||
// Detect Bullish Pattern ...
|
||||
hasLong =
|
||||
//
|
||||
cBar.IsBullish()
|
||||
//
|
||||
&&
|
||||
//
|
||||
isBullishTrend
|
||||
//
|
||||
&&
|
||||
//
|
||||
cBar.close > tms[1]
|
||||
//
|
||||
&&
|
||||
//
|
||||
ll5 < tms[1]
|
||||
//
|
||||
&&
|
||||
//
|
||||
strConditions.isTrendSwitchedToBullish
|
||||
//
|
||||
&&
|
||||
//
|
||||
(
|
||||
//
|
||||
isHammer
|
||||
//
|
||||
||
|
||||
//
|
||||
isMorningStar
|
||||
//
|
||||
||
|
||||
//
|
||||
isBullishMarubozu
|
||||
//
|
||||
||
|
||||
//
|
||||
isBullishEngulfing
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
if (hasLong)
|
||||
{
|
||||
//
|
||||
type = POSITION_TYPE_BUY;
|
||||
|
||||
//
|
||||
sl = tmpLSW[ArraySize(tmpLSW) - 1].low;
|
||||
}
|
||||
|
||||
//
|
||||
// Short ...
|
||||
bool isShootingStar = !useShootingStar
|
||||
? false
|
||||
: cBar.IsShootingStar();
|
||||
bool isEveningStar = !useEveningStar
|
||||
? false
|
||||
: cBar.IsEveningStar();
|
||||
bool isBearishEngulfing = !useBearishEngulfing
|
||||
? false
|
||||
: cBar.IsBearishEngulfing();
|
||||
bool isBearishMaurubozu = !useBearishMaurubozu
|
||||
? false
|
||||
: cBar.IsBearishMarubozu();
|
||||
|
||||
//
|
||||
bool isBearishTrend = cBar.HasBearishTrend(
|
||||
tmpHSW,
|
||||
tmpLSW,
|
||||
true //
|
||||
);
|
||||
|
||||
//
|
||||
hasShort =
|
||||
//
|
||||
cBar.IsBearish()
|
||||
//
|
||||
&&
|
||||
//
|
||||
isBearishTrend
|
||||
//
|
||||
&&
|
||||
//
|
||||
cBar.close < tms[1]
|
||||
//
|
||||
&&
|
||||
//
|
||||
hh5 > tms[1]
|
||||
//
|
||||
&&
|
||||
//
|
||||
strConditions.isTrendSwitchedToBearish
|
||||
//
|
||||
&&
|
||||
//
|
||||
(
|
||||
//
|
||||
isShootingStar
|
||||
//
|
||||
||
|
||||
//
|
||||
isEveningStar
|
||||
//
|
||||
||
|
||||
//
|
||||
isBearishEngulfing
|
||||
//
|
||||
||
|
||||
//
|
||||
isBearishMaurubozu
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
if (hasShort)
|
||||
{
|
||||
//
|
||||
type = POSITION_TYPE_SELL;
|
||||
|
||||
//
|
||||
sl = tmpHSW[ArraySize(tmpHSW) - 1].high;
|
||||
}
|
||||
|
||||
//
|
||||
result = hasLong || hasShort;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
entry = GetEntry(mSymbol, type);
|
||||
CalculateTPSLByPrice(
|
||||
sl,
|
||||
tp,
|
||||
type,
|
||||
entry,
|
||||
r2r //
|
||||
);
|
||||
|
||||
//
|
||||
result = signal.Prepare(
|
||||
mSymbol,
|
||||
GetTag(),
|
||||
mPeriod,
|
||||
type,
|
||||
mode,
|
||||
entry,
|
||||
mVolume,
|
||||
sl,
|
||||
tp //
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Protected ...
|
||||
protected:
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
XTMInputs mTMInputs; // Tren Magic Inputs ...
|
||||
XSCXTMHelper *mTMHelper; // Trend Magic Helper Class ...
|
||||
|
||||
//
|
||||
XSTRInputs mSTRInputs; // Super Trend Inputs ...
|
||||
XSCXSTRHelper *mSTRHelper; // Super Trend Helper Class ...
|
||||
|
||||
//
|
||||
// Private ...
|
||||
private:
|
||||
//
|
||||
|
||||
//
|
||||
// Set Default TM Inputs ...
|
||||
void ConfigureRequirements()
|
||||
{
|
||||
//
|
||||
mTMInputs.maShift = 0;
|
||||
mTMInputs.maPeriod = 100;
|
||||
mTMInputs.maMethod = MODE_EMA;
|
||||
mTMInputs.maAppliedTo = PRICE_CLOSE;
|
||||
|
||||
//
|
||||
mTMInputs.showLine = true;
|
||||
|
||||
//
|
||||
mTMHelper = new XSCXTMHelper();
|
||||
|
||||
//
|
||||
mTMHelper.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
mTMInputs //
|
||||
);
|
||||
|
||||
//
|
||||
mSTRInputs.length = 14;
|
||||
mSTRInputs.multiplier = 3.5;
|
||||
mSTRInputs.appliedTo = PRICE_CLOSE;
|
||||
|
||||
//
|
||||
mSTRInputs.showTrends = true;
|
||||
mSTRInputs.fillTrends = false;
|
||||
|
||||
//
|
||||
mSTRHelper = new XSCXSTRHelper();
|
||||
mSTRHelper.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
mSTRInputs //
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,384 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center XNNTest MQL5 Expert Advisor
|
||||
// -------------------------------------------------
|
||||
// Name: XNNTest
|
||||
// Description: an Exper Advisor which used RSI and MA
|
||||
// to Analyse Market ...
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////x
|
||||
//
|
||||
// Global Properties ...
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XNNTest"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../Classes/x-saherelm.xtrade.class.mq5"
|
||||
|
||||
//
|
||||
#define ShortName "XNNTest"
|
||||
|
||||
//
|
||||
// Inputs ...
|
||||
input group "Weights";
|
||||
input double w0 = 0.5;
|
||||
input double w1 = 0.5;
|
||||
input double w2 = 0.5;
|
||||
input double w3 = 0.5;
|
||||
input double w4 = 0.5;
|
||||
input double w5 = 0.5;
|
||||
input double w6 = 0.5;
|
||||
input double w7 = 0.5;
|
||||
input double w8 = 0.5;
|
||||
input double w9 = 0.5;
|
||||
|
||||
//
|
||||
input double eaVolume = 0.01;
|
||||
|
||||
//
|
||||
// Variables ...
|
||||
int barsTotal;
|
||||
|
||||
//
|
||||
string eaSymbol;
|
||||
ENUM_TIMEFRAMES eaPeriod;
|
||||
|
||||
//
|
||||
// This is our Data Provider ...
|
||||
int rsiHandler = INVALID_HANDLE;
|
||||
double rsi[];
|
||||
|
||||
//
|
||||
double nnInputs[]; // Storing Inputs
|
||||
double nnWeights[]; // Storing Weights;
|
||||
|
||||
//
|
||||
double nnOutput; // Output Neuron Value
|
||||
|
||||
//
|
||||
XSCTrade *mTrader;
|
||||
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
if (!InitialEA())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// De Initialize XSampleEA Providers ...
|
||||
IndicatorRelease(rsiHandler);
|
||||
ArrayFree(rsi);
|
||||
ArrayFree(nnInputs);
|
||||
ArrayFree(nnWeights);
|
||||
}
|
||||
|
||||
//
|
||||
// On Tick Handler ...
|
||||
void OnTick()
|
||||
{
|
||||
//
|
||||
XPosition positions[];
|
||||
|
||||
//
|
||||
XPosition longs[];
|
||||
int longsCount = 0;
|
||||
|
||||
//
|
||||
XPosition shorts[];
|
||||
int shortsCount = 0;
|
||||
|
||||
//
|
||||
int positionsCount = mTrader.GetPositions(
|
||||
positions //
|
||||
);
|
||||
if (IsValidSize(positionsCount))
|
||||
{
|
||||
//
|
||||
ExtractPositions(
|
||||
positions,
|
||||
longs,
|
||||
shorts //
|
||||
);
|
||||
|
||||
//
|
||||
longsCount = ArraySize(longs);
|
||||
shortsCount = ArraySize(shorts);
|
||||
}
|
||||
|
||||
//
|
||||
if (longsCount == 0 && shortsCount == 0)
|
||||
{
|
||||
//
|
||||
double longEntry = GetEntry(eaSymbol, POSITION_TYPE_BUY);
|
||||
mTrader.Buy(
|
||||
eaSymbol,
|
||||
eaPeriod,
|
||||
eaVolume,
|
||||
longEntry //
|
||||
);
|
||||
|
||||
//
|
||||
double shortEntry = GetEntry(eaSymbol, POSITION_TYPE_SELL);
|
||||
mTrader.Sell(
|
||||
eaSymbol,
|
||||
eaPeriod,
|
||||
eaVolume,
|
||||
shortEntry //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return;
|
||||
// int rsiCopiedData = CopyBuffer(
|
||||
// rsiHandler,
|
||||
// 0, // Line Index
|
||||
// 1, // BarIndex
|
||||
// 10, // Count
|
||||
// rsi // Buffer
|
||||
// );
|
||||
// if (rsiCopiedData < 0)
|
||||
// {
|
||||
// //
|
||||
// // Ignore Moving Forward when there isn't any Copied Data ...
|
||||
// return;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // Normalize Input Data ...
|
||||
// double lower = 0;
|
||||
// double upper = 1;
|
||||
|
||||
// //
|
||||
// double max = rsi[ArrayMaximum(rsi)];
|
||||
// double min = rsi[ArrayMinimum(rsi)];
|
||||
|
||||
// //
|
||||
// ArrayFree(nnInputs);
|
||||
// ArrayResize(nnInputs, 10);
|
||||
|
||||
// //
|
||||
// for (int i = 0; i < ArraySize(rsi); i++)
|
||||
// {
|
||||
// nnInputs[i] = ((rsi[i] - min) * (upper - lower) / (max - min)) + lower;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // Calculating Output ...
|
||||
// nnOutput = CalculateNeuron(
|
||||
// nnInputs,
|
||||
// nnWeights //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Now we Can Use NN Output for Placing Trades ...
|
||||
|
||||
// //
|
||||
// bool canBuy = nnOutput < 0.5;
|
||||
// bool canSell = nnOutput >= 0.5;
|
||||
|
||||
// //
|
||||
// XPosition positions[];
|
||||
// XPosition longs[];
|
||||
// XPosition shorts[];
|
||||
// int positionsCount = mTrader.GetPositions(
|
||||
// positions //
|
||||
// );
|
||||
// if (IsValidSize(positionsCount))
|
||||
// {
|
||||
// //
|
||||
// ExtractPositions(
|
||||
// positions,
|
||||
// longs,
|
||||
// shorts //
|
||||
// );
|
||||
|
||||
// //
|
||||
// if (canBuy)
|
||||
// {
|
||||
// //
|
||||
// mTrader.Close(shorts, "Opposit");
|
||||
|
||||
// //
|
||||
// if (ArraySize(longs) > 0)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// else if (canSell)
|
||||
// {
|
||||
// //
|
||||
// mTrader.Close(longs, "Opposit");
|
||||
|
||||
// //
|
||||
// if (ArraySize(shorts) > 0)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// //
|
||||
// double mEntry =
|
||||
// canBuy
|
||||
// ? GetEntry(eaSymbol, POSITION_TYPE_BUY)
|
||||
// : GetEntry(eaSymbol, POSITION_TYPE_SELL);
|
||||
|
||||
// //
|
||||
// if (canBuy)
|
||||
// {
|
||||
// //
|
||||
// mTrader.Buy(
|
||||
// eaSymbol,
|
||||
// eaPeriod,
|
||||
// eaVolume,
|
||||
// mEntry //
|
||||
// );
|
||||
// }
|
||||
// else if (canSell)
|
||||
// {
|
||||
// //
|
||||
// mTrader.Sell(
|
||||
// eaSymbol,
|
||||
// eaPeriod,
|
||||
// eaVolume,
|
||||
// mEntry //
|
||||
// );
|
||||
// }
|
||||
}
|
||||
|
||||
//
|
||||
// Custom Functions ...
|
||||
|
||||
//
|
||||
bool InitialEA()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
eaSymbol = _Symbol;
|
||||
eaPeriod = _Period;
|
||||
|
||||
//
|
||||
// Initialize RSI Handler ...
|
||||
rsiHandler = iRSI(
|
||||
eaSymbol,
|
||||
eaPeriod,
|
||||
14,
|
||||
PRICE_CLOSE //
|
||||
);
|
||||
result = rsiHandler != INVALID_HANDLE;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
mTrader = new XSCTrade(
|
||||
1,
|
||||
78692110 //
|
||||
);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(rsi, true);
|
||||
|
||||
//
|
||||
ArrayResize(nnWeights, 10);
|
||||
|
||||
//
|
||||
// Filling Weights Buffer ...
|
||||
nnWeights[0] = w0;
|
||||
nnWeights[1] = w1;
|
||||
nnWeights[2] = w2;
|
||||
nnWeights[3] = w3;
|
||||
nnWeights[4] = w4;
|
||||
nnWeights[5] = w5;
|
||||
nnWeights[6] = w6;
|
||||
nnWeights[7] = w7;
|
||||
nnWeights[8] = w8;
|
||||
nnWeights[9] = w9;
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Activation Function ...
|
||||
double Activate(double neuron)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
result = 1 / (1 + exp(-neuron));
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculating Neuron ...
|
||||
// NET Inputs ...
|
||||
double CalculateNeuron(
|
||||
double &x[], // Inputs
|
||||
double &w[] // Weights
|
||||
)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
double netInput = 0;
|
||||
for (int i = 0; i < ArraySize(x); i++)
|
||||
{
|
||||
//
|
||||
netInput += x[i] * w[i];
|
||||
}
|
||||
|
||||
//
|
||||
// Change The Shape of Sigmoid Graph for Smoothing ...
|
||||
netInput *= 0.4;
|
||||
|
||||
//
|
||||
// Calculate Activated Result ...
|
||||
result = Activate(netInput);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,678 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Class Library
|
||||
// ----------------------------------------------
|
||||
// Name: XADXTD
|
||||
// Description: provides Indicator implementation
|
||||
// requirements ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../Classes/x-saherelm.base.class.mq5"
|
||||
|
||||
//
|
||||
// Indicator Buffers ...
|
||||
enum ENUM_XADXTD_BUFFERS
|
||||
{
|
||||
XADXTD_STRENGTH_LINE = 0, // Strenght Buffer ...
|
||||
XADXTD_BULL_LINE = 1, // Bull Buffer ...
|
||||
XADXTD_BEAR_LINE = 2, // Bear Buffer ...
|
||||
};
|
||||
|
||||
//
|
||||
string GetTitle(ENUM_XADXTD_BUFFERS bufferLine)
|
||||
{
|
||||
//
|
||||
string result = NULL;
|
||||
|
||||
//
|
||||
switch (bufferLine)
|
||||
{
|
||||
//
|
||||
case XADXTD_STRENGTH_LINE:
|
||||
result = "XStrength";
|
||||
break;
|
||||
|
||||
//
|
||||
case XADXTD_BULL_LINE:
|
||||
result = "XBull";
|
||||
break;
|
||||
|
||||
//
|
||||
case XADXTD_BEAR_LINE:
|
||||
result = "XBear";
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// XADXTD Indicator Inputs ...
|
||||
struct XADXTDInputs
|
||||
{
|
||||
//
|
||||
// Props ...
|
||||
string version;
|
||||
|
||||
//
|
||||
// Market ...
|
||||
|
||||
//
|
||||
int length; // Length
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XADXTDInputs()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
//
|
||||
// Initial Inputs ...
|
||||
bool Init(
|
||||
int _length = 21 // Length
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
this.length = _length;
|
||||
|
||||
//
|
||||
result = IsValid();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
length = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Default ...
|
||||
void Default()
|
||||
{
|
||||
//
|
||||
length = 21;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
bool IsValid()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
length > 0
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve Max Length ...
|
||||
int Max()
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
int values[1] = {
|
||||
length //
|
||||
};
|
||||
|
||||
//
|
||||
result = GetMax(values);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Define Conditions ...
|
||||
struct XADXTDConditions
|
||||
{
|
||||
//
|
||||
// Common ...
|
||||
string symbol;
|
||||
ENUM_TIMEFRAMES period;
|
||||
datetime time;
|
||||
|
||||
//
|
||||
// Buffers ...
|
||||
double strength[];
|
||||
double bullp[];
|
||||
double bearp[];
|
||||
|
||||
//
|
||||
// Conditions ...
|
||||
|
||||
//
|
||||
bool isStrong;
|
||||
bool isBullish;
|
||||
bool isBearish;
|
||||
bool isSwitchedToBullish;
|
||||
bool isSwitchedToBearish;
|
||||
bool isStrongSwitchedToBullish;
|
||||
bool isStrongSwitchedToBearish;
|
||||
|
||||
//
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
Clean(strength);
|
||||
Clean(bullp);
|
||||
Clean(bearp);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(strength, true);
|
||||
ArraySetAsSeries(bullp, true);
|
||||
ArraySetAsSeries(bearp, true);
|
||||
|
||||
//
|
||||
isStrong = false;
|
||||
isBullish = false;
|
||||
isBearish = false;
|
||||
isSwitchedToBullish = false;
|
||||
isSwitchedToBearish = false;
|
||||
isStrongSwitchedToBullish = false;
|
||||
isStrongSwitchedToBearish = false;
|
||||
}
|
||||
|
||||
//
|
||||
void GenerateScore(
|
||||
double &bullishScore,
|
||||
double &bearishScore //
|
||||
)
|
||||
{
|
||||
//
|
||||
bullishScore = 0;
|
||||
bearishScore = 0;
|
||||
|
||||
//
|
||||
if (isBullish)
|
||||
{
|
||||
//
|
||||
bullishScore++;
|
||||
if (isStrong)
|
||||
{
|
||||
bullishScore++;
|
||||
}
|
||||
}
|
||||
if (isBearish)
|
||||
{
|
||||
bearishScore++;
|
||||
if (isStrong)
|
||||
{
|
||||
bearishScore++;
|
||||
}
|
||||
}
|
||||
if (isSwitchedToBullish)
|
||||
{
|
||||
bullishScore++;
|
||||
if (isStrong)
|
||||
{
|
||||
bullishScore++;
|
||||
}
|
||||
}
|
||||
if (isSwitchedToBearish)
|
||||
{
|
||||
bearishScore++;
|
||||
if (isStrong)
|
||||
{
|
||||
bearishScore++;
|
||||
}
|
||||
}
|
||||
if (isStrongSwitchedToBullish)
|
||||
{
|
||||
bullishScore++;
|
||||
}
|
||||
if (isStrongSwitchedToBearish)
|
||||
{
|
||||
bearishScore++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
string GenerateSummary(
|
||||
bool onlyCommons = false,
|
||||
bool onlyConditions = false,
|
||||
bool includeScores = true,
|
||||
bool ignoreFalseConditions = true,
|
||||
string separator = "\n" //
|
||||
)
|
||||
{
|
||||
//
|
||||
string result = NULL;
|
||||
|
||||
//
|
||||
double bullishScore = 0;
|
||||
double bearishScore = 0;
|
||||
GenerateScore(
|
||||
bullishScore,
|
||||
bearishScore //
|
||||
);
|
||||
|
||||
//
|
||||
string scoresStr =
|
||||
//
|
||||
"Scores: " + separator +
|
||||
"---------------" + separator +
|
||||
"Bullish: " + ToString(bullishScore) + separator +
|
||||
"Bearish: " + ToString(bearishScore) + separator +
|
||||
""
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
string commonStr = GenerateSpecifiedCommonSummary(
|
||||
this,
|
||||
separator,
|
||||
includeScores //
|
||||
);
|
||||
|
||||
//
|
||||
string conditionsStr =
|
||||
//
|
||||
ToString("isStrong", isStrong, ignoreFalseConditions, separator) +
|
||||
ToString("isBullish", isBullish, ignoreFalseConditions, separator) +
|
||||
ToString("isBearish", isBearish, ignoreFalseConditions, separator) +
|
||||
ToString("isSwitchedToBullish", isSwitchedToBullish, ignoreFalseConditions, separator) +
|
||||
ToString("isSwitchedToBearish", isSwitchedToBearish, ignoreFalseConditions, separator) +
|
||||
ToString("isStrongSwitchedToBullish", isStrongSwitchedToBullish, ignoreFalseConditions, separator) +
|
||||
ToString("isStrongSwitchedToBearish", isStrongSwitchedToBearish, ignoreFalseConditions, separator) +
|
||||
""
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
"[" + GetTag() + "]" + separator +
|
||||
(onlyConditions
|
||||
? ""
|
||||
: commonStr) +
|
||||
(!includeScores
|
||||
? ""
|
||||
: scoresStr) +
|
||||
" " + separator +
|
||||
(onlyCommons
|
||||
? ""
|
||||
: conditionsStr) +
|
||||
""
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
string GetTag()
|
||||
{
|
||||
return "XADXTD";
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Indicator Class ...
|
||||
|
||||
class XSCXADXTDHelper : public XSCBase
|
||||
{
|
||||
//
|
||||
// Public ...
|
||||
public:
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
// Constructor(s) ...
|
||||
void XSCXADXTDHelper(
|
||||
string symbol, // Trading Symbol
|
||||
ENUM_TIMEFRAMES period // Trading TimeFrame
|
||||
)
|
||||
{
|
||||
//
|
||||
mSymbol = symbol;
|
||||
mPeriod = period;
|
||||
}
|
||||
|
||||
//
|
||||
// Deconstructor ...
|
||||
void ~XSCXADXTDHelper() {}
|
||||
|
||||
//
|
||||
// Initialize Indicator ...
|
||||
bool Init(
|
||||
XADXTDInputs &inputs // Indicator Properties
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = inputs.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Set Inputs ...
|
||||
this.mInputs = inputs;
|
||||
|
||||
//
|
||||
// Validate Indicator State ...
|
||||
result = this.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = DefineBuffers();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
handler = iADX(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
mInputs.length //
|
||||
);
|
||||
result = handler != INVALID_HANDLE;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
XADXTDInputs GetInputs()
|
||||
{
|
||||
return mInputs;
|
||||
}
|
||||
|
||||
//
|
||||
bool SetInputs(
|
||||
XADXTDInputs &inputs // Indicator Properties
|
||||
)
|
||||
{
|
||||
return Init(inputs);
|
||||
}
|
||||
|
||||
//
|
||||
// Get Tag ...
|
||||
string GetTag()
|
||||
{
|
||||
//
|
||||
string result = NULL;
|
||||
|
||||
//
|
||||
result = GetToken();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Get Token ...
|
||||
string GetToken()
|
||||
{
|
||||
//
|
||||
string result = NULL;
|
||||
|
||||
//
|
||||
result = GetSpecificToken(this);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
string GetSymbol()
|
||||
{
|
||||
return mSymbol;
|
||||
}
|
||||
|
||||
//
|
||||
ENUM_TIMEFRAMES GetPeriod()
|
||||
{
|
||||
return mPeriod;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
bool IsValid()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
mInputs.IsValid() &&
|
||||
IsSpecifiedValid(mPeriod) &&
|
||||
IsSpecifiedValid(mSymbol)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// De Initialize Class ...
|
||||
void DeInit(int reason)
|
||||
{
|
||||
//
|
||||
IndicatorRelease(handler);
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
int CopyData(
|
||||
ENUM_XADXTD_BUFFERS line,
|
||||
double &dest[],
|
||||
int start = 0,
|
||||
int count = 1 //
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
int mLine = -1;
|
||||
switch (line)
|
||||
{
|
||||
//
|
||||
case XADXTD_STRENGTH_LINE:
|
||||
mLine = MAIN_LINE;
|
||||
break;
|
||||
|
||||
//
|
||||
case XADXTD_BULL_LINE:
|
||||
mLine = PLUSDI_LINE;
|
||||
break;
|
||||
|
||||
//
|
||||
case XADXTD_BEAR_LINE:
|
||||
mLine = MINUSDI_LINE;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
if (mLine == -1 || handler == INVALID_HANDLE)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = CopyBuffer(
|
||||
handler,
|
||||
mLine,
|
||||
start,
|
||||
count,
|
||||
dest //
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool GetConditions(
|
||||
XADXTDConditions &conditions, //
|
||||
int barIndex = 0, //
|
||||
int loopback = 3 //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = true;
|
||||
|
||||
//
|
||||
if (loopback < 3)
|
||||
{
|
||||
loopback = 3;
|
||||
}
|
||||
|
||||
//
|
||||
conditions.Clean();
|
||||
|
||||
//
|
||||
conditions.symbol = mSymbol;
|
||||
conditions.period = mPeriod;
|
||||
conditions.time = TimeCurrent();
|
||||
|
||||
//
|
||||
int zIndex = barIndex;
|
||||
int cIndex = zIndex + 1;
|
||||
int pIndex = cIndex + 1;
|
||||
int ppIndex = pIndex + 1;
|
||||
|
||||
//
|
||||
CopyData(
|
||||
XADXTD_STRENGTH_LINE,
|
||||
conditions.strength,
|
||||
zIndex,
|
||||
loopback //
|
||||
);
|
||||
CopyData(
|
||||
XADXTD_BULL_LINE,
|
||||
conditions.bullp,
|
||||
zIndex,
|
||||
loopback //
|
||||
);
|
||||
CopyData(
|
||||
XADXTD_BEAR_LINE,
|
||||
conditions.bearp,
|
||||
zIndex,
|
||||
loopback //
|
||||
);
|
||||
|
||||
//
|
||||
// Calculate Conditions ...
|
||||
|
||||
//
|
||||
bool isStrong = conditions.strength[cIndex] >= 20;
|
||||
|
||||
//
|
||||
bool isBullish = conditions.bullp[cIndex] > conditions.bearp[cIndex];
|
||||
bool isBearish = conditions.bearp[cIndex] > conditions.bullp[cIndex];
|
||||
|
||||
//
|
||||
bool isBullishPrev = conditions.bullp[pIndex] > conditions.bearp[pIndex];
|
||||
bool isBearishPrev = conditions.bearp[pIndex] > conditions.bullp[pIndex];
|
||||
|
||||
//
|
||||
bool isSwitchedToBullish = isBullish &&
|
||||
!isBullishPrev;
|
||||
bool isSwitchedToBearish = isBearish &&
|
||||
!isBearishPrev;
|
||||
|
||||
//
|
||||
bool isStrongSwitchedToBullish = isStrong &&
|
||||
isSwitchedToBullish;
|
||||
bool isStrongSwitchedToBearish = isStrong &&
|
||||
isSwitchedToBearish;
|
||||
|
||||
//
|
||||
conditions.isStrong = isStrong;
|
||||
conditions.isBullish = isBullish;
|
||||
conditions.isBearish = isBearish;
|
||||
conditions.isSwitchedToBullish = isSwitchedToBullish;
|
||||
conditions.isSwitchedToBearish = isSwitchedToBearish;
|
||||
conditions.isStrongSwitchedToBullish = isStrongSwitchedToBullish;
|
||||
conditions.isStrongSwitchedToBearish = isStrongSwitchedToBearish;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Protected ...
|
||||
protected:
|
||||
//
|
||||
// Props ...
|
||||
int handler;
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
bool DefineBuffers()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Private ...
|
||||
private:
|
||||
//
|
||||
// Props ...
|
||||
//
|
||||
string mSymbol; // Symbol
|
||||
ENUM_TIMEFRAMES mPeriod; // TimeFrame
|
||||
|
||||
//
|
||||
XADXTDInputs mInputs; // Properties
|
||||
};
|
||||
|
||||
//
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,766 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Class Library
|
||||
// --------------------------------------
|
||||
// Name: XSCXOBVGStrategy
|
||||
// Description: provides all based classes for use ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
/// Imports ...
|
||||
#include "../Helpers/x-saherelm.xtm.helper.mq5"
|
||||
#include "../Helpers/x-saherelm.xstr.helper.mq5"
|
||||
#include "../Classes/x-saherelm.xstrategy.class.mq5"
|
||||
|
||||
//
|
||||
string XOBVGStartegyToken = "XOBVG";
|
||||
|
||||
//
|
||||
class XSCXOBVGStrategy : public XSCBaseStrategy
|
||||
{
|
||||
//
|
||||
// Public ...
|
||||
public:
|
||||
//
|
||||
// Constructor(s) ...
|
||||
void XSCXOBVGStrategy(
|
||||
//
|
||||
// Base ...
|
||||
string _symbol, // Trading Symbol
|
||||
ENUM_TIMEFRAMES _period, // Trading TimeFrame
|
||||
ENUM_TIMEFRAMES _hindPeriod, // Hind Period
|
||||
ENUM_TIMEFRAMES _mediestPeriod, // Mediest Period
|
||||
double _volume, // Voluem
|
||||
double _r2r, // Risk/Reward Ratio
|
||||
int _slippage, // Trader Slippage
|
||||
long _magicNumber, // Trader Magic Number
|
||||
bool _useTPSLAsPoint = false, // Converts TP and SL by Provided Points
|
||||
bool _forceMaxTPSLAsPoint = false, // Force Max TP and SL by Provided Points
|
||||
double _tpPoint = 0, // TP As Point
|
||||
double _slPoint = 0, // SL As Point
|
||||
bool _allowLong = true,
|
||||
bool _allowShort = true,
|
||||
int _maxAllowedLongs = 0,
|
||||
int _maxAllowedShorts = 0 //
|
||||
) : XSCBaseStrategy(_symbol,
|
||||
_period,
|
||||
_volume,
|
||||
_r2r,
|
||||
_slippage,
|
||||
_magicNumber,
|
||||
_useTPSLAsPoint,
|
||||
_forceMaxTPSLAsPoint,
|
||||
_tpPoint,
|
||||
_slPoint,
|
||||
_allowLong,
|
||||
_allowShort,
|
||||
_maxAllowedLongs,
|
||||
_maxAllowedShorts //
|
||||
)
|
||||
{
|
||||
//
|
||||
mHindPeriod = _hindPeriod;
|
||||
mMediestPeriod = _mediestPeriod;
|
||||
|
||||
//
|
||||
SetAlertPrefix(GetTag());
|
||||
|
||||
//
|
||||
hindBar.Clean();
|
||||
hindBullishOrderBlock.Clean();
|
||||
hindBearishOrderBlock.Clean();
|
||||
|
||||
//
|
||||
medBar.Clean();
|
||||
medBullishOrderBlock.Clean();
|
||||
medBearishOrderBlock.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Deconstructor ...
|
||||
void ~XSCXOBVGStrategy()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Getter / Setter (s) ...
|
||||
|
||||
//
|
||||
ENUM_TIMEFRAMES HindPeriod()
|
||||
{
|
||||
return mHindPeriod;
|
||||
}
|
||||
|
||||
//
|
||||
void HindPeriod(ENUM_TIMEFRAMES value)
|
||||
{
|
||||
mHindPeriod = value;
|
||||
}
|
||||
|
||||
//
|
||||
ENUM_TIMEFRAMES MediestPeriod()
|
||||
{
|
||||
return mMediestPeriod;
|
||||
}
|
||||
|
||||
//
|
||||
void MediestPeriod(ENUM_TIMEFRAMES value)
|
||||
{
|
||||
mMediestPeriod = value;
|
||||
}
|
||||
|
||||
//
|
||||
// Overrides ...
|
||||
|
||||
//
|
||||
// Customize Strategy Identifier ...
|
||||
string GetTag() override
|
||||
{
|
||||
return XOBVGStartegyToken;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Conditions For Signal ...
|
||||
bool HasSignal(
|
||||
XSignal &signal //
|
||||
) override
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
signal.Clean();
|
||||
|
||||
//
|
||||
double sl = 0;
|
||||
double tp = 0;
|
||||
double risk = 0;
|
||||
double entry = 0;
|
||||
double reward = 0;
|
||||
double r2r = R2R();
|
||||
ENUM_POSITION_TYPE type = POSITION_TYPE_BUY;
|
||||
ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET;
|
||||
|
||||
//
|
||||
bool hasLong = false;
|
||||
bool hasShort = false;
|
||||
|
||||
//
|
||||
XOHCL tmpHSW[];
|
||||
XOHCL tmpLSW[];
|
||||
|
||||
//
|
||||
bool useHammer = true;
|
||||
bool useMorningStar = false;
|
||||
bool useBullishEngulfing = true;
|
||||
bool useBullishMaurubozu = true;
|
||||
|
||||
//
|
||||
bool useShootingStar = true;
|
||||
bool useEveningStar = false;
|
||||
bool useBearishEngulfing = true;
|
||||
bool useBearishMaurubozu = true;
|
||||
|
||||
//
|
||||
XOHCL cBar;
|
||||
result = cBar.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
1 //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double ll3 = cBar.FindLowest(
|
||||
3,
|
||||
MODE_LOW //
|
||||
);
|
||||
double hh3 = cBar.FindHighest(
|
||||
3,
|
||||
MODE_HIGH //
|
||||
);
|
||||
|
||||
//
|
||||
result = hindBar.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
result = hindBar.Init(
|
||||
mSymbol,
|
||||
mHindPeriod,
|
||||
1 //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
bool hasBullishOrderBlock = hindBullishOrderBlock.IsValid();
|
||||
bool hasBearishOrderBlock = hindBearishOrderBlock.IsValid();
|
||||
result =
|
||||
//
|
||||
hasBullishOrderBlock
|
||||
//
|
||||
||
|
||||
//
|
||||
hasBearishOrderBlock
|
||||
//
|
||||
;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
hasBullishOrderBlock = hindBar.HasBullishOrderBlock(hindBullishOrderBlock);
|
||||
hasBearishOrderBlock = hindBar.HasBearishOrderBlock(hindBearishOrderBlock);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
hasBullishOrderBlock
|
||||
//
|
||||
||
|
||||
//
|
||||
hasBearishOrderBlock
|
||||
//
|
||||
;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
hindBar.Clean();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (hasBullishOrderBlock)
|
||||
{
|
||||
//
|
||||
DrawBullishOrderBlock(
|
||||
hindBullishOrderBlock,
|
||||
ChartID() //
|
||||
);
|
||||
|
||||
//
|
||||
// Try to Detect and Order Block Inside this ...
|
||||
// in Mediest ...
|
||||
result = medBar.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
result = medBar.Init(
|
||||
mSymbol,
|
||||
mMediestPeriod,
|
||||
1 //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
medBar.Clean();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result = medBar.HasBullishOrderBlock(medBullishOrderBlock);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
medBar.Clean();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
DrawBullishOrderBlock(
|
||||
medBullishOrderBlock,
|
||||
ChartID() //
|
||||
);
|
||||
|
||||
//
|
||||
// Check Order Block Is Inside HINDOB ...
|
||||
result =
|
||||
//
|
||||
(medBullishOrderBlock.low >= hindBullishOrderBlock.low &&
|
||||
medBullishOrderBlock.low <= hindBullishOrderBlock.high)
|
||||
//
|
||||
||
|
||||
//
|
||||
(medBullishOrderBlock.high <= hindBullishOrderBlock.high &&
|
||||
medBullishOrderBlock.high >= hindBullishOrderBlock.low)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
// Check Price ...
|
||||
result =
|
||||
//
|
||||
ll3 < medBullishOrderBlock.high &&
|
||||
ll3 > hindBullishOrderBlock.low
|
||||
//
|
||||
;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
hindBar.Clean();
|
||||
hindBullishOrderBlock.Clean();
|
||||
hindBearishOrderBlock.Clean();
|
||||
|
||||
//
|
||||
medBar.Clean();
|
||||
medBullishOrderBlock.Clean();
|
||||
medBearishOrderBlock.Clean();
|
||||
|
||||
//
|
||||
fvgUpper = 0;
|
||||
fvgLower = 0;
|
||||
|
||||
//
|
||||
RemoveDraws();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
hasLong = result;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Detect and FVG Inside ...
|
||||
result = medBar.HasBullishFVG(
|
||||
fvgUpper,
|
||||
fvgLower //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
hindBar.Clean();
|
||||
hindBullishOrderBlock.Clean();
|
||||
hindBearishOrderBlock.Clean();
|
||||
|
||||
//
|
||||
medBar.Clean();
|
||||
medBullishOrderBlock.Clean();
|
||||
medBearishOrderBlock.Clean();
|
||||
|
||||
//
|
||||
fvgUpper = 0;
|
||||
fvgLower = 0;
|
||||
|
||||
//
|
||||
RemoveDraws();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
DrawBullishFVG(
|
||||
medBar,
|
||||
fvgUpper,
|
||||
fvgLower,
|
||||
ChartID() //
|
||||
);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
(fvgLower >= hindBullishOrderBlock.low &&
|
||||
fvgLower <= hindBullishOrderBlock.high)
|
||||
//
|
||||
||
|
||||
//
|
||||
(fvgUpper <= hindBullishOrderBlock.high &&
|
||||
fvgUpper >= hindBullishOrderBlock.low)
|
||||
//
|
||||
;
|
||||
//
|
||||
// Check Price ...
|
||||
result =
|
||||
//
|
||||
ll3 < fvgUpper &&
|
||||
ll3 > hindBullishOrderBlock.low
|
||||
//
|
||||
;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
hindBar.Clean();
|
||||
hindBullishOrderBlock.Clean();
|
||||
hindBearishOrderBlock.Clean();
|
||||
|
||||
//
|
||||
medBar.Clean();
|
||||
medBullishOrderBlock.Clean();
|
||||
medBearishOrderBlock.Clean();
|
||||
|
||||
//
|
||||
fvgUpper = 0;
|
||||
fvgLower = 0;
|
||||
|
||||
//
|
||||
RemoveDraws();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
hasLong = result;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (hasBearishOrderBlock)
|
||||
{
|
||||
//
|
||||
DrawBearishOrderBlock(
|
||||
hindBearishOrderBlock,
|
||||
ChartID() //
|
||||
);
|
||||
|
||||
//
|
||||
// Try to Detect and Order Block Inside this ...
|
||||
// in Mediest ...
|
||||
result = medBar.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
result = medBar.Init(
|
||||
mSymbol,
|
||||
mMediestPeriod,
|
||||
1 //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
medBar.Clean();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result = medBar.HasBearishOrderBlock(medBearishOrderBlock);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
medBar.Clean();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
DrawBearishOrderBlock(
|
||||
medBearishOrderBlock,
|
||||
ChartID() //
|
||||
);
|
||||
|
||||
//
|
||||
// Check Order Block Is Inside HINDOB ...
|
||||
result =
|
||||
//
|
||||
(medBullishOrderBlock.low >= hindBearishOrderBlock.low &&
|
||||
medBearishOrderBlock.low <= hindBearishOrderBlock.high)
|
||||
//
|
||||
||
|
||||
//
|
||||
(medBearishOrderBlock.high <= hindBearishOrderBlock.high &&
|
||||
medBearishOrderBlock.high >= hindBearishOrderBlock.low)
|
||||
//
|
||||
;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
// Detect and FVG Inside ...
|
||||
result = medBar.HasBearishFVG(
|
||||
fvgUpper,
|
||||
fvgLower //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
hindBar.Clean();
|
||||
hindBullishOrderBlock.Clean();
|
||||
hindBearishOrderBlock.Clean();
|
||||
|
||||
//
|
||||
medBar.Clean();
|
||||
medBullishOrderBlock.Clean();
|
||||
medBearishOrderBlock.Clean();
|
||||
|
||||
//
|
||||
fvgUpper = 0;
|
||||
fvgLower = 0;
|
||||
|
||||
//
|
||||
RemoveDraws();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
DrawBearishFVG(
|
||||
medBar,
|
||||
fvgUpper,
|
||||
fvgLower,
|
||||
ChartID() //
|
||||
);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
(fvgLower >= hindBearishOrderBlock.low &&
|
||||
fvgLower <= hindBearishOrderBlock.high)
|
||||
//
|
||||
||
|
||||
//
|
||||
(fvgUpper <= hindBearishOrderBlock.high &&
|
||||
fvgUpper >= hindBearishOrderBlock.low)
|
||||
//
|
||||
;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
hindBar.Clean();
|
||||
hindBullishOrderBlock.Clean();
|
||||
hindBearishOrderBlock.Clean();
|
||||
|
||||
//
|
||||
medBar.Clean();
|
||||
medBullishOrderBlock.Clean();
|
||||
medBearishOrderBlock.Clean();
|
||||
|
||||
//
|
||||
fvgUpper = 0;
|
||||
fvgLower = 0;
|
||||
|
||||
//
|
||||
RemoveDraws();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result = hasLong || hasShort;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
if (hasLong)
|
||||
{
|
||||
//
|
||||
// Long ...
|
||||
|
||||
//
|
||||
bool isHammer = !useHammer
|
||||
? false
|
||||
: cBar.IsHammer();
|
||||
bool isMorningStar = !useMorningStar
|
||||
? false
|
||||
: cBar.IsMorningStar();
|
||||
bool isBullishMarubozu = !useBullishEngulfing
|
||||
? false
|
||||
: cBar.IsBullishMarubozu();
|
||||
bool isBullishEngulfing = !useBullishMaurubozu
|
||||
? false
|
||||
: cBar.IsBullishEngulfing();
|
||||
|
||||
//
|
||||
bool isBullishTrend = cBar.HasBullishTrend(
|
||||
tmpHSW,
|
||||
tmpLSW,
|
||||
true //
|
||||
);
|
||||
|
||||
//
|
||||
// Find Swing Low Above of EMA ...
|
||||
// Find Swing High Above of EMA ...
|
||||
// Fins Swing Low Below of EMA ...
|
||||
// Detect Bullish Pattern ...
|
||||
hasLong =
|
||||
//
|
||||
true
|
||||
//
|
||||
&&
|
||||
//
|
||||
(
|
||||
//
|
||||
isHammer
|
||||
//
|
||||
||
|
||||
//
|
||||
isMorningStar
|
||||
//
|
||||
||
|
||||
//
|
||||
isBullishMarubozu
|
||||
//
|
||||
||
|
||||
//
|
||||
isBullishEngulfing
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
if (hasLong)
|
||||
{
|
||||
//
|
||||
type = POSITION_TYPE_BUY;
|
||||
|
||||
//
|
||||
// sl = tmpLSW[ArraySize(tmpLSW) - 1].low;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (hasShort)
|
||||
{
|
||||
//
|
||||
// Short ...
|
||||
bool isShootingStar = !useShootingStar
|
||||
? false
|
||||
: cBar.IsShootingStar();
|
||||
bool isEveningStar = !useEveningStar
|
||||
? false
|
||||
: cBar.IsEveningStar();
|
||||
bool isBearishEngulfing = !useBearishEngulfing
|
||||
? false
|
||||
: cBar.IsBearishEngulfing();
|
||||
bool isBearishMaurubozu = !useBearishMaurubozu
|
||||
? false
|
||||
: cBar.IsBearishMarubozu();
|
||||
|
||||
//
|
||||
bool isBearishTrend = cBar.HasBearishTrend(
|
||||
tmpHSW,
|
||||
tmpLSW,
|
||||
true //
|
||||
);
|
||||
|
||||
//
|
||||
hasShort =
|
||||
//
|
||||
false
|
||||
//
|
||||
&&
|
||||
//
|
||||
(
|
||||
//
|
||||
isShootingStar
|
||||
//
|
||||
||
|
||||
//
|
||||
isEveningStar
|
||||
//
|
||||
||
|
||||
//
|
||||
isBearishEngulfing
|
||||
//
|
||||
||
|
||||
//
|
||||
isBearishMaurubozu
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
if (hasShort)
|
||||
{
|
||||
//
|
||||
type = POSITION_TYPE_SELL;
|
||||
|
||||
//
|
||||
// sl = tmpHSW[ArraySize(tmpHSW) - 1].high;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result = hasLong || hasShort;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
entry = GetEntry(mSymbol, type);
|
||||
CalculateTPSLByPrice(
|
||||
sl,
|
||||
tp,
|
||||
type,
|
||||
entry,
|
||||
r2r //
|
||||
);
|
||||
|
||||
//
|
||||
result = signal.Prepare(
|
||||
mSymbol,
|
||||
GetTag(),
|
||||
mPeriod,
|
||||
type,
|
||||
mode,
|
||||
entry,
|
||||
mVolume,
|
||||
sl,
|
||||
tp //
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Protected ...
|
||||
protected:
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
ENUM_TIMEFRAMES mHindPeriod; // Hind Period
|
||||
ENUM_TIMEFRAMES mMediestPeriod; // Mediest Period
|
||||
|
||||
//
|
||||
// Private ...
|
||||
private:
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
XOHCL hindBar;
|
||||
XOHCL hindBullishOrderBlock;
|
||||
XOHCL hindBearishOrderBlock;
|
||||
|
||||
//
|
||||
XOHCL medBar;
|
||||
XOHCL medBullishOrderBlock;
|
||||
XOHCL medBearishOrderBlock;
|
||||
|
||||
//
|
||||
double fvgUpper;
|
||||
double fvgLower;
|
||||
};
|
||||
|
||||
//
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,792 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Class Library
|
||||
// --------------------------------------
|
||||
// Name: XSCXSRBRStrategy
|
||||
// Description: provides all based classes for use ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
/// Imports ...
|
||||
#include "../Classes/x-saherelm.xstrategy.class.mq5"
|
||||
|
||||
//
|
||||
string XSRBRStartegyToken = "XSRBR";
|
||||
|
||||
//
|
||||
class XSCXSRBRStrategy : public XSCBaseStrategy
|
||||
{
|
||||
//
|
||||
// Public ...
|
||||
public:
|
||||
//
|
||||
// Constructor(s) ...
|
||||
void XSCXSRBRStrategy(
|
||||
//
|
||||
// Base ...
|
||||
string _symbol, // Trading Symbol
|
||||
ENUM_TIMEFRAMES _period, // Trading TimeFrame
|
||||
double _volume, // Voluem
|
||||
double _r2r, // Risk/Reward Ratio
|
||||
int _slippage, // Trader Slippage
|
||||
long _magicNumber, // Trader Magic Number
|
||||
bool _allowLong = true,
|
||||
bool _allowShort = true,
|
||||
int _maxAllowedLongs = 0,
|
||||
int _maxAllowedShorts = 0 //
|
||||
) : XSCBaseStrategy(_symbol,
|
||||
_period,
|
||||
_volume,
|
||||
_r2r,
|
||||
_slippage,
|
||||
_magicNumber,
|
||||
_allowLong,
|
||||
_allowShort,
|
||||
_maxAllowedLongs,
|
||||
_maxAllowedShorts //
|
||||
)
|
||||
{
|
||||
//
|
||||
mThreshold = 5;
|
||||
mVerificationsStep = 21;
|
||||
mConditionsValidationAge = 20;
|
||||
|
||||
//
|
||||
SetAlertPrefix(XSRBRStartegyToken);
|
||||
}
|
||||
|
||||
//
|
||||
// Getter / Setter (s) ...
|
||||
|
||||
//
|
||||
double Treshold()
|
||||
{
|
||||
return mThreshold;
|
||||
}
|
||||
|
||||
//
|
||||
void Treshold(double value)
|
||||
{
|
||||
//
|
||||
if (value < 0)
|
||||
{
|
||||
value = 0;
|
||||
}
|
||||
|
||||
//
|
||||
mThreshold = value;
|
||||
}
|
||||
|
||||
//
|
||||
int VerificationsStep()
|
||||
{
|
||||
return mVerificationsStep;
|
||||
}
|
||||
|
||||
//
|
||||
void VerificationsStep(int value)
|
||||
{
|
||||
//
|
||||
if (value < 5)
|
||||
{
|
||||
value = 5;
|
||||
}
|
||||
|
||||
//
|
||||
mVerificationsStep = value;
|
||||
}
|
||||
|
||||
//
|
||||
int ConditionsValidationAge()
|
||||
{
|
||||
return mConditionsValidationAge;
|
||||
}
|
||||
|
||||
//
|
||||
void ConditionsValidationAge(int value)
|
||||
{
|
||||
//
|
||||
if (value < 0)
|
||||
{
|
||||
value = 0;
|
||||
}
|
||||
|
||||
//
|
||||
mConditionsValidationAge = value;
|
||||
}
|
||||
|
||||
//
|
||||
bool DarwSupportAndResistances()
|
||||
{
|
||||
return mDarwSupportAndResistances;
|
||||
}
|
||||
|
||||
//
|
||||
void DarwSupportAndResistances(bool value)
|
||||
{
|
||||
//
|
||||
mDarwSupportAndResistances = value;
|
||||
|
||||
//
|
||||
if (!value)
|
||||
{
|
||||
//
|
||||
supportPivot.Remove();
|
||||
resistancePivot.Remove();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Overrides ...
|
||||
|
||||
//
|
||||
// Customize Strategy Identifier ...
|
||||
string GetTag() override
|
||||
{
|
||||
return XSRBRStartegyToken;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Conditions For Signal ...
|
||||
bool HasSignal(
|
||||
XSignal &signal //
|
||||
) override
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Try to Detect Trend ...
|
||||
result = trendDetector.HasTrend();
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
result = trendDetector.FindTrend(
|
||||
mSymbol,
|
||||
mPeriod //
|
||||
);
|
||||
|
||||
//
|
||||
if (!result ||
|
||||
(!trendDetector.isUpTrend && !trendDetector.isDownTrend))
|
||||
{
|
||||
//
|
||||
trendDetector.Clean();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check Resistance Exists or not ...
|
||||
// if Not, Try to Find One ...
|
||||
if (!resistancePivot.isResistance)
|
||||
{
|
||||
//
|
||||
result = resistancePivot.FindLastResistance(
|
||||
mSymbol,
|
||||
mPeriod //
|
||||
);
|
||||
|
||||
//
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
resistancePivot.Clean();
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
if (DarwSupportAndResistances())
|
||||
{
|
||||
resistancePivot.Draw(ChartID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check Support Exists or not ...
|
||||
// if Not, try to Find One ...
|
||||
if (!supportPivot.isSupport)
|
||||
{
|
||||
//
|
||||
result = supportPivot.FindLastSupport(
|
||||
mSymbol,
|
||||
mPeriod //
|
||||
);
|
||||
|
||||
//
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
supportPivot.Clean();
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
if (DarwSupportAndResistances())
|
||||
{
|
||||
supportPivot.Draw(ChartID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve Bar 1 ...
|
||||
XOHCL cBar;
|
||||
result = cBar.Init(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
1 //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
CheckConditionLife();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
signal.Clean();
|
||||
|
||||
//
|
||||
double sl = 0;
|
||||
double tp = 0;
|
||||
double risk = 0;
|
||||
double entry = 0;
|
||||
double reward = 0;
|
||||
double r2r = R2R();
|
||||
ENUM_POSITION_TYPE type;
|
||||
ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET;
|
||||
|
||||
//
|
||||
bool isSupportBreaked = supportPivot.IsBreaked();
|
||||
bool isSupportRejected = supportPivot.IsRejected();
|
||||
|
||||
//
|
||||
bool isResistancetBreaked = resistancePivot.IsBreaked();
|
||||
bool isResistancetRejected = resistancePivot.IsRejected();
|
||||
|
||||
//
|
||||
bool isBarBullishPattern =
|
||||
//
|
||||
cBar.IsBullish() &&
|
||||
cBar.HasStrongBody() &&
|
||||
(cBar.IsHammer() ||
|
||||
cBar.IsBullishEngulf())
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
bool isBarBearishPattern =
|
||||
//
|
||||
cBar.IsBearish() &&
|
||||
cBar.HasStrongBody() &&
|
||||
(cBar.IsShootingStar() ||
|
||||
cBar.IsBearishEngulf())
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
// Up Trend ...
|
||||
if (trendDetector.isUpTrend)
|
||||
{
|
||||
//
|
||||
// During Up Trend ...
|
||||
// Supports Must Rejected ...
|
||||
// Resistance Must Breaked ...
|
||||
|
||||
//
|
||||
// Check Trend Trading ...
|
||||
// Check Based Support ...
|
||||
bool hasSupportLong =
|
||||
//
|
||||
isSupportRejected &&
|
||||
isBarBullishPattern
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
// Check Trend Trading ...
|
||||
// Check Based On Resistance ...
|
||||
bool hasResistanceLong =
|
||||
//
|
||||
isResistancetBreaked &&
|
||||
isBarBullishPattern
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
// Check Trend Reversal Trading ...
|
||||
// Check Based Support ...
|
||||
bool hasSupportShort =
|
||||
//
|
||||
isSupportBreaked &&
|
||||
isBarBearishPattern
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
// Check Trend Reversal Trading ...
|
||||
// Check Based On Resistance ...
|
||||
bool hasResistanceShort =
|
||||
//
|
||||
isResistancetRejected &&
|
||||
isBarBearishPattern
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
// Check Trend Trading ...
|
||||
bool hasLong =
|
||||
//
|
||||
hasSupportLong ||
|
||||
hasResistanceLong
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
// Check Trend Reversal Trading ...
|
||||
bool hasShort =
|
||||
//
|
||||
hasSupportShort ||
|
||||
hasResistanceShort
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
// Filling Signal ...
|
||||
if (hasLong)
|
||||
{
|
||||
//
|
||||
type = POSITION_TYPE_BUY;
|
||||
entry = GetEntry(
|
||||
_Symbol,
|
||||
type //
|
||||
);
|
||||
|
||||
//
|
||||
if (hasSupportLong)
|
||||
{
|
||||
//
|
||||
sl = supportPivot.price;
|
||||
if (supportPivot._threshold > 0)
|
||||
{
|
||||
//
|
||||
double threshold = GetPoints(_Symbol) * supportPivot._threshold;
|
||||
sl -= threshold;
|
||||
}
|
||||
|
||||
//
|
||||
CalculateTPSLBtPrice(
|
||||
sl,
|
||||
tp,
|
||||
type,
|
||||
entry,
|
||||
r2r //
|
||||
);
|
||||
}
|
||||
else if (hasResistanceLong)
|
||||
{
|
||||
//
|
||||
sl = resistancePivot.price;
|
||||
if (resistancePivot._threshold > 0)
|
||||
{
|
||||
//
|
||||
double threshold = GetPoints(_Symbol) * resistancePivot._threshold;
|
||||
sl -= threshold;
|
||||
}
|
||||
|
||||
//
|
||||
CalculateTPSLBtPrice(
|
||||
sl,
|
||||
tp,
|
||||
type,
|
||||
entry,
|
||||
r2r //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
result = signal.Prepare(
|
||||
_Symbol,
|
||||
"XSUPRES",
|
||||
_Period,
|
||||
type,
|
||||
mode,
|
||||
entry,
|
||||
mVolume,
|
||||
sl,
|
||||
tp //
|
||||
);
|
||||
}
|
||||
else if (hasShort)
|
||||
{
|
||||
//
|
||||
type = POSITION_TYPE_SELL;
|
||||
entry = GetEntry(
|
||||
_Symbol,
|
||||
type //
|
||||
);
|
||||
|
||||
//
|
||||
if (hasSupportShort)
|
||||
{
|
||||
//
|
||||
sl = supportPivot.price;
|
||||
if (supportPivot._threshold > 0)
|
||||
{
|
||||
//
|
||||
double threshold = GetPoints(_Symbol) * supportPivot._threshold;
|
||||
sl += threshold;
|
||||
}
|
||||
|
||||
//
|
||||
CalculateTPSLBtPrice(
|
||||
sl,
|
||||
tp,
|
||||
type,
|
||||
entry,
|
||||
r2r //
|
||||
);
|
||||
}
|
||||
else if (hasResistanceShort)
|
||||
{
|
||||
//
|
||||
sl = resistancePivot.price;
|
||||
if (resistancePivot._threshold > 0)
|
||||
{
|
||||
//
|
||||
double threshold = GetPoints(_Symbol) * resistancePivot._threshold;
|
||||
sl += threshold;
|
||||
}
|
||||
|
||||
//
|
||||
CalculateTPSLBtPrice(
|
||||
sl,
|
||||
tp,
|
||||
type,
|
||||
entry,
|
||||
r2r //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
result = signal.Prepare(
|
||||
_Symbol,
|
||||
"XSUPRES",
|
||||
_Period,
|
||||
type,
|
||||
mode,
|
||||
entry,
|
||||
mVolume,
|
||||
sl,
|
||||
tp //
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Down Trend ...
|
||||
else if (trendDetector.isDownTrend)
|
||||
{
|
||||
//
|
||||
// During Down Trend ...
|
||||
// Supports Must Breaked ...
|
||||
// Resistance Must Rejected ...
|
||||
|
||||
//
|
||||
// Check Trend Reversal Trading ...
|
||||
// Check Based Support ...
|
||||
bool hasSupportLong =
|
||||
//
|
||||
isSupportRejected &&
|
||||
isBarBullishPattern
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
// Check Trend Reversal Trading ...
|
||||
// Check Based On Resistance ...
|
||||
bool hasResistanceLong =
|
||||
//
|
||||
isResistancetBreaked &&
|
||||
isBarBullishPattern
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
// Check Trend Trading ...
|
||||
// Check Based Support ...
|
||||
bool hasSupportShort =
|
||||
//
|
||||
isSupportBreaked &&
|
||||
isBarBearishPattern
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
// Check Trend Trading ...
|
||||
// Check Based On Resistance ...
|
||||
bool hasResistanceShort =
|
||||
//
|
||||
isResistancetRejected &&
|
||||
isBarBearishPattern
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
// Check Trend Reversal Trading ...
|
||||
bool hasLong =
|
||||
//
|
||||
hasSupportLong ||
|
||||
hasResistanceLong
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
// Check Trend Trading ...
|
||||
bool hasShort =
|
||||
//
|
||||
hasSupportShort ||
|
||||
hasResistanceShort
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
// Filling Signal ...
|
||||
if (hasLong)
|
||||
{
|
||||
//
|
||||
type = POSITION_TYPE_BUY;
|
||||
entry = GetEntry(
|
||||
_Symbol,
|
||||
type //
|
||||
);
|
||||
|
||||
//
|
||||
if (hasSupportLong)
|
||||
{
|
||||
//
|
||||
sl = supportPivot.price;
|
||||
if (supportPivot._threshold > 0)
|
||||
{
|
||||
//
|
||||
double threshold = GetPoints(_Symbol) * supportPivot._threshold;
|
||||
sl -= threshold;
|
||||
}
|
||||
|
||||
//
|
||||
CalculateTPSLBtPrice(
|
||||
sl,
|
||||
tp,
|
||||
type,
|
||||
entry,
|
||||
r2r //
|
||||
);
|
||||
}
|
||||
else if (hasResistanceLong)
|
||||
{
|
||||
//
|
||||
sl = resistancePivot.price;
|
||||
if (resistancePivot._threshold > 0)
|
||||
{
|
||||
//
|
||||
double threshold = GetPoints(_Symbol) * resistancePivot._threshold;
|
||||
sl -= threshold;
|
||||
}
|
||||
|
||||
//
|
||||
CalculateTPSLBtPrice(
|
||||
sl,
|
||||
tp,
|
||||
type,
|
||||
entry,
|
||||
r2r //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
result = signal.Prepare(
|
||||
_Symbol,
|
||||
"XSUPRES",
|
||||
_Period,
|
||||
type,
|
||||
mode,
|
||||
entry,
|
||||
mVolume,
|
||||
sl,
|
||||
tp //
|
||||
);
|
||||
}
|
||||
else if (hasShort)
|
||||
{
|
||||
//
|
||||
type = POSITION_TYPE_SELL;
|
||||
entry = GetEntry(
|
||||
_Symbol,
|
||||
type //
|
||||
);
|
||||
|
||||
//
|
||||
if (hasSupportShort)
|
||||
{
|
||||
//
|
||||
sl = supportPivot.price;
|
||||
if (supportPivot._threshold > 0)
|
||||
{
|
||||
//
|
||||
double threshold = GetPoints(_Symbol) * supportPivot._threshold;
|
||||
sl += threshold;
|
||||
}
|
||||
|
||||
//
|
||||
CalculateTPSLBtPrice(
|
||||
sl,
|
||||
tp,
|
||||
type,
|
||||
entry,
|
||||
r2r //
|
||||
);
|
||||
}
|
||||
else if (hasResistanceShort)
|
||||
{
|
||||
//
|
||||
sl = resistancePivot.price;
|
||||
if (resistancePivot._threshold > 0)
|
||||
{
|
||||
//
|
||||
double threshold = GetPoints(_Symbol) * resistancePivot._threshold;
|
||||
sl += threshold;
|
||||
}
|
||||
|
||||
//
|
||||
CalculateTPSLBtPrice(
|
||||
sl,
|
||||
tp,
|
||||
type,
|
||||
entry,
|
||||
r2r //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
result = signal.Prepare(
|
||||
_Symbol,
|
||||
"XSUPRES",
|
||||
_Period,
|
||||
type,
|
||||
mode,
|
||||
entry,
|
||||
mVolume,
|
||||
sl,
|
||||
tp //
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (!result)
|
||||
{
|
||||
CheckConditionLife();
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Notify Signal Execution ...
|
||||
void OnSignalExecuted(XSignal &signal) override
|
||||
{
|
||||
ResetConditions();
|
||||
}
|
||||
|
||||
//
|
||||
// Protected ...
|
||||
protected:
|
||||
//
|
||||
// Pivots Detecting ...
|
||||
double mThreshold; // Pivots Edge's Threshold ...
|
||||
int mVerificationsStep; // Pivots Verification Steps ...
|
||||
int mConditionsValidationAge; // How Many Bars a Support or Resistance is Valid ...
|
||||
|
||||
//
|
||||
XPivot supportPivot;
|
||||
XPivot resistancePivot;
|
||||
|
||||
//
|
||||
bool mDarwSupportAndResistances; // Draw Last Found Support and Resistance
|
||||
|
||||
//
|
||||
// Private ...
|
||||
private:
|
||||
//
|
||||
// Check Conditions Time Life ...
|
||||
void CheckConditionLife()
|
||||
{
|
||||
//
|
||||
datetime cTime = TimeCurrent();
|
||||
datetime lTime =
|
||||
//
|
||||
supportPivot.time < resistancePivot.time
|
||||
? supportPivot.time
|
||||
: resistancePivot.time
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
bool canReset =
|
||||
//
|
||||
(
|
||||
//
|
||||
(((int)cTime - (int)lTime) / PeriodSeconds(mPeriod)) > mConditionsValidationAge
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
if (canReset)
|
||||
{
|
||||
ResetConditions();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Reset Conditions ...
|
||||
void ResetConditions()
|
||||
{
|
||||
//
|
||||
trendDetector.Clean();
|
||||
|
||||
//
|
||||
supportPivot.Remove();
|
||||
supportPivot.Clean();
|
||||
|
||||
//
|
||||
resistancePivot.Remove();
|
||||
resistancePivot.Clean();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
@@ -0,0 +1,619 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center XSAMPLE MQL5 Expert Advisor
|
||||
// -------------------------------------------------
|
||||
// Name: XSAMPLE
|
||||
// Description: an Exper Advisor which used RSI and MA
|
||||
// to Analyse Market ...
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////x
|
||||
//
|
||||
// Global Properties ...
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XSAMPLE"
|
||||
#property strict
|
||||
|
||||
//
|
||||
#include "../Libraries/x-saherelm.draw.lib.mq5"
|
||||
#include "../Classes/x-saherelm.xalert.class.mq5"
|
||||
#include "../Classes/x-saherelm.xtrade.class.mq5"
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
#define ShortName "XSAMPLE"
|
||||
|
||||
//
|
||||
int pivotLifeTime = 20;
|
||||
int pivotBreakoutsLifeTime = 10;
|
||||
ENUM_TIMEFRAMES destPEriod = PERIOD_H4;
|
||||
|
||||
//
|
||||
int xAge = 0;
|
||||
|
||||
//
|
||||
double lastHH = 0;
|
||||
double lastUpper = 0;
|
||||
double lastDestHH = 0;
|
||||
|
||||
//
|
||||
double lastLL = 0;
|
||||
double lastLower = 0;
|
||||
double lastDestLL = 0;
|
||||
|
||||
//
|
||||
datetime lastTime = NULL;
|
||||
datetime lastDestTime = NULL;
|
||||
|
||||
//
|
||||
XSCAlert *mAlert;
|
||||
XSCTrade *mTrader;
|
||||
|
||||
//
|
||||
XBarTracker xBarTracker;
|
||||
XMarketCycle xDestCycle;
|
||||
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
drawPrefix = ShortName;
|
||||
|
||||
//
|
||||
if (!InitialEA())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// De Initialize XSampleEA Providers ...
|
||||
}
|
||||
|
||||
//
|
||||
// On Tick Handler ...
|
||||
void OnTick()
|
||||
{
|
||||
//
|
||||
if (!xBarTracker.IsNewBar())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
xDestCycle.Update(0);
|
||||
|
||||
//
|
||||
Analyze();
|
||||
|
||||
//
|
||||
ManxAge();
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
bool InitialEA()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
mAlert = new XSCAlert();
|
||||
mAlert.SetLogAlerts(true);
|
||||
mAlert.SetPrefix(ShortName);
|
||||
mAlert.SetEnableAlerts(true);
|
||||
mAlert.SetPushAlerts(false);
|
||||
mAlert.SetMailAlerts(false);
|
||||
mAlert.SetTerminalAlerts(false);
|
||||
|
||||
//
|
||||
mTrader = new XSCTrade(
|
||||
10,
|
||||
78692110,
|
||||
0,
|
||||
0,
|
||||
0 //
|
||||
);
|
||||
|
||||
//
|
||||
result = xBarTracker.Init(
|
||||
_Symbol,
|
||||
_Period //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = xDestCycle.Init(
|
||||
_Symbol,
|
||||
_Period,
|
||||
X_MARKET_CYCLE_MEDIUM,
|
||||
X_PERIOD_MANUALLY,
|
||||
destPEriod,
|
||||
"DEST" //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
void Analyze()
|
||||
{
|
||||
//
|
||||
XOHCL cBar;
|
||||
cBar.Init(
|
||||
_Symbol,
|
||||
_Period,
|
||||
1 //
|
||||
);
|
||||
|
||||
//
|
||||
if (IsLookingForBoundary())
|
||||
{
|
||||
FindBoundary();
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
double longSLPrice = 0;
|
||||
double shortSLPrice = 0;
|
||||
|
||||
// //
|
||||
// xAge = 0;
|
||||
// if (IsValid(lastTime))
|
||||
// {
|
||||
// //
|
||||
// xAge = iBarShift(
|
||||
// _Symbol,
|
||||
// _Period,
|
||||
// lastTime //
|
||||
// );
|
||||
// }
|
||||
|
||||
// //
|
||||
// if (xAge > pivotBreakoutsLifeTime)
|
||||
// {
|
||||
// //
|
||||
// lastHH = cBar.FindHighest(
|
||||
// xAge - 1,
|
||||
// MODE_HIGH //
|
||||
// );
|
||||
|
||||
// //
|
||||
// lastLL = cBar.FindLowest(
|
||||
// xAge - 1,
|
||||
// MODE_LOW //
|
||||
// );
|
||||
|
||||
// //
|
||||
// DrawPivot(lastLL, clrAqua, "PVB_L_", true);
|
||||
// DrawPivot(lastHH, clrMagenta, "PVB_H_", true);
|
||||
// }
|
||||
|
||||
//
|
||||
// Detect Breakouts for Long ...
|
||||
// - Upper Must Breaked as Resistance ...
|
||||
// - Lower Must Rejects as Support ...
|
||||
|
||||
// //
|
||||
// bool isSupRejected = cBar.IsSupportRejected(lastLower);
|
||||
// bool isResBreaked = cBar.IsResistanceBreaked(lastUpper);
|
||||
// bool isLastLLRejectedAsSupport = cBar.IsSupportRejected(lastDestLL);
|
||||
// bool isLastHHBreakedAsResistance = cBar.IsResistanceBreaked(lastDestHH);
|
||||
|
||||
// //
|
||||
// bool hasLong =
|
||||
// //
|
||||
// cBar.HasStrongBody() &&
|
||||
// (
|
||||
// //
|
||||
// (isLastLLRejectedAsSupport
|
||||
// //
|
||||
// ||
|
||||
// //
|
||||
// isLastHHBreakedAsResistance)
|
||||
// //
|
||||
// ||
|
||||
// //
|
||||
// (cBar.GetMid() > MathMax(lastLower, lastUpper) &&
|
||||
// (isResBreaked
|
||||
// //
|
||||
// ||
|
||||
// //
|
||||
// isSupRejected))
|
||||
// //
|
||||
// )
|
||||
// //
|
||||
// ;
|
||||
|
||||
// //
|
||||
// if (hasLong)
|
||||
// {
|
||||
// //
|
||||
// longSLPrice = isResBreaked
|
||||
// ? lastUpper
|
||||
// : isLastHHBreakedAsResistance
|
||||
// ? lastDestHH
|
||||
// : isSupRejected
|
||||
// ? lastLower
|
||||
// : lastDestLL;
|
||||
// }
|
||||
|
||||
//
|
||||
// Detect Breakouts for Long ...
|
||||
// - Upper Must Rejects as Resistance ...
|
||||
// - Lower Must Breaked as Support ...
|
||||
|
||||
// //
|
||||
// bool isResRejected = cBar.IsResistanceRejected(lastUpper);
|
||||
// bool isSupBreaked = cBar.IsSupportBreaked(lastLower);
|
||||
// bool isLastLLBreadedAsSupport = cBar.IsSupportBreaked(lastDestLL);
|
||||
// bool isLastHHRejectedAsResistance = cBar.IsResistanceRejected(lastDestHH);
|
||||
|
||||
// //
|
||||
// bool hasShort =
|
||||
// //
|
||||
// cBar.HasStrongBody() &&
|
||||
// (
|
||||
// //
|
||||
// (isLastLLBreadedAsSupport
|
||||
// //
|
||||
// ||
|
||||
// //
|
||||
// isLastHHRejectedAsResistance)
|
||||
// //
|
||||
// ||
|
||||
// //
|
||||
// (cBar.GetMid() < MathMin(lastLower, lastUpper) &&
|
||||
// (isSupBreaked
|
||||
// //
|
||||
// ||
|
||||
// //
|
||||
// isResRejected))
|
||||
// //
|
||||
// )
|
||||
// //
|
||||
// ;
|
||||
|
||||
// //
|
||||
// if (hasShort)
|
||||
// {
|
||||
// //
|
||||
// shortSLPrice = isSupBreaked
|
||||
// ? lastLower
|
||||
// : isLastLLBreadedAsSupport
|
||||
// ? lastDestLL
|
||||
// : isResRejected
|
||||
// ? lastUpper
|
||||
// : lastDestHH;
|
||||
// }
|
||||
|
||||
//
|
||||
//
|
||||
bool hasLong = false;
|
||||
bool hasShort = false;
|
||||
|
||||
//
|
||||
bool hasSignal = hasLong || hasShort;
|
||||
if (hasSignal)
|
||||
{
|
||||
//
|
||||
double slPrice =
|
||||
hasLong
|
||||
? longSLPrice
|
||||
: shortSLPrice;
|
||||
// double slPrice =
|
||||
// hasLong
|
||||
// ? shortSLPrice
|
||||
// : longSLPrice;
|
||||
|
||||
//
|
||||
ENUM_POSITION_TYPE mType =
|
||||
hasLong
|
||||
? POSITION_TYPE_BUY
|
||||
: POSITION_TYPE_SELL
|
||||
//
|
||||
;
|
||||
// ENUM_POSITION_TYPE mType =
|
||||
// hasLong
|
||||
// ? POSITION_TYPE_BUY
|
||||
// : POSITION_TYPE_SELL
|
||||
// //
|
||||
// ;
|
||||
|
||||
//
|
||||
double mEntry = GetEntry(
|
||||
_Symbol,
|
||||
mType //
|
||||
);
|
||||
|
||||
//
|
||||
double priceToRisk = PointToPrice(30, _Symbol);
|
||||
double priceToReward = PointToPrice(30, _Symbol);
|
||||
|
||||
//
|
||||
double mSL = 0;
|
||||
double mTP = 0;
|
||||
CalculateTPSL(
|
||||
mSL,
|
||||
mTP,
|
||||
mType,
|
||||
mEntry,
|
||||
1,
|
||||
slPrice,
|
||||
0,
|
||||
priceToRisk,
|
||||
priceToReward //
|
||||
);
|
||||
|
||||
//
|
||||
// Ignore Zero TP SL ...
|
||||
if (mTP > 0 && mSL > 0)
|
||||
{
|
||||
//
|
||||
XSignal signal;
|
||||
bool isPrepared = signal.Prepare(
|
||||
_Symbol,
|
||||
"X92",
|
||||
_Period,
|
||||
mType,
|
||||
X_ORDER_MODE_MARKET,
|
||||
mEntry,
|
||||
0.01,
|
||||
mSL,
|
||||
mTP //
|
||||
);
|
||||
|
||||
//
|
||||
if (isPrepared)
|
||||
{
|
||||
//
|
||||
ENUM_X_SIGNAL_EXECUTION_RESULT state;
|
||||
bool isExecuted = mTrader.ExecuteSignal(
|
||||
signal,
|
||||
state //
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
bool resetLast =
|
||||
xAge > pivotLifeTime || hasSignal;
|
||||
|
||||
//
|
||||
if (resetLast)
|
||||
{
|
||||
//
|
||||
lastUpper = 0;
|
||||
lastLower = 0;
|
||||
|
||||
//
|
||||
RemoveDraws();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void ManxAge()
|
||||
{
|
||||
//
|
||||
return;
|
||||
double profit = mTrader.Profit();
|
||||
if (profit > 50 || profit < -100)
|
||||
{
|
||||
//
|
||||
string comment = "EQM Hedge: " + ToString(profit);
|
||||
|
||||
//
|
||||
int numberOfClosed = mTrader.Close(comment);
|
||||
if (numberOfClosed > 0)
|
||||
{
|
||||
mAlert.Alert(comment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
bool IsLookingForBoundary()
|
||||
{
|
||||
//
|
||||
bool result = lastUpper == 0 && lastLower == 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
void FindBoundary()
|
||||
{
|
||||
//
|
||||
int zIndex = 0;
|
||||
int cIndex = 1;
|
||||
int pIndex = 2;
|
||||
int ppIndex = 3;
|
||||
|
||||
//
|
||||
// Detect Inside Bar ...
|
||||
XOHCL cBar;
|
||||
cBar.Init(
|
||||
_Symbol,
|
||||
_Period,
|
||||
1 //
|
||||
);
|
||||
|
||||
//
|
||||
XOHCL cDestBar = xDestCycle.GetBar(1);
|
||||
|
||||
//
|
||||
if (cDestBar.time != lastDestTime) {
|
||||
//
|
||||
lastDestLL = cDestBar.low;
|
||||
lastDestHH = cDestBar.high;
|
||||
|
||||
//
|
||||
lastDestTime = cDestBar.time;
|
||||
|
||||
//
|
||||
DrawPivot(lastUpper, clrOrangeRed, "Pvt_");
|
||||
DrawPivot(lastLower, clrLimeGreen, "Pvt_");
|
||||
}
|
||||
|
||||
//
|
||||
// if (cDestBar.IsInsideBar())
|
||||
// {
|
||||
// //
|
||||
// lastUpper = cDestBar.high;
|
||||
// lastLower = cDestBar.low;
|
||||
|
||||
// //
|
||||
// lastTime = TimeCurrent();
|
||||
|
||||
// //
|
||||
// DrawPivot(lastUpper, clrOrangeRed, "Pvt_");
|
||||
// DrawPivot(lastLower, clrLimeGreen, "Pvt_");
|
||||
// }
|
||||
|
||||
// //
|
||||
// if (lastUpper != cDestBar.high && lastLower != cDestBar.low)
|
||||
// {
|
||||
// //
|
||||
// lastDestHH = cDestBar.high;
|
||||
// lastDestLL = cDestBar.low;
|
||||
|
||||
// //
|
||||
// DrawPivot(lastDestLL, clrYellow, "LDST_LL_", true);
|
||||
// DrawPivot(lastDestHH, clrYellow, "LDST_HH_", true);
|
||||
|
||||
// //
|
||||
// lastDestTime = TimeCurrent();
|
||||
// }
|
||||
|
||||
//
|
||||
DrawFibo();
|
||||
}
|
||||
|
||||
//
|
||||
void DrawPivot(
|
||||
double price,
|
||||
color clr,
|
||||
string prefix,
|
||||
bool forceRemove = false //
|
||||
)
|
||||
{
|
||||
//
|
||||
long chartID = ChartID();
|
||||
datetime time1 = iTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
2 //
|
||||
);
|
||||
datetime time = iTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
0 //
|
||||
);
|
||||
|
||||
//
|
||||
string pPrefix = prefix + "P_" +
|
||||
ToString(price);
|
||||
|
||||
//
|
||||
if (IsDrawExists(prefix) && forceRemove)
|
||||
{
|
||||
RemoveDraws(prefix);
|
||||
}
|
||||
|
||||
//
|
||||
if (IsDrawExists(pPrefix))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
DrawTrendLine(
|
||||
chartID,
|
||||
pPrefix,
|
||||
0,
|
||||
time1,
|
||||
price,
|
||||
time,
|
||||
price,
|
||||
clr,
|
||||
STYLE_SOLID,
|
||||
2,
|
||||
false,
|
||||
false,
|
||||
true //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
void DrawFibo()
|
||||
{
|
||||
//
|
||||
if (!IsValid(lastDestTime) || lastDestHH == 0 || lastDestLL == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
string name = "LDST_FIb";
|
||||
|
||||
//
|
||||
datetime time1 = TimeCurrent();
|
||||
datetime time0 = lastDestTime;
|
||||
|
||||
//
|
||||
RemoveDraw(name);
|
||||
|
||||
//
|
||||
DrawFibonacci(
|
||||
ChartID(),
|
||||
name,
|
||||
0,
|
||||
time0,
|
||||
lastDestHH,
|
||||
time1,
|
||||
lastDestLL,
|
||||
clrAquamarine,
|
||||
STYLE_DOT //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -0,0 +1,387 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center XTest MQL5 Expert Advisor
|
||||
// -------------------------------------------------
|
||||
// Name: XTestPivotsEA
|
||||
// Description: an Exper Advisor which used XTestSetup
|
||||
// to Analyse Market ...
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////x
|
||||
//
|
||||
// Global Properties ...
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XTestPivotsEA"
|
||||
#property strict
|
||||
|
||||
//
|
||||
#define ShortName "XTestPivotsEA"
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../Helpers/x-saherelm.xct.helper.mq5"
|
||||
#include "../Helpers/x-saherelm.xcc.helper.mq5"
|
||||
#include "../Strategies/x-saherelm.xsrbr.strategy.mq5"
|
||||
|
||||
//
|
||||
// Inputs ...
|
||||
long mMagicNumber = 78692110; // Magic Number
|
||||
int mSlippage = 10; // Slippgae
|
||||
|
||||
//
|
||||
double eaVolume = 0.01;
|
||||
double eaAllowLong = true;
|
||||
double eaAllowShort = true;
|
||||
|
||||
//
|
||||
// Variables ...
|
||||
XSCXCTHelper *mCTHelper;
|
||||
XSCXCCHelper *mCCHelper;
|
||||
|
||||
//
|
||||
XSCBaseStrategy *strategies[];
|
||||
|
||||
//
|
||||
// Event Handlers ...
|
||||
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
if (!InitialEA())
|
||||
{
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// EventSetTimer(1);
|
||||
// EventSetMillisecondTimer(100);
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// De Initialize XSampleEA Providers ...
|
||||
delete mCTHelper;
|
||||
delete mCCHelper;
|
||||
|
||||
//
|
||||
// EventKillTimer();
|
||||
|
||||
//
|
||||
Clean(strategies);
|
||||
}
|
||||
|
||||
//
|
||||
// On Tick Handler ...
|
||||
void OnTick()
|
||||
{
|
||||
HandleStrategiesOnTick();
|
||||
}
|
||||
|
||||
//
|
||||
// On Timer ...
|
||||
void OnTimer()
|
||||
{
|
||||
//
|
||||
// HandleStrategiesOnTick();
|
||||
}
|
||||
|
||||
//
|
||||
// Custom Functions ...
|
||||
|
||||
//
|
||||
// Validate Inputs ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize all Requirements ...
|
||||
bool InitialEA()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Bar Timer ...
|
||||
XCTInputs ctInputs;
|
||||
ctInputs.Default();
|
||||
mCTHelper = new XSCXCTHelper();
|
||||
result = mCTHelper.Init(
|
||||
_Symbol,
|
||||
_Period,
|
||||
ctInputs //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Bar Styles ...
|
||||
XCCInputs ccInputs;
|
||||
ccInputs.Default();
|
||||
mCCHelper = new XSCXCCHelper();
|
||||
result = mCCHelper.Init(
|
||||
_Symbol,
|
||||
_Period,
|
||||
ccInputs //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
XSymbolParser symbolParser;
|
||||
|
||||
//
|
||||
bool drawAreas = false;
|
||||
|
||||
//
|
||||
// EURUSD ...
|
||||
string eurusdSymbol = "EURUSDb"; // symbolParser.GetEURUSDSymbol();
|
||||
if (IsValid(eurusdSymbol))
|
||||
{
|
||||
//
|
||||
// MAGIC NUMBER ...
|
||||
long magicNumber = mMagicNumber + 1;
|
||||
|
||||
// //
|
||||
// // Register XSRBR on EURUSD in M5 ...
|
||||
// XSCXSRBRStrategy *eurusdM5SRBRStrategy;
|
||||
// eurusdM5SRBRStrategy = new XSCXSRBRStrategy(
|
||||
// eurusdSymbol,
|
||||
// PERIOD_M5,
|
||||
// eaVolume,
|
||||
// 1.5, // R2R ...
|
||||
// mSlippage,
|
||||
// magicNumber,
|
||||
// eaAllowLong,
|
||||
// eaAllowShort,
|
||||
// 0, // Max Longs
|
||||
// 0 // Max Shorts
|
||||
// );
|
||||
// eurusdM5SRBRStrategy.SetAlertLogAlerts(true);
|
||||
// eurusdM5SRBRStrategy.SetAlertEnableAlerts(true);
|
||||
// eurusdM5SRBRStrategy.DarwSupportAndResistances(drawAreas);
|
||||
// RegisterStrategy(eurusdM5SRBRStrategy);
|
||||
|
||||
// //
|
||||
// // Register XSRBR on EURUSD in M10 ...
|
||||
// XSCXSRBRStrategy *eurusdM10SRBRStrategy;
|
||||
// eurusdM10SRBRStrategy = new XSCXSRBRStrategy(
|
||||
// eurusdSymbol,
|
||||
// PERIOD_M10,
|
||||
// eaVolume,
|
||||
// 1.5, // R2R ...
|
||||
// mSlippage,
|
||||
// magicNumber,
|
||||
// eaAllowLong,
|
||||
// eaAllowShort,
|
||||
// 0, // Max Longs
|
||||
// 0 // Max Shorts
|
||||
// );
|
||||
// eurusdM10SRBRStrategy.SetAlertLogAlerts(true);
|
||||
// eurusdM10SRBRStrategy.SetAlertEnableAlerts(true);
|
||||
// eurusdM10SRBRStrategy.DarwSupportAndResistances(drawAreas);
|
||||
// RegisterStrategy(eurusdM10SRBRStrategy);
|
||||
}
|
||||
|
||||
// //
|
||||
// // XAUUSD ...
|
||||
// string xauusdSymbol = "XAUUSDb";
|
||||
// if (IsValid(xauusdSymbol))
|
||||
// {
|
||||
// //
|
||||
// // MAGIC NUMBER ...
|
||||
// long magicNumber = mMagicNumber + 2;
|
||||
|
||||
// //
|
||||
// // Register XSRBR on XAUUSD in M5 ...
|
||||
// XSCXSRBRStrategy *xauusdM5SRBRStrategy;
|
||||
// xauusdM5SRBRStrategy = new XSCXSRBRStrategy(
|
||||
// xauusdSymbol,
|
||||
// PERIOD_M15,
|
||||
// eaVolume,
|
||||
// 1.5, // R2R ...
|
||||
// mSlippage,
|
||||
// magicNumber,
|
||||
// eaAllowLong,
|
||||
// eaAllowShort,
|
||||
// 0, // Max Longs
|
||||
// 0 // Max Shorts
|
||||
// );
|
||||
// xauusdM5SRBRStrategy.SetAlertLogAlerts(true);
|
||||
// xauusdM5SRBRStrategy.SetAlertEnableAlerts(true);
|
||||
// xauusdM5SRBRStrategy.DarwSupportAndResistances(drawAreas);
|
||||
// RegisterStrategy(xauusdM5SRBRStrategy);
|
||||
// }
|
||||
|
||||
//
|
||||
// GBPUSD ...
|
||||
string gbpusdSymbol = "GBPUSDb";
|
||||
if (IsValid(gbpusdSymbol))
|
||||
{
|
||||
//
|
||||
// MAGIC NUMBER ...
|
||||
long magicNumber = mMagicNumber + 3;
|
||||
|
||||
// //
|
||||
// // Register XSRBR on XAUUSD in M5 ...
|
||||
// XSCXSRBRStrategy *gbpusdM15SRBRStrategy;
|
||||
// gbpusdM15SRBRStrategy = new XSCXSRBRStrategy(
|
||||
// gbpusdSymbol,
|
||||
// PERIOD_M15,
|
||||
// eaVolume,
|
||||
// 1.5, // R2R ...
|
||||
// mSlippage,
|
||||
// magicNumber,
|
||||
// eaAllowLong,
|
||||
// eaAllowShort,
|
||||
// 0, // Max Longs
|
||||
// 0 // Max Shorts
|
||||
// );
|
||||
// gbpusdM15SRBRStrategy.SetAlertLogAlerts(true);
|
||||
// gbpusdM15SRBRStrategy.SetAlertEnableAlerts(true);
|
||||
// gbpusdM15SRBRStrategy.DarwSupportAndResistances(drawAreas);
|
||||
// RegisterStrategy(gbpusdM15SRBRStrategy);
|
||||
|
||||
//
|
||||
// Register XSRBR on XAUUSD in M5 ...
|
||||
// XSCXSRBRStrategy *gbpusdM30SRBRStrategy;
|
||||
// gbpusdM30SRBRStrategy = new XSCXSRBRStrategy(
|
||||
// gbpusdSymbol,
|
||||
// PERIOD_M30,
|
||||
// eaVolume,
|
||||
// 1.5, // R2R ...
|
||||
// mSlippage,
|
||||
// magicNumber,
|
||||
// eaAllowLong,
|
||||
// eaAllowShort,
|
||||
// 0, // Max Longs
|
||||
// 0 // Max Shorts
|
||||
// );
|
||||
// gbpusdM30SRBRStrategy.SetAlertLogAlerts(true);
|
||||
// gbpusdM30SRBRStrategy.SetAlertEnableAlerts(true);
|
||||
// gbpusdM30SRBRStrategy.DarwSupportAndResistances(drawAreas);
|
||||
// RegisterStrategy(gbpusdM30SRBRStrategy);
|
||||
}
|
||||
|
||||
//
|
||||
// USDJPY ...
|
||||
string usdjpySymbol = "USDJPYb";
|
||||
if (IsValid(usdjpySymbol))
|
||||
{
|
||||
//
|
||||
// MAGIC NUMBER ...
|
||||
long magicNumber = mMagicNumber + 3;
|
||||
|
||||
// //
|
||||
// // Register XSRBR on XAUUSD in M5 ...
|
||||
// XSCXSRBRStrategy *usdjpyM5SRBRStrategy;
|
||||
// usdjpyM5SRBRStrategy = new XSCXSRBRStrategy(
|
||||
// usdjpySymbol,
|
||||
// PERIOD_M5,
|
||||
// eaVolume,
|
||||
// 1.5, // R2R ...
|
||||
// mSlippage,
|
||||
// magicNumber,
|
||||
// eaAllowLong,
|
||||
// eaAllowShort,
|
||||
// 0, // Max Longs
|
||||
// 0 // Max Shorts
|
||||
// );
|
||||
// usdjpyM5SRBRStrategy.SetAlertLogAlerts(true);
|
||||
// usdjpyM5SRBRStrategy.SetAlertEnableAlerts(true);
|
||||
// usdjpyM5SRBRStrategy.DarwSupportAndResistances(drawAreas);
|
||||
// RegisterStrategy(usdjpyM5SRBRStrategy);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Register Strategy ...
|
||||
void RegisterStrategy(XSCBaseStrategy *strategy)
|
||||
{
|
||||
//
|
||||
if (strategy == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
ArrayResize(
|
||||
strategies,
|
||||
ArraySize(strategies) + 1 //
|
||||
);
|
||||
|
||||
//
|
||||
strategies[ArraySize(strategies) - 1] = strategy;
|
||||
}
|
||||
|
||||
//
|
||||
// Call All Registered Strategis Tick Handler Functions ...
|
||||
void HandleStrategiesOnTick()
|
||||
{
|
||||
//
|
||||
int count = ArraySize(strategies);
|
||||
if (!IsValidSize(count))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
// Call Tick Handler Function ...
|
||||
strategies[i].HandleTick();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Custom Testing Functions ...
|
||||
|
||||
//
|
||||
@@ -0,0 +1,263 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center XZoneTest MQL5 Expert Advisor
|
||||
// -------------------------------------------------
|
||||
// Name: XZoneTest
|
||||
// Description: an Exper Advisor which used RSI and MA
|
||||
// to Analyse Market ...
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////x
|
||||
//
|
||||
// Global Properties ...
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XZoneTest"
|
||||
#property strict
|
||||
|
||||
//
|
||||
#include "../Classes/x-saherelm.xczone.class.mq5"
|
||||
|
||||
//
|
||||
#define ShortName "XZoneTest"
|
||||
|
||||
//
|
||||
// Inputs ...
|
||||
input int zoneRange = 21;
|
||||
input ENUM_TIMEFRAMES zonePeriod = PERIOD_M1;
|
||||
|
||||
//
|
||||
// Variables ...
|
||||
int barsTotal;
|
||||
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
if (!InitialEA())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// De Initialize XSampleEA Providers ...
|
||||
}
|
||||
|
||||
//
|
||||
// On Tick Handler ...
|
||||
void OnTick()
|
||||
{
|
||||
//
|
||||
int bars = iBars(
|
||||
_Symbol,
|
||||
zonePeriod //
|
||||
);
|
||||
if (barsTotal == bars)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
barsTotal = bars;
|
||||
|
||||
//
|
||||
datetime startTime = iTime(
|
||||
_Symbol,
|
||||
zonePeriod,
|
||||
zoneRange + 1 //
|
||||
);
|
||||
datetime endTime = iTime(
|
||||
_Symbol,
|
||||
zonePeriod,
|
||||
1 //
|
||||
);
|
||||
|
||||
//
|
||||
MqlTick ticks[];
|
||||
CopyTicksRange(
|
||||
_Symbol,
|
||||
ticks,
|
||||
COPY_TICKS_ALL,
|
||||
startTime * 1000,
|
||||
endTime * 1000 //
|
||||
);
|
||||
|
||||
//
|
||||
double highs[];
|
||||
CopyHigh(
|
||||
_Symbol,
|
||||
zonePeriod,
|
||||
startTime,
|
||||
endTime,
|
||||
highs //
|
||||
);
|
||||
double iHigh = highs[ArrayMaximum(highs)];
|
||||
|
||||
//
|
||||
double lows[];
|
||||
CopyLow(
|
||||
_Symbol,
|
||||
zonePeriod,
|
||||
startTime,
|
||||
endTime,
|
||||
lows //
|
||||
);
|
||||
double iLow = lows[ArrayMinimum(lows)];
|
||||
|
||||
//
|
||||
double iSize = iHigh - iLow;
|
||||
|
||||
//
|
||||
CArrayObj zones;
|
||||
int zCount = 10;
|
||||
for (int i = 0; i < zCount; i++)
|
||||
{
|
||||
//
|
||||
double iH = iHigh - iSize * i / zCount;
|
||||
double iL = iHigh - iSize * (i + 1) / zCount;
|
||||
|
||||
//
|
||||
XSCZone *iZone = new XSCZone();
|
||||
iZone.high = iH;
|
||||
iZone.low = iL;
|
||||
|
||||
//
|
||||
zones.Add(iZone);
|
||||
}
|
||||
|
||||
//
|
||||
// Fill Ticks ...
|
||||
for (int i = 0; i < ArraySize(ticks); i++)
|
||||
{
|
||||
//
|
||||
MqlTick iTick = ticks[i];
|
||||
|
||||
//
|
||||
for (int j = 0; j < zones.Total(); j++)
|
||||
{
|
||||
//
|
||||
XSCZone *jZone = zones.At(j);
|
||||
|
||||
//
|
||||
bool isInRange = iTick.bid >= jZone.low && iTick.bid <= jZone.high;
|
||||
if (isInRange)
|
||||
{
|
||||
//
|
||||
jZone.ticks++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Sorting Zones ...
|
||||
zones.Sort();
|
||||
|
||||
//
|
||||
CArrayObj mChartObjects;
|
||||
for (int i = 0; i < zones.Total(); i++)
|
||||
{
|
||||
//
|
||||
XSCZone *iZone = zones.At(i);
|
||||
|
||||
//
|
||||
string iZoneName = "Zone " + IntegerToString(i);
|
||||
|
||||
//
|
||||
// Create Zone Rectangle ...
|
||||
CChartObjectRectangle *iRect = new CChartObjectRectangle();
|
||||
iRect.Create(
|
||||
0,
|
||||
iZoneName,
|
||||
0,
|
||||
startTime,
|
||||
iZone.high,
|
||||
endTime,
|
||||
iZone.low //
|
||||
);
|
||||
iRect.Fill(true);
|
||||
|
||||
//
|
||||
// Create Zone Label ...
|
||||
CChartObjectLabel *iLabel = new CChartObjectLabel();
|
||||
iLabel.Create(
|
||||
0,
|
||||
iZoneName + "_lbl",
|
||||
0,
|
||||
startTime,
|
||||
iZone.high //
|
||||
);
|
||||
iLabel.Color(clrWhite);
|
||||
|
||||
//
|
||||
// Calculate TickPercent ...
|
||||
double iZoneTickPercent = (double)iZone.ticks / ArraySize(ticks) * 100;
|
||||
iZoneTickPercent = NormalizeDouble(iZoneTickPercent, 2);
|
||||
string iZoneTickPercentStr = (string)iZoneTickPercent + "%";
|
||||
|
||||
//
|
||||
iLabel.Description(iZoneTickPercentStr);
|
||||
|
||||
//
|
||||
if (iZone.ticks > ArraySize(ticks) * 0.15)
|
||||
{
|
||||
iRect.Color(clrOrangeRed);
|
||||
}
|
||||
else if (iZone.ticks > ArraySize(ticks) * 0.10)
|
||||
{
|
||||
iRect.Color(clrOrange);
|
||||
}
|
||||
else
|
||||
{
|
||||
iRect.Color(clrLightGray);
|
||||
}
|
||||
|
||||
//
|
||||
// mChartObjects.Add(iRect);
|
||||
// mChartObjects.Add(iLabel);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
bool InitialEA()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -0,0 +1,202 @@
|
||||
//
|
||||
// Filter Long Conditions ...
|
||||
bool FilterLongConditions(
|
||||
X121SetupConditions &conditions, // Conditions
|
||||
int pusher, // Pushers
|
||||
string provider // Provider
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Generating Conditions Score ...
|
||||
double bullishScore = 0;
|
||||
double bearishScore = 0;
|
||||
conditions.GenerateScore(
|
||||
bullishScore,
|
||||
bearishScore //
|
||||
);
|
||||
|
||||
//
|
||||
bool isGBPUSD = symbolParser.IsGBPUSD(conditions.symbol);
|
||||
|
||||
//
|
||||
bool isM5Period = conditions.period == PERIOD_M5;
|
||||
bool isM15Period = conditions.period == PERIOD_M15;
|
||||
bool isH1Period = conditions.period == PERIOD_H1;
|
||||
bool isH4Period = conditions.period == PERIOD_H4;
|
||||
|
||||
//
|
||||
// Set Default Result to True ...
|
||||
result = true;
|
||||
|
||||
//
|
||||
// Global Conditions ...
|
||||
result =
|
||||
//
|
||||
result &&
|
||||
//
|
||||
!(
|
||||
//
|
||||
(
|
||||
//
|
||||
// XICH ...
|
||||
conditions.ichConditions.isClosedUnderKijunSen &&
|
||||
conditions.ichConditions.isTenkanSenOverKijunSen
|
||||
//
|
||||
)
|
||||
//
|
||||
||
|
||||
//
|
||||
(
|
||||
//
|
||||
// XICH ...
|
||||
conditions.ichConditions.isTenkanSenUnderKijunSen
|
||||
//
|
||||
)
|
||||
//
|
||||
||
|
||||
//
|
||||
(
|
||||
//
|
||||
// XICH ...
|
||||
conditions.ichConditions.isSenkouSpanAOverB &&
|
||||
!conditions.ichConditions.isSenkouSpanAOverLast
|
||||
//
|
||||
)
|
||||
//
|
||||
||
|
||||
//
|
||||
(
|
||||
//
|
||||
// XICH ...
|
||||
conditions.ichConditions.isSenkouSpanAUnderB &&
|
||||
conditions.ichConditions.isSenkouSpanAUnderLast
|
||||
//
|
||||
)
|
||||
//
|
||||
||
|
||||
//
|
||||
(
|
||||
//
|
||||
// XICH ...
|
||||
conditions.ichConditions.isSenkouSpanAOverB &&
|
||||
!conditions.ichConditions.isSenkouSpanAOverLast &&
|
||||
conditions.ichConditions.isTenkanSenCrossedOverKijunSen &&
|
||||
//
|
||||
// XVLM ...
|
||||
conditions.vlmConditions.isVolumeUnderLast
|
||||
//
|
||||
)
|
||||
//
|
||||
||
|
||||
//
|
||||
(
|
||||
//
|
||||
// XICH ...
|
||||
conditions.ichConditions.isClosedOverKijunSen &&
|
||||
conditions.ichConditions.isTenkanSenOverKijunSen &&
|
||||
conditions.ichConditions.isSenkouSpanAUnderB
|
||||
//
|
||||
)
|
||||
//
|
||||
||
|
||||
//
|
||||
(
|
||||
//
|
||||
// XPV ...
|
||||
!conditions.pvConditions.isSCBullish &&
|
||||
!conditions.pvConditions.isSCHHBullish &&
|
||||
!conditions.pvConditions.isSCLLBullish &&
|
||||
!conditions.pvConditions.isMCBullish &&
|
||||
!conditions.pvConditions.isMCHHBullish &&
|
||||
!conditions.pvConditions.isMCLLBullish &&
|
||||
!conditions.pvConditions.isLCBullish &&
|
||||
!conditions.pvConditions.isLCHHBullish &&
|
||||
!conditions.pvConditions.isLCLLBullish &&
|
||||
!conditions.pvConditions.isHCBullish &&
|
||||
!conditions.pvConditions.isHCHHBullish &&
|
||||
!conditions.pvConditions.isHCLLBullish &&
|
||||
//
|
||||
// XICH ...
|
||||
conditions.ichConditions.isClosedOverKijunSen &&
|
||||
(conditions.ichConditions.isTenkanSenOverKijunSen ||
|
||||
conditions.ichConditions.isTenkanSenCrossedOverKijunSen)
|
||||
//
|
||||
)
|
||||
//
|
||||
||
|
||||
//
|
||||
(
|
||||
//
|
||||
(
|
||||
//
|
||||
// XPV ...
|
||||
conditions.pvConditions.isNewPeak &&
|
||||
conditions.pvConditions.isNewPeakOverLast &&
|
||||
conditions.pvConditions.isFiboIncreased &&
|
||||
conditions.pvConditions.isCloseOverFib1 &&
|
||||
conditions.pvConditions.isCloseOverFib2 &&
|
||||
conditions.pvConditions.isCloseOverFib3 &&
|
||||
conditions.pvConditions.isCloseOverFib4 &&
|
||||
conditions.pvConditions.isCloseOverFib5
|
||||
//
|
||||
)
|
||||
//
|
||||
&&
|
||||
//
|
||||
(
|
||||
//
|
||||
// XSCORES ...
|
||||
bearishScore < 5 &&
|
||||
bullishScore > bearishScore * 10
|
||||
//
|
||||
)
|
||||
//
|
||||
&&
|
||||
//
|
||||
(
|
||||
//
|
||||
(
|
||||
//
|
||||
// XPV ...
|
||||
conditions.pvConditions.isSCBullish &&
|
||||
conditions.pvConditions.isSCHHBullish &&
|
||||
conditions.pvConditions.isSCLLBullish &&
|
||||
conditions.pvConditions.isMCBullish &&
|
||||
conditions.pvConditions.isMCHHBullish &&
|
||||
conditions.pvConditions.isMCLLBullish &&
|
||||
conditions.pvConditions.isLCBullish &&
|
||||
conditions.pvConditions.isLCHHBullish &&
|
||||
conditions.pvConditions.isLCLLBullish &&
|
||||
conditions.pvConditions.isHCBullish &&
|
||||
conditions.pvConditions.isHCHHBullish &&
|
||||
conditions.pvConditions.isHCLLBullish
|
||||
//
|
||||
)
|
||||
//
|
||||
)
|
||||
//
|
||||
)
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
// Apply Filter ...
|
||||
// Based On Symbol and Period ...
|
||||
// if necessary ...
|
||||
if (isGBPUSD)
|
||||
{
|
||||
//
|
||||
// MEDIUM ...
|
||||
if (isH1Period)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
//
|
||||
// Filter Short Conditions ...
|
||||
bool FilterShortConditions(
|
||||
X121SetupConditions &conditions, // Conditions
|
||||
int pusher, // Pushers
|
||||
string provider // Provider
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Generating Conditions Score ...
|
||||
double bullishScore = 0;
|
||||
double bearishScore = 0;
|
||||
conditions.GenerateScore(
|
||||
bullishScore,
|
||||
bearishScore //
|
||||
);
|
||||
|
||||
//
|
||||
bool isGBPUSD = symbolParser.IsGBPUSD(conditions.symbol);
|
||||
|
||||
//
|
||||
bool isM5Period = conditions.period == PERIOD_M5;
|
||||
bool isM15Period = conditions.period == PERIOD_M15;
|
||||
bool isH1Period = conditions.period == PERIOD_H1;
|
||||
bool isH4Period = conditions.period == PERIOD_H4;
|
||||
|
||||
//
|
||||
// Set Default Result to True ...
|
||||
result = true;
|
||||
|
||||
//
|
||||
// Global Conditions ...
|
||||
result =
|
||||
//
|
||||
result &&
|
||||
//
|
||||
!(
|
||||
//
|
||||
(
|
||||
//
|
||||
// XICH ...
|
||||
conditions.ichConditions.isClosedOverKijunSen &&
|
||||
conditions.ichConditions.isTenkanSenUnderKijunSen
|
||||
//
|
||||
)
|
||||
//
|
||||
||
|
||||
//
|
||||
(
|
||||
//
|
||||
// XICH ...
|
||||
conditions.ichConditions.isTenkanSenOverKijunSen
|
||||
//
|
||||
)
|
||||
//
|
||||
||
|
||||
//
|
||||
(
|
||||
//
|
||||
// XICH ...
|
||||
conditions.ichConditions.isSenkouSpanAUnderB &&
|
||||
!conditions.ichConditions.isSenkouSpanAUnderLast
|
||||
//
|
||||
)
|
||||
//
|
||||
||
|
||||
//
|
||||
(
|
||||
//
|
||||
// XPV ...
|
||||
conditions.pvConditions.isNewVale &&
|
||||
conditions.pvConditions.isNewValeUnderLast &&
|
||||
conditions.pvConditions.isFiboDecreased &&
|
||||
conditions.pvConditions.isSCBearish &&
|
||||
!conditions.pvConditions.isMCBearish &&
|
||||
//
|
||||
// XICH ...
|
||||
conditions.ichConditions.isClosedOverKijunSen &&
|
||||
//
|
||||
// XHK ...
|
||||
conditions.hkConditions.isHKSwitchedToBearish &&
|
||||
conditions.hkConditions.isSMHKSwitchedToBearish
|
||||
|
||||
)
|
||||
//
|
||||
||
|
||||
//
|
||||
(
|
||||
//
|
||||
// XPV ...
|
||||
conditions.pvConditions.isNewVale &&
|
||||
conditions.pvConditions.isNewValeUnderLast &&
|
||||
conditions.pvConditions.isFiboDecreased &&
|
||||
!conditions.pvConditions.isSCBearish &&
|
||||
!conditions.pvConditions.isSCHHBearish &&
|
||||
//
|
||||
// XVLM ...
|
||||
conditions.vlmConditions.isVolumeBearish &&
|
||||
!conditions.vlmConditions.isVolumeOverLast
|
||||
//
|
||||
)
|
||||
//
|
||||
||
|
||||
//
|
||||
(
|
||||
//
|
||||
(
|
||||
//
|
||||
// XPV ...
|
||||
conditions.pvConditions.isNewVale &&
|
||||
conditions.pvConditions.isNewValeUnderLast &&
|
||||
conditions.pvConditions.isFiboDecreased &&
|
||||
conditions.pvConditions.isCloseUnderFib1 &&
|
||||
conditions.pvConditions.isCloseUnderFib2 &&
|
||||
conditions.pvConditions.isCloseUnderFib3 &&
|
||||
conditions.pvConditions.isCloseUnderFib4 &&
|
||||
conditions.pvConditions.isCloseUnderFib5
|
||||
//
|
||||
)
|
||||
//
|
||||
&&
|
||||
//
|
||||
(
|
||||
//
|
||||
(
|
||||
//
|
||||
(
|
||||
//
|
||||
// XVLM ...
|
||||
conditions.vlmConditions.isVolumeBearish &&
|
||||
conditions.vlmConditions.isVolumeOverLast
|
||||
//
|
||||
)
|
||||
//
|
||||
&&
|
||||
//
|
||||
(
|
||||
//
|
||||
(
|
||||
//
|
||||
conditions.pvConditions.isSCBearish &&
|
||||
conditions.pvConditions.isSCHHBearish &&
|
||||
conditions.pvConditions.isSCLLBearish &&
|
||||
conditions.pvConditions.isMCBearish &&
|
||||
conditions.pvConditions.isMCHHBearish &&
|
||||
conditions.pvConditions.isMCLLBearish &&
|
||||
conditions.pvConditions.isLCBearish &&
|
||||
conditions.pvConditions.isLCHHBearish &&
|
||||
conditions.pvConditions.isLCLLBearish &&
|
||||
conditions.pvConditions.isHCBearish &&
|
||||
conditions.pvConditions.isHCHHBearish &&
|
||||
conditions.pvConditions.isHCLLBearish &&
|
||||
//
|
||||
// XICH ...
|
||||
conditions.ichConditions.isClosedUnderKijunSen &&
|
||||
conditions.ichConditions.isTenkanSenUnderKijunSen &&
|
||||
conditions.ichConditions.isSenkouSpanAUnderB &&
|
||||
conditions.ichConditions.isSenkouSpanAUnderLast &&
|
||||
conditions.ichConditions.isFutureSenkouSpanAUnderB &&
|
||||
conditions.ichConditions.isFutureSenkouSpanAUnderLast &&
|
||||
conditions.ichConditions.isSenkouSpanACrossedUnderLast
|
||||
//
|
||||
)
|
||||
//
|
||||
||
|
||||
//
|
||||
(
|
||||
//
|
||||
// XICH ...
|
||||
conditions.ichConditions.isSenkouSpanACrossedUnderB
|
||||
//
|
||||
)
|
||||
//
|
||||
)
|
||||
//
|
||||
)
|
||||
//
|
||||
||
|
||||
//
|
||||
(
|
||||
//
|
||||
// XRL ...
|
||||
conditions.rlConditions.isFastBearish &&
|
||||
conditions.rlConditions.isSlowBearish &&
|
||||
conditions.rlConditions.isFastOverSlow &&
|
||||
conditions.rlConditions.isVerifierBearish
|
||||
//
|
||||
)
|
||||
//
|
||||
)
|
||||
//
|
||||
&&
|
||||
//
|
||||
// XSCORES ...
|
||||
bullishScore < 5 &&
|
||||
bearishScore > bullishScore * 10
|
||||
//
|
||||
)
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
// Apply Filter ...
|
||||
// Based On Symbol and Period ...
|
||||
// if necessary ...
|
||||
if (isGBPUSD)
|
||||
{
|
||||
//
|
||||
// MEDIUM ...
|
||||
if (isH1Period)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "Indicator.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CiCustom. |
|
||||
//| Purpose: Class of custom indicators. |
|
||||
//| Derives from class CIndicator. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CiCustom : public CIndicator
|
||||
{
|
||||
protected:
|
||||
int m_num_params; // number of creation parameters
|
||||
MqlParam m_params[]; // creation parameters
|
||||
|
||||
public:
|
||||
CiCustom(void);
|
||||
~CiCustom(void);
|
||||
//--- methods of access to protected data
|
||||
bool NumBuffers(const int buffers);
|
||||
int NumParams(void) const { return(m_num_params); }
|
||||
ENUM_DATATYPE ParamType(const int ind) const;
|
||||
long ParamLong(const int ind) const;
|
||||
double ParamDouble(const int ind) const;
|
||||
string ParamString(const int ind) const;
|
||||
//--- method of identifying
|
||||
virtual int Type(void) const { return(IND_CUSTOM); }
|
||||
|
||||
protected:
|
||||
//--- methods of tuning
|
||||
virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CiCustom::CiCustom(void) : m_num_params(0)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CiCustom::~CiCustom(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Set number of buffers of indicator |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CiCustom::NumBuffers(const int buffers)
|
||||
{
|
||||
bool result=true;
|
||||
//---
|
||||
if(m_buffers_total==0)
|
||||
{
|
||||
m_buffers_total=buffers;
|
||||
return(true);
|
||||
}
|
||||
if(m_buffers_total!=buffers)
|
||||
{
|
||||
Shutdown();
|
||||
result=CreateBuffers(m_symbol,m_period,buffers);
|
||||
if(result)
|
||||
{
|
||||
//--- create buffers
|
||||
for(int i=0;i<m_buffers_total;i++)
|
||||
((CIndicatorBuffer*)At(i)).Name("LINE "+IntegerToString(i));
|
||||
}
|
||||
}
|
||||
//---
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Get type of specified parameter of creation |
|
||||
//+------------------------------------------------------------------+
|
||||
ENUM_DATATYPE CiCustom::ParamType(const int ind) const
|
||||
{
|
||||
if(ind>=m_num_params)
|
||||
return(WRONG_VALUE);
|
||||
//---
|
||||
return(m_params[ind].type);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Get specified parameter of creatiob as a long value |
|
||||
//+------------------------------------------------------------------+
|
||||
long CiCustom::ParamLong(const int ind) const
|
||||
{
|
||||
if(ind>=m_num_params)
|
||||
return(0);
|
||||
switch(m_params[ind].type)
|
||||
{
|
||||
case TYPE_DOUBLE:
|
||||
case TYPE_FLOAT:
|
||||
case TYPE_STRING:
|
||||
return(0);
|
||||
}
|
||||
//---
|
||||
return(m_params[ind].integer_value);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Get specified parameter of creation as a double value |
|
||||
//+------------------------------------------------------------------+
|
||||
double CiCustom::ParamDouble(const int ind) const
|
||||
{
|
||||
if(ind>=m_num_params)
|
||||
return(EMPTY_VALUE);
|
||||
switch(m_params[ind].type)
|
||||
{
|
||||
case TYPE_DOUBLE:
|
||||
case TYPE_FLOAT:
|
||||
break;
|
||||
default:
|
||||
return(EMPTY_VALUE);
|
||||
}
|
||||
//---
|
||||
return(m_params[ind].double_value);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Get specified parameter of creation as a string value |
|
||||
//+------------------------------------------------------------------+
|
||||
string CiCustom::ParamString(const int ind) const
|
||||
{
|
||||
if(ind>=m_num_params || m_params[ind].type!=TYPE_STRING)
|
||||
return("");
|
||||
//---
|
||||
return(m_params[ind].string_value);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize the indicator with universal parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CiCustom::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[])
|
||||
{
|
||||
int i;
|
||||
//--- tune
|
||||
if(m_buffers_total==0)
|
||||
m_buffers_total=256;
|
||||
if(CreateBuffers(symbol,period,m_buffers_total))
|
||||
{
|
||||
//--- string of status of drawing
|
||||
m_name ="Custom "+params[0].string_value;
|
||||
m_status="("+symbol+","+PeriodDescription();
|
||||
for(i=1;i<num_params;i++)
|
||||
{
|
||||
switch(params[i].type)
|
||||
{
|
||||
case TYPE_BOOL:
|
||||
m_status=m_status+","+((params[i].integer_value)?"true":"false");
|
||||
break;
|
||||
case TYPE_CHAR:
|
||||
case TYPE_UCHAR:
|
||||
case TYPE_SHORT:
|
||||
case TYPE_USHORT:
|
||||
case TYPE_INT:
|
||||
case TYPE_UINT:
|
||||
case TYPE_LONG:
|
||||
case TYPE_ULONG:
|
||||
m_status=m_status+","+IntegerToString(params[i].integer_value);
|
||||
break;
|
||||
case TYPE_COLOR:
|
||||
m_status=m_status+","+ColorToString((color)params[i].integer_value);
|
||||
break;
|
||||
case TYPE_DATETIME:
|
||||
m_status=m_status+","+TimeToString(params[i].integer_value);
|
||||
break;
|
||||
case TYPE_FLOAT:
|
||||
case TYPE_DOUBLE:
|
||||
m_status=m_status+","+DoubleToString(params[i].double_value);
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
m_status=m_status+",'"+params[i].string_value+"'";
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_status=m_status+") H="+IntegerToString(m_handle);
|
||||
//--- save settings
|
||||
ArrayResize(m_params,num_params);
|
||||
for(i=0;i<num_params;i++)
|
||||
{
|
||||
m_params[i].type =params[i].type;
|
||||
m_params[i].integer_value=params[i].integer_value;
|
||||
m_params[i].double_value =params[i].double_value;
|
||||
m_params[i].string_value =params[i].string_value;
|
||||
}
|
||||
m_num_params=num_params;
|
||||
//--- create buffers
|
||||
for(i=0;i<m_buffers_total;i++)
|
||||
((CIndicatorBuffer*)At(i)).Name("LINE "+IntegerToString(i));
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//--- error
|
||||
return(false);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,136 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Trend.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "Indicator.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CiADX. |
|
||||
//| Purpose: Class of the "Average Directional Index" indicator. |
|
||||
//| Derives from class CIndicator. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CiADX : public CIndicator
|
||||
{
|
||||
protected:
|
||||
int m_ma_period;
|
||||
|
||||
public:
|
||||
CiADX(void);
|
||||
~CiADX(void);
|
||||
//--- methods of access to protected data
|
||||
int MaPeriod(void) const { return (m_ma_period); }
|
||||
//--- method of creation
|
||||
bool Create(const string symbol, const ENUM_TIMEFRAMES period, const int ma_period);
|
||||
//--- methods of access to indicator data
|
||||
double Main(const int index) const;
|
||||
double Plus(const int index) const;
|
||||
double Minus(const int index) const;
|
||||
//--- method of identifying
|
||||
virtual int Type(void) const { return (IND_ADX); }
|
||||
|
||||
protected:
|
||||
//--- methods of tuning
|
||||
virtual bool Initialize(const string symbol, const ENUM_TIMEFRAMES period, const int num_params, const MqlParam ¶ms[]);
|
||||
bool Initialize(const string symbol, const ENUM_TIMEFRAMES period, const int ma_period);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CiADX::CiADX(void) : m_ma_period(-1)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CiADX::~CiADX(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create the "Average Directional Index" indicator |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CiADX::Create(const string symbol, const ENUM_TIMEFRAMES period, const int ma_period)
|
||||
{
|
||||
//--- check history
|
||||
if (!SetSymbolPeriod(symbol, period))
|
||||
return (false);
|
||||
//--- create
|
||||
m_handle = iADX(symbol, period, ma_period);
|
||||
//--- check result
|
||||
if (m_handle == INVALID_HANDLE)
|
||||
return (false);
|
||||
//--- indicator successfully created
|
||||
if (!Initialize(symbol, period, ma_period))
|
||||
{
|
||||
//--- initialization failed
|
||||
IndicatorRelease(m_handle);
|
||||
m_handle = INVALID_HANDLE;
|
||||
return (false);
|
||||
}
|
||||
//--- ok
|
||||
return (true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize the indicator with universal parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CiADX::Initialize(const string symbol, const ENUM_TIMEFRAMES period, const int num_params, const MqlParam ¶ms[])
|
||||
{
|
||||
return (Initialize(symbol, period, (int)params[0].integer_value));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize indicator with the special parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CiADX::Initialize(const string symbol, const ENUM_TIMEFRAMES period, const int ma_period)
|
||||
{
|
||||
if (CreateBuffers(symbol, period, 3))
|
||||
{
|
||||
//--- string of status of drawing
|
||||
m_name = "ADX";
|
||||
m_status = "(" + symbol + "," + PeriodDescription() + "," + IntegerToString(ma_period) + ") H=" + IntegerToString(m_handle);
|
||||
//--- save settings
|
||||
m_ma_period = ma_period;
|
||||
//--- create buffers
|
||||
((CIndicatorBuffer *)At(0)).Name("MAIN_LINE");
|
||||
((CIndicatorBuffer *)At(1)).Name("PLUS_LINE");
|
||||
((CIndicatorBuffer *)At(2)).Name("MINUS_LINE");
|
||||
//--- ok
|
||||
return (true);
|
||||
}
|
||||
//--- error
|
||||
return (false);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Access to Main buffer of "Average Directional Index" |
|
||||
//+------------------------------------------------------------------+
|
||||
double CiADX::Main(const int index) const
|
||||
{
|
||||
CIndicatorBuffer *buffer = At(0);
|
||||
//--- check
|
||||
if (buffer == NULL)
|
||||
return (EMPTY_VALUE);
|
||||
//---
|
||||
return (buffer.At(index));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Access to Plus buffer of "Average Directional Index" |
|
||||
//+------------------------------------------------------------------+
|
||||
double CiADX::Plus(const int index) const
|
||||
{
|
||||
CIndicatorBuffer *buffer = At(1);
|
||||
//--- check
|
||||
if (buffer == NULL)
|
||||
return (EMPTY_VALUE);
|
||||
//---
|
||||
return (buffer.At(index));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Access to Minus buffer of "Average Directional Index" |
|
||||
//+------------------------------------------------------------------+
|
||||
double CiADX::Minus(const int index) const
|
||||
{
|
||||
CIndicatorBuffer *buffer = At(2);
|
||||
//--- check
|
||||
if (buffer == NULL)
|
||||
return (EMPTY_VALUE);
|
||||
//---
|
||||
return (buffer.At(index));
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CiIchimoku. |
|
||||
//| Purpose: Class of the "Ichimoku Kinko Hyo" indicator. |
|
||||
//| Derives from class CIndicator. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CiIchimoku : public CIndicator
|
||||
{
|
||||
protected:
|
||||
int m_tenkan_sen;
|
||||
int m_kijun_sen;
|
||||
int m_senkou_span_b;
|
||||
|
||||
public:
|
||||
CiIchimoku(void);
|
||||
~CiIchimoku(void);
|
||||
//--- methods of access to protected data
|
||||
int TenkanSenPeriod(void) const { return (m_tenkan_sen); }
|
||||
int KijunSenPeriod(void) const { return (m_kijun_sen); }
|
||||
int SenkouSpanBPeriod(void) const { return (m_senkou_span_b); }
|
||||
//--- method of creation
|
||||
bool Create(const string symbol, const ENUM_TIMEFRAMES period,
|
||||
const int tenkan_sen, const int kijun_sen, const int senkou_span_b);
|
||||
//--- methods of access to indicator data
|
||||
double TenkanSen(const int index) const;
|
||||
double KijunSen(const int index) const;
|
||||
double SenkouSpanA(const int index) const;
|
||||
double SenkouSpanB(const int index) const;
|
||||
double ChinkouSpan(const int index) const;
|
||||
//--- method of identifying
|
||||
virtual int Type(void) const { return (IND_ICHIMOKU); }
|
||||
|
||||
protected:
|
||||
//--- methods of tuning
|
||||
virtual bool Initialize(const string symbol, const ENUM_TIMEFRAMES period, const int num_params, const MqlParam ¶ms[]);
|
||||
bool Initialize(const string symbol, const ENUM_TIMEFRAMES period,
|
||||
const int tenkan_sen, const int kijun_sen, const int senkou_span_b);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CiIchimoku::CiIchimoku(void) : m_tenkan_sen(-1),
|
||||
m_kijun_sen(-1),
|
||||
m_senkou_span_b(-1)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CiIchimoku::~CiIchimoku(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create indicator "Ichimoku Kinko Hyo" |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CiIchimoku::Create(const string symbol, const ENUM_TIMEFRAMES period,
|
||||
const int tenkan_sen, const int kijun_sen, const int senkou_span_b)
|
||||
{
|
||||
//--- check history
|
||||
if (!SetSymbolPeriod(symbol, period))
|
||||
return (false);
|
||||
//--- create
|
||||
m_handle = iIchimoku(symbol, period, tenkan_sen, kijun_sen, senkou_span_b);
|
||||
//--- check result
|
||||
if (m_handle == INVALID_HANDLE)
|
||||
return (false);
|
||||
//--- indicator successfully created
|
||||
if (!Initialize(symbol, period, tenkan_sen, kijun_sen, senkou_span_b))
|
||||
{
|
||||
//--- initialization failed
|
||||
IndicatorRelease(m_handle);
|
||||
m_handle = INVALID_HANDLE;
|
||||
return (false);
|
||||
}
|
||||
//--- ok
|
||||
return (true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize the indicator with universal parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CiIchimoku::Initialize(const string symbol, const ENUM_TIMEFRAMES period, const int num_params, const MqlParam ¶ms[])
|
||||
{
|
||||
return (Initialize(symbol, period, (int)params[0].integer_value, (int)params[1].integer_value, (int)params[2].integer_value));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize indicator with the special parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CiIchimoku::Initialize(const string symbol, const ENUM_TIMEFRAMES period,
|
||||
const int tenkan_sen, const int kijun_sen, const int senkou_span_b)
|
||||
{
|
||||
if (CreateBuffers(symbol, period, 5))
|
||||
{
|
||||
//--- string of status of drawing
|
||||
m_name = "Ichimoku";
|
||||
m_status = "(" + symbol + "," + PeriodDescription() + "," +
|
||||
IntegerToString(tenkan_sen) + "," + IntegerToString(kijun_sen) + "," +
|
||||
IntegerToString(senkou_span_b) + ") H=" + IntegerToString(m_handle);
|
||||
//--- save settings
|
||||
m_tenkan_sen = tenkan_sen;
|
||||
m_kijun_sen = kijun_sen;
|
||||
m_senkou_span_b = senkou_span_b;
|
||||
//--- create buffers
|
||||
((CIndicatorBuffer *)At(0)).Name("TENKANSEN_LINE");
|
||||
((CIndicatorBuffer *)At(1)).Name("KIJUNSEN_LINE");
|
||||
((CIndicatorBuffer *)At(2)).Name("SENKOUSPANA_LINE");
|
||||
((CIndicatorBuffer *)At(2)).Offset(kijun_sen);
|
||||
((CIndicatorBuffer *)At(3)).Name("SENKOUSPANB_LINE");
|
||||
((CIndicatorBuffer *)At(3)).Offset(kijun_sen);
|
||||
((CIndicatorBuffer *)At(4)).Name("CHIKOUSPAN_LINE");
|
||||
((CIndicatorBuffer *)At(4)).Offset(-kijun_sen);
|
||||
//--- ok
|
||||
return (true);
|
||||
}
|
||||
//--- error
|
||||
return (false);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Access to TenkanSen buffer of "Ichimoku Kinko Hyo" |
|
||||
//+------------------------------------------------------------------+
|
||||
double CiIchimoku::TenkanSen(const int index) const
|
||||
{
|
||||
CIndicatorBuffer *buffer = At(0);
|
||||
//--- check
|
||||
if (buffer == NULL)
|
||||
return (EMPTY_VALUE);
|
||||
//---
|
||||
return (buffer.At(index));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Access to KijunSen buffer of "Ichimoku Kinko Hyo" |
|
||||
//+------------------------------------------------------------------+
|
||||
double CiIchimoku::KijunSen(const int index) const
|
||||
{
|
||||
CIndicatorBuffer *buffer = At(1);
|
||||
//--- check
|
||||
if (buffer == NULL)
|
||||
return (EMPTY_VALUE);
|
||||
//---
|
||||
return (buffer.At(index));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Access to SenkouSpanA buffer of "Ichimoku Kinko Hyo" |
|
||||
//+------------------------------------------------------------------+
|
||||
double CiIchimoku::SenkouSpanA(const int index) const
|
||||
{
|
||||
CIndicatorBuffer *buffer = At(2);
|
||||
//--- check
|
||||
if (buffer == NULL)
|
||||
return (EMPTY_VALUE);
|
||||
//---
|
||||
return (buffer.At(index));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Access to SenkouSpanB buffer of "Ichimoku Kinko Hyo" |
|
||||
//+------------------------------------------------------------------+
|
||||
double CiIchimoku::SenkouSpanB(const int index) const
|
||||
{
|
||||
CIndicatorBuffer *buffer = At(3);
|
||||
//--- check
|
||||
if (buffer == NULL)
|
||||
return (EMPTY_VALUE);
|
||||
//---
|
||||
return (buffer.At(index));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Access to ChikouSpan buffer of "Ichimoku Kinko Hyo" |
|
||||
//+------------------------------------------------------------------+
|
||||
double CiIchimoku::ChinkouSpan(const int index) const
|
||||
{
|
||||
CIndicatorBuffer *buffer = At(4);
|
||||
//--- check
|
||||
if (buffer == NULL)
|
||||
return (EMPTY_VALUE);
|
||||
//---
|
||||
return (buffer.At(index));
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,115 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| DCC_Piercing.mq5 |
|
||||
//| Rajesh Nait, Copyright 2023 |
|
||||
//| https://www.mql5.com/en/users/rajeshnait/seller |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Rajesh Nait, Copyright 2023"
|
||||
#property link "https://www.mql5.com/en/users/rajeshnait/seller"
|
||||
#property version "1.00"
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 2
|
||||
#property indicator_plots 2
|
||||
|
||||
//--- plot Bullish Marubozu
|
||||
#property indicator_label1 "+DCCP"
|
||||
#property indicator_type1 DRAW_ARROW
|
||||
#property indicator_color1 clrSnow
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
//--- plot Bearish Marubozu
|
||||
#property indicator_label2 "-DCCP"
|
||||
#property indicator_type2 DRAW_ARROW
|
||||
#property indicator_color2 clrSnow
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 1
|
||||
|
||||
|
||||
//--- input parameters
|
||||
input group "Bearish"
|
||||
input uchar InpBullishDCCPCode = 217; // BullishDCCP: code for style DRAW_ARROW (font Wingdings)
|
||||
input int InpBullishDCCPShift = 10; // BullishDCCP: vertical shift of arrows in pixels
|
||||
input group "Bullish"
|
||||
input uchar InpBearishDCCPCode = 218; // BearishDCCP: code for style DRAW_ARROW (font Wingdings)
|
||||
input int InpBearishDCCPShift =10; // BearishDCCP: vertical shift of arrows in pixels
|
||||
//--- indicator buffers
|
||||
double BullishDCCPBuffer[];
|
||||
double BearishDCCPBuffer[];
|
||||
int min_rates_total;
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit() {
|
||||
min_rates_total=2;
|
||||
//--- indicator buffers mapping
|
||||
SetIndexBuffer(0,BullishDCCPBuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(1,BearishDCCPBuffer,INDICATOR_DATA);
|
||||
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,Digits());
|
||||
//--- setting a code from the Wingdings charset as the property of PLOT_ARROW
|
||||
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,min_rates_total);
|
||||
PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,min_rates_total);
|
||||
|
||||
PlotIndexSetInteger(0,PLOT_ARROW,InpBullishDCCPCode);
|
||||
PlotIndexSetInteger(1,PLOT_ARROW,InpBearishDCCPCode);
|
||||
|
||||
ArraySetAsSeries(BullishDCCPBuffer,true);
|
||||
ArraySetAsSeries(BearishDCCPBuffer,true);
|
||||
|
||||
//--- set the vertical shift of arrows in pixels
|
||||
PlotIndexSetInteger(0,PLOT_ARROW_SHIFT,InpBullishDCCPShift);
|
||||
PlotIndexSetInteger(1,PLOT_ARROW_SHIFT,-InpBearishDCCPShift);
|
||||
//--- set as an empty value 0.0
|
||||
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
|
||||
PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0);
|
||||
//---
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| 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[]) {
|
||||
//---
|
||||
if(rates_total<min_rates_total)
|
||||
return(0);
|
||||
|
||||
int limit;
|
||||
|
||||
if(prev_calculated>rates_total || prev_calculated<=0) {
|
||||
limit=rates_total-min_rates_total;
|
||||
} else {
|
||||
limit=rates_total-prev_calculated;
|
||||
}
|
||||
ArraySetAsSeries(open,true);
|
||||
ArraySetAsSeries(high,true);
|
||||
ArraySetAsSeries(low,true);
|
||||
ArraySetAsSeries(close,true);
|
||||
|
||||
//---
|
||||
|
||||
for(int i=limit; i>=0 && !IsStopped(); i--) {
|
||||
BullishDCCPBuffer[i]=0.0;
|
||||
BearishDCCPBuffer[i]=0.0;
|
||||
|
||||
|
||||
BearishDCCPBuffer[0]=0.0;
|
||||
if(open[i]>close[i] && open[i+1]<close[i+1] && open[i]>close[i+1])
|
||||
BearishDCCPBuffer[i]=high[i];
|
||||
|
||||
BullishDCCPBuffer[0]=0.0;
|
||||
if(open[i]<close[i] && open[i+1]>close[i+1] && open[i]<close[i+1])
|
||||
BullishDCCPBuffer[i]=low[i];
|
||||
|
||||
}
|
||||
//--- return value of prev_calculated for next call
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,99 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Dominant.mq5 |
|
||||
//| Copyright 2024, Rajesh Kumar Nait |
|
||||
//| https://www.mql5.com/en/users/rajeshnait/seller |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2024, Rajesh Kumar Nait"
|
||||
#property link "https://www.mql5.com/en/users/rajeshnait/seller"
|
||||
#property version "1.00"
|
||||
#property indicator_chart_window
|
||||
#property indicator_plots 0
|
||||
string prefix="c_";
|
||||
input int total = 1000; // Number of Bars
|
||||
input color clr = clrSnow; // Adjust color as required
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit() {
|
||||
//--- indicator buffers mapping
|
||||
|
||||
//---
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason) {
|
||||
ObjectsDeleteAll(0,prefix);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| 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[]) {
|
||||
//---
|
||||
ArraySetAsSeries(open,true);
|
||||
ArraySetAsSeries(high,true);
|
||||
ArraySetAsSeries(low,true);
|
||||
ArraySetAsSeries(close,true);
|
||||
ArraySetAsSeries(time,true);
|
||||
|
||||
if(rates_total<total) {
|
||||
Print("Required Bars not available");
|
||||
return(rates_total);
|
||||
}
|
||||
|
||||
for(int i=1; i<total; i++) {
|
||||
//bullish
|
||||
if(open[i]<close[i] && open[i+1]<close[i+1] && open[i]>=close[i+1] && low[i]<close[i+1] && high[i+1]>open[i])
|
||||
crearFlecha(prefix+"Bull_Dominanat"+IntegerToString(i),time[i],low[i+1],clr,225,ANCHOR_TOP);
|
||||
|
||||
if(open[i]>close[i] && open[i+1]>close[i+1] && open[i]<=close[i+1] && high[i]>close[i+1] && low[i+1]<open[i])
|
||||
crearFlecha(prefix+"Bear_Dominanat"+IntegerToString(i),time[i],high[i+1],clr,226,ANCHOR_BOTTOM);
|
||||
}
|
||||
|
||||
//--- return value of prev_calculated for next call
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| CREATE ARROWS
|
||||
//+------------------------------------------------------------------+
|
||||
bool crearFlecha(string nameAux, datetime timeAux, double priceAux, color clrAux, int code, ENUM_ARROW_ANCHOR anchorAux) {
|
||||
const long chart_ID=0; // chart's ID
|
||||
const string name=nameAux; // arrow name
|
||||
const int sub_window=0; // subwindow index
|
||||
datetime time=timeAux; // anchor point time
|
||||
double price=priceAux; // anchor point price
|
||||
const int arrow_code=code; // arrow code
|
||||
const ENUM_ARROW_ANCHOR anchor=anchorAux; // anchor point position
|
||||
const color clr_=clrAux; // arrow color
|
||||
const ENUM_LINE_STYLE style=STYLE_SOLID; // border line style
|
||||
const int width=1; // arrow size
|
||||
const bool back=true; // in the background
|
||||
const bool selection=false; // highlight to move
|
||||
const bool hidden=true; // hidden in the object list
|
||||
const long z_order=0; // priority for mouse click
|
||||
|
||||
ObjectCreate(chart_ID,name,OBJ_ARROW,sub_window,time,price);
|
||||
ObjectSetInteger(chart_ID,name,OBJPROP_ARROWCODE,arrow_code);
|
||||
ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchorAux);
|
||||
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr_);
|
||||
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
|
||||
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
|
||||
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
|
||||
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
|
||||
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
|
||||
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
|
||||
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,105 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Fair_Value_Gap.mq5 |
|
||||
//| Copyright 2024, Rajesh Kumar Nait |
|
||||
//| https://www.mql5.com/en/users/rajeshnait/seller |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2024, Rajesh Kumar Nait"
|
||||
#property link "https://www.mql5.com/en/users/rajeshnait/seller"
|
||||
#property version "1.00"
|
||||
#property indicator_chart_window
|
||||
#property indicator_plots 0
|
||||
|
||||
|
||||
//--- input parameters
|
||||
input color InpColorToUP = clrLime; // Color of the gap up
|
||||
input color InpColorToDN = clrDeepPink; // Color of the gap down
|
||||
input int maxbars = 300;// how many bars to Look back
|
||||
|
||||
string prefix;
|
||||
double price;
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit() {
|
||||
//--- indicator buffers mapping
|
||||
prefix=MQLInfoString(MQL_PROGRAM_NAME)+"_";
|
||||
//---
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason) {
|
||||
ObjectsDeleteAll(0,prefix);
|
||||
ChartRedraw();
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| 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[]) {
|
||||
//---
|
||||
if(rates_total<4) return 0;
|
||||
price = close[0];
|
||||
ArraySetAsSeries(open,true);
|
||||
ArraySetAsSeries(high,true);
|
||||
ArraySetAsSeries(low,true);
|
||||
ArraySetAsSeries(close,true);
|
||||
ArraySetAsSeries(time,true);
|
||||
int limit=rates_total-prev_calculated;
|
||||
if(limit>1) {
|
||||
limit=rates_total-5;
|
||||
}
|
||||
for(int i=maxbars; i>=0 && !IsStopped(); i--) {
|
||||
if(low[i]-high[i+2]>=Point()) {
|
||||
|
||||
double up=fmin(high[i],low[i]);
|
||||
double dn=fmax(high[i+2],low[i+2]);
|
||||
|
||||
DrawArea(i,up,dn,time,InpColorToUP,1);
|
||||
|
||||
}
|
||||
if(low[i+2]-high[i]>=Point()) {
|
||||
|
||||
double up=fmin(high[i+2],low[i+2]);
|
||||
double dn=fmax(high[i],low[i]);
|
||||
DrawArea(i,up,dn,time,InpColorToDN,0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--- return value of prev_calculated for next call
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
void DrawArea(const int index, const double price_up,const double price_dn,const datetime &time[],const color color_area,const char dir) {
|
||||
string name=prefix+(dir>0 ? "up_" : "dn_")+TimeToString(time[index]);
|
||||
|
||||
if(ObjectFind(0,name)<0 )
|
||||
ObjectCreate(0,name,OBJ_RECTANGLE,0,0,0,0);
|
||||
ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
|
||||
ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);
|
||||
ObjectSetInteger(0,name,OBJPROP_FILL,true);
|
||||
ObjectSetInteger(0,name,OBJPROP_BACK,true);
|
||||
ObjectSetString(0,name,OBJPROP_TOOLTIP,"\n");
|
||||
//---
|
||||
ObjectSetInteger(0,name,OBJPROP_COLOR,color_area);
|
||||
ObjectSetInteger(0,name,OBJPROP_TIME,0,time[index+2]);
|
||||
ObjectSetInteger(0,name,OBJPROP_TIME,1,time[index]);
|
||||
ObjectSetDouble(0,name,OBJPROP_PRICE,0,price_up);
|
||||
ObjectSetDouble(0,name,OBJPROP_PRICE,1,price_dn);
|
||||
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,111 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Geometric Moving Average.mq5 |
|
||||
//| Copyright 2024, Rosh Jardine |
|
||||
//| https://www.mql5.com/en/users/roshjardine |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2024, Lyn Astara"
|
||||
#property link "https://www.mql5.com/en/users/roshjardine"
|
||||
#property version "1.00"
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 1
|
||||
#property indicator_plots 1
|
||||
//--- plot GeoMALine
|
||||
#property indicator_label1 "GeoMALine"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrRed
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
|
||||
input int InputGeoMAPeriod = 7;
|
||||
input int InputGeoMAShift = 0;
|
||||
input ENUM_APPLIED_PRICE InputAppliedPriceEnum = PRICE_CLOSE;
|
||||
//--- indicator buffers
|
||||
double GeoMALineBuffer[];
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- indicator buffers mapping
|
||||
SetIndexBuffer(0,GeoMALineBuffer,INDICATOR_DATA);
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
|
||||
/*** setting values of the indicator that won't be visible on a chart ***/
|
||||
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);
|
||||
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InputGeoMAPeriod);
|
||||
//--- line shifts when drawing
|
||||
PlotIndexSetInteger(0,PLOT_SHIFT,InputGeoMAShift);
|
||||
string short_name = "GeoMA-"+EnumToString(InputAppliedPriceEnum)+"("+IntegerToString(InputGeoMAPeriod)+")";
|
||||
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
|
||||
/*const double x = double(1)/double(4);
|
||||
double t = MathPow(90,x);
|
||||
Print("t=",DoubleToString(t,4));*/
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| 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[])
|
||||
{
|
||||
double p_t = 0.0; double p_0 = 0.0; static const double x = double(1)/double(InputGeoMAPeriod);
|
||||
if (rates_total<=0) { return(0); }
|
||||
|
||||
if (prev_calculated<=0)
|
||||
{
|
||||
p_t = GET_APPLIED_PRICE(open[0],low[0],high[0],close[0]);
|
||||
GeoMALineBuffer[0] = EMPTY_VALUE;
|
||||
for (int i=1; i<InputGeoMAPeriod; i++)
|
||||
{
|
||||
p_t *= GET_APPLIED_PRICE(open[i],low[i],high[i],close[i]);
|
||||
}
|
||||
GeoMALineBuffer[InputGeoMAPeriod-1] = MathPow(p_t,x);
|
||||
for (int i=InputGeoMAPeriod; i<rates_total; i++)
|
||||
{
|
||||
p_0 = p_t/GET_APPLIED_PRICE(open[i-InputGeoMAPeriod],low[i-InputGeoMAPeriod],high[i-InputGeoMAPeriod],close[i-InputGeoMAPeriod]);
|
||||
p_t = p_0*GET_APPLIED_PRICE(open[i],low[i],high[i],close[i]);
|
||||
GeoMALineBuffer[i] = MathPow(p_t,x);
|
||||
}
|
||||
return(rates_total);
|
||||
}
|
||||
for (int i=prev_calculated; i<=rates_total-1; i++)
|
||||
{
|
||||
p_0 = p_t/GET_APPLIED_PRICE(open[i-InputGeoMAPeriod],low[i-InputGeoMAPeriod],high[i-InputGeoMAPeriod],close[i-InputGeoMAPeriod]);
|
||||
p_t = p_0*GET_APPLIED_PRICE(open[i],low[i],high[i],close[i]);
|
||||
GeoMALineBuffer[i] = MathPow(p_t,x);
|
||||
}
|
||||
//--- return value of prev_calculated for next call
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
double GET_APPLIED_PRICE(const double ParamOpenPriceDouble,const double ParamLowPriceDouble,
|
||||
const double ParamHighPriceDouble,const double ParamClosePriceDouble)
|
||||
{
|
||||
//+----------------------------------------------------------------------------------------------------------------------------------------+
|
||||
/*** close price as the default ***/
|
||||
double PriceResultDouble = ParamClosePriceDouble;
|
||||
int AppliedPriceInt = int(InputAppliedPriceEnum);
|
||||
//+----------------------------------------------------------------------------------------------------------------------------------------+
|
||||
switch(AppliedPriceInt)
|
||||
{
|
||||
case 1 : PriceResultDouble = ParamOpenPriceDouble; break;
|
||||
case 2 : PriceResultDouble = ParamLowPriceDouble; break;
|
||||
case 3 : PriceResultDouble = ParamHighPriceDouble; break;
|
||||
case 4 : PriceResultDouble = ParamClosePriceDouble; break;
|
||||
/*** Median price ***/
|
||||
case 5 : PriceResultDouble = (ParamHighPriceDouble + ParamLowPriceDouble)/2; break;
|
||||
/*** Typical price ***/
|
||||
case 6 : PriceResultDouble = (ParamHighPriceDouble + ParamLowPriceDouble + ParamClosePriceDouble)/3; break;
|
||||
/*** Weighted price ***/
|
||||
default : PriceResultDouble = (ParamHighPriceDouble + ParamLowPriceDouble + ParamClosePriceDouble + ParamClosePriceDouble)/4; break;
|
||||
}
|
||||
return(PriceResultDouble);
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,110 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Harmonic Moving Average.mq5 |
|
||||
//| Copyright 2024, Rosh Jardine |
|
||||
//| https://www.mql5.com/en/users/roshjardine |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2024, Rosh Jardine"
|
||||
#property link "https://www.mql5.com/en/users/roshjardine"
|
||||
#property version "1.00"
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 1
|
||||
#property indicator_plots 1
|
||||
//--- plot HMALine
|
||||
#property indicator_label1 "HMALine"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrRed
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
|
||||
input int InputHMAPeriod = 7;
|
||||
input int InputHMAShift = 0;
|
||||
input ENUM_APPLIED_PRICE InputAppliedPriceEnum = PRICE_CLOSE;
|
||||
//--- indicator buffers
|
||||
double HMALineBuffer[];
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- indicator buffers mapping
|
||||
SetIndexBuffer(0,HMALineBuffer,INDICATOR_DATA);
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
|
||||
/*** setting values of the indicator that won't be visible on a chart ***/
|
||||
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);
|
||||
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InputHMAShift);
|
||||
//--- line shifts when drawing
|
||||
PlotIndexSetInteger(0,PLOT_SHIFT,InputHMAShift);
|
||||
string short_name = "HMA-"+EnumToString(InputAppliedPriceEnum)+"("+IntegerToString(InputHMAPeriod)+")";
|
||||
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| 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[])
|
||||
{
|
||||
if (rates_total<=0) { return(0); }
|
||||
|
||||
if (prev_calculated<=0)
|
||||
{
|
||||
double rsd = 0.0;
|
||||
for (int i=0; i<InputHMAPeriod; i++)
|
||||
{
|
||||
rsd += double(1/GET_APPLIED_PRICE(open[i],low[i],high[i],close[i]));
|
||||
HMALineBuffer[i] = 0.0;
|
||||
}
|
||||
HMALineBuffer[InputHMAPeriod-1] = InputHMAPeriod/rsd;
|
||||
|
||||
for (int i=InputHMAPeriod; i<rates_total; i++)
|
||||
{
|
||||
double lrs = InputHMAPeriod/HMALineBuffer[i-1];
|
||||
double vlfr = 1/GET_APPLIED_PRICE(open[i-InputHMAPeriod],low[i-InputHMAPeriod],high[i-InputHMAPeriod],close[i-InputHMAPeriod]);
|
||||
HMALineBuffer[i] = InputHMAPeriod/(lrs-vlfr+(1/GET_APPLIED_PRICE(open[i],low[i],high[i],close[i])));
|
||||
}
|
||||
return(rates_total);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i=prev_calculated; i<=rates_total-1; i++)
|
||||
{
|
||||
double lrs = double(InputHMAPeriod)/HMALineBuffer[i-1];
|
||||
double vlfr = 1/GET_APPLIED_PRICE(open[i-InputHMAPeriod],low[i-InputHMAPeriod],high[i-InputHMAPeriod],close[i-InputHMAPeriod]);
|
||||
HMALineBuffer[i] = InputHMAPeriod/(lrs-vlfr+(1/GET_APPLIED_PRICE(open[i],low[i],high[i],close[i])));
|
||||
}
|
||||
return(rates_total);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
double GET_APPLIED_PRICE(const double ParamOpenPriceDouble,const double ParamLowPriceDouble,
|
||||
const double ParamHighPriceDouble,const double ParamClosePriceDouble)
|
||||
{
|
||||
//+----------------------------------------------------------------------------------------------------------------------------------------+
|
||||
/*** close price as the default ***/
|
||||
double PriceResultDouble = ParamClosePriceDouble;
|
||||
int AppliedPriceInt = int(InputAppliedPriceEnum);
|
||||
//+----------------------------------------------------------------------------------------------------------------------------------------+
|
||||
switch(AppliedPriceInt)
|
||||
{
|
||||
case 1 : PriceResultDouble = ParamOpenPriceDouble; break;
|
||||
case 2 : PriceResultDouble = ParamLowPriceDouble; break;
|
||||
case 3 : PriceResultDouble = ParamHighPriceDouble; break;
|
||||
case 4 : PriceResultDouble = ParamClosePriceDouble; break;
|
||||
/*** Median price ***/
|
||||
case 5 : PriceResultDouble = (ParamHighPriceDouble + ParamLowPriceDouble)/2; break;
|
||||
/*** Typical price ***/
|
||||
case 6 : PriceResultDouble = (ParamHighPriceDouble + ParamLowPriceDouble + ParamClosePriceDouble)/3; break;
|
||||
/*** Weighted price ***/
|
||||
default : PriceResultDouble = (ParamHighPriceDouble + ParamLowPriceDouble + ParamClosePriceDouble + ParamClosePriceDouble)/4; break;
|
||||
}
|
||||
return(PriceResultDouble);
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,96 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Marubozu.mq5 |
|
||||
//| Rajesh Nait, Copyright 2023 |
|
||||
//| https://www.mql5.com/en/users/rajeshnait/seller |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Rajesh Nait, Copyright 2023"
|
||||
#property link "https://www.mql5.com/en/users/rajeshnait/seller"
|
||||
#property version "1.00"
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 2
|
||||
#property indicator_plots 2
|
||||
|
||||
//--- plot Bullish Marubozu
|
||||
#property indicator_label1 "+M"
|
||||
#property indicator_type1 DRAW_ARROW
|
||||
#property indicator_color1 clrLimeGreen
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
//--- plot Bearish Marubozu
|
||||
#property indicator_label2 "-M"
|
||||
#property indicator_type2 DRAW_ARROW
|
||||
#property indicator_color2 clrDeepPink
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 1
|
||||
|
||||
//--- input parameters
|
||||
input group "Bullish Marubozu"
|
||||
sinput uchar InpBullishMarubozuCode = 167; // Bullish Marubozu: code for style DRAW_ARROW (font Wingdings)
|
||||
sinput int InpBullishMarubozuShift = 10; // Bullish Marubozu: vertical shift of arrows in pixels
|
||||
input group "Bearish Marubozu"
|
||||
sinput uchar InpBearishMarubozuCode = 167; // Bearish Marubozu: code for style DRAW_ARROW (font Wingdings)
|
||||
sinput int InpBearishMarubozuShift = 10; // Bearish Marubozu: vertical shift of arrows in pixels
|
||||
//--- indicator buffers
|
||||
double BullishMarubozuBuffer[];
|
||||
double BearishMarubozuBuffer[];
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit() {
|
||||
//--- indicator buffers mapping
|
||||
//--- indicator buffers mapping
|
||||
SetIndexBuffer(0,BullishMarubozuBuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(1,BearishMarubozuBuffer,INDICATOR_DATA);
|
||||
//--- setting a code from the Wingdings charset as the property of PLOT_ARROW
|
||||
PlotIndexSetInteger(0,PLOT_ARROW,InpBullishMarubozuCode);
|
||||
PlotIndexSetInteger(1,PLOT_ARROW,InpBearishMarubozuCode);
|
||||
//--- set the vertical shift of arrows in pixels
|
||||
PlotIndexSetInteger(0,PLOT_ARROW_SHIFT,InpBullishMarubozuShift);
|
||||
PlotIndexSetInteger(1,PLOT_ARROW_SHIFT,-InpBearishMarubozuShift);
|
||||
//--- set as an empty value 0.0
|
||||
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
|
||||
PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0);
|
||||
//---
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| 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[]) {
|
||||
//---
|
||||
if(rates_total<3)
|
||||
return(0);
|
||||
//---
|
||||
int limit=prev_calculated-1;
|
||||
if(prev_calculated==0) {
|
||||
limit=1;
|
||||
BullishMarubozuBuffer[0]=0.0;
|
||||
BearishMarubozuBuffer[0]=0.0;
|
||||
}
|
||||
for(int i=limit; i<rates_total; i++) {
|
||||
BullishMarubozuBuffer[i]=0.0;
|
||||
BearishMarubozuBuffer[i]=0.0;
|
||||
if(i>0) {
|
||||
|
||||
if(open[i]==high[i] && close[i]==low[i]) {
|
||||
BearishMarubozuBuffer[i]=high[i];
|
||||
}
|
||||
|
||||
if(close[i]==high[i] && open[i]==low[i]) {
|
||||
BullishMarubozuBuffer[i]=low[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- return value of prev_calculated for next call
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,133 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| MinChangeSignal.mq5 |
|
||||
//| Copyright 2013, Rone. |
|
||||
//| rone.sergey@gmail.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2013, Rone."
|
||||
#property link "rone.sergey@gmail.com"
|
||||
#property version "1.00"
|
||||
#property description "The signal is formed if the changes sum calculated on the last bar "
|
||||
#property description "is less, than the smallest of sums calculated on the specified number of previous bars."
|
||||
//---
|
||||
#property indicator_separate_window
|
||||
#property indicator_buffers 3
|
||||
#property indicator_plots 3
|
||||
//--- plot CurrentChange
|
||||
#property indicator_label1 "Current Change Sum"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrBlue
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 2
|
||||
//--- plot MinChange
|
||||
#property indicator_label2 "Min Change Sum"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrRed
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 2
|
||||
//--- plot Signal
|
||||
#property indicator_label3 "Signal"
|
||||
#property indicator_type3 DRAW_ARROW
|
||||
#property indicator_color3 clrLime
|
||||
#property indicator_style3 STYLE_SOLID
|
||||
#property indicator_width3 3
|
||||
//--- input parameters
|
||||
input int InpChangesPeriod = 4; // Changes Period
|
||||
input int InpCheckPeriod = 10; // Check Period
|
||||
input bool InpAbsChange = false; // Abs Change
|
||||
//--- indicator buffers
|
||||
double CurrentSumBuffer[];
|
||||
double MinSumBuffer[];
|
||||
double SignalBuffer[];
|
||||
//---
|
||||
int changes_period;
|
||||
int check_period;
|
||||
int min_required_bars;
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit() {
|
||||
//---
|
||||
if ( InpChangesPeriod < 1 || InpCheckPeriod < 2 ) {
|
||||
changes_period = 3;
|
||||
check_period = 10;
|
||||
printf("Incorrect input value InpChangesPeriod = %d or/and InpCheckPeriod =%d. "
|
||||
"Indicator will use values %d and %d respectively.", InpChangesPeriod, InpCheckPeriod,
|
||||
changes_period, check_period);
|
||||
} else {
|
||||
changes_period = InpChangesPeriod;
|
||||
check_period = InpCheckPeriod;
|
||||
}
|
||||
min_required_bars = changes_period + check_period + 1;
|
||||
//--- indicator buffers mapping
|
||||
SetIndexBuffer(0, CurrentSumBuffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(1, MinSumBuffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(2, SignalBuffer, INDICATOR_DATA);
|
||||
//--- setting a code from the Wingdings charset as the property of PLOT_ARROW
|
||||
PlotIndexSetInteger(2, PLOT_ARROW, 159);
|
||||
//---
|
||||
for ( int plot = 0; plot < 3; plot++ ) {
|
||||
PlotIndexSetInteger(plot, PLOT_DRAW_BEGIN, min_required_bars - 1);
|
||||
PlotIndexSetInteger(plot, PLOT_SHIFT, 0);
|
||||
PlotIndexSetDouble(plot, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||
}
|
||||
//---
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, "Min Price Change ("+(string)changes_period
|
||||
+", "+(string)check_period+")");
|
||||
//---
|
||||
return(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator iteration function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const int begin,
|
||||
const double &price[])
|
||||
{
|
||||
//---
|
||||
int change_start_bar, check_start_bar, signal_start_bar;
|
||||
//---
|
||||
if ( rates_total < min_required_bars ) {
|
||||
Print("Not enough bars for calculations.");
|
||||
return(0);
|
||||
}
|
||||
//---
|
||||
if ( prev_calculated > rates_total || prev_calculated <= 0 ) {
|
||||
change_start_bar = changes_period;
|
||||
check_start_bar = change_start_bar + check_period;
|
||||
signal_start_bar = check_start_bar + 1;
|
||||
} else {
|
||||
change_start_bar = prev_calculated - 1;
|
||||
check_start_bar = change_start_bar;
|
||||
signal_start_bar = change_start_bar;
|
||||
}
|
||||
//---
|
||||
for ( int bar = change_start_bar; bar < rates_total; bar++ ) {
|
||||
double sum = 0.0;
|
||||
|
||||
for ( int shift = bar - changes_period + 1; shift <= bar; shift++ ) {
|
||||
if ( InpAbsChange ) {
|
||||
sum += MathAbs(price[shift] - price[shift-1]);
|
||||
} else {
|
||||
sum += price[shift] - price[shift-1];
|
||||
}
|
||||
}
|
||||
CurrentSumBuffer[bar] = MathAbs(sum);
|
||||
}
|
||||
for ( int bar = check_start_bar; bar < rates_total; bar++ ) {
|
||||
MinSumBuffer[bar] = CurrentSumBuffer[ArrayMinimum(CurrentSumBuffer,
|
||||
bar-check_period, check_period)];
|
||||
}
|
||||
for ( int bar = signal_start_bar; bar < rates_total; bar++ ) {
|
||||
SignalBuffer[bar] = EMPTY_VALUE;
|
||||
if ( CurrentSumBuffer[bar] < MinSumBuffer[bar]
|
||||
&& CurrentSumBuffer[bar-1] >= MinSumBuffer[bar-1] )
|
||||
{
|
||||
SignalBuffer[bar] = MinSumBuffer[bar];
|
||||
}
|
||||
}
|
||||
//--- return value of prev_calculated for next call
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,208 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Round price DOC.mq5 |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "mladen"
|
||||
#property link "mladenfx@gmail.com"
|
||||
#property version "1.00"
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 7
|
||||
#property indicator_plots 7
|
||||
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 Gold
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 DeepSkyBlue
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 DeepSkyBlue
|
||||
#property indicator_type4 DRAW_LINE
|
||||
#property indicator_color4 DeepSkyBlue
|
||||
#property indicator_type5 DRAW_LINE
|
||||
#property indicator_color5 PaleVioletRed
|
||||
#property indicator_type6 DRAW_LINE
|
||||
#property indicator_color6 PaleVioletRed
|
||||
#property indicator_type7 DRAW_LINE
|
||||
#property indicator_color7 PaleVioletRed
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
input int T3Period = 89; // T3 Calculation period
|
||||
input double T3Hot = 0.7; // T3 hot value
|
||||
input bool T3Original = false; // T3 original Tillson calculation?
|
||||
input ENUM_APPLIED_PRICE T3Price = PRICE_CLOSE; // T3 price to use
|
||||
input int Delta1 = 89; // Distance in points for first band
|
||||
input int Delta2 = 144; // Distance in points for second band
|
||||
input int Delta3 = 233; // Distance in points for third band
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
double t3[];
|
||||
double t3Up1[];
|
||||
double t3Up2[];
|
||||
double t3Up3[];
|
||||
double t3Dn1[];
|
||||
double t3Dn2[];
|
||||
double t3Dn3[];
|
||||
|
||||
double c1,c2,c3,c4,t3Alpha;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
int OnInit()
|
||||
{
|
||||
SetIndexBuffer( 0,t3 ,INDICATOR_DATA);
|
||||
SetIndexBuffer( 1,t3Up1,INDICATOR_DATA);
|
||||
SetIndexBuffer( 2,t3Up2,INDICATOR_DATA);
|
||||
SetIndexBuffer( 3,t3Up3,INDICATOR_DATA);
|
||||
SetIndexBuffer( 4,t3Dn1,INDICATOR_DATA);
|
||||
SetIndexBuffer( 5,t3Dn2,INDICATOR_DATA);
|
||||
SetIndexBuffer( 6,t3Dn3,INDICATOR_DATA);
|
||||
|
||||
PlotIndexSetString(0,PLOT_LABEL,"T3");
|
||||
for (int i=1; i<4; i++)
|
||||
{
|
||||
PlotIndexSetString(i ,PLOT_LABEL,"T3 upper band "+(string)i);
|
||||
PlotIndexSetString(i+3,PLOT_LABEL,"T3 lower band "+(string)i);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
double a = MathMax(MathMin(T3Hot,1),0.0001);;
|
||||
c1 = -a*a*a;
|
||||
c2 = 3*(a*a+a*a*a);
|
||||
c3 = -3*(2*a*a+a+a*a*a);
|
||||
c4 = 1+3*a+a*a*a+3*a*a;
|
||||
double t3period = T3Period;
|
||||
if (!T3Original) t3period = 1.0 + (t3period-1.0)/2.0;
|
||||
t3Alpha = 2.0/(1.0 + t3period);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
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 &TickVolume[],
|
||||
const long &Volume[],
|
||||
const int &Spread[])
|
||||
{
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
for (int i=(int)MathMax(prev_calculated-1,0); i<rates_total; i++)
|
||||
{
|
||||
double price;
|
||||
switch (T3Price)
|
||||
{
|
||||
case PRICE_CLOSE : price = Close[i]; break;
|
||||
case PRICE_OPEN : price = Open[i]; break;
|
||||
case PRICE_HIGH : price = High[i]; break;
|
||||
case PRICE_LOW : price = Low[i]; break;
|
||||
case PRICE_MEDIAN : price = (High[i]+Low[i])/2.0; break;
|
||||
case PRICE_TYPICAL : price = (High[i]+Low[i]+Close[i])/3.0; break;
|
||||
case PRICE_WEIGHTED : price = (High[i]+Low[i]+Close[i]+Close[i])/4.0; break;
|
||||
default : price = 0;
|
||||
}
|
||||
|
||||
t3[i] = calcT3(price,i,rates_total);
|
||||
t3Up1[i] = t3[i]+Delta1*_Point;
|
||||
t3Up2[i] = t3[i]+Delta2*_Point;
|
||||
t3Up3[i] = t3[i]+Delta3*_Point;
|
||||
t3Dn1[i] = t3[i]-Delta1*_Point;
|
||||
t3Dn2[i] = t3[i]-Delta2*_Point;
|
||||
t3Dn3[i] = t3[i]-Delta3*_Point;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
return(rates_total);
|
||||
}
|
||||
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
double t3Values[][6];
|
||||
double calcT3(double price, int r, int bars, int s=0)
|
||||
{
|
||||
if (ArrayRange(t3Values,0)!=bars) ArrayResize(t3Values,bars);
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
if (r < 2)
|
||||
{
|
||||
t3Values[r][s+0] = price;
|
||||
t3Values[r][s+1] = price;
|
||||
t3Values[r][s+2] = price;
|
||||
t3Values[r][s+3] = price;
|
||||
t3Values[r][s+4] = price;
|
||||
t3Values[r][s+5] = price;
|
||||
}
|
||||
else
|
||||
{
|
||||
t3Values[r][s+0] = t3Values[r-1][s+0]+t3Alpha*(price -t3Values[r-1][s+0]);
|
||||
t3Values[r][s+1] = t3Values[r-1][s+1]+t3Alpha*(t3Values[r][s+0]-t3Values[r-1][s+1]);
|
||||
t3Values[r][s+2] = t3Values[r-1][s+2]+t3Alpha*(t3Values[r][s+1]-t3Values[r-1][s+2]);
|
||||
t3Values[r][s+3] = t3Values[r-1][s+3]+t3Alpha*(t3Values[r][s+2]-t3Values[r-1][s+3]);
|
||||
t3Values[r][s+4] = t3Values[r-1][s+4]+t3Alpha*(t3Values[r][s+3]-t3Values[r-1][s+4]);
|
||||
t3Values[r][s+5] = t3Values[r-1][s+5]+t3Alpha*(t3Values[r][s+4]-t3Values[r-1][s+5]);
|
||||
}
|
||||
return(c1*t3Values[r][s+5] + c2*t3Values[r][s+4] + c3*t3Values[r][s+3] + c4*t3Values[r][s+2]);
|
||||
}
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,451 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Strong_Levels_V0.mq5 |
|
||||
//| Copyright 2023, MetaQuotes Ltd. |
|
||||
//| https://www.pipcrop.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2023, MetaQuotes Ltd."
|
||||
#property link "https://www.pipcrop.com"
|
||||
#property version "1.00"
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 0
|
||||
#property indicator_plots 0
|
||||
#property version "1.00"
|
||||
|
||||
#property description "Rule 1(bull candle on sup. level): if close - low > Jump Factor"
|
||||
#property description "Rule 2(bull candle on res. level): if close - low > Jump Factor & (close-low)/(high-low)>ratio"
|
||||
|
||||
#include <..\include\Math\Alglib\dataanalysis.mqh>
|
||||
CKMeans *Cclustering;
|
||||
|
||||
enum filterrules {
|
||||
rule1, // Rule 1
|
||||
rule12, // Rule 1+2
|
||||
rule2 // Rule 2
|
||||
};
|
||||
|
||||
input filterrules myfilters = 1; // Rule(s) for data gather
|
||||
input int LNo = 15; // Number of Levels to extract
|
||||
input ENUM_TIMEFRAMES tf0 = PERIOD_M1; // Analysing TF
|
||||
input double Jumpmulti = 100.0; // Min. Jump after touch (Percent of ATR)
|
||||
input double ratio = 0.6667; // Ratio
|
||||
input int ATRPer = 55; // ATR Period
|
||||
input color ResColor = clrPink; // Resistance color for Panel
|
||||
input color SupColor = clrPowderBlue; // Support color for Panel
|
||||
input color BGColor = C'23,27,38'; // Back-ground
|
||||
input color ResColor0 = clrRed; // Resistance Levels color
|
||||
input color SupColor0 = clrBlue; // Support Levels color
|
||||
input int LevelsInt = 2; // Levels Width
|
||||
|
||||
int ATRHndler, size0, xini=5, yini=20, maxbar, minbar=10, Ysize = 30, dyy=5, xdis = 0, lastbars = 0, LastLNo=0, minLN=3;
|
||||
int sup_xyz[], res_xyz[];
|
||||
long NextChart;
|
||||
string ToolName = "SH_Levels_", OBJName;
|
||||
double atr[], Jmulti;
|
||||
CMatrixDouble res_mat, sup_mat, supclusters, resclusters;
|
||||
bool startCluster = false;
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
ObjectsDeleteAll(0, ToolName);
|
||||
Jmulti = Jumpmulti/100.0;
|
||||
|
||||
ATRHndler = iATR(Symbol(), tf0, ATRPer);
|
||||
SetScreen();
|
||||
|
||||
maxbar = 100000;
|
||||
|
||||
OBJName = ToolName + "Analyse"; xdis = xini;
|
||||
ObjectCreate(0, OBJName, OBJ_BUTTON, 0, 0, 0);
|
||||
OBJSet(OBJName, "Analyse Sup./Res.", xini, yini, 180, 2*Ysize+dyy,12, C'240,240,240', clrNONE, clrBlack, ALIGN_CENTER, CORNER_LEFT_UPPER, true);
|
||||
|
||||
OBJName = ToolName + " Loadbar"; xdis+= (int)ObjectGetInteger(ChartID(), ToolName + "Analyse", OBJPROP_XSIZE) + dyy;
|
||||
ObjectCreate(0, OBJName, OBJ_EDIT, 0, 0, 0);
|
||||
OBJSet(OBJName, "0.0 %", xdis, yini, 50, Ysize, 10, clrGold, clrGold, BGColor, ALIGN_LEFT, CORNER_LEFT_UPPER, true);
|
||||
|
||||
OBJName = ToolName + "clusterLoadbar"; xdis = xini+(int)ObjectGetInteger(ChartID(), ToolName + "Analyse", OBJPROP_XSIZE) + dyy; yini += Ysize + dyy;
|
||||
ObjectCreate(0, OBJName, OBJ_EDIT, 0, 0, 0);
|
||||
OBJSet(OBJName, "0.0 %", xdis, yini, 50, Ysize, 10, clrGold, clrGold, BGColor, ALIGN_LEFT, CORNER_LEFT_UPPER, true);
|
||||
|
||||
OBJName = ToolName + " LN"; yini+=Ysize+dyy;
|
||||
ObjectCreate(0, OBJName, OBJ_EDIT, 0, 0, 0);
|
||||
OBJSet(OBJName, "Level No.", xini, yini, 80, Ysize, 10, clrGold, clrGold, BGColor, ALIGN_LEFT, CORNER_LEFT_UPPER, true);
|
||||
|
||||
OBJName = ToolName + " LN.e"; xdis=xini+80+dyy;
|
||||
ObjectCreate(0, OBJName, OBJ_EDIT, 0, 0, 0);
|
||||
OBJSet(OBJName, IntegerToString(LNo), xdis, yini, 100-dyy, Ysize, 10, BGColor, clrGold, clrGold, ALIGN_RIGHT, CORNER_LEFT_UPPER, false);
|
||||
LastLNo = LNo;
|
||||
|
||||
OBJName = ToolName + " bars"; xdis=xini; yini+=Ysize+dyy;
|
||||
ObjectCreate(0, OBJName, OBJ_EDIT, 0, 0, 0);
|
||||
OBJSet(OBJName, "Bar count", xdis, yini, 80, Ysize, 10, clrGold, clrGold, BGColor, ALIGN_LEFT, CORNER_LEFT_UPPER, true);
|
||||
|
||||
OBJName = ToolName + " bars.e"; xdis+=80+dyy;
|
||||
ObjectCreate(0, OBJName, OBJ_EDIT, 0, 0, 0);
|
||||
OBJSet(OBJName, IntegerToString(maxbar), xdis, yini, 100-dyy, Ysize, 10, BGColor, clrGold, clrGold, ALIGN_RIGHT, CORNER_LEFT_UPPER, false);
|
||||
lastbars = maxbar;
|
||||
|
||||
OBJName = ToolName + " TotalRes"; yini+=Ysize+3*dyy;
|
||||
ObjectCreate(0, OBJName, OBJ_EDIT, 0, 0, 0);
|
||||
OBJSet(OBJName, "Res. Count: ", xini, yini, 180, Ysize, 12, ResColor, ResColor, BGColor, ALIGN_LEFT, CORNER_LEFT_UPPER, true);
|
||||
|
||||
OBJName = ToolName + " TotalSup"; yini+=Ysize+dyy;
|
||||
ObjectCreate(0, OBJName, OBJ_EDIT, 0, 0, 0);
|
||||
OBJSet(OBJName, "Sup. Count: ", xini, yini, 180, Ysize, 12, SupColor, SupColor, BGColor, ALIGN_LEFT, CORNER_LEFT_UPPER, true);
|
||||
|
||||
EventSetMillisecondTimer(5);
|
||||
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| 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[])
|
||||
{
|
||||
//---
|
||||
|
||||
//--- return value of prev_calculated for next call
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
if (reason==1 || reason==4)
|
||||
{
|
||||
ObjectsDeleteAll(0, ToolName);
|
||||
EventKillTimer();
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
void Analyse()
|
||||
{
|
||||
// Reset Graphics
|
||||
OBJName = ToolName + "Zone_";
|
||||
ObjectsDeleteAll(ChartID(), OBJName); ChartRedraw();
|
||||
|
||||
OBJName = ToolName + " Loadbar";
|
||||
ObjectSetString(0, OBJName, OBJPROP_TEXT, "0.0 %");
|
||||
ObjectSetInteger(0, OBJName, OBJPROP_XSIZE, 50);
|
||||
|
||||
OBJName = ToolName + "clusterLoadbar";
|
||||
ObjectSetInteger(0, OBJName, OBJPROP_XSIZE, 50);
|
||||
ObjectSetString(0, OBJName, OBJPROP_TEXT, "0.0 %");
|
||||
|
||||
Ysize = 30;
|
||||
|
||||
// Set data limits from screen
|
||||
int bars = lastbars, ctype[];
|
||||
double low[], high[], close[], open[], total[];
|
||||
ArrayResize(ctype, bars); ArrayInitialize(ctype, 0);
|
||||
|
||||
int resi = (int) (bars / 1000.0)-1;
|
||||
if (resi<=0) resi=2;
|
||||
|
||||
// Copy bars data
|
||||
if (CopyBuffer(ATRHndler, 0, 0, bars, atr)<=0) return;
|
||||
if (CopyLow(Symbol(), tf0, 0, bars, low)<=0) return;
|
||||
if (CopyHigh(Symbol(), tf0, 0, bars, high)<=0) return;
|
||||
if (CopyClose(Symbol(), tf0, 0, bars, close)<=0) return;
|
||||
if (CopyOpen(Symbol(), tf0, 0, bars, open)<=0) return;
|
||||
|
||||
bars = (int) MathMin(ArraySize(open), MathMin((double) bars, ArraySize(close)));
|
||||
|
||||
// Fill candle type (Bull? Bear?)
|
||||
for (int i=bars-ATRPer-1; i>=0; i--)
|
||||
{
|
||||
Print(i," ",ArraySize(close));
|
||||
if (close[i]>open[i]) ctype[i] = +1;
|
||||
else if (close[i]<open[i]) ctype[i] = -1;
|
||||
}
|
||||
|
||||
// Fill S/R matrixes base on selected time-frame candels OHLC data
|
||||
// Implementing Jump rules and candle type limits
|
||||
sup_mat.Resize(0, 0); supclusters.Resize(0, 0);
|
||||
res_mat.Resize(0, 0); resclusters.Resize(0,0);
|
||||
|
||||
for (int i=bars-ATRPer-1; i>=0; i--)
|
||||
{
|
||||
if (myfilters<=1 && ctype[i]==+1 && close[i]-low[i]>=atr[i]*Jmulti) Addsup(low[i]);
|
||||
if (myfilters>=1 && ctype[i]==-1 && close[i]-low[i]>=atr[i]*Jmulti && (close[i]-low[i])/(high[i]-low[i])>=ratio) Addsup(low[i]);
|
||||
|
||||
if (myfilters<=1 && ctype[i]==-1 && high[i]-close[i]>=atr[i]*Jmulti) Addres(high[i]);
|
||||
if (myfilters>=1 && ctype[i]==+1 && high[i]-close[i]>=atr[i]*Jmulti && (high[i]-close[i])/(high[i]-low[i])>=ratio) Addres(high[i]);
|
||||
|
||||
if (MathMod((double) i, resi) == 0)
|
||||
{
|
||||
ObjectSetString(0, ToolName + " Loadbar", OBJPROP_TEXT, DoubleToString(100*(double) (bars-ATRPer-1-i)/(bars-ATRPer-1),1) + " %");
|
||||
ObjectSetInteger(0, ToolName + " Loadbar", OBJPROP_XSIZE, 50 + (int) (300 * ((double) (bars-ATRPer-i+1)/(bars-ATRPer-1))));
|
||||
ObjectSetString(0, ToolName + " TotalRes", OBJPROP_TEXT, "Res. Count: " + IntegerToString(res_mat.Rows()));
|
||||
ObjectSetString(0, ToolName + " TotalSup", OBJPROP_TEXT, "Sup. Count: " + IntegerToString(sup_mat.Rows()));
|
||||
|
||||
ChartRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
startCluster = true;
|
||||
OBJName = ToolName + "clusterLoadbar";
|
||||
ObjectSetInteger(0, OBJName, OBJPROP_XSIZE, 350);
|
||||
ObjectSetString(0, OBJName, OBJPROP_TEXT, "Wait for Cluster Calculation...");
|
||||
|
||||
int supinfo, resinfo, Restarts=5;
|
||||
Cclustering.KMeansGenerate(sup_mat, sup_mat.Rows(), sup_mat.Cols(), LastLNo, Restarts, supinfo, supclusters, sup_xyz);
|
||||
Cclustering.KMeansGenerate(res_mat, res_mat.Rows(), res_mat.Cols(), LastLNo, Restarts, resinfo, resclusters, res_xyz);
|
||||
|
||||
startCluster = false;
|
||||
ObjectSetString(0, OBJName, OBJPROP_TEXT, "Cluster Calculation done!");
|
||||
|
||||
double LevelRes[], LevelSup[], LevelTotal[];
|
||||
ArrayResize(LevelRes, LastLNo); ArrayResize(LevelSup, LastLNo); ArrayResize(LevelTotal, LastLNo);
|
||||
|
||||
OBJName = ToolName + "clusterLoadbar";
|
||||
int stat_x = (int) ObjectGetInteger(ChartID(), OBJName, OBJPROP_XDISTANCE);
|
||||
OBJName = ToolName + " Loadbar";;
|
||||
stat_x += (int) ObjectGetInteger(ChartID(), OBJName, OBJPROP_XSIZE) + dyy;
|
||||
OBJName = ToolName + "Analyse";
|
||||
int stat_y = (int) ObjectGetInteger(ChartID(), OBJName, OBJPROP_YDISTANCE);
|
||||
|
||||
// Closters Graphical
|
||||
OBJName = ToolName + "Zone_Res_Header";
|
||||
ObjectCreate(0, OBJName, OBJ_EDIT, 0, 0, 0);
|
||||
OBJSet(OBJName, "Res. Levels", stat_x, stat_y, 135, Ysize, 12, ResColor, ResColor, BGColor, ALIGN_CENTER, CORNER_LEFT_UPPER, true);
|
||||
|
||||
OBJName = ToolName + "Zone_Sup_Header";
|
||||
ObjectCreate(0, OBJName, OBJ_EDIT, 0, 0, 0); stat_x+=135+dyy;
|
||||
OBJSet(OBJName, "Sup. Levels", stat_x, stat_y, 135, Ysize, 12, SupColor, SupColor, BGColor, ALIGN_CENTER, CORNER_LEFT_UPPER, true);
|
||||
|
||||
stat_y+=Ysize+dyy;
|
||||
Ysize/=2;
|
||||
|
||||
for (int i=0; i<LastLNo; i++)
|
||||
{
|
||||
stat_x -=135+dyy;
|
||||
OBJName = ToolName + "Zone_Res_" + IntegerToString(i);
|
||||
ObjectCreate(0, OBJName, OBJ_EDIT, 0, 0, 0);
|
||||
OBJSet(OBJName, DoubleToString(resclusters.Get(0, i), Digits()), stat_x, stat_y, 135, Ysize, 12, ResColor, ResColor, BGColor, ALIGN_CENTER, CORNER_LEFT_UPPER, true);
|
||||
|
||||
stat_x +=135+dyy;
|
||||
OBJName = ToolName + "Zone_Sup_" + IntegerToString(i);
|
||||
ObjectCreate(0, OBJName, OBJ_EDIT, 0, 0, 0);
|
||||
OBJSet(OBJName, DoubleToString(supclusters.Get(0, i), Digits()), stat_x, stat_y, 135, Ysize, 12, SupColor, SupColor, BGColor, ALIGN_CENTER, CORNER_LEFT_UPPER, true);
|
||||
stat_y+=Ysize+dyy;
|
||||
}
|
||||
|
||||
|
||||
NextChart = ChartOpen(Symbol(), Period());
|
||||
datetime future = TimeCurrent()+ PeriodSeconds(PERIOD_MN1) * 100;
|
||||
double price;
|
||||
|
||||
for (int i=0; i<LastLNo; i++)
|
||||
{
|
||||
price = NormalizeDouble(resclusters.Get(0, i), Digits());
|
||||
OBJName = ToolName + "Zone_Res_" + IntegerToString(i+LastLNo+1);
|
||||
ObjectCreate(NextChart, OBJName, OBJ_HLINE, 0, 0, 0);
|
||||
TrendSet(OBJName, 0, NextChart, price, price, ResColor0, LevelsInt, STYLE_SOLID, true);
|
||||
|
||||
price = NormalizeDouble(supclusters.Get(0, i), Digits());
|
||||
OBJName = ToolName + "Zone_Sup_" + IntegerToString(i+LastLNo+1);
|
||||
ObjectCreate(NextChart, OBJName, OBJ_HLINE, 0, 0, 0);
|
||||
TrendSet(OBJName, 0, NextChart, price, price, SupColor0, LevelsInt, STYLE_SOLID, true);
|
||||
}
|
||||
|
||||
ChartRedraw(NextChart);
|
||||
delete Cclustering;
|
||||
ArrayFree(sup_xyz); ArrayFree(res_xyz);
|
||||
ArrayFree(atr);
|
||||
|
||||
Ysize = 30;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Timer function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnTimer()
|
||||
{
|
||||
if (startCluster)
|
||||
{
|
||||
OBJName = ToolName + "clusterLoadbar";
|
||||
|
||||
if (ObjectGetString(0, OBJName, OBJPROP_TEXT)=="Wait for Cluster Calculation")
|
||||
ObjectSetString(0, OBJName, OBJPROP_TEXT, "Wait for Cluster Calculation.");
|
||||
else if (ObjectGetString(0, OBJName, OBJPROP_TEXT)=="Wait for Cluster Calculation.")
|
||||
ObjectSetString(0, OBJName, OBJPROP_TEXT, "Wait for Cluster Calculation..");
|
||||
else if (ObjectGetString(0, OBJName, OBJPROP_TEXT)=="Wait for Cluster Calculation..")
|
||||
ObjectSetString(0, OBJName, OBJPROP_TEXT, "Wait for Cluster Calculation...");
|
||||
else if (ObjectGetString(0, OBJName, OBJPROP_TEXT)=="Wait for Cluster Calculation..")
|
||||
ObjectSetString(0, OBJName, OBJPROP_TEXT, "Wait for Cluster Calculation");
|
||||
|
||||
ChartRedraw();
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
void MeanNormalization(matrix &mat)
|
||||
{
|
||||
vector v = {};
|
||||
|
||||
for(ulong i=0; i<mat.Cols(); i++)
|
||||
{
|
||||
v = mat.Col(i);
|
||||
MeanNormalization(v);
|
||||
mat.Col(v, i);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
void MeanNormalization(vector &v)
|
||||
{
|
||||
double mean = v.Mean(),
|
||||
max = v.Max(),
|
||||
min = v.Min();
|
||||
|
||||
for(ulong i=0; i<v.Size(); i++)
|
||||
v[i] = (v[i] - mean) / (max - min);
|
||||
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
void Addsup(double price)
|
||||
{
|
||||
int msize = sup_mat.Rows();
|
||||
sup_mat.Resize(msize+1, 1);
|
||||
sup_mat.Set(msize, 0, price);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
void Addres(double price)
|
||||
{
|
||||
int msize = res_mat.Rows();
|
||||
res_mat.Resize(msize+1, 1);
|
||||
res_mat.Set(msize, 0, price);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| ChartEvent function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnChartEvent(const int id,
|
||||
const long &lparam,
|
||||
const double &dparam,
|
||||
const string &sparam)
|
||||
{
|
||||
if (id == CHARTEVENT_OBJECT_CLICK && sparam==ToolName + "Analyse")
|
||||
{
|
||||
Sleep(100);
|
||||
ObjectSetInteger(ChartID(), sparam, OBJPROP_STATE, false);
|
||||
ChartRedraw();
|
||||
Analyse();
|
||||
}
|
||||
|
||||
if (id == CHARTEVENT_OBJECT_ENDEDIT && sparam==ToolName + " bars.e")
|
||||
{
|
||||
OBJName = sparam;
|
||||
int bar = (int) StringToInteger(ObjectGetString(ChartID(), OBJName, OBJPROP_TEXT));
|
||||
if (bar<0) bar=iBars(Symbol(), tf0)+1;
|
||||
|
||||
if (bar<minbar)
|
||||
{
|
||||
MessageBox("Min. bar to analyse is " + IntegerToString(minbar) + "!", "Min. bar limit", 0);
|
||||
ObjectSetString(0, OBJName, OBJPROP_TEXT, IntegerToString(minbar));
|
||||
}
|
||||
else if (bar>iBars(Symbol(), tf0))
|
||||
{
|
||||
MessageBox("Max. bar to analyse is " + IntegerToString(iBars(Symbol(), tf0)) + "!","Max. bar limit", 0);
|
||||
ObjectSetString(0, OBJName, OBJPROP_TEXT, IntegerToString(iBars(Symbol(), tf0)));
|
||||
}
|
||||
else if (bar>900000)
|
||||
{
|
||||
int mes = MessageBox(IntegerToString(bar) + " bars to analyse is so much and will take time more than 1 minute! Are you sure?", "Max. bar warning", 1);
|
||||
if (mes==2) ObjectSetString(0, OBJName, OBJPROP_TEXT, IntegerToString(lastbars));
|
||||
}
|
||||
|
||||
lastbars = (int) StringToInteger(ObjectGetString(ChartID(), OBJName, OBJPROP_TEXT));
|
||||
}
|
||||
|
||||
|
||||
if (id == CHARTEVENT_OBJECT_ENDEDIT && sparam==ToolName + " LN.e")
|
||||
{
|
||||
OBJName = sparam;
|
||||
int bar = (int) StringToInteger(ObjectGetString(ChartID(), OBJName, OBJPROP_TEXT));
|
||||
if (bar<0) bar=LNo;
|
||||
|
||||
if (bar<minLN)
|
||||
{
|
||||
MessageBox("Min. Level No. to analyse is " + IntegerToString(minLN) + "!", "Min. Level No. limit", 0);
|
||||
ObjectSetString(0, OBJName, OBJPROP_TEXT, IntegerToString(minLN));
|
||||
}
|
||||
else if (bar>500)
|
||||
{
|
||||
MessageBox("Max. Level No. to analyse is 500" + "!","Max. bar limit", 0);
|
||||
ObjectSetString(0, OBJName, OBJPROP_TEXT, IntegerToString(500));
|
||||
}
|
||||
else if (bar>100)
|
||||
{
|
||||
int mes = MessageBox(IntegerToString(bar) + " Level No. analyse is so much and will take time more than 1 minute! Are you sure?", "Max. Level No. warning", 1);
|
||||
if (mes==2) ObjectSetString(0, OBJName, OBJPROP_TEXT, IntegerToString(LastLNo));
|
||||
}
|
||||
|
||||
LastLNo = (int) StringToInteger(ObjectGetString(ChartID(), OBJName, OBJPROP_TEXT));
|
||||
}
|
||||
|
||||
ChartRedraw();
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
void SetScreen()
|
||||
{
|
||||
ChartSetInteger(ChartID(), CHART_FOREGROUND, false);
|
||||
ChartSetInteger(0, CHART_COLOR_CANDLE_BEAR, BGColor);
|
||||
ChartSetInteger(0, CHART_COLOR_CANDLE_BULL, BGColor);
|
||||
ChartSetInteger(0, CHART_COLOR_CHART_LINE, BGColor);
|
||||
ChartSetInteger(0, CHART_COLOR_CHART_DOWN, BGColor);
|
||||
ChartSetInteger(0, CHART_COLOR_CHART_UP, BGColor);
|
||||
ChartSetInteger(0, CHART_COLOR_ASK, BGColor);
|
||||
ChartSetInteger(0, CHART_COLOR_BID, BGColor);
|
||||
ChartSetInteger(0, CHART_COLOR_GRID, BGColor);
|
||||
ChartSetInteger(0, CHART_COLOR_BACKGROUND, BGColor);
|
||||
ChartSetInteger(0, CHART_COLOR_FOREGROUND, BGColor);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
void OBJSet(string OBJNameSet, string txt, int XDis, int YDis, int XSize, int YSize, int FSize, color Fill, color Border, color TColor, ENUM_ALIGN_MODE myAlign, ENUM_BASE_CORNER mycorner, bool myread)
|
||||
{
|
||||
ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_CORNER, mycorner);
|
||||
ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_ANCHOR, ANCHOR_LEFT_UPPER);
|
||||
ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_XDISTANCE, XDis);
|
||||
ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_YDISTANCE, YDis);
|
||||
ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_XSIZE, XSize);
|
||||
ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_YSIZE, YSize);
|
||||
ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_FONTSIZE, FSize);
|
||||
ObjectSetString(ChartID(), OBJNameSet, OBJPROP_TEXT,txt);
|
||||
ObjectSetString(ChartID(), OBJNameSet, OBJPROP_FONT,"Calibri");
|
||||
|
||||
ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_BGCOLOR, Fill);
|
||||
ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_BORDER_COLOR, Border);
|
||||
ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_COLOR, TColor);
|
||||
ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_ALIGN, myAlign);
|
||||
|
||||
ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_BACK, false);
|
||||
ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_ZORDER,5);
|
||||
ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_HIDDEN, true);
|
||||
ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_READONLY, myread);
|
||||
ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_SELECTABLE, false);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
void TrendSet(string TrendName, datetime time0, datetime time1, double price1, double price2, color Tcolor, int Twidth, ENUM_LINE_STYLE Tstyle, int b)
|
||||
{
|
||||
ObjectSetInteger(NextChart, TrendName, OBJPROP_TIME, 0, time0);
|
||||
ObjectSetInteger(NextChart, TrendName, OBJPROP_TIME, 1, time1);
|
||||
ObjectSetInteger(NextChart, TrendName, OBJPROP_COLOR, Tcolor);
|
||||
ObjectSetInteger(NextChart, TrendName, OBJPROP_RAY, false);
|
||||
ObjectSetInteger(NextChart, TrendName, OBJPROP_WIDTH, Twidth);
|
||||
ObjectSetInteger(NextChart, TrendName, OBJPROP_STYLE, Tstyle);
|
||||
ObjectSetInteger(NextChart, TrendName, OBJPROP_BACK, true);
|
||||
ObjectSetInteger(NextChart, TrendName, OBJPROP_SELECTABLE, false);
|
||||
ObjectSetInteger(NextChart, TrendName, OBJPROP_TIMEFRAMES, b?OBJ_ALL_PERIODS:OBJ_NO_PERIODS);
|
||||
ObjectSetDouble(NextChart, TrendName, OBJPROP_PRICE, 0, price1);
|
||||
ObjectSetDouble(NextChart, TrendName, OBJPROP_PRICE, 1, price2);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
//------------------------------------------------------------------
|
||||
#property copyright "www.forex-tsd.com"
|
||||
#property link "www.forex-tsd.com"
|
||||
//------------------------------------------------------------------
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 2
|
||||
#property indicator_plots 1
|
||||
#property indicator_label1 "Super trend hull"
|
||||
#property indicator_type1 DRAW_COLOR_LINE
|
||||
#property indicator_color1 clrLimeGreen,clrPaleVioletRed
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 2
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
enum enPrices
|
||||
{
|
||||
pr_close, // Close
|
||||
pr_open, // Open
|
||||
pr_high, // High
|
||||
pr_low, // Low
|
||||
pr_median, // Median
|
||||
pr_typical, // Typical
|
||||
pr_weighted, // Weighted
|
||||
pr_average // Average (high+low+oprn+close)/4
|
||||
};
|
||||
|
||||
input int hullPeriod = 12; // Hull period
|
||||
input enPrices Price = pr_median; // Price
|
||||
input int atrPeriod = 12; // ATR period
|
||||
input double atrMultiplier = 0.66; // ATR multiplier
|
||||
|
||||
double st[];
|
||||
double colorBuffer[];
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
int OnInit()
|
||||
{
|
||||
SetIndexBuffer(0,st,INDICATOR_DATA);
|
||||
SetIndexBuffer(1,colorBuffer,INDICATOR_COLOR_INDEX);
|
||||
return(0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
double Up[];
|
||||
double Dn[];
|
||||
double Direction[];
|
||||
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[])
|
||||
{
|
||||
if (ArraySize(Direction)!=rates_total)
|
||||
{
|
||||
ArrayResize(Up,rates_total);
|
||||
ArrayResize(Dn,rates_total);
|
||||
ArrayResize(Direction,rates_total);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
for (int i=(int)MathMax(prev_calculated-1,1); i<rates_total; i++)
|
||||
{
|
||||
double atr = 0;
|
||||
for (int k=0;k<atrPeriod && (i-k-1)>=0; k++)
|
||||
atr += MathMax(high[i-k],close[i-k-1])-MathMin(low[i-k],close[i-k-1]);
|
||||
atr /= atrPeriod;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
double cprice = close[i];
|
||||
double mprice = iHull(getPrice(Price,open,close,high,low,i,rates_total),hullPeriod,i,rates_total);
|
||||
Up[i] = mprice+atrMultiplier*atr;
|
||||
Dn[i] = mprice-atrMultiplier*atr;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
colorBuffer[i] = colorBuffer[i-1];
|
||||
Direction[i] = Direction[i-1];
|
||||
if (cprice > Up[i-1]) Direction[i] = 1;
|
||||
if (cprice < Dn[i-1]) Direction[i] = -1;
|
||||
if (Direction[i] > 0)
|
||||
{ Dn[i] = MathMax(Dn[i],Dn[i-1]); st[i] = Dn[i]; }
|
||||
else { Up[i] = MathMin(Up[i],Up[i-1]); st[i] = Up[i]; }
|
||||
if (Direction[i]== 1) colorBuffer[i] = 0;
|
||||
if (Direction[i]==-1) colorBuffer[i] = 1;
|
||||
}
|
||||
return(rates_total);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
double workHull[][2];
|
||||
double iHull(double price, double period, int r, int bars, int instanceNo=0)
|
||||
{
|
||||
if (ArrayRange(workHull,0)!= bars) ArrayResize(workHull,bars);
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
int HmaPeriod = (int)MathMax(period,2);
|
||||
int HalfPeriod = (int)MathFloor(HmaPeriod/2);
|
||||
int HullPeriod = (int)MathFloor(MathSqrt(HmaPeriod));
|
||||
double hma,hmw,weight; instanceNo *= 2;
|
||||
|
||||
workHull[r][instanceNo] = price;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
hmw = HalfPeriod; hma = hmw*price;
|
||||
for(int k=1; k<HalfPeriod && (r-k)>=0; k++)
|
||||
{
|
||||
weight = HalfPeriod-k;
|
||||
hmw += weight;
|
||||
hma += weight*workHull[r-k][instanceNo];
|
||||
}
|
||||
workHull[r][instanceNo+1] = 2.0*hma/hmw;
|
||||
|
||||
hmw = HmaPeriod; hma = hmw*price;
|
||||
for(int k=1; k<period && (r-k)>=0; k++)
|
||||
{
|
||||
weight = HmaPeriod-k;
|
||||
hmw += weight;
|
||||
hma += weight*workHull[r-k][instanceNo];
|
||||
}
|
||||
workHull[r][instanceNo+1] -= hma/hmw;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
hmw = HullPeriod; hma = hmw*workHull[r][instanceNo+1];
|
||||
for(int k=1; k<HullPeriod && (r-k)>=0; k++)
|
||||
{
|
||||
weight = HullPeriod-k;
|
||||
hmw += weight;
|
||||
hma += weight*workHull[r-k][1+instanceNo];
|
||||
}
|
||||
return(hma/hmw);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
Binary file not shown.
@@ -0,0 +1,192 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SuperTrend.mq5 |
|
||||
//| Copyright 2011, FxGeek |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2011, FxGeek"
|
||||
#property link " http://www.mql5.com"
|
||||
#property version "1.00"
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 9
|
||||
#property indicator_plots 2
|
||||
|
||||
#property indicator_label1 "Filling"
|
||||
#property indicator_type1 DRAW_FILLING
|
||||
#property indicator_color1 clrBisque, clrPaleGreen
|
||||
|
||||
#property indicator_label2 "SuperTrend"
|
||||
#property indicator_type2 DRAW_COLOR_LINE
|
||||
#property indicator_color2 clrGreen, clrRed
|
||||
|
||||
input int Periode=10;
|
||||
input double Multiplier=3;
|
||||
input bool Show_Filling=true; // Show as DRAW_FILLING
|
||||
|
||||
double Filled_a[];
|
||||
double Filled_b[];
|
||||
double SuperTrend[];
|
||||
double ColorBuffer[];
|
||||
double Atr[];
|
||||
double Up[];
|
||||
double Down[];
|
||||
double Middle[];
|
||||
double trend[];
|
||||
|
||||
int atrHandle;
|
||||
int changeOfTrend;
|
||||
int flag;
|
||||
int flagh;
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- indicator buffers mapping
|
||||
SetIndexBuffer(0,Filled_a,INDICATOR_DATA);
|
||||
SetIndexBuffer(1,Filled_b,INDICATOR_DATA);
|
||||
SetIndexBuffer(2,SuperTrend,INDICATOR_DATA);
|
||||
SetIndexBuffer(3,ColorBuffer,INDICATOR_COLOR_INDEX);
|
||||
SetIndexBuffer(4,Atr,INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(5,Up,INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(6,Down,INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(7,Middle,INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(8,trend,INDICATOR_CALCULATIONS);
|
||||
|
||||
atrHandle=iATR(_Symbol,_Period,Periode);
|
||||
//---
|
||||
return(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| 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 to_copy;
|
||||
if(prev_calculated>rates_total || prev_calculated<0) to_copy=rates_total;
|
||||
else
|
||||
{
|
||||
to_copy=rates_total-prev_calculated;
|
||||
if(prev_calculated>0) to_copy++;
|
||||
}
|
||||
|
||||
if(IsStopped()) return(0); //Checking for stop flag
|
||||
if(CopyBuffer(atrHandle,0,0,to_copy,Atr)<=0)
|
||||
{
|
||||
Print("Getting Atr is failed! Error",GetLastError());
|
||||
return(0);
|
||||
}
|
||||
|
||||
int first;
|
||||
if(prev_calculated>rates_total || prev_calculated<=0) // checking for the first start of calculation of an indicator
|
||||
{
|
||||
first=Periode; // starting index for calculation of all bars
|
||||
}
|
||||
else
|
||||
{
|
||||
first=prev_calculated-1; // starting number for calculation of new bars
|
||||
}
|
||||
for(int i=first; i<rates_total && !IsStopped(); i++)
|
||||
{
|
||||
Middle[i]=(high[i]+low[i])/2;
|
||||
Up[i] = Middle[i] +(Multiplier*Atr[i]);
|
||||
Down[i]= Middle[i] -(Multiplier*Atr[i]);
|
||||
|
||||
if(close[i]>Up[i-1])
|
||||
{
|
||||
trend[i]=1;
|
||||
if(trend[i-1]==-1) changeOfTrend=1;
|
||||
|
||||
}
|
||||
else if(close[i]<Down[i-1])
|
||||
{
|
||||
trend[i]=-1;
|
||||
if(trend[i-1]==1) changeOfTrend=1;
|
||||
}
|
||||
else if(trend[i-1]==1)
|
||||
{
|
||||
trend[i]=1;
|
||||
changeOfTrend=0;
|
||||
}
|
||||
else if(trend[i-1]==-1)
|
||||
{
|
||||
trend[i]=-1;
|
||||
changeOfTrend=0;
|
||||
}
|
||||
|
||||
if(trend[i]<0 && trend[i-1]>0)
|
||||
{
|
||||
flag=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
flag=0;
|
||||
}
|
||||
|
||||
if(trend[i]>0 && trend[i-1]<0)
|
||||
{
|
||||
flagh=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
flagh=0;
|
||||
}
|
||||
|
||||
if(trend[i]>0 && Down[i]<Down[i-1])
|
||||
Down[i]=Down[i-1];
|
||||
|
||||
if(trend[i]<0 && Up[i]>Up[i-1])
|
||||
Up[i]=Up[i-1];
|
||||
|
||||
if(flag==1)
|
||||
Up[i]=Middle[i]+(Multiplier*Atr[i]);
|
||||
|
||||
if(flagh==1)
|
||||
Down[i]=Middle[i]-(Multiplier*Atr[i]);
|
||||
|
||||
//-- Draw the indicator
|
||||
if(trend[i]==1)
|
||||
{
|
||||
SuperTrend[i]=Down[i];
|
||||
if(changeOfTrend==1)
|
||||
{
|
||||
SuperTrend[i-1]=SuperTrend[i-2];
|
||||
changeOfTrend=0;
|
||||
}
|
||||
ColorBuffer[i]=0.0;
|
||||
}
|
||||
else if(trend[i]==-1)
|
||||
{
|
||||
SuperTrend[i]=Up[i];
|
||||
if(changeOfTrend==1)
|
||||
{
|
||||
SuperTrend[i-1]= SuperTrend[i-2];
|
||||
changeOfTrend = 0;
|
||||
}
|
||||
ColorBuffer[i]=1.0;
|
||||
}
|
||||
|
||||
if(Show_Filling)
|
||||
{
|
||||
Filled_a[i]= SuperTrend[i];
|
||||
Filled_b[i]= close[i];
|
||||
}else{
|
||||
Filled_a[i]= EMPTY_VALUE;
|
||||
Filled_b[i]= EMPTY_VALUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//--- return value of prev_calculated for next call
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,117 @@
|
||||
//------------------------------------------------------------------
|
||||
#property copyright "www.forex-tsd.com"
|
||||
#property link "www.forex-tsd.com"
|
||||
//------------------------------------------------------------------
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 2
|
||||
#property indicator_plots 1
|
||||
#property indicator_label1 "Swing line"
|
||||
#property indicator_type1 DRAW_COLOR_LINE
|
||||
#property indicator_color1 clrLimeGreen,clrPaleVioletRed
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 3
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
double swli[];
|
||||
double colorBuffer[];
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
int OnInit()
|
||||
{
|
||||
SetIndexBuffer(0,swli,INDICATOR_DATA);
|
||||
SetIndexBuffer(1,colorBuffer,INDICATOR_COLOR_INDEX);
|
||||
return(0);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
double work[][5];
|
||||
#define hHi 0
|
||||
#define hLo 1
|
||||
#define lHi 2
|
||||
#define lLo 3
|
||||
#define trend 4
|
||||
|
||||
|
||||
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[])
|
||||
{
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
if (ArrayRange(work,0)!=rates_total) ArrayResize(work,rates_total);
|
||||
for (int i=(int)MathMax(prev_calculated-1,0); i<rates_total; i++)
|
||||
{
|
||||
if (i==0)
|
||||
{
|
||||
work[i][hHi] = high[i]; work[i][hLo] = low[i];
|
||||
work[i][lHi] = high[i]; work[i][lLo] = low[i];
|
||||
work[i][trend] = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
work[i][trend] = work[i-1][trend];
|
||||
work[i][hHi] = work[i-1][hHi]; work[i][hLo] = work[i-1][hLo];
|
||||
work[i][lHi] = work[i-1][lHi]; work[i][lLo] = work[i-1][lLo];
|
||||
|
||||
if (work[i-1][trend] == 1)
|
||||
{
|
||||
work[i][hHi] = MathMax(work[i-1][hHi],high[i]);
|
||||
work[i][hLo] = MathMax(work[i-1][hLo],low[i]);
|
||||
if (high[i]<work[i][hLo]) { work[i][trend] = -1; work[i][lHi] = high[i]; work[i][lLo] = low[i]; }
|
||||
}
|
||||
if (work[i-1][trend] == -1)
|
||||
{
|
||||
work[i][lHi] = MathMin(work[i-1][lHi],high[i]);
|
||||
work[i][lLo] = MathMin(work[i-1][lLo],low[i]);
|
||||
if (low[i]>work[i][lHi]) { work[i][trend] = 1; work[i][hHi] = high[i]; work[i][hLo] = low[i]; }
|
||||
}
|
||||
|
||||
if (work[i][trend]==1)
|
||||
swli[i] = work[i][hLo];
|
||||
else swli[i] = work[i][lHi];
|
||||
colorBuffer[i] = colorBuffer[i-1];
|
||||
if (work[i][trend]== 1) colorBuffer[i]= 0;
|
||||
if (work[i][trend]==-1) colorBuffer[i]= 1;
|
||||
}
|
||||
return(rates_total);
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,97 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Swings.mq5 |
|
||||
//| Rajesh Nait, Copyright 2023 |
|
||||
//| https://www.mql5.com/en/users/rajeshnait/seller |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Rajesh Nait, Copyright 2023"
|
||||
#property link "https://www.mql5.com/en/users/rajeshnait/seller"
|
||||
#property version "1.00"
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 2
|
||||
#property indicator_plots 2
|
||||
|
||||
//--- plot Bullish Marubozu
|
||||
#property indicator_label1 "+S"
|
||||
#property indicator_type1 DRAW_ARROW
|
||||
#property indicator_color1 clrSnow
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
//--- plot Bearish Marubozu
|
||||
#property indicator_label2 "-S"
|
||||
#property indicator_type2 DRAW_ARROW
|
||||
#property indicator_color2 clrSnow
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 1
|
||||
|
||||
//--- input parameters
|
||||
input group "Swing Low"
|
||||
uchar InpSwingLowCode = 110; // Swing Low: code for style DRAW_ARROW (font Wingdings)
|
||||
int InpSwingLowShift = 10; // Swing Low: vertical shift of arrows in pixels
|
||||
input group "Swing High"
|
||||
uchar InpSwingHighCode = 110; // SwingHigh: code for style DRAW_ARROW (font Wingdings)
|
||||
int InpSwingHighShift =10; // SwingHigh: vertical shift of arrows in pixels
|
||||
//--- indicator buffers
|
||||
double SwingLowBuffer[];
|
||||
double SwingHighBuffer[];
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit() {
|
||||
//--- indicator buffers mapping
|
||||
//--- indicator buffers mapping
|
||||
SetIndexBuffer(0,SwingLowBuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(1,SwingHighBuffer,INDICATOR_DATA);
|
||||
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,Digits());
|
||||
//--- setting a code from the Wingdings charset as the property of PLOT_ARROW
|
||||
PlotIndexSetInteger(0,PLOT_ARROW,InpSwingLowCode);
|
||||
PlotIndexSetInteger(1,PLOT_ARROW,InpSwingHighCode);
|
||||
//--- set the vertical shift of arrows in pixels
|
||||
PlotIndexSetInteger(0,PLOT_ARROW_SHIFT,InpSwingLowShift);
|
||||
PlotIndexSetInteger(1,PLOT_ARROW_SHIFT,-InpSwingHighShift);
|
||||
//--- set as an empty value 0.0
|
||||
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
|
||||
PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0);
|
||||
//---
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| 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[]) {
|
||||
//---
|
||||
if(rates_total<3)
|
||||
return(0);
|
||||
//---
|
||||
int limit=prev_calculated-1;
|
||||
if(prev_calculated==0)
|
||||
limit=2;
|
||||
|
||||
for(int i=limit; i<rates_total-2; i++) {
|
||||
SwingLowBuffer[i]=0.0;
|
||||
SwingHighBuffer[i]=0.0;
|
||||
if(i>0) {
|
||||
SwingHighBuffer[0]=EMPTY_VALUE;
|
||||
if(high[i+2]<high[i+1] && high[i+1]<high[i])
|
||||
if(high[i]>high[i-1] && high[i-1]>high[i-2])
|
||||
SwingHighBuffer[i]=high[i];
|
||||
|
||||
SwingLowBuffer[0]=EMPTY_VALUE;
|
||||
if(low[i+2]>low[i+1] && low[i+1]>low[i])
|
||||
if(low[i]<low[i-1] && low[i-1]<low[i-2])
|
||||
SwingLowBuffer[i]=low[i];
|
||||
}
|
||||
}
|
||||
//--- return value of prev_calculated for next call
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,289 @@
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
#define MName "Time Segmented Volume (TSV)"
|
||||
#define MVersion "1.01"
|
||||
#define MBuild "2023-03-27 21:02 WET"
|
||||
#define MCopyright "Copyright \x00A9 2023, Fernando M. I. Carreiro, All rights reserved"
|
||||
#define MProfile "https://www.mql5.com/en/users/FMIC"
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
#property strict
|
||||
#property version MVersion
|
||||
#property description MName
|
||||
#property description "MetaTrader Indicator (Build "MBuild")"
|
||||
#property copyright MCopyright
|
||||
#property link MProfile
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
//--- Setup
|
||||
|
||||
#property indicator_separate_window
|
||||
|
||||
// Define number of buffers and plots
|
||||
#define MPlots 3
|
||||
#define MBuffers 7
|
||||
#ifdef __MQL4__
|
||||
#property indicator_buffers ( MPlots + 1 )
|
||||
#else
|
||||
#property indicator_buffers MBuffers
|
||||
#property indicator_plots MPlots
|
||||
#endif
|
||||
|
||||
// Define plot colours and respective indices
|
||||
#define MClrCandleNone C'239,166,117'
|
||||
#define MClrCandleUp C'38,166,154'
|
||||
#define MClrCandleDown C'239,83,80'
|
||||
|
||||
// Display properties for plots
|
||||
#ifdef __MQL4__
|
||||
// Summation plots
|
||||
#property indicator_label1 "Summation (positive)"
|
||||
#property indicator_type1 DRAW_HISTOGRAM
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 3
|
||||
#property indicator_color1 MClrCandleUp
|
||||
#property indicator_label2 "Summation (negative)"
|
||||
#property indicator_type2 DRAW_HISTOGRAM
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 3
|
||||
#property indicator_color2 MClrCandleDown
|
||||
// Simple averaging plot
|
||||
#property indicator_label3 "Averaging (simple)"
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_style3 STYLE_SOLID
|
||||
#property indicator_width3 2
|
||||
#property indicator_color3 MClrCandleNone
|
||||
// Exponential averaging plot
|
||||
#property indicator_label4 "Averaging (exponential)"
|
||||
#property indicator_type4 DRAW_LINE
|
||||
#property indicator_style4 STYLE_SOLID
|
||||
#property indicator_width4 1
|
||||
#property indicator_color4 MClrCandleNone
|
||||
#else
|
||||
// Define colour index for plots
|
||||
#define MIdxCandleNone 0.0
|
||||
#define MIdxCandleUp 1.0
|
||||
#define MIdxCandleDown 2.0
|
||||
// Summation plot
|
||||
#property indicator_label1 "Summation"
|
||||
#property indicator_type1 DRAW_COLOR_HISTOGRAM
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 5
|
||||
#property indicator_color1 MClrCandleNone, MClrCandleUp, MClrCandleDown
|
||||
// Simple averaging plot
|
||||
#property indicator_label2 "Averaging (simple)"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 2
|
||||
#property indicator_color2 MClrCandleNone
|
||||
// Exponential averaging plot
|
||||
#property indicator_label3 "Averaging (exponential)"
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_style3 STYLE_SOLID
|
||||
#property indicator_width3 1
|
||||
#property indicator_color3 MClrCandleNone
|
||||
#endif
|
||||
|
||||
//--- Enumarations
|
||||
|
||||
// Volume weight enumaraton
|
||||
enum EVolumeWeight
|
||||
{
|
||||
EVW_None = 0, // No volume weighting
|
||||
EVW_TickVolume, // Tick volume
|
||||
#ifndef __MQL4__
|
||||
EVW_RealVolume, // Real volume
|
||||
#endif
|
||||
EVW_PriceRange // True price range (pseudo volume)
|
||||
};
|
||||
|
||||
//--- Parameter settings
|
||||
|
||||
input uint i_nSummationPeriod = 13, // Summation period
|
||||
i_nAveragingPeriod = 7; // Averaging period
|
||||
input ENUM_APPLIED_PRICE i_ePriceApplied = PRICE_CLOSE; // Applied price
|
||||
input EVolumeWeight i_eVolumeWeight = EVW_TickVolume; // Applied volume
|
||||
|
||||
//--- Macro definitions
|
||||
|
||||
// Define OnCalculate loop sequencing macros
|
||||
#define MOnCalcPrevTest ( prev_calculated < 1 || prev_calculated > rates_total )
|
||||
#ifdef __MQL4__ // for MQL4 (as series)
|
||||
#define MOnCalcNext( _index ) ( _index-- )
|
||||
#define MOnCalcBack( _index, _offset ) ( _index + _offset )
|
||||
#define MOnCalcCheck( _index ) ( _index >= 0 )
|
||||
#define MOnCalcValid( _index ) ( _index < rates_total )
|
||||
#define MOnCalcStart \
|
||||
( rates_total - ( MOnCalcPrevTest ? 1 : prev_calculated ) )
|
||||
#else // for MQL5 (as non-series)
|
||||
#define MOnCalcNext( _index ) ( _index++ )
|
||||
#define MOnCalcBack( _index, _offset ) ( _index - _offset )
|
||||
#define MOnCalcCheck( _index ) ( _index < rates_total )
|
||||
#define MOnCalcValid( _index ) ( _index >= 0 )
|
||||
#define MOnCalcStart \
|
||||
( MOnCalcPrevTest ? 0 : prev_calculated - 1 )
|
||||
#endif
|
||||
|
||||
// Define applied price macro
|
||||
#define MSetAppliedPrice( _type, _where, _index ) { switch( _type ) { \
|
||||
case PRICE_WEIGHTED: _where = ( high[ _index ] + low[ _index ] + close[ _index ] \
|
||||
+ close[ _index ] ) * 0.25; break; \
|
||||
case PRICE_TYPICAL: _where = ( high[ _index ] + low[ _index ] + close[ _index ] ) / 3.0; break; \
|
||||
case PRICE_MEDIAN: _where = ( high[ _index ] + low[ _index ] ) * 0.5; break; \
|
||||
case PRICE_HIGH: _where = high[ _index ]; break; \
|
||||
case PRICE_LOW: _where = low[ _index ]; break; \
|
||||
case PRICE_OPEN: _where = open[ _index ]; break; \
|
||||
case PRICE_CLOSE: \
|
||||
default: _where = close[ _index ]; }; }
|
||||
|
||||
// Define macro for invalid parameter values
|
||||
#define MCheckParameter( _condition, _text ) if( _condition ) \
|
||||
{ Print( "Error: Invalid ", _text ); return INIT_PARAMETERS_INCORRECT; }
|
||||
|
||||
//--- Global variable declarations
|
||||
|
||||
// Indicator buffers
|
||||
double g_adbPriceApplied[], // Buffer for applied price
|
||||
g_adbVolumePriceDelta[], // Buffer for volume weight price delta change
|
||||
g_adbSummation[], // Buffer for summation of volume weighte price change
|
||||
g_adbSummationSimple[], // Buffer for summation of summation for simple averaging
|
||||
g_adbAveragingSimple[], // Buffer for simple averaging
|
||||
g_adbAveragingExponential[]; // Buffer for exponential averaging
|
||||
#ifdef __MQL4__
|
||||
double g_adbSummationPositive[], // Buffer for positive summation of volume weighte price change
|
||||
g_adbSummationNegative[]; // Buffer for negative summation of volume weighte price change
|
||||
#else
|
||||
double g_adbSummationColour[]; // Buffer for summation colourisation
|
||||
#endif
|
||||
|
||||
// Miscellaneous global variables
|
||||
double g_dbEmaWeight; // Weight to be used for exponential moving averages
|
||||
|
||||
//--- Event handling functions
|
||||
|
||||
// Initialisation event handler
|
||||
int OnInit(void) {
|
||||
// Validate input parameters
|
||||
MCheckParameter( i_nSummationPeriod < 1, "summation period" );
|
||||
MCheckParameter( i_nAveragingPeriod < 1 ||
|
||||
i_nAveragingPeriod > i_nSummationPeriod, "averaging period" );
|
||||
|
||||
// Calculate parameter variables
|
||||
g_dbEmaWeight = 2.0 / ( i_nAveragingPeriod + 1.0 );
|
||||
|
||||
// Set number of significant digits (precision)
|
||||
IndicatorSetInteger( INDICATOR_DIGITS, _Digits );
|
||||
|
||||
// Set buffers
|
||||
int iBuffer = 0;
|
||||
#ifdef __MQL4__
|
||||
IndicatorBuffers( MBuffers + 1 ); // Set total number of buffers (MQL4 Only)
|
||||
SetIndexBuffer( iBuffer++, g_adbSummationPositive, INDICATOR_DATA );
|
||||
SetIndexBuffer( iBuffer++, g_adbSummationNegative, INDICATOR_DATA );
|
||||
#else
|
||||
SetIndexBuffer( iBuffer++, g_adbSummation, INDICATOR_DATA );
|
||||
SetIndexBuffer( iBuffer++, g_adbSummationColour, INDICATOR_COLOR_INDEX );
|
||||
#endif
|
||||
SetIndexBuffer( iBuffer++, g_adbAveragingSimple, INDICATOR_DATA );
|
||||
SetIndexBuffer( iBuffer++, g_adbAveragingExponential, INDICATOR_DATA );
|
||||
SetIndexBuffer( iBuffer++, g_adbPriceApplied, INDICATOR_CALCULATIONS );
|
||||
SetIndexBuffer( iBuffer++, g_adbVolumePriceDelta, INDICATOR_CALCULATIONS );
|
||||
SetIndexBuffer( iBuffer++, g_adbSummationSimple, INDICATOR_CALCULATIONS );
|
||||
#ifdef __MQL4__
|
||||
SetIndexBuffer( iBuffer++, g_adbSummation, INDICATOR_CALCULATIONS );
|
||||
#endif
|
||||
|
||||
// Set indicator name
|
||||
IndicatorSetString( INDICATOR_SHORTNAME, StringFormat(
|
||||
MName " ( %d, %d )", i_nSummationPeriod, i_nAveragingPeriod ) );
|
||||
|
||||
return INIT_SUCCEEDED; // Successful initialisation of indicator
|
||||
};
|
||||
|
||||
// Calculation event handler
|
||||
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[]
|
||||
)
|
||||
{
|
||||
// Main loop — fill in the arrays with data values
|
||||
for( int iCur = MOnCalcStart,
|
||||
iPrev = MOnCalcBack( iCur, 1 ),
|
||||
iSumPrev = MOnCalcBack( iCur, (int) i_nSummationPeriod ),
|
||||
iAvgPrev = MOnCalcBack( iCur, (int) i_nAveragingPeriod );
|
||||
!IsStopped() && MOnCalcCheck( iCur );
|
||||
MOnCalcNext( iCur ), MOnCalcNext( iPrev ), MOnCalcNext( iSumPrev ), MOnCalcNext( iAvgPrev ) )
|
||||
{
|
||||
// Calculate volume to apply
|
||||
double dbVolume = 1.0;
|
||||
switch( i_eVolumeWeight ) {
|
||||
#ifndef __MQL4__
|
||||
case EVW_RealVolume: dbVolume = (double) volume[ iCur ]; break;
|
||||
#endif
|
||||
case EVW_TickVolume: dbVolume = (double) tick_volume[ iCur ]; break;
|
||||
case EVW_PriceRange: if( MOnCalcValid( iPrev ) ) {
|
||||
double dbClosePrev = close[ iPrev ];
|
||||
dbVolume = fmax( high[ iCur ], dbClosePrev )
|
||||
- fmin( low[ iCur ], dbClosePrev );
|
||||
} else dbVolume = high[ iCur ] - low[ iCur ];
|
||||
};
|
||||
|
||||
// Calculate price to apply
|
||||
double dbPriceCur;
|
||||
MSetAppliedPrice( i_ePriceApplied, dbPriceCur, iCur );
|
||||
|
||||
// Calculate volume weighted price delta and sum
|
||||
double dbPricePrev = MOnCalcValid( iPrev ) ? g_adbPriceApplied [ iPrev ] : open[ iCur ],
|
||||
dbPriceDelta = dbPriceCur - dbPricePrev,
|
||||
dbVolumePriceDelta = dbPriceDelta * dbVolume,
|
||||
dbSummation = dbVolumePriceDelta
|
||||
+ ( MOnCalcValid( iPrev ) ? g_adbSummation[ iPrev ] : 0.0 )
|
||||
- ( MOnCalcValid( iSumPrev ) ? g_adbVolumePriceDelta[ iSumPrev ] : 0.0 );
|
||||
// Define colourasation
|
||||
#ifdef __MQL4__
|
||||
double dbSummationPositive = dbSummation > 0.0 ? dbSummation : 0.0,
|
||||
dbSummationNegative = dbSummation < 0.0 ? dbSummation : 0.0;
|
||||
#else
|
||||
double dbSummationColour = dbSummation > 0.0 ? MIdxCandleUp
|
||||
: ( dbSummation < 0.0 ? MIdxCandleDown
|
||||
: MIdxCandleNone );
|
||||
#endif
|
||||
|
||||
// Calculate simple summation and averaging
|
||||
double dbSumSimpleCur = dbSummation
|
||||
+ ( MOnCalcValid( iPrev ) ? g_adbSummationSimple[ iPrev ] : 0.0 )
|
||||
- ( MOnCalcValid( iAvgPrev ) ? g_adbSummation[ iAvgPrev ] : 0.0 ),
|
||||
dbAverageSimpleCur = dbSumSimpleCur / i_nAveragingPeriod;
|
||||
|
||||
// Calculate exponential averaging
|
||||
double dbAverageExponentialPrev = MOnCalcValid( iPrev ) ? g_adbAveragingExponential[ iPrev ] : dbSummation,
|
||||
dbAverageExponentialCur = dbAverageExponentialPrev
|
||||
+ ( dbSummation - dbAverageExponentialPrev )
|
||||
* g_dbEmaWeight;
|
||||
|
||||
// Set buffer values
|
||||
g_adbPriceApplied[ iCur ] = dbPriceCur;
|
||||
g_adbVolumePriceDelta[ iCur ] = dbVolumePriceDelta;
|
||||
g_adbSummation[ iCur ] = dbSummation;
|
||||
g_adbSummationSimple[ iCur ] = dbSumSimpleCur;
|
||||
g_adbAveragingSimple[ iCur ] = dbAverageSimpleCur;
|
||||
g_adbAveragingExponential[ iCur ] = dbAverageExponentialCur;
|
||||
#ifdef __MQL4__
|
||||
g_adbSummationPositive[ iCur ] = dbSummationPositive;
|
||||
g_adbSummationNegative[ iCur ] = dbSummationNegative;
|
||||
#else
|
||||
g_adbSummationColour[ iCur ] = dbSummationColour;
|
||||
#endif
|
||||
};
|
||||
|
||||
return rates_total; // Return value for prev_calculated of next call
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
Binary file not shown.
@@ -0,0 +1,114 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Timeframe Confluence Detector.mq5 |
|
||||
//| |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "phade"
|
||||
#property version "1.00"
|
||||
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 5
|
||||
#property indicator_plots 3
|
||||
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrBurlyWood
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrGray
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 1
|
||||
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrDarkGray
|
||||
#property indicator_style3 STYLE_SOLID
|
||||
#property indicator_width3 1
|
||||
|
||||
#define offset 60
|
||||
|
||||
input ENUM_TIMEFRAMES timeframe_a = PERIOD_CURRENT; //Current period
|
||||
input ENUM_TIMEFRAMES timeframe_b = PERIOD_H2; // 1st timeframe deviation to current period
|
||||
input ENUM_TIMEFRAMES timeframe_c = PERIOD_H1; // 2nd timeframe deviation to current period
|
||||
|
||||
int bars;
|
||||
|
||||
double buf_a[];
|
||||
double buf_b[];
|
||||
double buf_c[];
|
||||
|
||||
double deviator_a[], deviator_b[];
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
IndicatorRelease(0);
|
||||
|
||||
SetIndexBuffer(0, buf_a, INDICATOR_DATA);
|
||||
SetIndexBuffer(1, deviator_a, INDICATOR_DATA);
|
||||
SetIndexBuffer(2, deviator_b, INDICATOR_DATA);
|
||||
SetIndexBuffer(3, buf_b, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(4, buf_c, INDICATOR_CALCULATIONS);
|
||||
|
||||
ArraySetAsSeries(buf_a,true);
|
||||
ArraySetAsSeries(buf_b,true);
|
||||
ArraySetAsSeries(buf_c,true);
|
||||
ArraySetAsSeries(deviator_a,true);
|
||||
ArraySetAsSeries(deviator_b,true);
|
||||
|
||||
PlotIndexSetString(0, PLOT_LABEL, TimeframeToString(timeframe_a));
|
||||
PlotIndexSetString(1, PLOT_LABEL, "Deviation from " + TimeframeToString(timeframe_b) + " to " + TimeframeToString(timeframe_a));
|
||||
PlotIndexSetString(2, PLOT_LABEL, "Deviation from " + TimeframeToString(timeframe_c) + " to " + TimeframeToString(timeframe_a));
|
||||
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| 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[])
|
||||
{
|
||||
CopySeries(Symbol(), timeframe_a, 0, rates_total, COPY_RATES_CLOSE, buf_a);
|
||||
CopySeries(Symbol(), timeframe_b, 0, rates_total, COPY_RATES_CLOSE, buf_b);
|
||||
CopySeries(Symbol(), timeframe_c, 0, rates_total, COPY_RATES_CLOSE, buf_c);
|
||||
|
||||
for(int i = rates_total - 1; i>=0; i--){
|
||||
|
||||
deviator_a[i] = MathAbs(buf_b[i] - buf_a[i]) + buf_b[i] - offset*_Point;
|
||||
deviator_b[i] = MathAbs(buf_c[i] - buf_a[i]) + buf_c[i] - (offset*2)*_Point;
|
||||
}
|
||||
|
||||
return(rates_total);
|
||||
}
|
||||
|
||||
|
||||
string TimeframeToString(const ENUM_TIMEFRAMES timeframe)
|
||||
{
|
||||
string result;
|
||||
switch (timeframe){
|
||||
|
||||
case PERIOD_M1: result = "M1"; break;
|
||||
case PERIOD_M5: result = "M5"; break;
|
||||
case PERIOD_M15: result = "M15"; break;
|
||||
case PERIOD_M30: result = "M30"; break;
|
||||
case PERIOD_H1: result = "H1"; break;
|
||||
case PERIOD_H2: result = "H2"; break;
|
||||
case PERIOD_H4: result = "H4"; break;
|
||||
case PERIOD_D1: result = "D1"; break;
|
||||
case PERIOD_W1: result = "W1"; break;
|
||||
case PERIOD_MN1: result = "MN1"; break;
|
||||
default: result = ""; break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| TrendLinearReg.mq5 |
|
||||
//| Copyright 2022, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2022, MetaQuotes Ltd."
|
||||
#property link "https://www.mql5.com"
|
||||
#property version "1.00"
|
||||
#property indicator_separate_window
|
||||
|
||||
#property indicator_buffers 2
|
||||
#property indicator_plots 2
|
||||
#property indicator_color1 LimeGreen
|
||||
#property indicator_type1 DRAW_HISTOGRAM
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
|
||||
#property indicator_color2 Red
|
||||
#property indicator_type2 DRAW_HISTOGRAM
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 1
|
||||
|
||||
extern int barsToCount=34; // Bars to calculate
|
||||
|
||||
double buffer0[];
|
||||
double buffer1[];
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- indicator buffers mapping
|
||||
SetIndexBuffer(0,buffer0);
|
||||
SetIndexBuffer(1,buffer1);
|
||||
//---
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| 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[])
|
||||
{
|
||||
//---
|
||||
|
||||
double b, c, sumy, sumx, sumxy, sumx2;
|
||||
double prev;
|
||||
double current;
|
||||
|
||||
if(rates_total <= barsToCount)
|
||||
return rates_total;
|
||||
|
||||
int start = prev_calculated;
|
||||
if(prev_calculated < barsToCount)
|
||||
start = barsToCount;
|
||||
|
||||
for(int index = start; index < rates_total; index++)
|
||||
{
|
||||
|
||||
sumy=0.0;
|
||||
sumx=0.0;
|
||||
sumxy=0.0;
|
||||
sumx2=0.0;
|
||||
for(int i=0; i < barsToCount ; i++)
|
||||
{
|
||||
sumy+=close[index-i];
|
||||
sumxy+=close[index-i]*(1+i);
|
||||
sumx+=(1+i);
|
||||
sumx2+=(1+i)*(1+i);
|
||||
}
|
||||
|
||||
c=sumx2*barsToCount-sumx*sumx;
|
||||
|
||||
if(c==0)
|
||||
c=0.1;
|
||||
|
||||
b=(sumxy*barsToCount-sumx*sumy)/c;
|
||||
|
||||
current=-1000*b;
|
||||
prev=current;
|
||||
|
||||
|
||||
if(buffer1[index-1] !=EMPTY_VALUE)
|
||||
prev=buffer1[index-1];
|
||||
else
|
||||
if(buffer0[index-1] !=EMPTY_VALUE)
|
||||
prev=buffer0[index-1];
|
||||
|
||||
if(current>=prev)
|
||||
{
|
||||
buffer0[index]= current;
|
||||
buffer1[index]= EMPTY_VALUE;
|
||||
}
|
||||
else
|
||||
if(current<prev)
|
||||
{
|
||||
buffer1[index]= current;
|
||||
buffer0[index]= EMPTY_VALUE;
|
||||
}
|
||||
/*
|
||||
*/
|
||||
}
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,67 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| YMA.mq5 |
|
||||
//| Yuriy Tokman |
|
||||
//| http://ytg.com.ua |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Yuriy Tokman"
|
||||
#property link "http://ytg.com.ua"
|
||||
#property version "1.00"
|
||||
#property indicator_chart_window
|
||||
|
||||
#property indicator_buffers 1
|
||||
#property indicator_plots 1
|
||||
#property indicator_width1 2
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrDarkViolet
|
||||
//--- input parameters
|
||||
input int YMA_Period=21; // Period
|
||||
//--- indicator buffers
|
||||
double Buffer[];
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
SetIndexBuffer(0,Buffer);
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
|
||||
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,YMA_Period);
|
||||
string short_name="YMA";
|
||||
IndicatorSetString(INDICATOR_SHORTNAME,short_name+"("+string(YMA_Period)+")");
|
||||
//---
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| 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 i,limit;
|
||||
//--- check for rates
|
||||
if(rates_total<YMA_Period) return(0);
|
||||
//--- preliminary calculations
|
||||
if(prev_calculated==0)limit=YMA_Period;
|
||||
else limit=prev_calculated-1;
|
||||
//--- the main loop of calculations
|
||||
for(i=limit;i<rates_total && !IsStopped();i++)
|
||||
{
|
||||
double res =0;
|
||||
for(int j=i;j>i-YMA_Period && j>0;j--)
|
||||
{
|
||||
res += (close[j]+open[j]+high[j]+low[j])/4;
|
||||
}
|
||||
Buffer[i]=res/YMA_Period;
|
||||
}
|
||||
//----
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,644 @@
|
||||
|
||||
//
|
||||
// Check Bar has Strong Body or Not ...
|
||||
bool HasStrongBody()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (!IsValid())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double body = GetBody();
|
||||
double shadow = GetShadows();
|
||||
|
||||
//
|
||||
result = body > shadow * 1.5;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Bar Must Open Below Prce
|
||||
// and Close Above it ...
|
||||
bool IsBreakUp(
|
||||
double price // a Price to Check Breake
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = HasStrongBody();
|
||||
if (!result || price <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Select required Prices ...
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
close > price &&
|
||||
open < price;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Bar Must Open Above Prce
|
||||
// and Close Below it ...
|
||||
bool IsBreakDown(
|
||||
double price // a Price to Check Breake
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = HasStrongBody();
|
||||
if (!result || price <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Select required Prices ...
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
open > price &&
|
||||
close < price;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool IsBreakOut(
|
||||
double price, // a Price to Check Breake
|
||||
bool useHighLow = true // if true using High and Low price for Breakeouts, if not use Open Close
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = HasStrongBody();
|
||||
if (!result || price <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Select required Prices ...
|
||||
|
||||
//
|
||||
double selectedUp =
|
||||
useHighLow
|
||||
? high
|
||||
: GetUp();
|
||||
double selectedDown =
|
||||
useHighLow
|
||||
? low
|
||||
: GetDown();
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
selectedUp > price &&
|
||||
selectedDown < price;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check a Support Line Rejected or not ...
|
||||
bool IsSupportRejected(
|
||||
double price // Support Price
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// this is zBar ...
|
||||
// so we are try to Recieve CBar ...
|
||||
XOHCL cBar;
|
||||
result = this.GetPreviousBar(cBar);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Now we are going to Recieve PBar ...
|
||||
XOHCL pBar;
|
||||
result = cBar.GetPreviousBar(pBar);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// We Have this (0) Bar, cBar (1) and pBar (2) ...
|
||||
|
||||
//
|
||||
// pBar Down Shadow must break Price Line ...
|
||||
// cBar and zBar Close must be Above Price Line ...
|
||||
// also zBar Open must be Above Price Line ...
|
||||
result =
|
||||
//
|
||||
pBar.high > price &&
|
||||
pBar.low < price &&
|
||||
cBar.close > price &&
|
||||
this.close > price &&
|
||||
this.open > price
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check a Support Line Breaked or not ...
|
||||
bool IsSupportBreaked(
|
||||
double price // Support Price
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// this is zBar ...
|
||||
// so we are try to Recieve CBar ...
|
||||
XOHCL cBar;
|
||||
result = this.GetPreviousBar(cBar);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Now we are going to Recieve PBar ...
|
||||
XOHCL pBar;
|
||||
result = cBar.GetPreviousBar(pBar);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// We Have this (0) Bar, cBar (1) and pBar (2) ...
|
||||
|
||||
//
|
||||
// pBar Down Shadow must break Price Line ...
|
||||
// cBar and zBar Close must be Below Price Line ...
|
||||
// also zBar Open must be Below Price Line ...
|
||||
result =
|
||||
//
|
||||
pBar.high > price &&
|
||||
pBar.low < price &&
|
||||
cBar.close < price &&
|
||||
this.close < price &&
|
||||
this.open < price
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check a Resistance Line Rejected or not ...
|
||||
bool IsResistanceRejected(
|
||||
double price // Resistance Price
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// this is zBar ...
|
||||
// so we are try to Recieve CBar ...
|
||||
XOHCL cBar;
|
||||
result = this.GetPreviousBar(cBar);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Now we are going to Recieve PBar ...
|
||||
XOHCL pBar;
|
||||
result = cBar.GetPreviousBar(pBar);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// We Have this (0) Bar, cBar (1) and pBar (2) ...
|
||||
|
||||
//
|
||||
// pBar Up Shadow must break Price Line ...
|
||||
// cBar and zBar Close must be Under Price Line ...
|
||||
// also zBar Open must be Under Price Line ...
|
||||
result =
|
||||
//
|
||||
pBar.high > price &&
|
||||
pBar.low < price &&
|
||||
cBar.close < price &&
|
||||
this.close < price &&
|
||||
this.open < price
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check a Resistance Line Breaked or not ...
|
||||
bool IsResistanceBreaked(
|
||||
double price // Support Price
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// this is zBar ...
|
||||
// so we are try to Recieve CBar ...
|
||||
XOHCL cBar;
|
||||
result = this.GetPreviousBar(cBar);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Now we are going to Recieve PBar ...
|
||||
XOHCL pBar;
|
||||
result = cBar.GetPreviousBar(pBar);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// We Have this (0) Bar, cBar (1) and pBar (2) ...
|
||||
|
||||
//
|
||||
// pBar Up Shadow must break Price Line ...
|
||||
// cBar and zBar Close must be Over Price Line ...
|
||||
// also zBar Open must be Pver Price Line ...
|
||||
result =
|
||||
//
|
||||
pBar.low < price &&
|
||||
pBar.high > price &&
|
||||
cBar.close > price &&
|
||||
this.close > price &&
|
||||
this.open > price
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Bar is Inside Previus Bar ...
|
||||
bool IsInsideBar(
|
||||
double threshold = 5 // Points Distance between Up and Down
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (threshold < 0)
|
||||
{
|
||||
threshold = 0;
|
||||
}
|
||||
|
||||
//
|
||||
XOHCL pBar;
|
||||
result = GetPreviousBar(pBar);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double offset = PointToPrice(threshold, this.symbol);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
pBar.high > this.high &&
|
||||
pBar.low < this.low &&
|
||||
MathAbs(pBar.low - this.low) > offset &&
|
||||
MathAbs(pBar.high - this.high) > offset
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Bar has Strongest Body in a Range ...
|
||||
bool HasStrongestBody(
|
||||
int mLoopback = 3 // loopback candles to compare it ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double body = GetBody();
|
||||
XOHCL prev = this;
|
||||
for (int i = 0; i < mLoopback; i++)
|
||||
{
|
||||
//
|
||||
bool isValid = prev.GetPreviousBar(prev);
|
||||
if (!isValid)
|
||||
{
|
||||
//
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
result &&
|
||||
body > prev.GetBody()
|
||||
//
|
||||
;
|
||||
if (!result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Bar has Weakest Body in a Range ...
|
||||
bool HasWeakestBody(
|
||||
int mLoopback = 3 // loopback candles to compare it ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double body = GetBody();
|
||||
XOHCL prev = this;
|
||||
for (int i = 0; i < mLoopback; i++)
|
||||
{
|
||||
//
|
||||
bool isValid = prev.GetPreviousBar(prev);
|
||||
if (!isValid)
|
||||
{
|
||||
//
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
result &&
|
||||
body < prev.GetBody()
|
||||
//
|
||||
;
|
||||
if (!result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Determines Swings based On this Bar ...
|
||||
// Calculates Based on atleast 3 Bars Prev ...
|
||||
ENUM_X_SWING_TYPE GetSwingType()
|
||||
{
|
||||
//
|
||||
ENUM_X_SWING_TYPE result = X_NO_SWING;
|
||||
|
||||
//
|
||||
// Find Current Index of Bar ...
|
||||
int barIndex = Index();
|
||||
if (barIndex <= -1)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// First we have to Retrieve atleast 3 Bars before this bar ...
|
||||
XOHCL bars[];
|
||||
int barsCount = GetBars(
|
||||
bars,
|
||||
symbol,
|
||||
period,
|
||||
barIndex + 1,
|
||||
3
|
||||
//
|
||||
);
|
||||
if (barsCount < 3)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Swing Start Candle has Strong Body ...
|
||||
bool isStrongBodyCandle = bars[2].HasStrongBody();
|
||||
if (!isStrongBodyCandle)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Swing Low Conditions ...
|
||||
bool isSwingLowOrderBlock =
|
||||
bars[2].low < bars[1].low &&
|
||||
bars[1].low < bars[0].low &&
|
||||
bars[2].low < bars[0].low;
|
||||
if (isSwingLowOrderBlock)
|
||||
{
|
||||
result = X_SWING_LOW;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Swing High Conditions ...
|
||||
bool isSwingHighOrderBlock =
|
||||
bars[2].high > bars[1].high &&
|
||||
bars[1].high > bars[0].high &&
|
||||
bars[2].high > bars[0].high;
|
||||
if (isSwingHighOrderBlock)
|
||||
{
|
||||
result = X_SWING_HIGH;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Check Bar Is Hammer Pattern ...
|
||||
bool IsHammer()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
double fib382 = GetFibonacciLevel(
|
||||
high,
|
||||
low,
|
||||
0.382,
|
||||
-1 //
|
||||
);
|
||||
|
||||
//
|
||||
result = GetDown() > fib382;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Bar Is Shooting Star Pattern ...
|
||||
bool IsShootingStar()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
double fib382 = GetFibonacciLevel(
|
||||
high,
|
||||
low,
|
||||
0.382,
|
||||
1 //
|
||||
);
|
||||
|
||||
//
|
||||
result = GetUp() < fib382;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Bar Bullish Engulfing Pattern ...
|
||||
bool IsBullishEngulf()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Current Bar Must be Bullish ...
|
||||
result = IsBullish();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve Previous Bar ...
|
||||
XOHCL pBar;
|
||||
result = GetPreviousBar(pBar);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
pBar.IsBearish() &&
|
||||
open < pBar.close && close > pBar.open &&
|
||||
high >= pBar.high && low <= pBar.low
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Bar Bearish Engulfing Pattern ...
|
||||
bool IsBearishEngulf()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Current Bar Must be Bearish ...
|
||||
result = IsBearish();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve Previous Bar ...
|
||||
XOHCL pBar;
|
||||
result = GetPreviousBar(pBar);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
pBar.IsBullish() &&
|
||||
open > pBar.close && close < pBar.open &&
|
||||
high >= pBar.high && low <= pBar.low
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,562 @@
|
||||
|
||||
//
|
||||
// Detect Trends ...
|
||||
struct XTrendDetector
|
||||
{
|
||||
//
|
||||
string symbol;
|
||||
ENUM_TIMEFRAMES period;
|
||||
|
||||
//
|
||||
double higherHighs[];
|
||||
datetime higherHighTimes[];
|
||||
|
||||
//
|
||||
double higherLows[];
|
||||
datetime higherLowTimes[];
|
||||
|
||||
//
|
||||
double lowerHighs[];
|
||||
datetime lowerHighTimes[];
|
||||
|
||||
//
|
||||
double lowerLows[];
|
||||
datetime lowerLowTimes[];
|
||||
|
||||
//
|
||||
bool isFirstLow;
|
||||
|
||||
//
|
||||
bool isUpTrend;
|
||||
bool isDownTrend;
|
||||
|
||||
//
|
||||
int _numberOfPivots;
|
||||
int _pivotShoulders;
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XTrendDetector()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
bool FindTrend(
|
||||
string _symbol,
|
||||
ENUM_TIMEFRAMES _period,
|
||||
int barIndex = 0,
|
||||
int _requiredPivots = 3,
|
||||
int _requiredShoulders = 3 //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (barIndex < 0)
|
||||
{
|
||||
barIndex = 0;
|
||||
}
|
||||
|
||||
//
|
||||
if (_requiredPivots < 3)
|
||||
{
|
||||
_requiredPivots = 3;
|
||||
}
|
||||
|
||||
//
|
||||
if (_requiredShoulders < 3)
|
||||
{
|
||||
_requiredShoulders = 3;
|
||||
}
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
IsValid(_symbol) &&
|
||||
IsValid(_period)
|
||||
//
|
||||
;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Find Swing Lows and Swing Highs ...
|
||||
|
||||
//
|
||||
int hhIndexes[];
|
||||
datetime hhTimes[];
|
||||
double hhs[];
|
||||
|
||||
//
|
||||
int llIndexes[];
|
||||
datetime llTimes[];
|
||||
double lls[];
|
||||
|
||||
//
|
||||
bool isEnough = false;
|
||||
|
||||
//
|
||||
double lastHH = 0;
|
||||
int lastHHIndex = barIndex;
|
||||
datetime lastHHTime = NULL;
|
||||
|
||||
//
|
||||
double lastLL = 0;
|
||||
int lastLLIndex = barIndex;
|
||||
datetime lastLLTime = NULL;
|
||||
|
||||
//
|
||||
// Calculate First ...
|
||||
lastHHIndex = FindSwing(
|
||||
_symbol,
|
||||
_period,
|
||||
X_SWING_HIGH,
|
||||
_requiredShoulders,
|
||||
lastHHIndex + 1 //
|
||||
);
|
||||
if (lastHHIndex >= 0)
|
||||
{
|
||||
//
|
||||
XOHCL lastBar;
|
||||
bool isInited = lastBar.Init(
|
||||
_symbol,
|
||||
_period,
|
||||
lastHHIndex //
|
||||
);
|
||||
if (isInited)
|
||||
{
|
||||
//
|
||||
lastHH = lastBar.high;
|
||||
lastHHTime = lastBar.time;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
lastLLIndex = FindSwing(
|
||||
_symbol,
|
||||
_period,
|
||||
X_SWING_LOW,
|
||||
_requiredShoulders,
|
||||
lastLLIndex + 1 //
|
||||
);
|
||||
if (lastLLIndex >= 0)
|
||||
{
|
||||
//
|
||||
XOHCL lastBar;
|
||||
bool isInited = lastBar.Init(
|
||||
_symbol,
|
||||
_period,
|
||||
lastLLIndex //
|
||||
);
|
||||
if (isInited)
|
||||
{
|
||||
//
|
||||
lastHH = lastBar.high;
|
||||
lastHHTime = lastBar.time;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
lastLLIndex >= 0 &&
|
||||
lastHHIndex >= 0
|
||||
//
|
||||
;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool isFirstLow =
|
||||
//
|
||||
lastLLIndex < lastHHIndex
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
while (!isEnough)
|
||||
{
|
||||
//
|
||||
int hhSize = ArraySize(hhs);
|
||||
if (hhSize < _requiredPivots)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
//
|
||||
int llSize = ArraySize(lls);
|
||||
if (llSize < _requiredPivots * 2)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
// while (!isEnough)
|
||||
// {
|
||||
// //
|
||||
// int hhSize = ArraySize(hhs);
|
||||
// if (hhSize < _requiredPivots * 2)
|
||||
// {
|
||||
// //
|
||||
// lastHHIndex = FindSwing(
|
||||
// _symbol,
|
||||
// _period,
|
||||
// X_SWING_HIGH,
|
||||
// _requiredShoulders,
|
||||
// lastHHIndex + 1 //
|
||||
// );
|
||||
// if (lastHHIndex >= 0)
|
||||
// {
|
||||
// //
|
||||
// XOHCL hBar;
|
||||
// bool isInited = hBar.Init(
|
||||
// _symbol,
|
||||
// _period,
|
||||
// lastHHIndex //
|
||||
// );
|
||||
// if (isInited)
|
||||
// {
|
||||
// //
|
||||
// Add(
|
||||
// hBar.high,
|
||||
// hhs //
|
||||
// );
|
||||
|
||||
// //
|
||||
// Add(
|
||||
// hBar.time,
|
||||
// hhTimes //
|
||||
// );
|
||||
|
||||
// //
|
||||
// Add(
|
||||
// lastHHIndex,
|
||||
// hhIndexes //
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// //
|
||||
// int llSize = ArraySize(lls);
|
||||
// if (llSize < _requiredPivots * 2)
|
||||
// {
|
||||
// //
|
||||
// lastLLIndex = FindSwing(
|
||||
// _symbol,
|
||||
// _period,
|
||||
// X_SWING_LOW,
|
||||
// _requiredShoulders,
|
||||
// lastLLIndex + 1 //
|
||||
// );
|
||||
// if (lastLLIndex >= 0)
|
||||
// {
|
||||
// //
|
||||
// XOHCL lBar;
|
||||
// bool isInited = lBar.Init(
|
||||
// _symbol,
|
||||
// _period,
|
||||
// lastLLIndex //
|
||||
// );
|
||||
// if (isInited)
|
||||
// {
|
||||
// //
|
||||
// Add(
|
||||
// lBar.low,
|
||||
// lls //
|
||||
// );
|
||||
|
||||
// //
|
||||
// Add(
|
||||
// lBar.time,
|
||||
// llTimes //
|
||||
// );
|
||||
|
||||
// //
|
||||
// Add(
|
||||
// lastHHIndex,
|
||||
// llIndexes //
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// //
|
||||
// hhSize = ArraySize(hhs);
|
||||
// llSize = ArraySize(lls);
|
||||
// isEnough =
|
||||
// //
|
||||
// hhSize == _requiredPivots * 2 &&
|
||||
// llSize == _requiredPivots * 2
|
||||
// //
|
||||
// ;
|
||||
// }
|
||||
|
||||
// //
|
||||
// ArrayReverse(hhs);
|
||||
// ArrayReverse(hhTimes);
|
||||
// ArrayReverse(hhIndexes);
|
||||
|
||||
// //
|
||||
// ArrayReverse(lls);
|
||||
// ArrayReverse(llTimes);
|
||||
// ArrayReverse(llIndexes);
|
||||
|
||||
//
|
||||
// Draws ...
|
||||
for (int i = 0; i < ArraySize(hhs); i++)
|
||||
{
|
||||
//
|
||||
DrawArrow(
|
||||
ChartID(),
|
||||
"XTRND_HH" + ToString(i),
|
||||
0,
|
||||
hhTimes[i],
|
||||
hhs[i],
|
||||
234,
|
||||
ANCHOR_BOTTOM,
|
||||
clrMagenta,
|
||||
STYLE_SOLID,
|
||||
3 //
|
||||
);
|
||||
|
||||
//
|
||||
DrawArrow(
|
||||
ChartID(),
|
||||
"XTRND_LL" + ToString(i),
|
||||
0,
|
||||
llTimes[i],
|
||||
lls[i],
|
||||
233,
|
||||
ANCHOR_TOP,
|
||||
clrAqua,
|
||||
STYLE_SOLID,
|
||||
3 //
|
||||
);
|
||||
}
|
||||
|
||||
// //
|
||||
// // Here We Try to Detect Trands ...
|
||||
// int idxHH = 0;
|
||||
// int idxLL = 0;
|
||||
// isEnough = false;
|
||||
// isFirstLow = llTimes[0] > hhTimes[0];
|
||||
// while(!isEnough) {
|
||||
// //
|
||||
// datetime firstTime = NULL;
|
||||
// if (isFirstLow) {
|
||||
// //
|
||||
// firstTime = llTimes[0];
|
||||
|
||||
// //
|
||||
// // Looking for a High ...
|
||||
|
||||
// //
|
||||
// if (hhs[hhIdx] > lls[llIdx]) {
|
||||
|
||||
// }
|
||||
// } else {
|
||||
// //
|
||||
// firstTime = hhTimes[0];
|
||||
|
||||
// //
|
||||
// // Looking for a Low ...
|
||||
// }
|
||||
// }
|
||||
|
||||
//
|
||||
isUpTrend =
|
||||
//
|
||||
isFirstLow
|
||||
?
|
||||
//
|
||||
lls[0] > lls[1] &&
|
||||
lls[1] > lls[2] &&
|
||||
//
|
||||
hhs[0] > hhs[1] &&
|
||||
hhs[1] > hhs[2]
|
||||
//
|
||||
:
|
||||
//
|
||||
hhs[0] > hhs[1] &&
|
||||
hhs[1] > hhs[2] &&
|
||||
//
|
||||
lls[0] > lls[1] &&
|
||||
lls[1] > lls[2]
|
||||
//
|
||||
;
|
||||
isDownTrend =
|
||||
//
|
||||
isFirstLow
|
||||
?
|
||||
//
|
||||
lls[0] < lls[1] &&
|
||||
lls[1] < lls[2] &&
|
||||
//
|
||||
hhs[0] < hhs[1] &&
|
||||
hhs[1] < hhs[2]
|
||||
//
|
||||
:
|
||||
//
|
||||
hhs[0] < hhs[1] &&
|
||||
hhs[1] < hhs[2] &&
|
||||
//
|
||||
lls[0] < lls[1] &&
|
||||
lls[1] < lls[2]
|
||||
//
|
||||
;
|
||||
for (int i = 1; i < _requiredPivots; i++)
|
||||
{
|
||||
//
|
||||
// Lows ...
|
||||
|
||||
//
|
||||
// Lower Lows ...
|
||||
if (lls[i - 1] < lls[i])
|
||||
{
|
||||
//
|
||||
Add(
|
||||
lls[i - 1],
|
||||
lowerLows //
|
||||
);
|
||||
|
||||
//
|
||||
Add(
|
||||
llTimes[i - 1],
|
||||
lowerLowTimes //
|
||||
);
|
||||
}
|
||||
else
|
||||
//
|
||||
// Higher Lows ...
|
||||
if (lls[i - 1] > lls[i])
|
||||
{
|
||||
//
|
||||
Add(
|
||||
lls[i - 1],
|
||||
higherLows //
|
||||
);
|
||||
|
||||
//
|
||||
Add(
|
||||
llTimes[i - 1],
|
||||
higherLowTimes //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Highs ...
|
||||
|
||||
//
|
||||
// Higher Highs ...
|
||||
if (hhs[i - 1] > hhs[i])
|
||||
{
|
||||
//
|
||||
Add(
|
||||
hhs[i - 1],
|
||||
higherHighs //
|
||||
);
|
||||
|
||||
//
|
||||
Add(
|
||||
hhTimes[i - 1],
|
||||
higherHighTimes //
|
||||
);
|
||||
}
|
||||
else
|
||||
//
|
||||
// Lower Highs ...
|
||||
if (hhs[i - 1] < hhs[i])
|
||||
{
|
||||
//
|
||||
Add(
|
||||
hhs[i - 1],
|
||||
lowerHighs //
|
||||
);
|
||||
|
||||
//
|
||||
Add(
|
||||
hhTimes[i - 1],
|
||||
lowerHighTimes //
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Remove Draws ...
|
||||
RemoveDraws("XTRND");
|
||||
|
||||
//
|
||||
symbol = _symbol;
|
||||
period = _period;
|
||||
_numberOfPivots = _requiredPivots;
|
||||
_pivotShoulders = _requiredShoulders;
|
||||
|
||||
//
|
||||
result = IsValid();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
symbol = NULL;
|
||||
period = NULL;
|
||||
|
||||
//
|
||||
_numberOfPivots = 0;
|
||||
_pivotShoulders = 0;
|
||||
|
||||
//
|
||||
Clean(higherHighs);
|
||||
Clean(higherHighTimes);
|
||||
|
||||
//
|
||||
Clean(higherLows);
|
||||
Clean(higherLowTimes);
|
||||
|
||||
//
|
||||
Clean(lowerHighs);
|
||||
Clean(lowerHighTimes);
|
||||
|
||||
//
|
||||
Clean(lowerLows);
|
||||
Clean(lowerLowTimes);
|
||||
}
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
bool IsValid()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
IsValid(symbol) &&
|
||||
IsValid(period)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,59 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Class Library
|
||||
// ----------------------------------------------
|
||||
// Name: XSCBaseInd
|
||||
// Description: provides Indicator implementation
|
||||
// requirements ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../../Classes/x-saherelm.xind.class.mq5"
|
||||
|
||||
//
|
||||
// a Simple Indicator ...
|
||||
|
||||
class XSCMid : public XSCBaseInd
|
||||
{
|
||||
//
|
||||
// Public ...
|
||||
public:
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
// Constructor(s) ...
|
||||
|
||||
//
|
||||
// Deconstructor ...
|
||||
|
||||
//
|
||||
// Property Getter(s) / Setter(s) ...
|
||||
|
||||
//
|
||||
// Override(s) ...
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
//
|
||||
// Protected ...
|
||||
protected:
|
||||
//
|
||||
// Private ...
|
||||
private:
|
||||
};
|
||||
@@ -0,0 +1,845 @@
|
||||
|
||||
//
|
||||
struct XPivot
|
||||
{
|
||||
//
|
||||
double pivot; // Pivot Price ...
|
||||
int breaks; // Number of Breaks ...
|
||||
int rejects; // Number of Rejects ...
|
||||
|
||||
//
|
||||
void XPivot()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
pivot = 0;
|
||||
breaks = 0;
|
||||
rejects = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
bool IsValid()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = pivot > 0;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
struct XPivotTracker
|
||||
{
|
||||
//
|
||||
XPivot pivots[];
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
void XPivotTracker()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
Clean(pivots);
|
||||
}
|
||||
|
||||
//
|
||||
int Count()
|
||||
{
|
||||
return ArraySize(pivots);
|
||||
}
|
||||
|
||||
//
|
||||
double Get(int index)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
NormalizeIndex(index, pivots);
|
||||
|
||||
//
|
||||
XPivot iPivot = pivots[index];
|
||||
|
||||
//
|
||||
result = iPivot.pivot;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
XPivot GetPivot(int index)
|
||||
{
|
||||
//
|
||||
XPivot result;
|
||||
|
||||
//
|
||||
NormalizeIndex(index, pivots);
|
||||
|
||||
//
|
||||
result = pivots[index];
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool Add(double mPivot)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = mPivot > 0 && !Has(mPivot);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
XPivot pivot;
|
||||
pivot.pivot = mPivot;
|
||||
|
||||
//
|
||||
AddRef(
|
||||
pivot,
|
||||
pivots //
|
||||
);
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int Adds(double &mPivots[])
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
int pivotsCount = ArraySize(mPivots);
|
||||
if (!IsValidSize(pivotsCount))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = 0; i < pivotsCount; i++)
|
||||
{
|
||||
//
|
||||
double iPivot = mPivots[i];
|
||||
|
||||
//
|
||||
bool isAdded = Add(iPivot);
|
||||
if (isAdded)
|
||||
{
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int FindIndex(double mPivot)
|
||||
{
|
||||
//
|
||||
int result = -1;
|
||||
|
||||
//
|
||||
if (mPivot <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int count = Count();
|
||||
if (!IsValidSize(count))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
XPivot iPivot = pivots[i];
|
||||
|
||||
//
|
||||
if (iPivot.pivot == mPivot)
|
||||
{
|
||||
//
|
||||
result = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double Has(double mPivot)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
int pivotIDX = FindIndex(mPivot);
|
||||
result = pivotIDX >= 0;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int Reject(double mPivot)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
int pivotIDX = FindIndex(mPivot);
|
||||
if (pivotIDX < 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
pivots[pivotIDX].rejects++;
|
||||
|
||||
//
|
||||
result = pivots[pivotIDX].rejects;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int Break(double mPivot)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
int pivotIDX = FindIndex(mPivot);
|
||||
if (pivotIDX < 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
pivots[pivotIDX].breaks++;
|
||||
|
||||
//
|
||||
result = pivots[pivotIDX].breaks;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool Remove(double mPivot)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
int pivotIDX = FindIndex(mPivot);
|
||||
result = pivotIDX >= 0;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = ArrayRemove(
|
||||
pivots,
|
||||
pivotIDX,
|
||||
1 //
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool HasChild()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
int count = Count();
|
||||
result = IsValidSize(count);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Model Support and Resistance
|
||||
// for Specific Bar ...
|
||||
struct XOHCLSupRes
|
||||
{
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
/// Resistances ...
|
||||
double res[];
|
||||
|
||||
//
|
||||
// Supports ...
|
||||
double sup[];
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XOHCLSupRes()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Init ...
|
||||
bool Init(
|
||||
double price, // Price ...
|
||||
const double &pivots[], // Provided Pivot Points ...
|
||||
int count = 3, // Number of Requireds ...
|
||||
double step = 0 // Distance between each item with it's Last Side ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
Clean();
|
||||
|
||||
//
|
||||
if (price <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int pivotsCount = ArraySize(pivots);
|
||||
if (pivotsCount <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
if (count <= 0 ||
|
||||
count > pivotsCount - 1)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double lastR = 0;
|
||||
double tmpR[];
|
||||
|
||||
//
|
||||
double lastS = 0;
|
||||
double tmpS[];
|
||||
|
||||
//
|
||||
// Extract Supports ...
|
||||
// which prices is under low of candle ...
|
||||
//
|
||||
// Extract Resistance ...
|
||||
// which prices is over high of candle ...
|
||||
for (int i = 0; i < pivotsCount; i++)
|
||||
{
|
||||
//
|
||||
double iFlat = pivots[i];
|
||||
|
||||
//
|
||||
if (iFlat > price)
|
||||
{
|
||||
//
|
||||
bool canAdd =
|
||||
step <= 0
|
||||
? true
|
||||
: lastR == 0 || MathAbs(iFlat - lastR) >= step;
|
||||
if (canAdd)
|
||||
{
|
||||
//
|
||||
Add(
|
||||
iFlat,
|
||||
tmpR);
|
||||
|
||||
//
|
||||
lastR = iFlat;
|
||||
}
|
||||
}
|
||||
else if (iFlat < price)
|
||||
{
|
||||
//
|
||||
bool canAdd =
|
||||
step <= 0
|
||||
? true
|
||||
: lastS == 0 || MathAbs(iFlat - lastS) >= step;
|
||||
if (canAdd)
|
||||
{
|
||||
//
|
||||
Add(
|
||||
iFlat,
|
||||
tmpS);
|
||||
|
||||
//
|
||||
lastS = iFlat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Sorting Founded Resistance and Supports ...
|
||||
|
||||
//
|
||||
// Since Resistance Levels must be Increasing ...
|
||||
ArraySort(tmpR);
|
||||
|
||||
//
|
||||
// Since Support Levels must be Decreasing ...
|
||||
ArraySort(tmpS);
|
||||
ArrayReverse(tmpS);
|
||||
|
||||
//
|
||||
// Fill Resistance ...
|
||||
int tmpRCount = ArraySize(tmpR);
|
||||
if (tmpRCount > 0)
|
||||
{
|
||||
//
|
||||
if (tmpRCount < count)
|
||||
{
|
||||
//
|
||||
ArrayCopy(
|
||||
res,
|
||||
tmpR);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
ArrayCopy(
|
||||
res,
|
||||
tmpR,
|
||||
0,
|
||||
0,
|
||||
count);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Fill Supports ...
|
||||
int tmpSCount = ArraySize(tmpS);
|
||||
if (tmpSCount > 0)
|
||||
{
|
||||
//
|
||||
if (tmpSCount < count)
|
||||
{
|
||||
//
|
||||
ArrayCopy(
|
||||
sup,
|
||||
tmpS);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
ArrayCopy(
|
||||
sup,
|
||||
tmpS,
|
||||
0,
|
||||
0,
|
||||
count);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result = IsValid();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
Clean(sup);
|
||||
Clean(res);
|
||||
}
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
bool IsValid()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
CountSupports() > 0 ||
|
||||
CountResistances() > 0
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int CountSupports()
|
||||
{
|
||||
return ArraySize(sup);
|
||||
}
|
||||
|
||||
//
|
||||
int CountResistances()
|
||||
{
|
||||
return ArraySize(res);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Track Value Changes ...
|
||||
template <typename T>
|
||||
struct XValueTracker
|
||||
{
|
||||
//
|
||||
// Definitions ...
|
||||
|
||||
//
|
||||
// Model a Value Change ...
|
||||
struct XValueChange
|
||||
{
|
||||
//
|
||||
// Props ...
|
||||
datetime at; // Change Time
|
||||
T from; // Before Change Value
|
||||
T to; // After Change Value
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XValueChange()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
at = NULL;
|
||||
from = NULL;
|
||||
to = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate ...
|
||||
bool IsValid()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = IsValid(at);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = NotEmpty(from) &&
|
||||
NotEmpty(to);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Props ...
|
||||
XValueChange changes[]; // Hold Changes
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XValueTracker()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Track a Change Happens Or Not ...
|
||||
bool Track(
|
||||
const T &source[] // Data Source for Track Changes
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (ArraySize(source) <= 1)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
datetime time = TimeCurrent();
|
||||
|
||||
//
|
||||
double from = source[1];
|
||||
double to = source[0];
|
||||
|
||||
//
|
||||
result = to != from;
|
||||
if (result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
XValueChange lastChange;
|
||||
bool hasLastChange =
|
||||
GetLastItem(
|
||||
lastChange,
|
||||
changes
|
||||
//
|
||||
);
|
||||
result =
|
||||
!hasLastChange
|
||||
? true
|
||||
: lastChange.at < time &&
|
||||
lastChange.to != to &&
|
||||
lastChange.from != from;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
lastChange.Clean();
|
||||
|
||||
//
|
||||
lastChange.to = to;
|
||||
lastChange.at = time;
|
||||
lastChange.from = from;
|
||||
|
||||
//
|
||||
AddRef(
|
||||
lastChange,
|
||||
changes
|
||||
//
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
//
|
||||
// Cleanup ...
|
||||
void Clean()
|
||||
{
|
||||
Clean(changes);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
int GenerateEQMOrders(
|
||||
XSignal &orders[], // Result
|
||||
XPosition &position, // Supported Position
|
||||
XOHCLSupRes &supRes, // Data Source
|
||||
bool longs = true,
|
||||
bool shorts = true //
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
Clean(orders);
|
||||
|
||||
//
|
||||
if (!supRes.IsValid() ||
|
||||
!position.IsValid())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
if (longs)
|
||||
{
|
||||
//
|
||||
double longLevels[];
|
||||
|
||||
//
|
||||
Copy(
|
||||
supRes.res,
|
||||
longLevels //
|
||||
);
|
||||
|
||||
//
|
||||
double minSup = GetMin(
|
||||
supRes.sup //
|
||||
);
|
||||
if (minSup > 0)
|
||||
{
|
||||
//
|
||||
Add(
|
||||
minSup,
|
||||
longLevels //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
ArraySort(longLevels);
|
||||
|
||||
//
|
||||
if (ArraySize(longLevels) > 2)
|
||||
{
|
||||
//
|
||||
for (int i = 0; i < ArraySize(longLevels) - 2; i++)
|
||||
{
|
||||
//
|
||||
double iSL = longLevels[i];
|
||||
double iEntry = longLevels[i + 1];
|
||||
double iTP = longLevels[i + 2];
|
||||
|
||||
//
|
||||
XSignal iSignal;
|
||||
bool isPrepared = iSignal.PrepareStopLong(
|
||||
position.symbol,
|
||||
XEQMSupportToken,
|
||||
position.period,
|
||||
iEntry,
|
||||
position.volume,
|
||||
iSL,
|
||||
iTP //
|
||||
);
|
||||
if (isPrepared)
|
||||
{
|
||||
//
|
||||
string comment = GenerateSupportTag(position.ticket);
|
||||
iSignal.comment = comment;
|
||||
|
||||
//
|
||||
AddRef(
|
||||
iSignal,
|
||||
orders //
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (shorts)
|
||||
{
|
||||
//
|
||||
double shortLevels[];
|
||||
|
||||
//
|
||||
Copy(
|
||||
supRes.sup,
|
||||
shortLevels //
|
||||
);
|
||||
|
||||
//
|
||||
double maxRes = GetMax(
|
||||
supRes.res //
|
||||
);
|
||||
if (maxRes > 0)
|
||||
{
|
||||
//
|
||||
Add(
|
||||
maxRes,
|
||||
shortLevels //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
ArraySort(shortLevels);
|
||||
ArrayReverse(shortLevels);
|
||||
|
||||
//
|
||||
if (ArraySize(shortLevels) > 2)
|
||||
{
|
||||
//
|
||||
for (int i = 0; i < ArraySize(shortLevels) - 2; i++)
|
||||
{
|
||||
//
|
||||
double iSL = shortLevels[i];
|
||||
double iEntry = shortLevels[i + 1];
|
||||
double iTP = shortLevels[i + 2];
|
||||
|
||||
//
|
||||
XSignal iSignal;
|
||||
bool isPrepared = iSignal.PrepareStopShort(
|
||||
position.symbol,
|
||||
XEQMSupportToken,
|
||||
position.period,
|
||||
iEntry,
|
||||
position.volume,
|
||||
iSL,
|
||||
iTP //
|
||||
);
|
||||
if (isPrepared)
|
||||
{
|
||||
//
|
||||
string comment = GenerateSupportTag(position.ticket);
|
||||
iSignal.comment = comment;
|
||||
|
||||
//
|
||||
AddRef(
|
||||
iSignal,
|
||||
orders //
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result = ArraySize(orders);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user