Initial Commit ...
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,947 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 RSI Signal Provider Library
|
||||
// --------------------------------------------------------
|
||||
// Name: XRSISignalProvider
|
||||
// Description: RSI based signal provider ...
|
||||
//
|
||||
//
|
||||
// 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
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input group "XRSI Provider";
|
||||
|
||||
//
|
||||
input group "XRSI Common";
|
||||
input bool enableRSIProvider = true; // Enable Provider
|
||||
input bool rsiEnableAlerts = true; // Enable Events Alert
|
||||
|
||||
//
|
||||
input group "XRSI Indicator";
|
||||
input int rsiPeriod = 14; // RSI Period
|
||||
input ENUM_APPLIED_PRICE rsiAppliedTo = PRICE_CLOSE; // RSI Applied To
|
||||
|
||||
//
|
||||
input group "XRSI Trader";
|
||||
input int rsiMagicNumber = 16940561; // RSI Trader MagicNumber
|
||||
input int rsiSlippage = 10; // RSI Trader Slippage
|
||||
input double rsiLongEntryLevel = 30; // RSI Long Entry Level
|
||||
input double rsiLongExitLevel = 60; // RSI Long Exit Level
|
||||
input double rsiShortEntryLevel = 70; // RSI Short Entry Level
|
||||
input double rsiShortExitLevel = 40; // RSI Short Exit Level
|
||||
|
||||
//
|
||||
input group "XRSI Neural Networks";
|
||||
input bool rsiUseNeuralNetworks = true; // Enable Neural Networks
|
||||
input bool rsiNNUseContinuesLearning = true; // Enable Continues Learning on Neural Networks
|
||||
input int rsiNNNumberOfNodes = 10; // Number Of Input Nodes
|
||||
input double rsiNNLongTargetOutput = 0.3; // BackPropagation Target Output for Long Trades
|
||||
input double rsiNNShortTargetOutput = -0.3; // BackPropagation Target Output for Short Trades
|
||||
|
||||
//
|
||||
input group "XRSI Trade Management";
|
||||
input bool rsiAllowLongTrades = true; // Allow Long Trades
|
||||
input bool rsiAllowShortTrades = true; // Allow Short Trades
|
||||
input bool rsiUseGridTrades = true; // Enable Grid Trades
|
||||
input double rsiGridVolumeMultiplier = 2; // Grid Volume Multiplier
|
||||
input double rsiGridDistancePips = 10; // Grid Position Distance in Pips
|
||||
|
||||
//
|
||||
input group "XRSI Risk Management";
|
||||
input bool rsiUseDynamicVolume = true; // Enable Dynamic Volume
|
||||
input double rsiStaticVolume = 0.01; // Static Volume
|
||||
// input double rsiBalanceIncreasedFactor = 0.1; // RSI Balance Increase Factor
|
||||
// input double rsiVolumeIncreasedFactor = 0.000001; // RSI Volume Increase Factor
|
||||
// //
|
||||
// // END Inputs ...
|
||||
// //
|
||||
input double rsiBalanceIncreased = 500; // RSI Balance Increase
|
||||
input double rsiVolumeIncreased = 0.01; // RSI Volume Increase
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Include Common Library ...
|
||||
#include "x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Logger Library ...
|
||||
#include "x-saherelm.log.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Alert Library ...
|
||||
#include "x-saherelm.alert.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Draw Library ...
|
||||
#include "x-saherelm.draw.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Class Libraries ...
|
||||
#include "x-saherelm.class.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Neural Networks Library ...
|
||||
#include "x-saherelm.nn.lib.mq5";
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
int rsiHandler = INVALID_HANDLE;
|
||||
double rsiBuffer[];
|
||||
|
||||
//
|
||||
XCTrade *rsiTrader;
|
||||
XCAccountInfo rsiAccountInfo;
|
||||
|
||||
//
|
||||
XCNNBase *rsiNN;
|
||||
|
||||
//
|
||||
double rsiGridLongPrice = 0;
|
||||
double rsiGridLongVolume = 0;
|
||||
|
||||
//
|
||||
double rsiGridShortPrice = 0;
|
||||
double rsiGridShortVolume = 0;
|
||||
|
||||
//
|
||||
// holds Neural Networks Output Value ...
|
||||
double rsiNNOutput;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Provided Functions ...
|
||||
//
|
||||
//
|
||||
// Initial Library if required ...
|
||||
bool OnInInitXRSISignalProviderLibrary()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Error Message ...
|
||||
string message = "";
|
||||
|
||||
//
|
||||
// Check RSI Period ...
|
||||
if (rsiPeriod < 5)
|
||||
{
|
||||
//
|
||||
message = "invalid rsi period ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check RSI Over Baught and Over Sold Levels ...
|
||||
if (
|
||||
rsiLongExitLevel <= 0 ||
|
||||
rsiLongEntryLevel <= 0 ||
|
||||
rsiShortExitLevel <= 0 ||
|
||||
rsiShortEntryLevel <= 0 ||
|
||||
rsiLongEntryLevel >= rsiLongExitLevel ||
|
||||
rsiLongEntryLevel >= rsiShortEntryLevel ||
|
||||
rsiShortEntryLevel <= rsiShortExitLevel ||
|
||||
rsiShortEntryLevel <= rsiLongEntryLevel)
|
||||
{
|
||||
//
|
||||
message = "invalid over baught / over seld level ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Risk Management ...
|
||||
if (rsiUseDynamicVolume)
|
||||
{
|
||||
//
|
||||
// if (rsiBalanceIncreasedFactor <= 0 || rsiVolumeIncreasedFactor <= 0)
|
||||
if (rsiBalanceIncreased <= 0 || rsiVolumeIncreased <= 0)
|
||||
{
|
||||
//
|
||||
message = "invalid volume increased factors ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
double maxAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
||||
double minAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
||||
|
||||
//
|
||||
if (rsiStaticVolume > maxAvailableVolume || rsiStaticVolume < minAvailableVolume)
|
||||
{
|
||||
//
|
||||
message = "invalid static volume ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check Neural Networks Inputs ...
|
||||
if (rsiUseNeuralNetworks)
|
||||
{
|
||||
//
|
||||
// Number Of Nodes ...
|
||||
if (rsiNNNumberOfNodes < 3)
|
||||
{
|
||||
//
|
||||
message = "invalid neurak networks inputs ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// if there is no error in nn inputs, make an instance of
|
||||
// Neural Networks Clsss ...
|
||||
rsiNN = new XCNNBase(
|
||||
rsiNNNumberOfNodes);
|
||||
}
|
||||
|
||||
//
|
||||
// Preparing RSI Handler ...
|
||||
rsiHandler = iRSI(_Symbol, _Period, rsiPeriod, rsiAppliedTo);
|
||||
if (rsiHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
message = "failed to initialize rsi indicator handler ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Make XCTrader instance ...
|
||||
rsiTrader = new XCTrade(
|
||||
_Symbol,
|
||||
rsiSlippage,
|
||||
rsiMagicNumber);
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
// Logging State ...
|
||||
message = "Initializion of (" + "XRSI Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitial Library if required ...
|
||||
void OnDeinitXRSISignalProviderLibrary()
|
||||
{
|
||||
//
|
||||
// Logging State ...
|
||||
string message = "De Initializion of (" + "XRSI Provider" + ") Succeeded ...";
|
||||
LogMessage(message);
|
||||
}
|
||||
|
||||
//
|
||||
// this is a Globally Function which do all of
|
||||
// checkings and positions handling ...
|
||||
void HandleXSignalProviderTick()
|
||||
{
|
||||
//
|
||||
// Reading RSI Values ...
|
||||
ArraySetAsSeries(rsiBuffer, true);
|
||||
|
||||
//
|
||||
// Copy RSI Buffers based on NN Conditions ...
|
||||
if (rsiUseNeuralNetworks)
|
||||
{
|
||||
//
|
||||
CopyBuffer(rsiHandler, 0, 0, rsiNNNumberOfNodes, rsiBuffer);
|
||||
|
||||
//
|
||||
// Calculate Neural Network Output Layer based on Inputs ...
|
||||
// since here there is no any external inputs except rsiBuffer
|
||||
// we passed it directly to our Neural Networks as Inputs ...
|
||||
rsiNNOutput = rsiNN.CalculateOutputLayer(rsiBuffer);
|
||||
|
||||
//
|
||||
// Check Continues Learning is Enabled ...
|
||||
if (rsiNNUseContinuesLearning)
|
||||
{
|
||||
//
|
||||
// Handle Back Propagation (Continues Learning) ...
|
||||
double targetOutput = 0;
|
||||
if (rsiBuffer[1] >= 50)
|
||||
{
|
||||
targetOutput = rsiNNLongTargetOutput;
|
||||
}
|
||||
else if (rsiBuffer[1] < 50)
|
||||
{
|
||||
targetOutput = rsiNNShortTargetOutput;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Calculate Weights ...
|
||||
if (targetOutput != 0)
|
||||
{
|
||||
rsiNN.BackPropagation(rsiBuffer, rsiNNOutput, targetOutput);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyBuffer(rsiHandler, 0, 0, 5, rsiBuffer);
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
HandleOpenTrades();
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
HandleCloseTrades();
|
||||
|
||||
//
|
||||
// Draw Signals ...
|
||||
// bool hasPrimaryLongSignal = HasPrimaryLongSignal();
|
||||
// bool hasPrimaryShortSignal = HasPrimaryShortSignal();
|
||||
// bool hasPrimarySignal = hasPrimaryLongSignal || hasPrimaryShortSignal;
|
||||
// if (hasPrimarySignal)
|
||||
// {
|
||||
// //
|
||||
// ENUM_X_SIGNAL_TYPE signalType = hasPrimaryLongSignal ? X_SIGNAL_LONG : X_SIGNAL_SHORT;
|
||||
// double signalPrice = signalType == X_SIGNAL_LONG ? GetAsk() : GetBid();
|
||||
// string signalName = logTag + "_" + EnumToString(signalType) + "_" + DoubleToString(signalPrice);
|
||||
// color signalColor = signalType == X_SIGNAL_LONG ? clrAqua : clrYellow;
|
||||
// datetime signalTime1 = iTime(_Symbol, _Period, 1);
|
||||
// datetime signalTime2 = iTime(_Symbol, _Period, 0);
|
||||
|
||||
// //
|
||||
// DrawTrendLine(
|
||||
// 0, // Chart Id ...
|
||||
// signalName, // Object Name ...
|
||||
// 0, // SubWindow ...
|
||||
// signalTime1, // Time 1 ...
|
||||
// signalPrice, // Price 1 ...
|
||||
// signalTime2, // Time 2 ...
|
||||
// signalPrice, // Price 2 ...
|
||||
// signalColor, // Color ...
|
||||
// STYLE_SOLID,
|
||||
// 5
|
||||
// );
|
||||
// }
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions to find Long Primary Signals ...
|
||||
bool HasPrimaryLongSignal()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Buy/Long Conditions ...
|
||||
result = rsiBuffer[1] >= rsiLongEntryLevel && rsiBuffer[2] < rsiLongEntryLevel;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions to find Short Primary Signals ...
|
||||
bool HasPrimaryShortSignal()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Sell/Short Conditions ...
|
||||
result = rsiBuffer[1] <= rsiShortEntryLevel && rsiBuffer[2] > rsiShortEntryLevel;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions to find Long Grid Signals ...
|
||||
bool HasGridLongSignal()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Buy/Long Conditions ...
|
||||
result = rsiBuffer[1] >= rsiLongEntryLevel && rsiBuffer[2] < rsiLongEntryLevel;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions to find Short Grid Signals ...
|
||||
bool HasGridShortSignal()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Sell/Short Conditions ...
|
||||
result = rsiBuffer[1] <= rsiShortEntryLevel && rsiBuffer[2] > rsiShortEntryLevel;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions for closing Long Trades ...
|
||||
bool CanCloseLongTrades()
|
||||
{
|
||||
//
|
||||
bool result = rsiBuffer[1] > rsiLongExitLevel && rsiBuffer[2] < rsiLongExitLevel;
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions for closing Short Trades ...
|
||||
bool CanCloseShortTrades()
|
||||
{
|
||||
//
|
||||
bool result = rsiBuffer[1] < rsiShortExitLevel && rsiBuffer[2] > rsiShortExitLevel;
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Long/Buy for Primary Trades...
|
||||
bool HandlePrimaryLong(
|
||||
XSignal &signal, // return structure if signal founded
|
||||
bool doTrade = true // do trade on signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// Check Conditions of Neural Networks if it's enabled ...
|
||||
bool canForward = !rsiUseNeuralNetworks ? true : rsiNNOutput > 0;
|
||||
|
||||
//
|
||||
if (HasPrimaryLongSignal() && rsiTrader.CountLongs() == 0 && canForward)
|
||||
{
|
||||
//
|
||||
double entry = GetAsk();
|
||||
double volume = CalculateVolume();
|
||||
|
||||
//
|
||||
double canDoTrade = CanDoTrade();
|
||||
|
||||
//
|
||||
signal.entry = entry;
|
||||
signal.volume = volume;
|
||||
signal.symbol = _Symbol;
|
||||
signal.type = X_SIGNAL_LONG;
|
||||
signal.magicNumber = rsiMagicNumber;
|
||||
signal.time = iTime(_Symbol, _Period, 0);
|
||||
signal.comment = "Primary XRSI Long";
|
||||
|
||||
//
|
||||
if (enableRSIProvider && rsiAllowLongTrades && doTrade && canDoTrade)
|
||||
{
|
||||
//
|
||||
// Execute Signal ...
|
||||
result = rsiTrader.ExecuteSignal(signal);
|
||||
|
||||
//
|
||||
// Since this means an error happens, we have to log this error ...
|
||||
if (!result)
|
||||
{
|
||||
string errMessage = "failed to execute Long signal: " + (string)GetLastError();
|
||||
LogMessage(errMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Alerts ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
if (rsiEnableAlerts)
|
||||
{
|
||||
SendAlert(signal, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogExecutedSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Short/Sell for Primary Trades...
|
||||
bool HandlePrimaryShort(
|
||||
XSignal &signal, // return structure if signal founded
|
||||
bool doTrade = true // do trade on signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// Check Conditions of Neural Networks if it's enabled ...
|
||||
bool canForward = !rsiUseNeuralNetworks ? true : rsiNNOutput < 0;
|
||||
|
||||
//
|
||||
if (HasPrimaryShortSignal() && rsiTrader.CountShorts() == 0 && canForward)
|
||||
{
|
||||
//
|
||||
double entry = GetBid();
|
||||
double volume = CalculateVolume();
|
||||
|
||||
//
|
||||
double canDoTrade = CanDoTrade();
|
||||
|
||||
//
|
||||
signal.entry = entry;
|
||||
signal.volume = volume;
|
||||
signal.symbol = _Symbol;
|
||||
signal.type = X_SIGNAL_SHORT;
|
||||
signal.magicNumber = rsiMagicNumber;
|
||||
signal.time = iTime(_Symbol, _Period, 0);
|
||||
signal.comment = "Primary XRSI Short";
|
||||
|
||||
//
|
||||
if (enableRSIProvider && rsiAllowShortTrades && doTrade && canDoTrade)
|
||||
{
|
||||
//
|
||||
// Execute Signal ...
|
||||
result = rsiTrader.ExecuteSignal(signal);
|
||||
|
||||
//
|
||||
// Since this means an error happens, we have to log this error ...
|
||||
if (!result)
|
||||
{
|
||||
string errMessage = "failed to execute Short signal: " + (string)GetLastError();
|
||||
LogMessage(errMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Alerts ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
if (rsiEnableAlerts)
|
||||
{
|
||||
SendAlert(signal, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogExecutedSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Long/Buy for Grid Trades...
|
||||
bool HandleGridLong(
|
||||
XSignal &signal, // return structure if signal founded
|
||||
bool doTrade = true // do trade on signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
double ask = GetAsk();
|
||||
bool canDoGridTrade = ask <= rsiGridLongPrice;
|
||||
if (HasGridLongSignal() && rsiTrader.CountLongs() > 0 && canDoGridTrade)
|
||||
{
|
||||
//
|
||||
double entry = ask;
|
||||
double volume = rsiGridLongVolume;
|
||||
|
||||
//
|
||||
double canDoTrade = CanDoTrade();
|
||||
|
||||
//
|
||||
signal.entry = entry;
|
||||
signal.volume = volume;
|
||||
signal.symbol = _Symbol;
|
||||
signal.type = X_SIGNAL_LONG;
|
||||
signal.magicNumber = rsiMagicNumber;
|
||||
signal.time = iTime(_Symbol, _Period, 0);
|
||||
signal.comment = "Grid XRSI Long";
|
||||
|
||||
//
|
||||
if (enableRSIProvider && rsiAllowLongTrades && rsiUseGridTrades && doTrade && canDoTrade)
|
||||
{
|
||||
//
|
||||
// Execute Signal ...
|
||||
result = rsiTrader.ExecuteSignal(signal);
|
||||
|
||||
//
|
||||
// Since this means an error happens, we have to log this error ...
|
||||
if (!result)
|
||||
{
|
||||
string errMessage = "failed to execute Long signal: " + (string)GetLastError();
|
||||
LogMessage(errMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Alerts ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
if (rsiEnableAlerts)
|
||||
{
|
||||
SendAlert(signal, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogExecutedSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Short/Sell for Grid Trades...
|
||||
bool HandleGridShort(
|
||||
XSignal &signal, // return structure if signal founded
|
||||
bool doTrade = true // do trade on signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
double bid = GetBid();
|
||||
bool canDoGridTrade = bid >= rsiGridShortPrice;
|
||||
if (HasGridShortSignal() && rsiTrader.CountShorts() > 0 && canDoGridTrade)
|
||||
{
|
||||
//
|
||||
double entry = bid;
|
||||
double volume = rsiGridShortVolume;
|
||||
|
||||
//
|
||||
double canDoTrade = CanDoTrade();
|
||||
|
||||
//
|
||||
signal.entry = entry;
|
||||
signal.volume = volume;
|
||||
signal.symbol = _Symbol;
|
||||
signal.type = X_SIGNAL_SHORT;
|
||||
signal.magicNumber = rsiMagicNumber;
|
||||
signal.time = iTime(_Symbol, _Period, 0);
|
||||
signal.comment = "Grid XRSI Short";
|
||||
|
||||
//
|
||||
if (enableRSIProvider && rsiAllowShortTrades && rsiUseGridTrades && doTrade && canDoTrade)
|
||||
{
|
||||
//
|
||||
// Execute Signal ...
|
||||
result = rsiTrader.ExecuteSignal(signal);
|
||||
|
||||
//
|
||||
// Since this means an error happens, we have to log this error ...
|
||||
if (!result)
|
||||
{
|
||||
string errMessage = "failed to execute Short signal: " + (string)GetLastError();
|
||||
LogMessage(errMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Alerts ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
if (rsiEnableAlerts)
|
||||
{
|
||||
SendAlert(signal, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogExecutedSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
void HandleOpenTrades()
|
||||
{
|
||||
//
|
||||
// Primary Long Trade ...
|
||||
XSignal primaryLongSignal = {};
|
||||
bool isPrimaryLongSignalExecuted = HandlePrimaryLong(primaryLongSignal);
|
||||
if (isPrimaryLongSignalExecuted)
|
||||
{
|
||||
//
|
||||
// Calculate Grid Long Conditions ...
|
||||
CalculateGridLongConditions(primaryLongSignal);
|
||||
}
|
||||
|
||||
//
|
||||
// Primary Short Trade ...
|
||||
XSignal primaryShortSignal = {};
|
||||
bool isPrimaryShortSignalExecuted = HandlePrimaryShort(primaryShortSignal);
|
||||
if (isPrimaryShortSignalExecuted)
|
||||
{
|
||||
//
|
||||
// Calculate Grid Short Conditions ...
|
||||
CalculateGridShortConditions(primaryShortSignal);
|
||||
}
|
||||
|
||||
//
|
||||
// Check Grid Trades ...
|
||||
if (rsiUseGridTrades)
|
||||
{
|
||||
//
|
||||
// Grid Long Trade ...
|
||||
XSignal gridLongSignal = {};
|
||||
bool isGridLongSignalExecuted = HandleGridLong(gridLongSignal);
|
||||
if (isGridLongSignalExecuted)
|
||||
{
|
||||
//
|
||||
// Calculate Grid Long Conditions ...
|
||||
CalculateGridLongConditions(gridLongSignal);
|
||||
}
|
||||
|
||||
//
|
||||
// Grid Short Trade ...
|
||||
XSignal gridShortSignal = {};
|
||||
bool isGridShortSignalExecuted = HandleGridShort(gridShortSignal);
|
||||
if (isGridShortSignalExecuted)
|
||||
{
|
||||
//
|
||||
// Calculate Grid Short Conditions ...
|
||||
CalculateGridShortConditions(gridShortSignal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
void HandleCloseTrades()
|
||||
{
|
||||
//
|
||||
// Handle Long/Buy Close ...
|
||||
if (rsiTrader.CountLongs() > 0 && CanCloseLongTrades())
|
||||
{
|
||||
//
|
||||
rsiTrader.CloseLongPositions();
|
||||
|
||||
//
|
||||
// Reset Grid Long Conditions ...
|
||||
rsiGridLongPrice = 0;
|
||||
rsiGridLongVolume = 0;
|
||||
|
||||
//
|
||||
string message = "XRSI Closing Long Trades ...";
|
||||
|
||||
//
|
||||
if (rsiEnableAlerts)
|
||||
{
|
||||
SendAlert(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Short/Sell Close ...
|
||||
if (rsiTrader.CountShorts() > 0 && CanCloseShortTrades())
|
||||
{
|
||||
//
|
||||
rsiTrader.CloseShortPositions();
|
||||
|
||||
//
|
||||
// Reset Grid Short Conditions ...
|
||||
rsiGridShortPrice = 0;
|
||||
rsiGridShortVolume = 0;
|
||||
|
||||
//
|
||||
string message = "XRSI Closing Short Trades ...";
|
||||
|
||||
//
|
||||
if (rsiEnableAlerts)
|
||||
{
|
||||
SendAlert(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Calculating Volume for Tradings ...
|
||||
double CalculateVolume()
|
||||
{
|
||||
//
|
||||
double result = rsiStaticVolume;
|
||||
if (!rsiUseDynamicVolume)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double accountBalance = rsiAccountInfo.GetBalance();
|
||||
// double accountInitialBalance = rsiAccountInfo.GetInitialBalance();
|
||||
// double balanceIncreased = accountInitialBalance * rsiBalanceIncreasedFactor;
|
||||
// double volumeIncreased = accountInitialBalance * rsiVolumeIncreasedFactor;
|
||||
double balanceIncreased = rsiBalanceIncreased;
|
||||
double volumeIncreased = rsiVolumeIncreased;
|
||||
|
||||
//
|
||||
result = (volumeIncreased * accountBalance) / balanceIncreased;
|
||||
|
||||
//
|
||||
// Normalize Volume ...
|
||||
result = NormalizeDouble(result, 2);
|
||||
|
||||
//
|
||||
double maxAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
||||
double minAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
||||
|
||||
//
|
||||
// Validate Result ...
|
||||
if (result > maxAvailableVolume)
|
||||
{
|
||||
result = maxAvailableVolume;
|
||||
}
|
||||
else if (result < minAvailableVolume)
|
||||
{
|
||||
result = minAvailableVolume;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Grid Long Trades Price and Volume ...
|
||||
void CalculateGridLongConditions(XSignal &signal)
|
||||
{
|
||||
//
|
||||
// Check Grid Trades Enable ...
|
||||
if (!rsiUseGridTrades)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate GridLongPrice and GridLongVolume ...
|
||||
rsiGridLongVolume = NormalizeDouble(signal.volume * rsiGridVolumeMultiplier, 2);
|
||||
rsiGridLongPrice = NormalizeDouble(signal.entry - (rsiGridDistancePips * 10 * _Point), _Digits);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Grid Short Trades Price and Volume ...
|
||||
void CalculateGridShortConditions(XSignal &signal)
|
||||
{
|
||||
//
|
||||
// Check Grid Trades Enable ...
|
||||
if (!rsiUseGridTrades)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate GridShortPrice and GridShortVolume ...
|
||||
rsiGridShortVolume = NormalizeDouble(signal.volume * rsiGridVolumeMultiplier, 2);
|
||||
rsiGridShortPrice = NormalizeDouble(signal.entry + (rsiGridDistancePips * 10 * _Point), _Digits);
|
||||
}
|
||||
|
||||
//
|
||||
// Determine based on current account state
|
||||
bool CanDoTrade()
|
||||
{
|
||||
//
|
||||
bool result = true;
|
||||
|
||||
//
|
||||
// TODO: Complete this ...
|
||||
|
||||
//
|
||||
return true;
|
||||
}
|
||||
//
|
||||
// END Provided Functions ...
|
||||
//
|
||||
@@ -0,0 +1,329 @@
|
||||
///////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XMAP Signal Provider Library Inputs
|
||||
// -----------------------------------------------------------
|
||||
// Name: XMAPSignalProvider
|
||||
// Description: XMAP based signal provider ...
|
||||
//
|
||||
//
|
||||
// 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 all Indicators Helper here ...
|
||||
input group "XMAP Provider Indicators";
|
||||
#include "x-saherelm.xmap.provider.xtm.indicator.helper.lib.mq5";
|
||||
#include "x-saherelm.xmap.provider.xtd.oscillator.helper.lib.mq5";
|
||||
#include "x-saherelm.xmap.provider.xobd.indicator.helper.lib.mq5";
|
||||
#include "x-saherelm.xmap.provider.xchma.oscillator.helper.lib.mq5";
|
||||
#include "x-saherelm.xmap.provider.xchlh.oscillator.helper.lib.mq5";
|
||||
|
||||
//
|
||||
int xMAPMaxLengthOfInputs = 0;
|
||||
int xMAPCalculatedBars = 0;
|
||||
|
||||
//
|
||||
// Init Indicators ...
|
||||
bool XMAPInitIndicators()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check and Calculate Max Length in Inputs ...
|
||||
xMAPMaxLengthOfInputs = MathMax(
|
||||
xCHLHScLength,
|
||||
xCHLHMcLength);
|
||||
|
||||
xMAPMaxLengthOfInputs = MathMax(
|
||||
xMAPMaxLengthOfInputs,
|
||||
xCHLHLcLength);
|
||||
|
||||
xMAPMaxLengthOfInputs = MathMax(
|
||||
xMAPMaxLengthOfInputs,
|
||||
xTDLength);
|
||||
|
||||
xMAPMaxLengthOfInputs = MathMax(
|
||||
xMAPMaxLengthOfInputs,
|
||||
xCHMALcFastLength);
|
||||
|
||||
xMAPMaxLengthOfInputs = MathMax(
|
||||
xMAPMaxLengthOfInputs,
|
||||
xCHMALcSlowLength);
|
||||
|
||||
xMAPMaxLengthOfInputs = MathMax(
|
||||
xMAPMaxLengthOfInputs,
|
||||
xCHMAMcFastLength);
|
||||
|
||||
xMAPMaxLengthOfInputs = MathMax(
|
||||
xMAPMaxLengthOfInputs,
|
||||
xCHMAMcSlowLength);
|
||||
|
||||
xMAPMaxLengthOfInputs = MathMax(
|
||||
xMAPMaxLengthOfInputs,
|
||||
xCHMAScFastLength);
|
||||
|
||||
xMAPMaxLengthOfInputs = MathMax(
|
||||
xMAPMaxLengthOfInputs,
|
||||
xCHMAScSlowLength);
|
||||
|
||||
//
|
||||
// Initialize Indicator/Oscillator Handlers ...
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// XCHMA Init ...
|
||||
result = XCHMAInitHandlers();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// XCHLH Init ...
|
||||
result = XCHLHInitHandlers();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// XTD Init ...
|
||||
result = XTDInitHandlers();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// XOBD Init ...
|
||||
result = XOBDInitHandlers();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// XTM Init ...
|
||||
result = XTMInitHandlers();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Release Indicators ...
|
||||
void XMAPReleaseIndicators()
|
||||
{
|
||||
//
|
||||
// Release Handlers ...
|
||||
XTDReleaseHandlers();
|
||||
XTMReleaseHandlers();
|
||||
XOBDReleaseHandlers();
|
||||
XCHMAReleaseHandlers();
|
||||
XCHLHReleaseHandlers();
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Reading Buffers ...
|
||||
void XMAPHandleReadingBuffers()
|
||||
{
|
||||
//
|
||||
// Reading Calculated Bars for a Simple Handler ...
|
||||
xMAPCalculatedBars = BarsCalculated(xCHMAHandler);
|
||||
|
||||
//
|
||||
// Read Indicators Buffers ...
|
||||
XTMReadBuffers();
|
||||
XTDReadBuffers();
|
||||
XOBDReadBuffers();
|
||||
XCHMAReadBuffers();
|
||||
XCHLHReadBuffers();
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// START Combination Functions ...
|
||||
//
|
||||
//
|
||||
|
||||
// //
|
||||
// // XTD Based Long Conditions ...
|
||||
// bool XTDHasLongConditions()
|
||||
// {
|
||||
// //
|
||||
// XOHCL c1 = GetCandle(1);
|
||||
// XOHCL c2 = GetCandle(2);
|
||||
// XOHCL c3 = GetCandle(3);
|
||||
// XOHCL c4 = GetCandle(4);
|
||||
// XOHCL c5 = GetCandle(5);
|
||||
|
||||
// //
|
||||
// double ask = GetAsk();
|
||||
// double bid = GetBid();
|
||||
// double entry = GetEntry();
|
||||
|
||||
// //
|
||||
// // XTD Detect Bullish Crossed Over Bearish ...
|
||||
// bool isXTDBullishCrossedOverBearish =
|
||||
// //
|
||||
// xTDBullishBuffer[1] > xTDBearishBuffer[1] &&
|
||||
// !(xTDBullishBuffer[2] > xTDBearishBuffer[2]);
|
||||
|
||||
// //
|
||||
// // XTD Detect Bullish Power Up ...
|
||||
// bool isXTDBullishTrendUp =
|
||||
// //
|
||||
// xTDBullishBuffer[1] > xTDBullishBuffer[2] &&
|
||||
// xTDBullishBuffer[1] > xTDBullishBuffer[3] &&
|
||||
// xTDBullishBuffer[1] > xTDBullishBuffer[4] &&
|
||||
// xTDBullishBuffer[1] > xTDBullishBuffer[5] &&
|
||||
// xTDBullishBuffer[1] > xTDBullishBuffer[6];
|
||||
|
||||
// //
|
||||
// // XTD Passed ...
|
||||
// bool result =
|
||||
// isXTDBullishTrendUp &&
|
||||
// isXTDBullishCrossedOverBearish;
|
||||
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // XCHMA Based Long Conditions ...
|
||||
// bool XCHMAHasLongCondition()
|
||||
// {
|
||||
// //
|
||||
// bool result = false;
|
||||
|
||||
// //
|
||||
// // We have to Find Peaks and Vales ...
|
||||
// // each indicator has specific way to find it ...
|
||||
|
||||
// //
|
||||
// // Method 7 ...
|
||||
// // Find all Vales for Starting Long Position ...
|
||||
// bool isMethod7HasSignal =
|
||||
// //
|
||||
// XTMHasLongConditions()
|
||||
// //
|
||||
// ;
|
||||
|
||||
// //
|
||||
// result =
|
||||
// //
|
||||
// // Method 7 ...
|
||||
// isMethod7HasSignal
|
||||
// //
|
||||
// ;
|
||||
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // XCHMA Based Check Can Close Long Trades ...
|
||||
// bool XCHMACanCloseLongTrades()
|
||||
// {
|
||||
// //
|
||||
// bool result = false;
|
||||
|
||||
// //
|
||||
// double xCHMAMinValue1 = XCHMAGetMinValue(1);
|
||||
// double xCHMAMinValue2 = XCHMAGetMinValue(2);
|
||||
|
||||
// //
|
||||
// bool isSCFastUnderSlow =
|
||||
// xCHMAScFastBuffer[1] < xCHMAScSlowBuffer[1] &&
|
||||
// xCHMAScFastBuffer[2] < xCHMAScSlowBuffer[2];
|
||||
|
||||
// //
|
||||
// bool isSCFastCrossedUnderMin =
|
||||
// xCHMAScFastBuffer[1] <= xCHMAMinValue1 && xCHMAScFastBuffer[2] > xCHMAMinValue2;
|
||||
|
||||
// //
|
||||
// result =
|
||||
// isSCFastUnderSlow &&
|
||||
// isSCFastCrossedUnderMin;
|
||||
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // XCHLH Based Check Can Close Long Trades ...
|
||||
// bool XCHLHCanCloseLongTrades()
|
||||
// {
|
||||
// //
|
||||
// bool result = false;
|
||||
|
||||
// //
|
||||
// // MC LL and SC LL same for Loopback Length ...
|
||||
// // and SC LL [1] < 2 < 3 < 4 < 5
|
||||
// // and SC HH < MC HH
|
||||
// // and SC HH[1] < 2 < 3 < 4 < 5
|
||||
|
||||
// //
|
||||
// bool isMCSCLLSameForLoopback = XCHLHIsSameMCSCLL(1);
|
||||
// bool isSCLLLessThanLoopback = true;
|
||||
// bool isSCHHLessThanMCHH = xCHLHScHHBuffer[1] < xCHLHMcHHBuffer[1];
|
||||
// bool isSCHHLessThanLoopback = true;
|
||||
// for (int i = 2; i < xCHLHScLength + 1; i++)
|
||||
// {
|
||||
// //
|
||||
// bool isSameLL = XCHLHIsSameMCSCLL(i);
|
||||
// isMCSCLLSameForLoopback = isMCSCLLSameForLoopback && isSameLL;
|
||||
|
||||
// //
|
||||
// bool isScLLLess = xCHLHScLLBuffer[1] < xCHLHScLLBuffer[i];
|
||||
// isSCLLLessThanLoopback = isSCLLLessThanLoopback || isScLLLess;
|
||||
|
||||
// //
|
||||
// bool isSCHHLessThanMC = xCHLHScHHBuffer[i] < xCHLHMcHHBuffer[i];
|
||||
// isSCHHLessThanMCHH = isSCHHLessThanMCHH && isSCHHLessThanMC;
|
||||
|
||||
// //
|
||||
// bool isSCHHLess = xCHLHScHHBuffer[1] < xCHLHScHHBuffer[i];
|
||||
// isSCHHLessThanLoopback = isSCHHLessThanLoopback || isSCHHLess;
|
||||
// }
|
||||
|
||||
// //
|
||||
// result =
|
||||
// //
|
||||
// isMCSCLLSameForLoopback &&
|
||||
// //
|
||||
// isSCLLLessThanLoopback &&
|
||||
// //
|
||||
// isSCHHLessThanMCHH &&
|
||||
// //
|
||||
// isSCHHLessThanLoopback
|
||||
// //
|
||||
// ;
|
||||
|
||||
// //
|
||||
// return result;
|
||||
// }
|
||||
|
||||
//
|
||||
//
|
||||
// END Combination Functions ...
|
||||
//
|
||||
//
|
||||
Binary file not shown.
@@ -0,0 +1,71 @@
|
||||
///////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XMAP Signal Provider Library Inputs
|
||||
// -----------------------------------------------------------
|
||||
// Name: XMAPSignalProvider
|
||||
// Description: XMAP based signal provider ...
|
||||
//
|
||||
//
|
||||
// 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
|
||||
|
||||
//
|
||||
input group "XMAP Provider";
|
||||
|
||||
//
|
||||
input group "XMAP Common";
|
||||
input bool enableXMAPProvider = true; // Enable Provider
|
||||
input bool xMAPEnableAlerts = false; // Enable Events Alert
|
||||
input int xMAPNumberOfItemsPerTick = 72; // Number Of items Readed In Each Tick
|
||||
|
||||
//
|
||||
input group "XMAP Trader";
|
||||
input int xMAPMagicNumber = 16940564; // Trader MagicNumber
|
||||
input int xMAPSlippage = 10; // Trader Slippage
|
||||
|
||||
//
|
||||
input group "XMAP Trade Management";
|
||||
input bool xMAPAllowLongTrades = true; // Allow Long Trades
|
||||
input bool xMAPAllowShortTrades = false; // Allow Short Trades
|
||||
|
||||
//
|
||||
input group "XMAP Risk Management";
|
||||
input int xMAPMaxAllowedPrimaryTrades = 1; // Max Allowed Primary Trades at same time
|
||||
input int xMAPMaxPrimaryTradeAge = 0; // Maximum Candles which a Primary Trade Can Open
|
||||
input int xMAPMaxAllowedGridTrades = 0; // Max Allowed Grid Trade belongs to one Primary Trade
|
||||
input double xMAPGridPriceDistanceInPips = 5; // Price Distance In Pips from Primary Trade to Open a Grid Trade
|
||||
input int xMAPMaxGridTradeAge = 0; // Maximum Candles which a Grid Trade Can Open
|
||||
input int xMAPGridVolumeMultiplier = 2; // Grid Trades Volume Multiplier
|
||||
input double xMAPStaticVolume = 0.01; // Static Volume
|
||||
input double xMAPMinRewardPerTradeInPips = 1; // Min Reward Per Trade In Pips
|
||||
input double xMAPFreeMarginFactorForOpenTrades = 0.5; // Minimum Free Marging for Open Trades
|
||||
input double xMAPBalanceFactorForOpenTrades = 0.5; // Minimum Balance for Open Trades
|
||||
input double xMAPMaxDrawDownPerTradeFactor = 0; // Max Allowed DrawDown Factor Per Trade
|
||||
// input bool xMAPUseDynamicVolume = false; // Enable Dynamic Volume
|
||||
// input double xMAPBalanceIncreased = 500; // Balance Increase
|
||||
// input double xMAPVolumeIncreased = 0.01; // Volume Increase
|
||||
|
||||
//
|
||||
// Validate Inputs before Initialization ...
|
||||
bool XMAPValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// TODO: Fix this ...
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,287 @@
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XOBD Indicator Helper for Signal Providers
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
// 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
|
||||
|
||||
//
|
||||
#include "..\Libraries\x-saherelm.log.lib.mq5"
|
||||
#include "..\Libraries\x-saherelm.common.lib.mq5"
|
||||
#include "x-saherelm.xmap.provider.inputs.lib.mq5"
|
||||
|
||||
//
|
||||
// START Enum Definitions ...
|
||||
//
|
||||
//
|
||||
// END Enum Definitions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input group "XOBD Indicator";
|
||||
input int xOBDLength = 14; // Market Length
|
||||
input double xOBDArrowDistanceFromPrice = 0; // Arrow Distrance from Price
|
||||
input uchar xOBDSwingHighArrowCode = 108; // Swing High Arrow Code
|
||||
input color xOBDSwingHighArrowColor = clrMagenta; // Swing High Arrow Color
|
||||
input uchar xOBDSwingLowArrowCode = 108; // Swing Low Arrow Code
|
||||
input color xOBDSwingLowArrowColor = clrAqua; // Swing Low Arrow Color
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Definitions ...
|
||||
//
|
||||
int xOBDHandler = INVALID_HANDLE;
|
||||
double xOBDSwingsBuffer[];
|
||||
//
|
||||
// END Definitions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Handler Functions ...
|
||||
//
|
||||
//
|
||||
// Init Indicators ...
|
||||
bool XOBDInitHandlers()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Initialize Indicator/Oscillator Handlers ...
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// XOBD Handler ...
|
||||
ArraySetAsSeries(xOBDSwingsBuffer, true);
|
||||
xOBDHandler = iCustom(
|
||||
_Symbol,
|
||||
_Period,
|
||||
"x-saherelm.xobd.indicator",
|
||||
//
|
||||
// Inputs ...
|
||||
xOBDLength,
|
||||
xOBDArrowDistanceFromPrice,
|
||||
xOBDSwingHighArrowCode,
|
||||
xOBDSwingHighArrowColor,
|
||||
xOBDSwingLowArrowCode,
|
||||
xOBDSwingLowArrowColor);
|
||||
if (xOBDHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
LogMessage("failed to Initialize XOBD Indicator: " + (string)GetLastError());
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Release Indicators ...
|
||||
void XOBDReleaseHandlers()
|
||||
{
|
||||
IndicatorRelease(xOBDHandler);
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Reading Buffers ...
|
||||
void XOBDReadBuffers()
|
||||
{
|
||||
CopyBuffer(
|
||||
xOBDHandler,
|
||||
0,
|
||||
0,
|
||||
xMAPNumberOfItemsPerTick,
|
||||
xOBDSwingsBuffer);
|
||||
}
|
||||
//
|
||||
// END Handler Funcions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START XOBD Custom Functions ...
|
||||
//
|
||||
//
|
||||
// Find Peak based On this Indicator ...
|
||||
bool XOBDIsPeak(
|
||||
int loopback // loopback length
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Find Vale based On this Indicator ...
|
||||
bool XOBDIsVale(
|
||||
int loopback // loopback length
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Find Lesser Swing Low ...
|
||||
double XOBDGetSmallestSwingLow(
|
||||
double price, // a price which swings compare with it
|
||||
int numberOfSwingsCheck = 4 // number of Swing Lows to Check
|
||||
)
|
||||
{
|
||||
//
|
||||
double result = price;
|
||||
|
||||
//
|
||||
double swings[];
|
||||
ArraySetAsSeries(swings, true);
|
||||
XOBDRetrieveSwings(
|
||||
numberOfSwingsCheck,
|
||||
X_SWING_LOW,
|
||||
swings);
|
||||
|
||||
//
|
||||
for (int i = 0; i < ArraySize(swings); i++)
|
||||
{
|
||||
//
|
||||
double swingVal = swings[i];
|
||||
|
||||
//
|
||||
result = swingVal < result ? swingVal : result;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Find Bigger Swing High ...
|
||||
double XOBDGetBiggestSwingHigh(
|
||||
double price, // a price which swings compare with it
|
||||
int numberOfSwingsCheck = 4 // number of Swing Lows to Check
|
||||
)
|
||||
{
|
||||
//
|
||||
double result = price;
|
||||
|
||||
//
|
||||
double swings[];
|
||||
ArraySetAsSeries(swings, true);
|
||||
XOBDRetrieveSwings(
|
||||
numberOfSwingsCheck,
|
||||
X_SWING_HIGH,
|
||||
swings);
|
||||
|
||||
//
|
||||
for (int i = 0; i < ArraySize(swings); i++)
|
||||
{
|
||||
//
|
||||
double swingVal = swings[i];
|
||||
|
||||
//
|
||||
result = swingVal > result ? swingVal : result;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Reading Special Type of Swings from Buffer until specific count passed ...
|
||||
void XOBDRetrieveSwings(
|
||||
int count, // Number of Swings to Retrieve
|
||||
ENUM_X_SWING_TYPE type, // Which Type of Swing to Retrieve
|
||||
double &result[] // Holds result
|
||||
)
|
||||
{
|
||||
//
|
||||
static int xMAPSwingsBufferReadItems = 50;
|
||||
|
||||
//
|
||||
// Clear Result ...
|
||||
ArrayFree(result);
|
||||
ArrayResize(result, 0);
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (count <= 0 || type == X_NO_SWING)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
double swingsBuffer[];
|
||||
ArraySetAsSeries(swingsBuffer, true);
|
||||
//
|
||||
// TODO:
|
||||
// CopyBuffer(xOBDHandler, 0, 0, xMAPSwingsBufferReadItems, swingsBuffer);
|
||||
int foundedSwings = ArraySize(swingsBuffer);
|
||||
if (foundedSwings <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Loop through Swings ...
|
||||
for (int i = 0; i < foundedSwings; i++)
|
||||
{
|
||||
//
|
||||
double swingValue = swingsBuffer[i];
|
||||
if (swingValue != type)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
ArrayResize(
|
||||
result,
|
||||
ArraySize(result) + 1);
|
||||
result[ArraySize(result) - 1] = swingValue;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Result count ...
|
||||
if (ArraySize(result) < count)
|
||||
{
|
||||
//
|
||||
xMAPSwingsBufferReadItems *= 2;
|
||||
XOBDRetrieveSwings(
|
||||
count,
|
||||
type,
|
||||
result);
|
||||
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
xMAPSwingsBufferReadItems = 50;
|
||||
}
|
||||
|
||||
//
|
||||
// END XOBD Custom Functions ...
|
||||
//
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,357 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XTM Indicator Helper for Signal Providers
|
||||
// --------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
// 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
|
||||
|
||||
//
|
||||
// Includes ...
|
||||
#include "..\Libraries\x-saherelm.log.lib.mq5"
|
||||
#include "..\Libraries\x-saherelm.common.lib.mq5"
|
||||
#include "x-saherelm.xmap.provider.inputs.lib.mq5"
|
||||
|
||||
//
|
||||
// START Enum Definitions ...
|
||||
//
|
||||
|
||||
//
|
||||
// XTM Indicator States ...
|
||||
enum ENUM_X_XTM_STATES
|
||||
{
|
||||
X_XTM_BULLISH = 1,
|
||||
X_XTM_BEARISH = -1,
|
||||
X_XTM_NEUTURAL = 0,
|
||||
};
|
||||
|
||||
//
|
||||
// XTM Indicator Buffer Lines ...
|
||||
enum ENUM_X_XTM_BUFFER_LINES
|
||||
{
|
||||
X_XTM_MA_LINE = 0,
|
||||
X_XTM_MC_COLOR_LINE = 1,
|
||||
X_XTM_STATE_LINE = 2,
|
||||
};
|
||||
//
|
||||
// END Enum Definitions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input group "XTM Indicator";
|
||||
input int xTMMaPeriod = 14; // Period
|
||||
input int xTMMaShift = 0; // Shift
|
||||
input ENUM_MA_METHOD xTMMaMethod = MODE_SMA; // Method
|
||||
input ENUM_APPLIED_PRICE xTMMaAppliedTo = PRICE_WEIGHTED; // Applied To
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Definitions ...
|
||||
int xTMHandler = INVALID_HANDLE;
|
||||
double xTMMaBuffer[];
|
||||
double xTMStateBuffer[];
|
||||
//
|
||||
// END Definitions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Handler Functions ...
|
||||
//
|
||||
//
|
||||
// Init Indicators ...
|
||||
bool XTMInitHandlers()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Initialize Indicator/Oscillator Handlers ...
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// XTM Handler ...
|
||||
ArraySetAsSeries(xTMMaBuffer, true);
|
||||
ArraySetAsSeries(xTMStateBuffer, true);
|
||||
xTMHandler = iCustom(
|
||||
_Symbol,
|
||||
_Period,
|
||||
"x-saherelm.xtm.indicator",
|
||||
//
|
||||
// Inputs ...
|
||||
xTMMaPeriod,
|
||||
xTMMaShift,
|
||||
xTMMaMethod,
|
||||
xTMMaAppliedTo);
|
||||
if (xTMHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
LogMessage("failed to Initialize XTM Indicator: " + (string)GetLastError());
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Release Indicators ...
|
||||
void XTMReleaseHandlers()
|
||||
{
|
||||
IndicatorRelease(xTMHandler);
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Reading Buffers ...
|
||||
void XTMReadBuffers()
|
||||
{
|
||||
//
|
||||
// Ma Buffer ...
|
||||
CopyBuffer(
|
||||
xTMHandler,
|
||||
X_XTM_MA_LINE,
|
||||
0,
|
||||
xMAPNumberOfItemsPerTick,
|
||||
xTMMaBuffer);
|
||||
|
||||
//
|
||||
// State Buffer ...
|
||||
CopyBuffer(
|
||||
xTMHandler,
|
||||
X_XTM_STATE_LINE,
|
||||
0,
|
||||
xMAPNumberOfItemsPerTick,
|
||||
xTMStateBuffer);
|
||||
}
|
||||
//
|
||||
// END Handler Funcions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Signal Related Conditions ...
|
||||
//
|
||||
//
|
||||
// XTM Long Conditions ...
|
||||
bool XTMCanOpenLongTrades()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bool isValue = XTMIsVale();
|
||||
|
||||
//
|
||||
double minValue = GetMinValue(
|
||||
xMAPNumberOfItemsPerTick,
|
||||
xTMMaBuffer);
|
||||
double maxValue = GetMaxValue(
|
||||
xMAPNumberOfItemsPerTick,
|
||||
xTMMaBuffer);
|
||||
double currentValue = xTMMaBuffer[1];
|
||||
bool isTMMinMaxPassed =
|
||||
currentValue < maxValue && currentValue > minValue;
|
||||
|
||||
//
|
||||
bool isInPeak = IsInPeak(
|
||||
14,
|
||||
xTMMaBuffer);
|
||||
|
||||
//
|
||||
bool isSharpChanged = IsSharpChanged(
|
||||
14,
|
||||
1,
|
||||
xTMMaBuffer);
|
||||
bool isCandleSharpChanged = IsSharpChanged(
|
||||
14,
|
||||
1,
|
||||
PRICE_CLOSE);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
isValue
|
||||
//
|
||||
&&
|
||||
//
|
||||
!isInPeak
|
||||
//
|
||||
&&
|
||||
//
|
||||
!isSharpChanged
|
||||
//
|
||||
&&
|
||||
//
|
||||
!isCandleSharpChanged
|
||||
//
|
||||
&&
|
||||
//
|
||||
isTMMinMaxPassed;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// XTM Close Long ...
|
||||
bool XTMCanCloseLongTrades()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// result = XTMCanOpenLongTrades();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// END Signal Related Conditions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START XTM Custom Functions ...
|
||||
//
|
||||
//
|
||||
// Find Peak based On this Indicator ...
|
||||
bool XTMIsPeak()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Is Peak ...
|
||||
|
||||
//
|
||||
// Must Increasing ...
|
||||
bool isDecreasing = IsDecreasing(
|
||||
1,
|
||||
3,
|
||||
xTMMaBuffer);
|
||||
|
||||
//
|
||||
// Must Decreasing ...
|
||||
bool isIncreasing = IsIncreasing(
|
||||
3,
|
||||
10,
|
||||
xTMMaBuffer);
|
||||
|
||||
//
|
||||
// Find State of First and Last ...
|
||||
double stateValue1 = xTMStateBuffer[1];
|
||||
double stateValue2 = xTMStateBuffer[2];
|
||||
bool isStatePassed =
|
||||
stateValue2 == X_XTM_NEUTURAL &&
|
||||
stateValue1 == X_XTM_BEARISH;
|
||||
|
||||
//
|
||||
// Calculate Result ...
|
||||
result =
|
||||
//
|
||||
isIncreasing
|
||||
//
|
||||
&&
|
||||
//
|
||||
isDecreasing
|
||||
//
|
||||
&&
|
||||
//
|
||||
isStatePassed
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Find Vale based On this Indicator ...
|
||||
bool XTMIsVale()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Is Vale ...
|
||||
|
||||
// //
|
||||
// // Retrieve Min Value ...
|
||||
// double minValue = GetMinValue(
|
||||
// loopback,
|
||||
// xTMMaBuffer);
|
||||
|
||||
// //
|
||||
// // Retrieve Max Value ...
|
||||
// double maxValue = GetMinValue(
|
||||
// loopback,
|
||||
// xTMMaBuffer);
|
||||
|
||||
// //
|
||||
// // Calculate Delta ...
|
||||
// double delta = maxValue - minValue;
|
||||
// bool isDeltaPassed = delta >= (xMAPNumberOfItemsPerTick * _Point);
|
||||
|
||||
//
|
||||
// Must Decreasing ...
|
||||
bool isIncreasing = IsIncreasing(
|
||||
3,
|
||||
1,
|
||||
xTMMaBuffer);
|
||||
|
||||
//
|
||||
// Must Increasing ...
|
||||
bool isDecreasing = IsDecreasing(
|
||||
10,
|
||||
3,
|
||||
xTMMaBuffer);
|
||||
|
||||
//
|
||||
// Find State of First and Last ...
|
||||
double stateValue1 = xTMStateBuffer[1];
|
||||
double stateValue2 = xTMStateBuffer[2];
|
||||
bool isStatePassed =
|
||||
stateValue2 == X_XTM_NEUTURAL &&
|
||||
stateValue1 == X_XTM_BULLISH;
|
||||
|
||||
//
|
||||
// Calculate Result ...
|
||||
result =
|
||||
//
|
||||
// isDeltaPassed
|
||||
// //
|
||||
// &&
|
||||
//
|
||||
isIncreasing
|
||||
//
|
||||
&&
|
||||
//
|
||||
isDecreasing
|
||||
//
|
||||
// &&
|
||||
// //
|
||||
// isStatePassed
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// END XTM Custom Functions ...
|
||||
//
|
||||
Reference in New Issue
Block a user