621 lines
13 KiB
Plaintext
621 lines
13 KiB
Plaintext
//
|
|
bool Prepare(
|
|
string mSymbol, // Trading Symbol
|
|
string mProvider, // Signal Provider
|
|
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
|
|
ENUM_POSITION_TYPE mType, // Long (Buy) or Short (Sell)
|
|
ENUM_X_ORDER_MODES mMode, // Execution Mode
|
|
double mEntry, // Entry Price
|
|
double mVolume, // Volume
|
|
double mSL = 0, // Stop Loss
|
|
double mTP = 0 // Take Profit
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
IsValid(mMode) &&
|
|
IsValid(mSymbol) &&
|
|
IsValid(mPeriod) &&
|
|
NotEmpty(mEntry) &&
|
|
NotEmpty(mVolume) &&
|
|
IsValid(mProvider)
|
|
//
|
|
;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (mTP < 0)
|
|
{
|
|
mTP = 0;
|
|
}
|
|
|
|
//
|
|
if (mSL < 0)
|
|
{
|
|
mSL = 0;
|
|
}
|
|
|
|
//
|
|
type = mType;
|
|
mode = mMode;
|
|
symbol = mSymbol;
|
|
period = mPeriod;
|
|
provider = mProvider;
|
|
|
|
//
|
|
// Normalization Values ...
|
|
sl = NormalizePrice(mSL, mSymbol);
|
|
tp = NormalizePrice(mTP, mSymbol);
|
|
mEntry = NormalizePrice(mEntry, mSymbol);
|
|
mVolume = NormalizeVolume(mVolume, mSymbol);
|
|
|
|
//
|
|
entry = mEntry;
|
|
volume = mVolume;
|
|
|
|
//
|
|
result = Normalize();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool PrepareComplex(
|
|
string mSymbol, // Trading Symbol
|
|
string mProvider, // Signal Provider
|
|
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
|
|
ENUM_POSITION_TYPE mType, // Long (Buy) or Short (Sell)
|
|
ENUM_X_ORDER_MODES mMode, // Execution Mode
|
|
double mEntry, // Entry Price
|
|
double mVolume, // Volume
|
|
double mSL = 0, // Stop Loss
|
|
//
|
|
// TP ...
|
|
double mFullTPLevel = 0, // Full TP Level
|
|
double mPartialCloseOnTPLevel = 0, // Partial Close On TP Level
|
|
double mPartialCloseMultiplier = 0, // Partial Close Multiplier
|
|
//
|
|
// RF ...
|
|
bool mRiskFreeOnBreakEven = false, // Risk Free Signal On Break Even ...
|
|
double mTpLevelForBreakEven = 0, // TP Level for Break Even ...
|
|
//
|
|
// SL Trail ...
|
|
bool mTrailSL = false, // Trail SL
|
|
double mTrailSLStartOnReachTPLevel = 0 // Trail SL Starts after Reached TP Level
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Validate Args ...
|
|
result =
|
|
//
|
|
// Common ...
|
|
mSL > 0 &&
|
|
mEntry > 0 &&
|
|
mVolume > 0 &&
|
|
IsValid(mSymbol) &&
|
|
IsValid(mPeriod) &&
|
|
IsValid(mProvider) &&
|
|
mMode != X_ORDER_MODE_NOTHING
|
|
//
|
|
&&
|
|
//
|
|
// TP ...
|
|
mFullTPLevel > 0
|
|
//
|
|
;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Prepare Regular Signal Values ...
|
|
double _risk = MathAbs(mEntry - mSL);
|
|
double _reward = _risk * mFullTPLevel;
|
|
|
|
//
|
|
bool isLong = IsLong(mType);
|
|
|
|
//
|
|
sl = mSL;
|
|
type = mType;
|
|
mode = mMode;
|
|
entry = mEntry;
|
|
symbol = mSymbol;
|
|
period = mPeriod;
|
|
volume = mVolume;
|
|
provider = mProvider;
|
|
fullTPLevel = mFullTPLevel;
|
|
tp = isLong
|
|
? mEntry + _reward
|
|
: mEntry - _reward;
|
|
|
|
//
|
|
result = Normalize();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Calculate Other Conditions ...
|
|
|
|
//
|
|
bool canPartialClose =
|
|
//
|
|
mPartialCloseOnTPLevel > 0 &&
|
|
mPartialCloseMultiplier > 0 &&
|
|
mPartialCloseOnTPLevel < mFullTPLevel
|
|
//
|
|
;
|
|
if (canPartialClose)
|
|
{
|
|
//
|
|
partialCloseOnTPLevel = mPartialCloseOnTPLevel;
|
|
partialCloseMultiplier = mPartialCloseMultiplier;
|
|
}
|
|
|
|
//
|
|
bool canRFOnBEP =
|
|
//
|
|
mRiskFreeOnBreakEven &&
|
|
mTpLevelForBreakEven > 0
|
|
//
|
|
;
|
|
if (canRFOnBEP)
|
|
{
|
|
//
|
|
riskFreeOnBreakEven = mRiskFreeOnBreakEven;
|
|
tpLevelForBreakEven = mTpLevelForBreakEven;
|
|
}
|
|
|
|
//
|
|
bool canTrailSL =
|
|
//
|
|
mTrailSL &&
|
|
mTrailSLStartOnReachTPLevel > 0 &&
|
|
mTrailSLStartOnReachTPLevel < mFullTPLevel
|
|
//
|
|
;
|
|
if (canTrailSL)
|
|
{
|
|
//
|
|
trailSL = mTrailSL;
|
|
trailSLStartOnReachTPLevel = mTrailSLStartOnReachTPLevel;
|
|
}
|
|
|
|
//
|
|
result = IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool PrepareLong(
|
|
string mSymbol, // Trading Symbol
|
|
string mProvider, // Signal Provider
|
|
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
|
|
ENUM_X_ORDER_MODES mMode, // Execution Mode
|
|
double mEntry, // Entry Price
|
|
double mVolume, // Volume
|
|
double mSL = 0, // Stop Loss
|
|
double mTP = 0 // Take Profit
|
|
)
|
|
{
|
|
//
|
|
return Prepare(
|
|
mSymbol,
|
|
mProvider,
|
|
mPeriod,
|
|
POSITION_TYPE_BUY,
|
|
mMode,
|
|
mEntry,
|
|
mVolume,
|
|
mSL,
|
|
mTP
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
bool PrepareShort(
|
|
string mSymbol, // Trading Symbol
|
|
string mProvider, // Signal Provider
|
|
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
|
|
ENUM_X_ORDER_MODES mMode, // Execution Mode
|
|
double mEntry, // Entry Price
|
|
double mVolume, // Volume
|
|
double mSL = 0, // Stop Loss
|
|
double mTP = 0 // Take Profit
|
|
)
|
|
{
|
|
//
|
|
return Prepare(
|
|
mSymbol,
|
|
mProvider,
|
|
mPeriod,
|
|
POSITION_TYPE_SELL,
|
|
mMode,
|
|
mEntry,
|
|
mVolume,
|
|
mSL,
|
|
mTP
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
// Market Mode ...
|
|
|
|
//
|
|
bool PrepareMarketLong(
|
|
string mSymbol, // Trading Symbol
|
|
string mProvider, // Signal Provider
|
|
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
|
|
double mEntry, // Entry Price
|
|
double mVolume, // Volume
|
|
double mSL = 0, // Stop Loss
|
|
double mTP = 0 // Take Profit
|
|
)
|
|
{
|
|
//
|
|
return PrepareLong(
|
|
mSymbol,
|
|
mProvider,
|
|
mPeriod,
|
|
X_ORDER_MODE_MARKET,
|
|
mEntry,
|
|
mVolume,
|
|
mSL,
|
|
mTP
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
bool PrepareMarketShort(
|
|
string mSymbol, // Trading Symbol
|
|
string mProvider, // Signal Provider
|
|
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
|
|
double mEntry, // Entry Price
|
|
double mVolume, // Volume
|
|
double mSL = 0, // Stop Loss
|
|
double mTP = 0 // Take Profit
|
|
)
|
|
{
|
|
//
|
|
return PrepareShort(
|
|
mSymbol,
|
|
mProvider,
|
|
mPeriod,
|
|
X_ORDER_MODE_MARKET,
|
|
mEntry,
|
|
mVolume,
|
|
mSL,
|
|
mTP
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
// Stop Mode ...
|
|
|
|
//
|
|
bool PrepareStopLong(
|
|
string mSymbol, // Trading Symbol
|
|
string mProvider, // Signal Provider
|
|
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
|
|
double mEntry, // Entry Price
|
|
double mVolume, // Volume
|
|
double mSL = 0, // Stop Loss
|
|
double mTP = 0 // Take Profit
|
|
)
|
|
{
|
|
//
|
|
return PrepareLong(
|
|
mSymbol,
|
|
mProvider,
|
|
mPeriod,
|
|
X_ORDER_MODE_STOP,
|
|
mEntry,
|
|
mVolume,
|
|
mSL,
|
|
mTP
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
bool PrepareStopShort(
|
|
string mSymbol, // Trading Symbol
|
|
string mProvider, // Signal Provider
|
|
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
|
|
double mEntry, // Entry Price
|
|
double mVolume, // Volume
|
|
double mSL = 0, // Stop Loss
|
|
double mTP = 0 // Take Profit
|
|
)
|
|
{
|
|
//
|
|
return PrepareShort(
|
|
mSymbol,
|
|
mProvider,
|
|
mPeriod,
|
|
X_ORDER_MODE_STOP,
|
|
mEntry,
|
|
mVolume,
|
|
mSL,
|
|
mTP
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
// Limit Mode ...
|
|
|
|
//
|
|
bool PrepareLimitLong(
|
|
string mSymbol, // Trading Symbol
|
|
string mProvider, // Signal Provider
|
|
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
|
|
double mEntry, // Entry Price
|
|
double mVolume, // Volume
|
|
double mSL = 0, // Stop Loss
|
|
double mTP = 0 // Take Profit
|
|
)
|
|
{
|
|
//
|
|
return PrepareLong(
|
|
mSymbol,
|
|
mProvider,
|
|
mPeriod,
|
|
X_ORDER_MODE_LIMIT,
|
|
mEntry,
|
|
mVolume,
|
|
mSL,
|
|
mTP
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
bool PrepareLimitShort(
|
|
string mSymbol, // Trading Symbol
|
|
string mProvider, // Signal Provider
|
|
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
|
|
double mEntry, // Entry Price
|
|
double mVolume, // Volume
|
|
double mSL = 0, // Stop Loss
|
|
double mTP = 0 // Take Profit
|
|
)
|
|
{
|
|
//
|
|
return PrepareShort(
|
|
mSymbol,
|
|
mProvider,
|
|
mPeriod,
|
|
X_ORDER_MODE_LIMIT,
|
|
mEntry,
|
|
mVolume,
|
|
mSL,
|
|
mTP
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
// Generate Opposit Direction ...
|
|
bool GenerateOpposit(
|
|
XSignal &mSignal // Oppsoit Signal
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
ENUM_POSITION_TYPE mType = Opposit(this.type);
|
|
double mEntry = GetExit(this.symbol, mType);
|
|
|
|
//
|
|
bool isLong = IsLong(mType);
|
|
|
|
//
|
|
// Calculate Risk Reward Ratio ...
|
|
double risk = GetRisk();
|
|
double reward = GetReward();
|
|
|
|
//
|
|
double mSL = isLong
|
|
? mEntry - risk
|
|
: mEntry + risk;
|
|
|
|
//
|
|
double mTP = isLong
|
|
? mEntry + reward
|
|
: mEntry - reward;
|
|
|
|
//
|
|
result = mSignal.Prepare(
|
|
this.symbol,
|
|
this.provider,
|
|
this.period,
|
|
mType,
|
|
this.mode,
|
|
mEntry,
|
|
this.volume,
|
|
mSL,
|
|
mTP //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Prepare Opposit Signal based On a Position ...
|
|
bool PrepareOpposit(
|
|
XPosition &source // Source Data
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
ENUM_POSITION_TYPE mType = Opposit(source.type);
|
|
double mEntry = GetEntry(source.symbol, mType);
|
|
|
|
//
|
|
bool isLong = IsLong(mType);
|
|
|
|
//
|
|
double risk = source.GetRisk();
|
|
double reward = source.GetReward();
|
|
|
|
//
|
|
double mSL = isLong
|
|
? mEntry - risk
|
|
: mEntry + risk;
|
|
|
|
//
|
|
double mTP = isLong
|
|
? mEntry + reward
|
|
: mEntry - reward;
|
|
|
|
//
|
|
return Prepare(
|
|
source.symbol,
|
|
source.provider,
|
|
source.period,
|
|
mType,
|
|
X_ORDER_MODE_MARKET,
|
|
mEntry,
|
|
source.volume,
|
|
mSL,
|
|
mTP //
|
|
);
|
|
|
|
//
|
|
result = IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// Handle Executing Support Signals ...
|
|
int supportsCount = ArraySize(mSignal.supports);
|
|
if (supportsCount > 0)
|
|
{
|
|
//
|
|
int executed = 0;
|
|
for (int i = 0; i < supportsCount; i++)
|
|
{
|
|
//
|
|
XSignal iSupport = mSignal.supports[i];
|
|
|
|
//
|
|
int supIndex = i + 1;
|
|
string iComment = GenerateSupportTag(ticket);
|
|
iSupport.comment = iComment;
|
|
|
|
//
|
|
bool isExecuted = ExecuteSignal(
|
|
iSupport,
|
|
state,
|
|
lifetime,
|
|
expiration
|
|
//
|
|
);
|
|
if (isExecuted)
|
|
{
|
|
executed++;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = executed == supportsCount;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// Handle Partial Close on Specified Targets ...
|
|
has = !trades[idx].signal.isPartiallyClosed &&
|
|
trades[idx].signal.partialCloseOnTPLevel > 0 &&
|
|
trades[idx].signal.partialCloseMultiplier > 0;
|
|
if (has)
|
|
{
|
|
//
|
|
// Check Reward Touched ...
|
|
double iCurrReward = iPosition.CalculateTouchedReward();
|
|
has = iCurrReward >= trades[idx].signal.partialCloseOnTPLevel;
|
|
if (has)
|
|
{
|
|
//
|
|
// Check Volume Multiplier ...
|
|
double volumeMultiplier = trades[idx].signal.partialCloseMultiplier;
|
|
has = volumeMultiplier > 0 &&
|
|
volumeMultiplier <= 1;
|
|
if (has)
|
|
{
|
|
//
|
|
// Do Partial Closing ...
|
|
double volume = iPosition.volume * volumeMultiplier;
|
|
|
|
//
|
|
// Normalizing Volume ...
|
|
volume = NormalizeVolume(
|
|
volume,
|
|
iPosition.symbol //
|
|
);
|
|
|
|
//
|
|
string comment = "PC On Target ...";
|
|
has = trader.ClosePartial(
|
|
iPosition.ticket,
|
|
volume,
|
|
comment //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Update Model ...
|
|
trades[idx].signal.isPartiallyClosed = true;
|
|
|
|
//
|
|
string message = prefix +
|
|
ToString(iPosition.type) +
|
|
" Position: " +
|
|
ToString(iPosition.ticket) +
|
|
" PC (" + ToString(volume) + ") On Traget: " + ToString(iCurrReward) +
|
|
" Successfully ...";
|
|
HandleReportProtector(message);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|