last ...
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| VPattern.mq5 |
|
||||
//| Copyright 2023, MetaQuotes Software Corp. |
|
||||
//| https://www.metaquotes.net/ |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2023, MetaQuotes Software Corp."
|
||||
#property link "https://www.metaquotes.net/"
|
||||
#property version "1.00"
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 4
|
||||
#property indicator_plots 2
|
||||
#property indicator_label1 "V Pattern Top"
|
||||
#property indicator_type1 DRAW_ARROW
|
||||
#property indicator_color1 clrGreen
|
||||
#property indicator_width1 2
|
||||
#property indicator_label2 "V Pattern Bottom"
|
||||
#property indicator_type2 DRAW_ARROW
|
||||
#property indicator_color2 clrRed
|
||||
#property indicator_width2 2
|
||||
|
||||
//--- Input parameters
|
||||
input int LookbackPeriod=20; // Bars to analyze for pattern
|
||||
input double MinDeclinePercent=2.0; // Minimum decline percentage
|
||||
input double MinRisePercent=2.0; // Minimum rise percentage
|
||||
input bool ShowAlerts=true; // Show alert messages
|
||||
input color ArrowUpColor=clrGreen; // Up arrow color
|
||||
input color ArrowDownColor=clrRed; // Down arrow color
|
||||
|
||||
//--- Indicator buffers
|
||||
double VTopBuffer[];
|
||||
double VBottomBuffer[];
|
||||
double TempHighBuffer[];
|
||||
double TempLowBuffer[];
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- indicator buffers mapping
|
||||
SetIndexBuffer(0, VTopBuffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(1, VBottomBuffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(2, TempHighBuffer, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(3, TempLowBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//--- setting arrow codes
|
||||
PlotIndexSetInteger(0, PLOT_ARROW, 233); // Up arrow
|
||||
PlotIndexSetInteger(1, PLOT_ARROW, 234); // Down arrow
|
||||
|
||||
//--- setting arrow colors
|
||||
PlotIndexSetInteger(0, PLOT_LINE_COLOR, ArrowUpColor);
|
||||
PlotIndexSetInteger(1, PLOT_LINE_COLOR, ArrowDownColor);
|
||||
|
||||
//--- setting buffer values as EMPTY_VALUE
|
||||
ArrayInitialize(VTopBuffer, EMPTY_VALUE);
|
||||
ArrayInitialize(VBottomBuffer, EMPTY_VALUE);
|
||||
|
||||
//--- name for DataWindow and indicator subwindow label
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, "V-Pattern Detector ("+string(LookbackPeriod)+")");
|
||||
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator iteration function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
//--- check for minimum bars required
|
||||
if(rates_total < LookbackPeriod)
|
||||
return(0);
|
||||
|
||||
//--- start calculation from bar determined by prev_calculated
|
||||
int start;
|
||||
if(prev_calculated == 0)
|
||||
start = LookbackPeriod;
|
||||
else
|
||||
start = prev_calculated - 1;
|
||||
|
||||
//--- main calculation loop
|
||||
for(int i=start; i<rates_total && !IsStopped(); i++)
|
||||
{
|
||||
// Reset buffers
|
||||
VTopBuffer[i] = EMPTY_VALUE;
|
||||
VBottomBuffer[i] = EMPTY_VALUE;
|
||||
|
||||
// Find the lowest low in the lookback period
|
||||
int lowestBar = iLowest(NULL, 0, MODE_LOW, LookbackPeriod, i-LookbackPeriod+1);
|
||||
double lowestLow = low[lowestBar];
|
||||
|
||||
// Find the highest high before the lowest low
|
||||
int highBeforeLow = iHighest(NULL, 0, MODE_HIGH, lowestBar-(i-LookbackPeriod+1)+1, i-LookbackPeriod+1);
|
||||
double highestBefore = high[highBeforeLow];
|
||||
|
||||
// Find the highest high after the lowest low
|
||||
int highAfterLow = iHighest(NULL, 0, MODE_HIGH, i-lowestBar, lowestBar+1);
|
||||
double highestAfter = high[highAfterLow];
|
||||
|
||||
// Calculate percentage moves
|
||||
double declinePercent = (highestBefore - lowestLow) / highestBefore * 100;
|
||||
double risePercent = (highestAfter - lowestLow) / lowestLow * 100;
|
||||
|
||||
// Check if we have a V pattern
|
||||
if(declinePercent >= MinDeclinePercent && risePercent >= MinRisePercent)
|
||||
{
|
||||
// Check if the low is in the middle third of the lookback period
|
||||
int lowPosition = lowestBar - (i-LookbackPeriod+1);
|
||||
if(lowPosition > LookbackPeriod/3 && lowPosition < 2*LookbackPeriod/3)
|
||||
{
|
||||
// Mark the pattern on chart
|
||||
VTopBuffer[highBeforeLow] = high[highBeforeLow];
|
||||
VBottomBuffer[lowestBar] = low[lowestBar];
|
||||
VTopBuffer[highAfterLow] = high[highAfterLow];
|
||||
|
||||
// Show alert if enabled
|
||||
if(ShowAlerts && i == rates_total-1)
|
||||
{
|
||||
string alertText = StringFormat("V-Pattern detected! Decline: %.2f%%, Rise: %.2f%%",
|
||||
declinePercent, risePercent);
|
||||
Alert(alertText);
|
||||
Comment(alertText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,620 @@
|
||||
//
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user