Initial Commit ...
This commit is contained in:
@@ -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 ...
|
||||
//
|
||||
Reference in New Issue
Block a user