948 lines
22 KiB
Plaintext
948 lines
22 KiB
Plaintext
////////////////////////////////////////////////////////////
|
|
//
|
|
// 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 ...
|
|
//
|