1351 lines
29 KiB
Plaintext
1351 lines
29 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Class Library
|
|
// ----------------------------------------------
|
|
// Name: XSCX121SetupCycle
|
|
// Description: provides implementation of X121
|
|
// Setup on Specified Market Cycle ...
|
|
//
|
|
//
|
|
// Maintainer:
|
|
// ------------
|
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
|
//
|
|
//////////////////////////////////////////////////////
|
|
//
|
|
// Global Properties ...
|
|
#property library
|
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
|
#property link "https://www.saherelm.ir"
|
|
#property version "1.00"
|
|
#property strict
|
|
|
|
//
|
|
// Imports ...
|
|
|
|
//
|
|
#include "../Classes/x-saherelm.xea.class.mq5"
|
|
#include "../Classes/x-saherelm.x121.setup.cycle.class.mq5"
|
|
|
|
//
|
|
// Definitions ...
|
|
|
|
//
|
|
struct XSignalInfo
|
|
{
|
|
//
|
|
ulong ticket; // Position Ticket
|
|
string symbol; // Trading Symbol
|
|
string provider; // Signaller
|
|
int pushers; // Signal Pushers
|
|
ENUM_TIMEFRAMES period; // Trading Timeframe
|
|
datetime time; // Issue Time (Open Position)
|
|
|
|
//
|
|
double profit; // Profit on Close
|
|
datetime endTime; // End Time
|
|
string message; // Close Reason
|
|
|
|
//
|
|
double bullishScore; // Bullish Score On Signal Time
|
|
double bearishScore; // Bearish Score On Signal Time
|
|
|
|
//
|
|
XSignal signal; // Generated Signal
|
|
X121SetupConditions conditions; // Generated Conditions
|
|
|
|
//
|
|
// Constructor ...
|
|
void XSignalInfo()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
//
|
|
// Cleanup ...
|
|
void Clean()
|
|
{
|
|
//
|
|
ticket = 0;
|
|
symbol = NULL;
|
|
period = NULL;
|
|
time = NULL;
|
|
profit = 0;
|
|
endTime = NULL;
|
|
message = NULL;
|
|
bullishScore = 0;
|
|
bearishScore = 0;
|
|
signal.Clean();
|
|
conditions.Clean();
|
|
}
|
|
|
|
//
|
|
bool Fill(
|
|
int _pushers,
|
|
XSignal &_signal,
|
|
X121SetupConditions &_conditions //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
IsValid(_signal.symbol) &&
|
|
IsValid(_signal.period) &&
|
|
IsValid(_signal.provider)
|
|
//
|
|
;
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
pushers = _pushers;
|
|
symbol = _signal.symbol;
|
|
period = _signal.period;
|
|
provider = _signal.provider;
|
|
|
|
//
|
|
signal = _signal;
|
|
conditions = _conditions;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsOwn(
|
|
ulong _ticket //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = _ticket == ticket;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsOwn(
|
|
string _symbol,
|
|
string _provider,
|
|
ENUM_TIMEFRAMES _period //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
IsValid(_symbol) &&
|
|
IsValid(_provider) &&
|
|
IsValid(_period) &&
|
|
//
|
|
symbol == _symbol &&
|
|
provider == _provider &&
|
|
period == _period
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Data Collector ...
|
|
|
|
//
|
|
bool IsValid()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
ticket > 0 &&
|
|
IsValid(time) &&
|
|
IsValid(symbol) &&
|
|
IsValid(period)
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string GetFileName()
|
|
{
|
|
//
|
|
string result = NULL;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result =
|
|
//
|
|
symbol + "_" +
|
|
provider + "_" +
|
|
ToString(ticket) + "_" +
|
|
ToString(period) + "_" +
|
|
ToString(time)
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string ToModelString()
|
|
{
|
|
//
|
|
string result = NULL;
|
|
|
|
//
|
|
string conditionsStr = conditions
|
|
.GenerateSummary(
|
|
false, // Only Commons ...
|
|
true, // Only Conditions ...
|
|
false, // Include Score ...
|
|
false // Include False Conditions ...ّ
|
|
);
|
|
|
|
//
|
|
result =
|
|
//
|
|
ToString("Ticket", ticket) +
|
|
ToString("Symbol", symbol) +
|
|
ToString("Period", period) +
|
|
ToString("Time", time) +
|
|
ToString("BullishScore", bullishScore) +
|
|
ToString("BearishScore", bearishScore) +
|
|
ToString("Profit", profit) +
|
|
ToString("End Time", endTime) +
|
|
ToString("Message", message) +
|
|
"-------------" + "\n" +
|
|
ToString("Signal", signal.ToModelString()) +
|
|
ToString("Conditions", conditionsStr) +
|
|
//
|
|
""
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
//
|
|
class XSignalInfoCollector
|
|
{
|
|
//
|
|
// Public ...
|
|
public:
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
// Constructor(s) ...
|
|
void XSignalInfoCollector(
|
|
string _path = NULL // Base Path
|
|
)
|
|
{
|
|
//
|
|
if (IsValid(_path))
|
|
{
|
|
mPath = _path;
|
|
}
|
|
else
|
|
{
|
|
mPath = "XSignalInfo";
|
|
}
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
void ~XSignalInfoCollector() {}
|
|
|
|
//
|
|
bool IsExists(XSignalInfo &item)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
int mHandler = GetFileHandlerForRead(item);
|
|
result = mHandler != INVALID_HANDLE;
|
|
FileClose(mHandler);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool Save(XSignalInfo &item)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Check info is Valid ...
|
|
result = item.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string content = item.ToModelString();
|
|
result = IsValid(content);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int mHandler = GetFileHandlerForWrite(item);
|
|
result = mHandler != INVALID_HANDLE;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
FileWrite(mHandler, content);
|
|
FileFlush(mHandler);
|
|
FileClose(mHandler);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Protected ...
|
|
protected:
|
|
//
|
|
// Private ...
|
|
private:
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
string mPath; // Base Path ...
|
|
|
|
//
|
|
string GetFilePath(XSignalInfo &item)
|
|
{
|
|
//
|
|
string fileName = item.GetFileName();
|
|
|
|
//
|
|
return GetFilePath(fileName);
|
|
}
|
|
string GetFilePath(string fileName)
|
|
{
|
|
//
|
|
string result = "";
|
|
|
|
//
|
|
result =
|
|
//
|
|
mPath + "\\" + fileName
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int GetFileHandlerForRead(XSignalInfo &item)
|
|
{
|
|
//
|
|
int result = INVALID_HANDLE;
|
|
|
|
//
|
|
string filePath = GetFilePath(item);
|
|
if (!IsValid(filePath))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = FileOpen(
|
|
filePath,
|
|
FILE_READ | FILE_TXT //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
int GetFileHandlerForWrite(XSignalInfo &item)
|
|
{
|
|
//
|
|
int result = INVALID_HANDLE;
|
|
|
|
//
|
|
string filePath = GetFilePath(item);
|
|
if (!IsValid(filePath))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = FileOpen(
|
|
filePath,
|
|
FILE_READ | FILE_WRITE | FILE_TXT //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
};
|
|
|
|
//
|
|
// Class ...
|
|
class XSCX121SetupEA : public XSCBaseEA
|
|
{
|
|
//
|
|
// Public ...
|
|
public:
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
// Constructors ...
|
|
XSCX121SetupEA(
|
|
//
|
|
// XTrade Class Requirements ...
|
|
int slippage, // Specify Slippage
|
|
ulong magicNumber, // Specify Magic Number
|
|
//
|
|
// XSCTrade Event Handlers ...
|
|
TOnStopLoss onStopLossTriggered = NULL, // On StopLoass Triggered Event Handler
|
|
TOnTakeProfit onTakeProfitTriggered = NULL, // On TakeProfit Triggered Event Handler
|
|
TOnDealsChanged onDealsChangedHandler = NULL, // On Deals Changed Event Handler
|
|
TOnOrdersChanged onOrdersChangedHandler = NULL, // On Orders Changed Event Handler
|
|
TOnPositionsChanged onPositionsChangedHandler = NULL, // On Positions Changed Event Handler
|
|
TOnTradeStateChanged onTradeStateChangedHandler = NULL // On Trade State Changed Event Handler
|
|
) : XSCBaseEA(slippage,
|
|
magicNumber,
|
|
onStopLossTriggered,
|
|
onTakeProfitTriggered,
|
|
onDealsChangedHandler,
|
|
onOrdersChangedHandler,
|
|
onPositionsChangedHandler,
|
|
onTradeStateChangedHandler //
|
|
)
|
|
{
|
|
//
|
|
Clean(mSignalInfos);
|
|
mSignalCollector = new XSignalInfoCollector();
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
~XSCX121SetupEA()
|
|
{
|
|
}
|
|
|
|
//
|
|
bool AddSetup(XSCX121SetupCycles *setup)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = setup != NULL;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
Add(
|
|
setup,
|
|
mSetups //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Getter(s) / Setter(s) ...
|
|
|
|
//
|
|
bool AllowLong()
|
|
{
|
|
return mAllowLong;
|
|
}
|
|
|
|
//
|
|
void AllowLong(bool value)
|
|
{
|
|
mAllowLong = value;
|
|
}
|
|
|
|
//
|
|
bool AllowShort()
|
|
{
|
|
return mAllowShort;
|
|
}
|
|
|
|
//
|
|
void AllowShort(bool value)
|
|
{
|
|
mAllowShort = value;
|
|
}
|
|
|
|
//
|
|
bool IsEnable()
|
|
{
|
|
return mAllowLong || mAllowShort;
|
|
}
|
|
|
|
//
|
|
// Overrides ...
|
|
|
|
//
|
|
// Customize Token ...
|
|
string GetToken() override
|
|
{
|
|
return GetSpecificToken(this);
|
|
}
|
|
|
|
//
|
|
string GetTag() override
|
|
{
|
|
return this.GetToken();
|
|
}
|
|
|
|
//
|
|
// Check Provider for any Guards ...
|
|
bool CheckForGuard(XGuard &guards[]) override
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Request Provider to Collect all
|
|
// Potentially Signals and then
|
|
// filters theme here and passed them
|
|
// for Executing ...
|
|
int RequestForSignal(
|
|
XSignal &signals[] // Holds Signals ...
|
|
) override
|
|
{
|
|
//
|
|
bool result = 0;
|
|
|
|
//
|
|
Clean(signals);
|
|
|
|
//
|
|
if (!IsEnable())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// IMPLEMENT ...
|
|
int count = CountSetups();
|
|
result = IsValidSize(count);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string separator = "\n";
|
|
|
|
//
|
|
X121SetupConditions cConditions;
|
|
X121SetupConditions sConditions;
|
|
X121SetupConditions mConditions;
|
|
X121SetupConditions lConditions;
|
|
X121SetupConditions hConditions;
|
|
|
|
//
|
|
XSignal cSignal;
|
|
XSignal sSignal;
|
|
XSignal mSignal;
|
|
XSignal lSignal;
|
|
XSignal hSignal;
|
|
|
|
//
|
|
int cPusher = 0;
|
|
int sPusher = 0;
|
|
int mPusher = 0;
|
|
int lPusher = 0;
|
|
int hPusher = 0;
|
|
|
|
//
|
|
X121SignalGenerator signalGenerator;
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
// Cleanup Signals ...
|
|
cSignal.Clean();
|
|
sSignal.Clean();
|
|
mSignal.Clean();
|
|
lSignal.Clean();
|
|
hSignal.Clean();
|
|
|
|
//
|
|
// Current ...
|
|
bool canProcess = mSetups[i]
|
|
.CanProcessBar(
|
|
X_MARKET_CYCLE_UNKNOWN //
|
|
);
|
|
if (canProcess)
|
|
{
|
|
//
|
|
bool iHasConditions = mSetups[i].GetConditions(
|
|
cConditions,
|
|
X_MARKET_CYCLE_UNKNOWN, // Current Market ...
|
|
0, // Bar Index ...
|
|
5 // Loop Back ...
|
|
);
|
|
|
|
//
|
|
if (!iHasConditions)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
mBullishScore = 0;
|
|
mBearishScore = 0;
|
|
|
|
//
|
|
// Retrieve Scores ...
|
|
double bullishScore = 0;
|
|
double bearishScore = 0;
|
|
cConditions.GenerateScore(
|
|
bullishScore,
|
|
bearishScore //
|
|
);
|
|
mBullishScore += bullishScore;
|
|
mBearishScore += bearishScore;
|
|
|
|
//
|
|
// Parse Conditions for Signal ...
|
|
bool hasSignal = signalGenerator.HasSignal(
|
|
cConditions,
|
|
cSignal,
|
|
cPusher,
|
|
mAllowLong,
|
|
mAllowShort //
|
|
);
|
|
|
|
//
|
|
if (hasSignal)
|
|
{
|
|
//
|
|
mSetups[i].WaitsUntilNextBar(
|
|
X_MARKET_CYCLE_UNKNOWN //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Short ...
|
|
canProcess = mSetups[i]
|
|
.CanProcessBar(
|
|
X_MARKET_CYCLE_SHORT //
|
|
);
|
|
if (canProcess)
|
|
{
|
|
//
|
|
bool iHasConditions = mSetups[i].GetConditions(
|
|
sConditions,
|
|
X_MARKET_CYCLE_SHORT, // Current Market ...
|
|
0, // Bar Index ...
|
|
5 // Loop Back ...
|
|
);
|
|
|
|
//
|
|
if (!iHasConditions)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Retrieve Scores ...
|
|
double bullishScore = 0;
|
|
double bearishScore = 0;
|
|
sConditions.GenerateScore(
|
|
bullishScore,
|
|
bearishScore //
|
|
);
|
|
mBullishScore += bullishScore;
|
|
mBearishScore += bearishScore;
|
|
|
|
//
|
|
// Parse Conditions for Signal ...
|
|
bool hasSignal = signalGenerator.HasSignal(
|
|
sConditions,
|
|
sSignal,
|
|
sPusher,
|
|
mAllowLong,
|
|
mAllowShort //
|
|
);
|
|
|
|
//
|
|
if (hasSignal)
|
|
{
|
|
//
|
|
mSetups[i].WaitsUntilNextBar(
|
|
X_MARKET_CYCLE_SHORT //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Medium ...
|
|
canProcess = mSetups[i]
|
|
.CanProcessBar(
|
|
X_MARKET_CYCLE_MEDIUM //
|
|
);
|
|
if (canProcess)
|
|
{
|
|
//
|
|
bool iHasConditions = mSetups[i].GetConditions(
|
|
mConditions,
|
|
X_MARKET_CYCLE_MEDIUM, // Current Market ...
|
|
0, // Bar Index ...
|
|
5 // Loop Back ...
|
|
);
|
|
|
|
//
|
|
if (!iHasConditions)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Retrieve Scores ...
|
|
double bullishScore = 0;
|
|
double bearishScore = 0;
|
|
mConditions.GenerateScore(
|
|
bullishScore,
|
|
bearishScore //
|
|
);
|
|
mBullishScore += bullishScore;
|
|
mBearishScore += bearishScore;
|
|
|
|
//
|
|
// Parse Conditions for Signal ...
|
|
bool hasSignal = signalGenerator.HasSignal(
|
|
mConditions,
|
|
mSignal,
|
|
mPusher,
|
|
mAllowLong,
|
|
mAllowShort //
|
|
);
|
|
|
|
//
|
|
if (hasSignal)
|
|
{
|
|
//
|
|
mSetups[i].WaitsUntilNextBar(
|
|
X_MARKET_CYCLE_MEDIUM //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Long ...
|
|
canProcess = mSetups[i]
|
|
.CanProcessBar(
|
|
X_MARKET_CYCLE_LONG //
|
|
);
|
|
if (canProcess)
|
|
{
|
|
//
|
|
bool iHasConditions = mSetups[i].GetConditions(
|
|
lConditions,
|
|
X_MARKET_CYCLE_LONG, // Current Market ...
|
|
0, // Bar Index ...
|
|
5 // Loop Back ...
|
|
);
|
|
|
|
//
|
|
if (!iHasConditions)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Retrieve Scores ...
|
|
double bullishScore = 0;
|
|
double bearishScore = 0;
|
|
lConditions.GenerateScore(
|
|
bullishScore,
|
|
bearishScore //
|
|
);
|
|
mBullishScore += bullishScore;
|
|
mBearishScore += bearishScore;
|
|
|
|
//
|
|
// Parse Conditions for Signal ...
|
|
bool hasSignal = signalGenerator.HasSignal(
|
|
lConditions,
|
|
lSignal,
|
|
lPusher,
|
|
mAllowLong,
|
|
mAllowShort //
|
|
);
|
|
|
|
//
|
|
if (hasSignal)
|
|
{
|
|
//
|
|
mSetups[i].WaitsUntilNextBar(
|
|
X_MARKET_CYCLE_LONG //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Hind ...
|
|
canProcess = mSetups[i]
|
|
.CanProcessBar(
|
|
X_MARKET_CYCLE_HIND //
|
|
);
|
|
if (canProcess)
|
|
{
|
|
//
|
|
bool iHasConditions = mSetups[i].GetConditions(
|
|
hConditions,
|
|
X_MARKET_CYCLE_HIND, // Current Market ...
|
|
0, // Bar Index ...
|
|
5 // Loop Back ...
|
|
);
|
|
|
|
//
|
|
if (!iHasConditions)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Retrieve Scores ...
|
|
double bullishScore = 0;
|
|
double bearishScore = 0;
|
|
hConditions.GenerateScore(
|
|
bullishScore,
|
|
bearishScore //
|
|
);
|
|
mBullishScore += bullishScore;
|
|
mBearishScore += bearishScore;
|
|
|
|
//
|
|
// Parse Conditions for Signal ...
|
|
bool hasSignal = signalGenerator.HasSignal(
|
|
hConditions,
|
|
hSignal,
|
|
hPusher,
|
|
mAllowLong,
|
|
mAllowShort //
|
|
);
|
|
|
|
//
|
|
if (hasSignal)
|
|
{
|
|
//
|
|
mSetups[i].WaitsUntilNextBar(
|
|
X_MARKET_CYCLE_HIND //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Parse Signals and Add them for Executing ...
|
|
// Here we can Save Signal and it's Conditions to
|
|
// Specified Collector then Update them on SL and TP ...
|
|
|
|
//
|
|
// Current Signals ...
|
|
if (cPusher > 0 && cSignal.IsValid())
|
|
{
|
|
//
|
|
AddRef(
|
|
cSignal,
|
|
signals //
|
|
);
|
|
|
|
//
|
|
AddNewSignal(
|
|
cPusher,
|
|
cSignal,
|
|
cConditions //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Short Signals ...
|
|
if (sPusher > 0 && sSignal.IsValid())
|
|
{
|
|
//
|
|
AddRef(
|
|
sSignal,
|
|
signals //
|
|
);
|
|
|
|
//
|
|
AddNewSignal(
|
|
sPusher,
|
|
sSignal,
|
|
sConditions //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Medium Signals ...
|
|
if (mPusher > 0 && mSignal.IsValid())
|
|
{
|
|
//
|
|
AddRef(
|
|
mSignal,
|
|
signals //
|
|
);
|
|
|
|
//
|
|
AddNewSignal(
|
|
mPusher,
|
|
mSignal,
|
|
mConditions //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Long Signals ...
|
|
if (lPusher > 0 && lSignal.IsValid())
|
|
{
|
|
//
|
|
AddRef(
|
|
lSignal,
|
|
signals //
|
|
);
|
|
|
|
//
|
|
AddNewSignal(
|
|
lPusher,
|
|
lSignal,
|
|
lConditions //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Hind Signals ...
|
|
if (hPusher > 0 && hSignal.IsValid())
|
|
{
|
|
//
|
|
AddRef(
|
|
hSignal,
|
|
signals //
|
|
);
|
|
|
|
//
|
|
AddNewSignal(
|
|
hPusher,
|
|
hSignal,
|
|
hConditions //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Create Score Summary for Commenting on Chart ...
|
|
string scoreSummary =
|
|
//
|
|
"Scores:" + separator +
|
|
"----------" + separator +
|
|
"Bullish: " + ToString(mBullishScore) + separator +
|
|
"Bearish: " + ToString(mBearishScore) + separator +
|
|
""
|
|
//
|
|
;
|
|
|
|
//
|
|
Comment(scoreSummary);
|
|
|
|
//
|
|
result = ArraySize(signals);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Here we Manage Signals for Executing ...
|
|
// - Check Policies based on their Signaller ...
|
|
// - Check Same Time Open Positions ...
|
|
// - Check Signal Age for new Trade ...
|
|
// and etc ...
|
|
int HandleSignalManagement(XSignal &signals[]) override
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
int signalsCount = ArraySize(signals);
|
|
if (!IsValidSize(signalsCount))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XSignal tmpSignals[];
|
|
Copy(
|
|
signals,
|
|
tmpSignals //
|
|
);
|
|
|
|
//
|
|
Clean(signals);
|
|
|
|
//
|
|
for (int i = 0; i < signalsCount; i++)
|
|
{
|
|
//
|
|
XSignal iSignal = tmpSignals[i];
|
|
|
|
//
|
|
AddRef(
|
|
iSignal,
|
|
signals //
|
|
);
|
|
}
|
|
|
|
//
|
|
result = ArraySize(signals);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Handle State Management ....
|
|
// here we can manage current state ...
|
|
// - Check for Long Positions for each Signaller to Close ...
|
|
// - Handle Hedging Signaller's Positions if it's enabled ...
|
|
// - Force Closing Position when Specified Time reached ...
|
|
// - Check Start and End time or Trading Dates ...
|
|
// - handle Trailing or Risk free Signals based on several conditions ...
|
|
// and etc ...
|
|
bool HandleStateManagement(XSignal &signals[]) override
|
|
{
|
|
//
|
|
const bool result = false;
|
|
|
|
//
|
|
// Here we Implement Account Protector ...
|
|
HandleAccountProtect();
|
|
|
|
//
|
|
// Do all State Management here ...
|
|
|
|
//
|
|
// if Returns true, Signal Execution failed ...
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Tools For Signal Info Collect ...
|
|
|
|
//
|
|
void OnDealsChangedHandler(int count)
|
|
{
|
|
//
|
|
XDeal deal;
|
|
bool hasDeal = mTrader.GetLastDeal(deal);
|
|
if (hasDeal)
|
|
{
|
|
UpdateSignalState(deal);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Protected ...
|
|
protected:
|
|
//
|
|
// Tools ...
|
|
|
|
//
|
|
// Do All Protection Senarios here ...
|
|
void HandleAccountProtect()
|
|
{
|
|
}
|
|
|
|
//
|
|
// Private ...
|
|
private:
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
bool mAllowLong; // Allow Long
|
|
bool mAllowShort; // Allow Short
|
|
|
|
//
|
|
// TODO:
|
|
// Add Volume and TP SL Points as Properties here ...
|
|
|
|
//
|
|
XSignalInfo mSignalInfos[];
|
|
XSignalInfoCollector *mSignalCollector;
|
|
|
|
//
|
|
int CountSignalInfos()
|
|
{
|
|
return ArraySize(mSignalInfos);
|
|
}
|
|
|
|
//
|
|
int FindSignalInfoIndex(
|
|
ulong positionTicket //
|
|
)
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
int count = CountSignalInfos();
|
|
if (!IsValidSize(count))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XSignalInfo iInfo = mSignalInfos[i];
|
|
|
|
//
|
|
bool isOwn = iInfo.IsOwn(
|
|
positionTicket //
|
|
);
|
|
if (isOwn)
|
|
{
|
|
//
|
|
result = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int FindSignalInfoIndex(
|
|
string symbol,
|
|
string provider,
|
|
ENUM_TIMEFRAMES period //
|
|
)
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
int count = CountSignalInfos();
|
|
if (!IsValidSize(count))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XSignalInfo iInfo = mSignalInfos[i];
|
|
|
|
//
|
|
bool isOwn = iInfo.IsOwn(
|
|
symbol,
|
|
provider,
|
|
period //
|
|
);
|
|
if (isOwn)
|
|
{
|
|
//
|
|
result = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int FindSignalInfoIndex(XDeal &deal)
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
if (!deal.IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (IsValid(deal.provider))
|
|
{
|
|
result = FindSignalInfoIndex(
|
|
deal.symbol,
|
|
deal.provider,
|
|
deal.period //
|
|
);
|
|
}
|
|
else
|
|
{
|
|
result = FindSignalInfoIndex(deal.positionId);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
void AddNewSignal(
|
|
int pusher,
|
|
XSignal &signal,
|
|
X121SetupConditions &conditions //
|
|
)
|
|
{
|
|
//
|
|
XSignalInfo info;
|
|
bool isFilled = info.Fill(
|
|
pusher,
|
|
signal,
|
|
conditions //
|
|
);
|
|
|
|
//
|
|
if (isFilled)
|
|
{
|
|
//
|
|
AddRef(
|
|
info,
|
|
mSignalInfos //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
void UpdateSignalState(XDeal &deal)
|
|
{
|
|
//
|
|
if (!deal.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
int infoIDX = FindSignalInfoIndex(deal);
|
|
if (!IsValidIndex(infoIDX))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
if (deal.entry == DEAL_ENTRY_IN)
|
|
{
|
|
//
|
|
mSignalInfos[infoIDX].time = deal.time;
|
|
mSignalInfos[infoIDX].ticket = deal.positionId;
|
|
Print("Open Position: " + ToString(deal.positionId));
|
|
}
|
|
else if (deal.entry == DEAL_ENTRY_OUT)
|
|
{
|
|
Print("Close Position: " + ToString(deal.positionId));
|
|
}
|
|
}
|
|
|
|
//
|
|
double mBullishScore;
|
|
double mBearishScore;
|
|
|
|
//
|
|
XSCX121SetupCycles *mSetups[]; // Number of Setups
|
|
|
|
//
|
|
// Tools ...
|
|
int CountSetups()
|
|
{
|
|
return ArraySize(mSetups);
|
|
}
|
|
|
|
//
|
|
int FindSetupIndex(
|
|
string symbol,
|
|
ENUM_TIMEFRAMES period //
|
|
)
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
int count = CountSetups();
|
|
if (!IsValidSize(count))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XSCX121SetupCycles *iSetup = mSetups[i];
|
|
|
|
//
|
|
X121SetupInputs iInputs = iSetup.GetInputs();
|
|
|
|
//
|
|
if (iInputs.symbol == symbol && iInputs.period == period)
|
|
{
|
|
//
|
|
result = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
};
|
|
|
|
//
|