1899 lines
48 KiB
Plaintext
1899 lines
48 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center XTest MQL5 Expert Advisor
|
|
// -------------------------------------------------
|
|
// Name: XBackTester
|
|
// Description: a Backtest Tools Strategy Tester
|
|
//
|
|
// Maintainer:
|
|
// ------------
|
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
|
//
|
|
//////////////////////////////////////////////////////x
|
|
//
|
|
// Global Properties ...
|
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
|
#property link "https://saherelm.ir"
|
|
#property version "1.00"
|
|
#property description "SaherElm XBackTester"
|
|
#property icon "../Images/SaherElm_Logo_Color.ico"
|
|
#property strict
|
|
|
|
//
|
|
#define ShortName "XBackTester"
|
|
|
|
//
|
|
// Imports ...
|
|
#include "../Classes/x-saherelm.x-backtester.expert.class.mq5"
|
|
#include "../XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5"
|
|
|
|
//
|
|
// Definitions ...
|
|
|
|
//
|
|
// Inputs ...
|
|
|
|
//
|
|
// Common ...
|
|
input group "Common";
|
|
input long eaMagicNumber = 78692110; // Magic Number
|
|
input int eaSlippage = 10; // Slippgae
|
|
input string eaLogSuffix = ""; // Log Suffix
|
|
|
|
//
|
|
// Alert ...
|
|
// Here we Provider All Requirements for
|
|
// Configuring Alert Provider ...
|
|
input group "Alert";
|
|
input bool eaEnableAlerts = true; // Enable Alerts
|
|
input bool eaLogAlerts = true; // Log Alerts
|
|
input bool eaMailAlerts = false; // Mail Alerts
|
|
input bool eaPushAlerts = false; // Push Alerts
|
|
input bool eaTerminalAlerts = false; // Terminal Alerts
|
|
|
|
//
|
|
// Configurations ...
|
|
input group "Configuration";
|
|
input bool eaProcessAllTicks = false; // Process All Ticks
|
|
input double eaSignallerR2R = 2.0; // Risk To Reward Ratio
|
|
input double eaSignallerVolume = 0.01; // Default Volume
|
|
input double eaSignallerRiskInPoint = 50; // Default Risk In Point
|
|
|
|
//
|
|
// Indicator Inputs ...
|
|
//
|
|
input group "Calculation";
|
|
|
|
//
|
|
// Short ...
|
|
input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Short Period
|
|
input ENUM_TIMEFRAMES scPeriod = NULL; // Short Period
|
|
|
|
//
|
|
// Medium ...
|
|
input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Medium Period
|
|
input ENUM_TIMEFRAMES mcPeriod = NULL; // Medium Period
|
|
|
|
//
|
|
// Long ...
|
|
input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Long Period
|
|
input ENUM_TIMEFRAMES lcPeriod = NULL; // Long Period
|
|
|
|
//
|
|
// Hind ...
|
|
input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Hind Period
|
|
input ENUM_TIMEFRAMES hcPeriod = NULL; // Hind Period
|
|
|
|
//
|
|
// PV ...
|
|
input ENUM_SERIESMODE upperMode = MODE_HIGH; // Peak Method
|
|
input ENUM_SERIESMODE lowerMode = MODE_LOW; // Vale Method
|
|
|
|
//
|
|
// Others ...
|
|
input ENUM_X_FIBO_LEVELS fiboUpperZoneLevel = X_FIBO_LEVEL_382; // Upper Zone Level
|
|
input ENUM_X_FIBO_LEVELS fiboMiddleZoneLevel = X_FIBO_LEVEL_500; // Middle Zone Level
|
|
input ENUM_X_FIBO_LEVELS fiboLowerZoneLevel = X_FIBO_LEVEL_618; // Lower Zone Level
|
|
input double sarStep = 0.02; // SAR Step
|
|
input double sarMax = 0.2; // SAR Maximum
|
|
input ENUM_MA_METHOD maMethod = MODE_EMA; // MA Method
|
|
input ENUM_APPLIED_PRICE maAppliedTo = PRICE_CLOSE; // MA Applied To
|
|
input int maFastLength = 7; // Fast MA Length
|
|
input int maSlowLength = 20; // Slow MA Length
|
|
input int maBandLength = 7; // MA Band Length
|
|
input int zigzagDepth = 12; // ZigZag Depth
|
|
input int zigzagDeviation = 5; // ZigZag Deviation
|
|
input int zigzagBackStep = 3; // ZigZag Back Step
|
|
input ENUM_X_PRICE zigzagUppersMode = X_PRICE_HIGH; // ZigZag High Detect Mode
|
|
input ENUM_X_PRICE zigzagLowersMode = X_PRICE_LOW; // ZigZag Low Detect Mode
|
|
|
|
//
|
|
input group "Bar Timer";
|
|
input int barTimeFontSize = 10; // Font Size
|
|
input string barTimeFont = "Arial"; // Font
|
|
input color barTimeColor = clrYellow; // Text Color
|
|
input ENUM_BASE_CORNER barTimeCorner = CORNER_RIGHT_LOWER; // Text Position
|
|
|
|
//
|
|
// Presentation ...
|
|
input group "Presentation";
|
|
input bool showPV = true; // Show PV
|
|
input bool showHK = true; // Show HK
|
|
input bool showSAR = true; // Show Sar
|
|
input bool showMAFast = true; // Show MA Fast
|
|
input bool showMASlow = true; // Show MA Slow
|
|
input bool showMABand = true; // Show MA Band
|
|
input bool showBarTime = true; // Show Bar Time
|
|
input bool showZigZag = true; // Show ZigZag
|
|
input bool showFiboZone = true; // Show Fibo Zone
|
|
|
|
//
|
|
input int startCalculationForLastBars = 1500; // Calculate Last n Bars
|
|
|
|
//
|
|
input int sarArrowCode = 159; // Parabolic Sar Arrow Code
|
|
input int peakArrowCode = 159; // Peaks Arrow Code
|
|
input int valeArrowCode = 159; // Vales Arrow Code
|
|
|
|
//
|
|
// Define Local Variables ...
|
|
|
|
//
|
|
// Requirements ...
|
|
string eaLogTag; // EA Log Prefix ...
|
|
XCBackTesterEA *eaExpert; // EA Expert ...
|
|
|
|
//
|
|
// Registered Signallers ...
|
|
XCXFIMAStrategy1Signaller *fima1Signaller; // XFIMA1 Signaller ...
|
|
|
|
//
|
|
XFIMAMarketStructure marketStructure; // POI Analysis Result ...
|
|
XFIMAPatternDetectorConfig detectorConfig; // POI Detector Config ...
|
|
XFIMAMarketStructureDrawerConfig marketStructureDrawerConfig; // POI Drawer Config ...
|
|
|
|
//
|
|
// Drawer and eaDraws ...
|
|
CArrayObj eaDraws; // Drawn Objects ...
|
|
CArrayObj *marketStructureObjects; // Market Structure Objects ...
|
|
|
|
//
|
|
XBarTracker eaBarTracker; // EA Bar Traker ...
|
|
|
|
//
|
|
// Registered Handlers ...
|
|
int eaCTHandler = INVALID_HANDLE; // Candle Timer Handler ...
|
|
|
|
//
|
|
bool eaIsNewBar; // Check New Bar ...
|
|
|
|
//
|
|
// Define Indicators Here ...
|
|
|
|
//
|
|
// Event Handlers ...
|
|
|
|
//
|
|
// Initialization ...
|
|
int OnInit()
|
|
{
|
|
//
|
|
// Preparing Tags ...
|
|
string eaTag =
|
|
(IsValid(eaLogSuffix)
|
|
? eaLogSuffix + "_"
|
|
: "") +
|
|
ShortName;
|
|
|
|
//
|
|
// Validate Inputs and Required Parameters
|
|
// for EA to Works fine ...
|
|
if (!ValidateInputs())
|
|
{
|
|
return INIT_PARAMETERS_INCORRECT;
|
|
}
|
|
|
|
//
|
|
// Initialize Timer ...
|
|
if (!InitTimer())
|
|
{
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
//
|
|
// Configure EA Expert Class ...
|
|
eaExpert = new XCBackTesterEA();
|
|
|
|
//
|
|
// Symbol / Period ...
|
|
eaExpert.symbol = _Symbol;
|
|
eaExpert.period = _Period;
|
|
|
|
//
|
|
// Common ...
|
|
eaExpert.eaMagicNumber = eaMagicNumber;
|
|
eaExpert.eaSlippage = eaSlippage;
|
|
eaExpert.eaLogSuffix = eaTag;
|
|
|
|
//
|
|
// Alert ...
|
|
eaExpert.eaEnableAlerts = eaEnableAlerts;
|
|
eaExpert.eaLogAlerts = eaLogAlerts;
|
|
eaExpert.eaMailAlerts = eaMailAlerts;
|
|
eaExpert.eaPushAlerts = eaPushAlerts;
|
|
eaExpert.eaTerminalAlerts = eaTerminalAlerts;
|
|
|
|
//
|
|
// Attach Event Handlers ...
|
|
eaExpert.AddOnDealsChangedEventHandler(OnDealsChanged);
|
|
eaExpert.AddOnStopLossEventHandler(OnStopLossTriggered);
|
|
eaExpert.AddOnOrdersChangedEventHandler(OnOrdersChanged);
|
|
eaExpert.AddOnTakeProfitEventHandler(OnTakeProfitTriggered);
|
|
eaExpert.AddOnModifyPositionEventHandler(OnPositionModified);
|
|
eaExpert.AddOnPositionsChangedEventHandler(OnPositionsChanged);
|
|
eaExpert.AddOnTradeStateChangedEventHandler(OnTradeStateChanged);
|
|
eaExpert.AddOnForceClosePositionEventHandler(OnPositionForceClosed);
|
|
eaExpert.AddOnPartialClosePositionEventHandler(OnPositionPartialClosed);
|
|
|
|
//
|
|
// Configure Other Requirements ...
|
|
eaExpert.allowedTPSLStep = 10;
|
|
eaExpert.minAllowedRiskInPoint = 20;
|
|
eaExpert.volume = eaSignallerVolume;
|
|
eaExpert.riskToRewardRatio = eaSignallerR2R;
|
|
eaExpert.riskInPoint = eaSignallerRiskInPoint;
|
|
|
|
//
|
|
// Try to Initialize eaExpert ...
|
|
bool isInited = eaExpert.HandleOnInit();
|
|
if (!isInited)
|
|
{
|
|
//
|
|
Print(ShortName, ": Initialization Failed ...");
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
//
|
|
// Here Instantiate Signaller Class ...
|
|
|
|
//
|
|
// Preparing Indicator Inputs ...
|
|
XFIMAInputs fimaInputs;
|
|
|
|
//
|
|
// This is Default Configuration ...
|
|
fimaInputs.Default();
|
|
fimaInputs.Hide();
|
|
|
|
//
|
|
// Here we Attach Inputs to Indicator ...
|
|
fimaInputs.scMethod = scMethod;
|
|
fimaInputs.scPeriod = scPeriod;
|
|
fimaInputs.mcMethod = mcMethod;
|
|
fimaInputs.mcPeriod = mcPeriod;
|
|
fimaInputs.lcMethod = lcMethod;
|
|
fimaInputs.lcPeriod = lcPeriod;
|
|
fimaInputs.hcMethod = hcMethod;
|
|
fimaInputs.hcPeriod = hcPeriod;
|
|
fimaInputs.upperMode = upperMode;
|
|
fimaInputs.lowerMode = lowerMode;
|
|
fimaInputs.fiboUpperZoneLevel = fiboUpperZoneLevel;
|
|
fimaInputs.fiboMiddleZoneLevel = fiboMiddleZoneLevel;
|
|
fimaInputs.fiboLowerZoneLevel = fiboLowerZoneLevel;
|
|
fimaInputs.sarStep = sarStep;
|
|
fimaInputs.sarMax = sarMax;
|
|
fimaInputs.maMethod = maMethod;
|
|
fimaInputs.maAppliedTo = maAppliedTo;
|
|
fimaInputs.maFastLength = maFastLength;
|
|
fimaInputs.maSlowLength = maSlowLength;
|
|
fimaInputs.maBandLength = maBandLength;
|
|
fimaInputs.zigzagDepth = zigzagDepth;
|
|
fimaInputs.zigzagDeviation = zigzagDeviation;
|
|
fimaInputs.zigzagBackStep = zigzagBackStep;
|
|
fimaInputs.zigzagUppersMode = zigzagUppersMode;
|
|
fimaInputs.zigzagLowersMode = zigzagLowersMode;
|
|
fimaInputs.showPV = showPV;
|
|
fimaInputs.showHK = showHK;
|
|
fimaInputs.showSAR = showSAR;
|
|
fimaInputs.showMAFast = showMAFast;
|
|
fimaInputs.showMASlow = showMASlow;
|
|
fimaInputs.showMABand = showMABand;
|
|
fimaInputs.showZigZag = showZigZag;
|
|
fimaInputs.showFiboZone = showFiboZone;
|
|
fimaInputs.startCalculationForLastBars = startCalculationForLastBars;
|
|
fimaInputs.sarArrowCode = sarArrowCode;
|
|
fimaInputs.peakArrowCode = peakArrowCode;
|
|
fimaInputs.valeArrowCode = valeArrowCode;
|
|
|
|
//
|
|
// Instantiate Signaller ...
|
|
|
|
//
|
|
// XFIMA1 Signaller ...
|
|
fima1Signaller = new XCXFIMAStrategy1Signaller(
|
|
_Symbol,
|
|
_Period,
|
|
fimaInputs,
|
|
eaProcessAllTicks, // Process All Ticks ...
|
|
eaSignallerR2R, // Signaller Risk to Reward Ratio ...
|
|
eaSignallerRiskInPoint, // Default Risk In Points ...
|
|
eaSignallerVolume // Defaul Volume ...
|
|
);
|
|
fima1Signaller.AddOnSignalEventHandler(OnSignalTriggered);
|
|
|
|
//
|
|
isInited =
|
|
fima1Signaller.IsValid();
|
|
if (!isInited)
|
|
{
|
|
//
|
|
Print(ShortName, ": Initialization Failed ...");
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
//
|
|
// Initialize Candle Timer Handler ...
|
|
eaCTHandler = iCustom(
|
|
_Symbol,
|
|
_Period,
|
|
"x-saherelm.x121.xct",
|
|
//
|
|
// Inputs ...
|
|
barTimeFontSize, // Font Size ...
|
|
barTimeFont, // Font ...
|
|
barTimeColor, // Text Color ...
|
|
barTimeCorner, // Text Position ...
|
|
//
|
|
// Presentation ...
|
|
"",
|
|
showBarTime // Show Candle Time
|
|
//
|
|
);
|
|
isInited = eaCTHandler != INVALID_HANDLE;
|
|
if (!isInited)
|
|
{
|
|
//
|
|
Print(ShortName, ": Initialization Failed ...");
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
//
|
|
// Initialize Bar Tracker ...
|
|
isInited = eaBarTracker.Init(
|
|
_Symbol,
|
|
_Period //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
//
|
|
Print(ShortName, ": Initialization Failed ...");
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
//
|
|
// Configure XFIMA POI Detector / Drawer ...
|
|
detectorConfig.Default();
|
|
detectorConfig.FullDetect();
|
|
marketStructureDrawerConfig.FullDraw();
|
|
|
|
//
|
|
Print(ShortName, ": Initialized Successfully ...");
|
|
return INIT_SUCCEEDED;
|
|
}
|
|
|
|
//
|
|
// DeInitialization ...
|
|
void OnDeinit(const int reason)
|
|
{
|
|
//
|
|
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
|
// REASON_REMOVE 1 Program removed from a chart
|
|
// REASON_RECOMPILE 2 Program recompiled
|
|
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
|
// REASON_CHARTCLOSE 4 Chart closed
|
|
// REASON_PARAMETERS 5 Inputs changed by a user
|
|
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
|
// REASON_TEMPLATE 7 Another chart template applied
|
|
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
|
// REASON_CLOSE 9 Terminal closed
|
|
|
|
//
|
|
// Destroy Timer ...
|
|
eaExpert.HandleOnDeInit();
|
|
|
|
//
|
|
// De Init Indicator ...
|
|
IndicatorRelease(eaCTHandler);
|
|
|
|
//
|
|
eaBarTracker.Clean();
|
|
|
|
//
|
|
delete fima1Signaller;
|
|
ZeroMemory(fima1Signaller);
|
|
|
|
//
|
|
delete eaExpert;
|
|
ZeroMemory(eaExpert);
|
|
}
|
|
|
|
//
|
|
// On Tick Handler ...
|
|
void OnTick()
|
|
{
|
|
//
|
|
eaIsNewBar = eaBarTracker.IsNewBar();
|
|
bool canProcess = eaProcessAllTicks
|
|
? true
|
|
: eaIsNewBar;
|
|
//
|
|
eaExpert.HandleOnTick();
|
|
|
|
//
|
|
if (!canProcess)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Bar Index ...
|
|
int barIndex = 1;
|
|
|
|
//
|
|
fima1Signaller.OnTick(barIndex);
|
|
|
|
//
|
|
// AnalyseMarket(barIndex);
|
|
}
|
|
|
|
//
|
|
// Handle On Trade Event ...
|
|
void OnTrade()
|
|
{
|
|
eaExpert.HandleOnTrade();
|
|
}
|
|
|
|
//
|
|
// On Timer ...
|
|
void OnTimer()
|
|
{
|
|
eaExpert.HandleOnTimer();
|
|
}
|
|
|
|
//
|
|
// Chart Event Handler ...
|
|
void OnChartEvent(
|
|
const int id,
|
|
const long &lparam,
|
|
const double &dparam,
|
|
const string &sparam //
|
|
)
|
|
{
|
|
eaExpert.HandleOnChartEvent(id, lparam, dparam, sparam);
|
|
}
|
|
|
|
//
|
|
// Custom Functions ...
|
|
|
|
/**
|
|
* Validate all Inputs of Expert Adviser ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool ValidateInputs()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
string errMessage = "";
|
|
|
|
//
|
|
bool isCommonValid = (
|
|
//
|
|
eaSlippage > 0 &&
|
|
eaMagicNumber > 0 &&
|
|
//
|
|
// Indicator Inputs ...
|
|
//
|
|
// MA ...
|
|
maFastLength >= 2 &&
|
|
maSlowLength >= 2 &&
|
|
maSlowLength > maFastLength &&
|
|
//
|
|
// SAR ...
|
|
sarMax > 0 &&
|
|
sarStep > 0 &&
|
|
sarMax > sarStep &&
|
|
//
|
|
// CYCLES ...
|
|
(IsValid(scMethod, scPeriod) &&
|
|
IsValid(mcMethod, mcPeriod) &&
|
|
IsValid(lcMethod, lcPeriod) &&
|
|
IsValid(hcMethod, hcPeriod)) &&
|
|
//
|
|
// ZIGZAG ...
|
|
zigzagDepth > 0 &&
|
|
zigzagDeviation > 0 &&
|
|
zigzagBackStep > 0 &&
|
|
//
|
|
// Validate Upper Mode Detection ...
|
|
IsXValid(zigzagUppersMode) &&
|
|
//
|
|
// Validate Lower Mode Detection ...
|
|
IsXValid(zigzagLowersMode)
|
|
//
|
|
);
|
|
if (!isCommonValid)
|
|
{
|
|
//
|
|
errMessage += "common configurations error;" + "\n";
|
|
}
|
|
|
|
//
|
|
result =
|
|
//
|
|
// Common ...
|
|
isCommonValid &&
|
|
//
|
|
// Otere ...
|
|
true
|
|
//
|
|
;
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
//
|
|
// Since here Logger not Initiallized, we Use Raw Print Command ...
|
|
Print(ShortName + " Errors: \n", errMessage);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Initialize Timer ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool InitTimer()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// TODO: Initialize Timer if necessary ...
|
|
// result = EventSetTimer(1);
|
|
// result = EventSetMillisecondTimer(100);
|
|
result = true;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Destroy Timer ...
|
|
*/
|
|
void DestroyTimer()
|
|
{
|
|
//
|
|
// TODO: Use This ...
|
|
// EventKillTimer();
|
|
}
|
|
|
|
/**
|
|
* Trigger OnSignal Event ...
|
|
*
|
|
* @param signal: XSignal
|
|
*/
|
|
void OnSignalTriggered(XSignal &signal)
|
|
{
|
|
//
|
|
// Validate Signal ...
|
|
if (!signal.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// TODO: Fix this ...
|
|
// return;
|
|
|
|
//
|
|
// Draw Signal on Chart ...
|
|
XCSignalObject *iSignalObj;
|
|
bool has = fima1Signaller.poiDrawer.DrawSignal(
|
|
signal,
|
|
iSignalObj,
|
|
7 //
|
|
);
|
|
|
|
//
|
|
if (has)
|
|
{
|
|
//
|
|
ENUM_X_SIGNAL_EXECUTION_RESULT result;
|
|
eaExpert.eaTrader.ExecuteSignal(
|
|
signal,
|
|
result //
|
|
);
|
|
|
|
//
|
|
Print("Signal Issued: ", signal.GetObjectID());
|
|
}
|
|
|
|
//
|
|
// Try to Execute Signal ...
|
|
|
|
//
|
|
// Draw Signal Vertical Line ...
|
|
|
|
// //
|
|
// CChartObjectVLine *iObj = new CChartObjectVLine();
|
|
|
|
// //
|
|
// string iName = signal.GetObjectID();
|
|
// color iColor = IsLong(signal.type) ? clrLime : clrRed;
|
|
|
|
// //
|
|
// bool has = iObj.Create(
|
|
// fima2Signaller.poiDrawer.ChartIdentification(),
|
|
// iName,
|
|
// fima2Signaller.poiDrawer.SubWindowIdentification(),
|
|
// signal.time //
|
|
// );
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// iObj.Width(2);
|
|
// iObj.Color(iColor);
|
|
|
|
// //
|
|
// // eaDraws.Add(iObj);
|
|
// }
|
|
|
|
// //
|
|
// // Alert Issued Signal ...
|
|
// string message = signal.GetMessage();
|
|
|
|
//
|
|
// int signalBarIndex = GetBarIndex(
|
|
// signal.symbol,
|
|
// signal.period,
|
|
// signal.time //
|
|
// );
|
|
// AnalyseMarket(signalBarIndex);
|
|
}
|
|
|
|
//
|
|
// Trade Event Handlers ...
|
|
|
|
/**
|
|
* Handle StopLoss Triggered Positions ...
|
|
*
|
|
* @param deal: XDeal instance ...
|
|
*/
|
|
void OnStopLossTriggered(const XDeal &deal)
|
|
{
|
|
eaExpert.HandleOnStopLossTriggered(deal);
|
|
}
|
|
|
|
/**
|
|
* Handle Take Profit Triggered Positions ...
|
|
*
|
|
* @param deal: XDeal instance ...
|
|
*/
|
|
void OnTakeProfitTriggered(const XDeal &deal)
|
|
{
|
|
eaExpert.HandleOnTakeProfitTriggered(deal);
|
|
}
|
|
|
|
/**
|
|
* Handle Force Close a Position ...
|
|
*
|
|
* @param ticket: ULONG ...
|
|
* @param position: XPosition instance ...
|
|
* @param comment: String ...
|
|
*/
|
|
void OnPositionForceClosed(
|
|
const ulong ticket,
|
|
const XPosition &position,
|
|
const string comment //
|
|
)
|
|
{
|
|
//
|
|
eaExpert.HandleOnPositionForceClosed(
|
|
ticket,
|
|
position,
|
|
comment //
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Handle Deals Changes ...
|
|
*
|
|
* @param count: Integer, Number of Changes ...
|
|
*/
|
|
void OnDealsChanged(int count)
|
|
{
|
|
eaExpert.HandleOnDealsChanged(count);
|
|
}
|
|
|
|
/**
|
|
* Handle Orders Changes ...
|
|
*
|
|
* @param count: Integer, Number of Changes ...
|
|
*/
|
|
void OnOrdersChanged(int count)
|
|
{
|
|
eaExpert.HandleOnOrdersChanged(count);
|
|
}
|
|
|
|
/**
|
|
* Handle Positions Changes ...
|
|
*
|
|
* @param count: Integer, Number of Changes ...
|
|
*/
|
|
void OnPositionsChanged(int count)
|
|
{
|
|
eaExpert.HandleOnPositionsChanged(count);
|
|
}
|
|
|
|
/**
|
|
* Handle Position Modified ...
|
|
*
|
|
* @param ticket: ulong, Position Ticket ...
|
|
* @param profit: double, Position Profit ...
|
|
* @param comment: string, Comment ...
|
|
*/
|
|
void OnPositionModified(
|
|
const ulong ticket,
|
|
const double profit,
|
|
const string comment //
|
|
)
|
|
{
|
|
//
|
|
eaExpert.HandleOnPositionModified(
|
|
ticket,
|
|
profit,
|
|
comment //
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Handle Position Partial Closed ...
|
|
*
|
|
* @param ticket: ulong, Position Ticket ...
|
|
* @param profit: double, Position Profit ...
|
|
* @param comment: string, Comment ...
|
|
*/
|
|
void OnPositionPartialClosed(
|
|
const ulong ticket,
|
|
const double profit,
|
|
const string comment //
|
|
)
|
|
{
|
|
//
|
|
eaExpert.HandleOnPositionPartialClosed(
|
|
ticket,
|
|
profit,
|
|
comment //
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Handle Trade State Changed ...
|
|
*
|
|
* @param state: XOnTradeHandlerState instance ...
|
|
*/
|
|
void OnTradeStateChanged(const XOnTradeHandlerState &state)
|
|
{
|
|
eaExpert.HandleOnTradeStateChanged(state);
|
|
}
|
|
|
|
//
|
|
void AnalyseMarket(int barIndex = 0)
|
|
{
|
|
//
|
|
bool has = false;
|
|
|
|
//
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
|
|
//
|
|
string symbol = fima1Signaller.symbol;
|
|
ENUM_TIMEFRAMES period = fima1Signaller.period;
|
|
|
|
//
|
|
// Retrieve Signal Bar ...
|
|
XOHCL bar;
|
|
has = bar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
if (!has)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
return;
|
|
}
|
|
|
|
//
|
|
// TODO: Remove this and add in OnInit() Method ...
|
|
|
|
//
|
|
// Configuring Detector ...
|
|
|
|
//
|
|
detectorConfig.detectOB = true;
|
|
detectorConfig.detectFVG = true;
|
|
|
|
//
|
|
detectorConfig.detectSupport = true;
|
|
detectorConfig.detectResistance = true;
|
|
detectorConfig.detectSwingTrend = true;
|
|
|
|
//
|
|
detectorConfig.detectPinned = true;
|
|
detectorConfig.detectMomentum = true;
|
|
detectorConfig.detectEngulfed = true;
|
|
detectorConfig.detectTrueGaped = true;
|
|
|
|
//
|
|
detectorConfig.detectStarPattern = true;
|
|
detectorConfig.detectFlagPattern = true;
|
|
detectorConfig.detectRisingPattern = true;
|
|
detectorConfig.detectPiercingPattern = true;
|
|
detectorConfig.detectSignalKeyBarPattern = true;
|
|
|
|
//
|
|
detectorConfig.analyseFIMAPVPivots = true;
|
|
detectorConfig.analyseFIMASARPivots = false;
|
|
detectorConfig.analyseFIMAZigZagPivots = true;
|
|
|
|
//
|
|
// Configure Drawer ...
|
|
|
|
//
|
|
marketStructureDrawerConfig.drawOB = false;
|
|
marketStructureDrawerConfig.drawFVG = false;
|
|
|
|
//
|
|
marketStructureDrawerConfig.drawPinned = false;
|
|
marketStructureDrawerConfig.drawEngulfed = true;
|
|
marketStructureDrawerConfig.drawTrueGaped = false;
|
|
marketStructureDrawerConfig.drawMomentum = false;
|
|
marketStructureDrawerConfig.drawFlagPattern = false;
|
|
marketStructureDrawerConfig.drawStarPattern = false;
|
|
marketStructureDrawerConfig.drawRisingPattern = false;
|
|
marketStructureDrawerConfig.drawPiercingPattern = false;
|
|
marketStructureDrawerConfig.drawSignalKeyBarPattern = true;
|
|
|
|
//
|
|
// Recents ...
|
|
marketStructureDrawerConfig.drawRecentPatterns = false;
|
|
marketStructureDrawerConfig.drawFakeBreakedZone = false;
|
|
marketStructureDrawerConfig.drawRecentlyTestedZones = false;
|
|
marketStructureDrawerConfig.drawRecentlyBreakedZones = false;
|
|
|
|
//
|
|
// XPV ...
|
|
marketStructureDrawerConfig.drawFIMAPVPivotsAnalysis = true;
|
|
marketStructureDrawerConfig.drawFIMAPVPivotsAnalysisZones = true;
|
|
marketStructureDrawerConfig.drawFIMAPVPivotsAnalysisTrends = true;
|
|
marketStructureDrawerConfig.drawFIMAPVPivotsAnalysisPivots = true;
|
|
|
|
//
|
|
// XSAR ...
|
|
marketStructureDrawerConfig.drawFIMASARPivotsAnalysis = false;
|
|
marketStructureDrawerConfig.drawFIMASARPivotsAnalysisZones = false;
|
|
marketStructureDrawerConfig.drawFIMASARPivotsAnalysisTrends = false;
|
|
marketStructureDrawerConfig.drawFIMASARPivotsAnalysisPivots = false;
|
|
|
|
//
|
|
// XZigZag ...
|
|
marketStructureDrawerConfig.drawFIMAZigZagPivotsAnalysis = true;
|
|
marketStructureDrawerConfig.drawFIMAZigZagPivotsAnalysisZones = true;
|
|
marketStructureDrawerConfig.drawFIMAZigZagPivotsAnalysisTrends = false;
|
|
marketStructureDrawerConfig.drawFIMAZigZagPivotsAnalysisPivots = false;
|
|
|
|
//
|
|
// Analyse Market on Signalling Bar ...
|
|
fima1Signaller.poiDetector.AnalyseMarket(
|
|
bar,
|
|
marketStructure,
|
|
detectorConfig //
|
|
);
|
|
|
|
//
|
|
XFIMASIgballer2First(bar);
|
|
// HandleLookupSignal(bar);
|
|
|
|
//
|
|
bar.Clean();
|
|
}
|
|
|
|
//
|
|
// Handle Signal Looking Up ...
|
|
// Register it as XFIMA Signaller 2 ...
|
|
void XFIMASIgballer2First(XOHCL &bar)
|
|
{
|
|
//
|
|
bool has =
|
|
bar.IsValid();
|
|
if (!has)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
XBoxZone iZone;
|
|
XSignal iSignal;
|
|
string iName = NULL;
|
|
XBoxZone supports[];
|
|
XBoxZone resistances[];
|
|
bool isBullish = false;
|
|
int barIndex = bar.Index();
|
|
double iPrice = EMPTY_VALUE;
|
|
ENUM_X_PRICE iPriceType = X_PRICE_NONE;
|
|
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Check Required Pattern Exists ...
|
|
bool hasPinnedBar = HasDirection(marketStructure.pinnedDir);
|
|
bool hasEngulfedBar = HasDirection(marketStructure.engulfedDir);
|
|
bool hasFlagPattern = HasDirection(marketStructure.flagPatternDir);
|
|
bool hasStarPattern = HasDirection(marketStructure.starPatternDir);
|
|
bool hasRisingPattern = HasDirection(marketStructure.risingPatternDir);
|
|
bool hasPiercingPattern = HasDirection(marketStructure.piercingPatternDir);
|
|
bool hasSignalKeyBar = HasDirection(marketStructure.signalKeyBarPatternDir);
|
|
|
|
//
|
|
// PV Trend Line ...
|
|
string pvTrendName = "XPVTrend";
|
|
CChartObjectTrend *pvTrendLine = NULL;
|
|
ENUM_X_DIRECTION pvTrend = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// ZigZag Trend Line ...
|
|
string zgTrendName = "XZGTrend";
|
|
CChartObjectTrend *zgTrendLine = NULL;
|
|
ENUM_X_DIRECTION zgTrend = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Check PV Analysis ...
|
|
bool hasPVAnalysis = marketStructure.pvAnalysis.IsValid();
|
|
if (hasPVAnalysis)
|
|
{
|
|
//
|
|
// Support ...
|
|
XBoxZone supportBox;
|
|
XCBoxObject *iSupportObj;
|
|
has = marketStructure.pvAnalysis.HasSupportBox(supportBox);
|
|
if (has)
|
|
{
|
|
//
|
|
supportBox.to = bar.time;
|
|
AddIfNotExists(
|
|
supportBox,
|
|
supports //
|
|
);
|
|
has = fima2Signaller.poiDrawer.DrawBox(
|
|
supportBox,
|
|
iSupportObj,
|
|
true, // Ignore At ...
|
|
supportBox.type // Name ...
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
XPOIStyle iStyle;
|
|
fima2Signaller.poiDrawer.GetBoxStyle(
|
|
iStyle,
|
|
supportBox.dir //
|
|
);
|
|
fima2Signaller.poiDrawer.ApplyBoxStyle(
|
|
iSupportObj,
|
|
iStyle //
|
|
);
|
|
iStyle.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Resistance ...
|
|
XBoxZone resistanceBox;
|
|
XCBoxObject *iResistanceObj;
|
|
has = marketStructure.pvAnalysis.HasResistanceBox(resistanceBox);
|
|
if (has)
|
|
{
|
|
//
|
|
resistanceBox.to = bar.time;
|
|
AddIfNotExists(
|
|
resistanceBox,
|
|
supports //
|
|
);
|
|
has = fima2Signaller.poiDrawer.DrawBox(
|
|
resistanceBox,
|
|
iResistanceObj,
|
|
true, // Ignore At ...
|
|
resistanceBox.type // Name ...
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
XPOIStyle iStyle;
|
|
fima2Signaller.poiDrawer.GetBoxStyle(
|
|
iStyle,
|
|
resistanceBox.dir //
|
|
);
|
|
fima2Signaller.poiDrawer.ApplyBoxStyle(
|
|
iResistanceObj,
|
|
iStyle //
|
|
);
|
|
iStyle.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Pivots ...
|
|
XPivot pivots[];
|
|
int pivotsCount = fima2Signaller.poiDetector.ExtractPVPivots(
|
|
pivots,
|
|
barIndex,
|
|
50 //
|
|
);
|
|
has = IsValidSize(pivotsCount);
|
|
|
|
//
|
|
// Sort ...
|
|
Sort(
|
|
pivots,
|
|
X_SORT_BY_DATE,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
|
|
//
|
|
// Remove Newest ...
|
|
ArrayRemove(
|
|
pivots,
|
|
0,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
// Check Trend ...
|
|
if (has)
|
|
{
|
|
//
|
|
XPivot highs[];
|
|
int highsCount = ExtractPivots(
|
|
highs,
|
|
pivots,
|
|
X_PIVOT_TYPE_PEAK //
|
|
);
|
|
Sort(
|
|
highs,
|
|
X_SORT_BY_DATE,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
|
|
//
|
|
XPivot lows[];
|
|
int lowsCount = ExtractPivots(
|
|
lows,
|
|
pivots,
|
|
X_PIVOT_TYPE_VALE //
|
|
);
|
|
Sort(
|
|
lows,
|
|
X_SORT_BY_DATE,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
|
|
//
|
|
// Check Highs and Lows ...
|
|
has = IsValidSize(lowsCount) &&
|
|
IsValidSize(highsCount) &&
|
|
lowsCount >= 2 &&
|
|
highsCount >= 2;
|
|
if (has)
|
|
{
|
|
//
|
|
// Try to Get Market Strucutre ...
|
|
|
|
//
|
|
bool hasLowerHigh = highs[0].value < highs[1].value;
|
|
bool hasLowerLow = lows[0].value < lows[1].value;
|
|
|
|
//
|
|
bool hasHigherHigh = highs[0].value > highs[1].value;
|
|
bool hasHigherLow = lows[0].value > lows[1].value;
|
|
|
|
//
|
|
pvTrend =
|
|
(hasHigherHigh &&
|
|
hasHigherLow)
|
|
? X_DIRECTION_BULLISH
|
|
: (hasLowerHigh &&
|
|
hasLowerLow)
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
has = HasDirection(pvTrend);
|
|
if (has)
|
|
{
|
|
//
|
|
// Select Swings for Trend Line ...
|
|
XOHCL tmpBar;
|
|
int llIDX = -1;
|
|
int hhIDX = -1;
|
|
datetime toTime = NULL;
|
|
datetime fromTime = NULL;
|
|
double toPrice = EMPTY_VALUE;
|
|
color trendColor = CLR_NONE;
|
|
double fromPrice = EMPTY_VALUE;
|
|
if (IsSpecifiedBullish(pvTrend))
|
|
{
|
|
//
|
|
llIDX = GetLowest(lows);
|
|
hhIDX = GetHighest(lows);
|
|
|
|
//
|
|
trendColor = clrAqua;
|
|
|
|
//
|
|
toTime = lows[hhIDX].time;
|
|
toPrice = lows[hhIDX].value;
|
|
|
|
//
|
|
fromTime = lows[llIDX].time;
|
|
fromPrice = lows[llIDX].value;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
llIDX = GetLowest(highs);
|
|
hhIDX = GetHighest(highs);
|
|
|
|
//
|
|
trendColor = clrMagenta;
|
|
|
|
//
|
|
toTime = highs[llIDX].time;
|
|
toPrice = highs[llIDX].value;
|
|
|
|
//
|
|
fromTime = highs[hhIDX].time;
|
|
fromPrice = highs[hhIDX].value;
|
|
}
|
|
|
|
//
|
|
// Check Requirements for Trend ...
|
|
has =
|
|
NotEmptyZero(toPrice) &&
|
|
NotEmptyZero(fromPrice) &&
|
|
IsSpecifiedValid(toTime) &&
|
|
IsSpecifiedValid(fromTime);
|
|
if (has)
|
|
{
|
|
//
|
|
has = fima2Signaller.poiDrawer.DrawTrendLine(
|
|
fromPrice,
|
|
fromTime,
|
|
toPrice,
|
|
toTime,
|
|
pvTrendLine,
|
|
pvTrendName,
|
|
true // Ray Right ...
|
|
);
|
|
if (has)
|
|
{
|
|
pvTrendLine.Color(trendColor);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
tmpBar.Clean();
|
|
}
|
|
|
|
//
|
|
if (!has)
|
|
{
|
|
SpecifiedClean(pivots);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
SpecifiedClean(lows);
|
|
SpecifiedClean(highs);
|
|
}
|
|
|
|
//
|
|
// Draw Pivots ...
|
|
has = HasChild(pivots);
|
|
if (has)
|
|
{
|
|
//
|
|
CArrayObj *drawnPivots = new CArrayObj();
|
|
pivotsCount = fima2Signaller.poiDrawer.DrawPivots(
|
|
pivots,
|
|
drawnPivots //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
SpecifiedClean(pivots);
|
|
}
|
|
|
|
//
|
|
// Check ZigZag Analysis ...
|
|
bool hasZGAnalysis = marketStructure.zigzagAnalysis.IsValid();
|
|
if (hasZGAnalysis)
|
|
{
|
|
//
|
|
// Support ...
|
|
XBoxZone supportBox;
|
|
XCBoxObject *iSupportObj;
|
|
has = marketStructure.zigzagAnalysis.HasSupportBox(supportBox);
|
|
if (has)
|
|
{
|
|
//
|
|
supportBox.to = bar.time;
|
|
AddIfNotExists(
|
|
supportBox,
|
|
supports //
|
|
);
|
|
has = fima2Signaller.poiDrawer.DrawBox(
|
|
supportBox,
|
|
iSupportObj,
|
|
true, // Ignore At ...
|
|
supportBox.type // Name ...
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
XPOIStyle iStyle;
|
|
fima2Signaller.poiDrawer.GetBoxStyle(
|
|
iStyle,
|
|
supportBox.dir //
|
|
);
|
|
fima2Signaller.poiDrawer.ApplyBoxStyle(
|
|
iSupportObj,
|
|
iStyle //
|
|
);
|
|
iStyle.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Resistance ...
|
|
XBoxZone resistanceBox;
|
|
XCBoxObject *iResistanceObj;
|
|
has = marketStructure.zigzagAnalysis.HasResistanceBox(resistanceBox);
|
|
if (has)
|
|
{
|
|
//
|
|
resistanceBox.to = bar.time;
|
|
AddIfNotExists(
|
|
resistanceBox,
|
|
supports //
|
|
);
|
|
has = fima2Signaller.poiDrawer.DrawBox(
|
|
resistanceBox,
|
|
iResistanceObj,
|
|
true, // Ignore At ...
|
|
resistanceBox.type // Name ...
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
XPOIStyle iStyle;
|
|
fima2Signaller.poiDrawer.GetBoxStyle(
|
|
iStyle,
|
|
resistanceBox.dir //
|
|
);
|
|
fima2Signaller.poiDrawer.ApplyBoxStyle(
|
|
iResistanceObj,
|
|
iStyle //
|
|
);
|
|
iStyle.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Pivots ...
|
|
XPivot pivots[];
|
|
int pivotsCount = fima2Signaller.poiDetector.ExtractZigZagPivots(
|
|
pivots,
|
|
barIndex,
|
|
10 //
|
|
);
|
|
has = IsValidSize(pivotsCount);
|
|
|
|
//
|
|
// Sort ...
|
|
Sort(
|
|
pivots,
|
|
X_SORT_BY_DATE,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
|
|
//
|
|
// Remove Newest ...
|
|
ArrayRemove(
|
|
pivots,
|
|
0,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
// Check Trend ...
|
|
if (has)
|
|
{
|
|
//
|
|
XPivot highs[];
|
|
int highsCount = ExtractPivots(
|
|
highs,
|
|
pivots,
|
|
X_PIVOT_TYPE_PEAK //
|
|
);
|
|
Sort(
|
|
highs,
|
|
X_SORT_BY_DATE,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
|
|
//
|
|
XPivot lows[];
|
|
int lowsCount = ExtractPivots(
|
|
lows,
|
|
pivots,
|
|
X_PIVOT_TYPE_VALE //
|
|
);
|
|
Sort(
|
|
lows,
|
|
X_SORT_BY_DATE,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
|
|
//
|
|
// Check Highs and Lows ...
|
|
has = IsValidSize(lowsCount) &&
|
|
IsValidSize(highsCount) &&
|
|
lowsCount >= 2 &&
|
|
highsCount >= 2;
|
|
if (has)
|
|
{
|
|
//
|
|
// Try to Get Market Strucutre ...
|
|
|
|
//
|
|
bool hasLowerHigh = highs[0].value < highs[1].value;
|
|
bool hasLowerLow = lows[0].value < lows[1].value;
|
|
|
|
//
|
|
bool hasHigherHigh = highs[0].value > highs[1].value;
|
|
bool hasHigherLow = lows[0].value > lows[1].value;
|
|
|
|
//
|
|
zgTrend =
|
|
(hasHigherHigh &&
|
|
hasHigherLow)
|
|
? X_DIRECTION_BULLISH
|
|
: (hasLowerHigh &&
|
|
hasLowerLow)
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
has = HasDirection(zgTrend);
|
|
if (has)
|
|
{
|
|
//
|
|
// Select Swings for Trend Line ...
|
|
XOHCL tmpBar;
|
|
int llIDX = -1;
|
|
int hhIDX = -1;
|
|
datetime toTime = NULL;
|
|
datetime fromTime = NULL;
|
|
double toPrice = EMPTY_VALUE;
|
|
color trendColor = CLR_NONE;
|
|
double fromPrice = EMPTY_VALUE;
|
|
if (IsSpecifiedBullish(zgTrend))
|
|
{
|
|
//
|
|
llIDX = GetLowest(lows);
|
|
hhIDX = GetHighest(lows);
|
|
|
|
//
|
|
trendColor = clrAqua;
|
|
|
|
//
|
|
toTime = lows[hhIDX].time;
|
|
toPrice = lows[hhIDX].value;
|
|
|
|
//
|
|
fromTime = lows[llIDX].time;
|
|
fromPrice = lows[llIDX].value;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
llIDX = GetLowest(highs);
|
|
hhIDX = GetHighest(highs);
|
|
|
|
//
|
|
trendColor = clrMagenta;
|
|
|
|
//
|
|
toTime = highs[llIDX].time;
|
|
toPrice = highs[llIDX].value;
|
|
|
|
//
|
|
fromTime = highs[hhIDX].time;
|
|
fromPrice = highs[hhIDX].value;
|
|
}
|
|
|
|
//
|
|
// Check Requirements for Trend ...
|
|
has =
|
|
NotEmptyZero(toPrice) &&
|
|
NotEmptyZero(fromPrice) &&
|
|
IsSpecifiedValid(toTime) &&
|
|
IsSpecifiedValid(fromTime);
|
|
if (has)
|
|
{
|
|
//
|
|
has = fima2Signaller.poiDrawer.DrawTrendLine(
|
|
fromPrice,
|
|
fromTime,
|
|
toPrice,
|
|
toTime,
|
|
zgTrendLine,
|
|
zgTrendName,
|
|
true // Ray Right ...
|
|
);
|
|
if (has)
|
|
{
|
|
zgTrendLine.Color(trendColor);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
tmpBar.Clean();
|
|
}
|
|
|
|
//
|
|
if (!has)
|
|
{
|
|
SpecifiedClean(pivots);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
SpecifiedClean(lows);
|
|
SpecifiedClean(highs);
|
|
}
|
|
|
|
//
|
|
// Draw Pivots ...
|
|
has = HasChild(pivots);
|
|
if (has)
|
|
{
|
|
//
|
|
CArrayObj *drawnPivots = new CArrayObj();
|
|
pivotsCount = fima2Signaller.poiDrawer.DrawPivots(
|
|
pivots,
|
|
drawnPivots //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
SpecifiedClean(pivots);
|
|
}
|
|
|
|
//
|
|
// Support ...
|
|
bool hasSupport = marketStructure.support.IsValid();
|
|
if (hasSupport)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
marketStructure.support,
|
|
supports //
|
|
);
|
|
|
|
//
|
|
XCBoxObject *iObj;
|
|
has = fima2Signaller.poiDrawer.DrawBox(
|
|
marketStructure.support,
|
|
iObj);
|
|
if (has)
|
|
{
|
|
}
|
|
}
|
|
|
|
//
|
|
// Resistance ...
|
|
bool hasResistance = marketStructure.resistance.IsValid();
|
|
if (hasResistance)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
marketStructure.resistance,
|
|
resistances //
|
|
);
|
|
|
|
//
|
|
XCBoxObject *iObj;
|
|
has = fima2Signaller.poiDrawer.DrawBox(
|
|
marketStructure.resistance,
|
|
iObj);
|
|
if (has)
|
|
{
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Bar Pattern Exists ...
|
|
has = hasPinnedBar ||
|
|
hasEngulfedBar ||
|
|
hasFlagPattern ||
|
|
hasStarPattern ||
|
|
hasSignalKeyBar ||
|
|
hasRisingPattern ||
|
|
hasPiercingPattern;
|
|
|
|
//
|
|
// Select Pattern Direction and Price and Price Type ...
|
|
if (has)
|
|
{
|
|
//
|
|
if (hasPinnedBar)
|
|
{
|
|
//
|
|
iDir = marketStructure.pinnedDir;
|
|
iName = "pinned" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
|
|
}
|
|
else if (hasEngulfedBar)
|
|
{
|
|
//
|
|
iDir = marketStructure.engulfedDir;
|
|
iName = "engulfed" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
|
|
}
|
|
else if (hasFlagPattern)
|
|
{
|
|
//
|
|
iDir = marketStructure.flagPatternDir;
|
|
iName = "flagPattern" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
|
|
}
|
|
else if (hasStarPattern)
|
|
{
|
|
//
|
|
iDir = marketStructure.starPatternDir;
|
|
iName = "starPattern" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
|
|
}
|
|
else if (hasSignalKeyBar)
|
|
{
|
|
//
|
|
iDir = marketStructure.risingPatternDir;
|
|
iName = "risingPattern" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
|
|
}
|
|
else if (hasRisingPattern)
|
|
{
|
|
//
|
|
iDir = marketStructure.piercingPatternDir;
|
|
iName = "piercingPattern" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
|
|
}
|
|
else if (hasPiercingPattern)
|
|
{
|
|
//
|
|
iDir = marketStructure.signalKeyBarPatternDir;
|
|
iName = "signalKeyBarPattern" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
|
|
}
|
|
|
|
//
|
|
isBullish = IsSpecifiedBullish(iDir);
|
|
|
|
//
|
|
// Retrieve Price Type for Validate ...
|
|
iPriceType = isBullish
|
|
? X_PRICE_LOW
|
|
: X_PRICE_HIGH;
|
|
iPrice = bar.GetPrice(iPriceType);
|
|
|
|
//
|
|
has = HasDirection(iDir);
|
|
}
|
|
|
|
//
|
|
// Validate Patterns based on MA Band ...
|
|
if (has)
|
|
{
|
|
//
|
|
// Retrieve MA Band for Validation ...
|
|
double iMABandUpper = fima2Signaller.fimaHelper.GetMABandUpper(barIndex);
|
|
double iMABandLower = fima2Signaller.fimaHelper.GetMABandLower(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
has = isBullish
|
|
? iPrice < iMABandLower
|
|
: iPrice > iMABandUpper;
|
|
}
|
|
|
|
//
|
|
// Select a Zone which Price inside it ...
|
|
|
|
//
|
|
// Validate Happens in Zone ...
|
|
int insideZoneIDX = -1;
|
|
has = has &&
|
|
(isBullish
|
|
? HasInside(
|
|
insideZoneIDX,
|
|
bar,
|
|
supports //
|
|
)
|
|
: HasInside(
|
|
insideZoneIDX,
|
|
bar,
|
|
resistances //
|
|
));
|
|
|
|
//
|
|
// Validate Selected Inside Zone ...
|
|
// whith Bars Edge ...
|
|
has = IsValidIndex(insideZoneIDX);
|
|
if (has)
|
|
{
|
|
//
|
|
if (isBullish)
|
|
{
|
|
iZone = supports[insideZoneIDX];
|
|
}
|
|
else
|
|
{
|
|
iZone = resistances[insideZoneIDX];
|
|
}
|
|
|
|
//
|
|
has = isBullish
|
|
? bar.high > supports[insideZoneIDX].upper
|
|
: bar.low < resistances[insideZoneIDX].lower;
|
|
}
|
|
|
|
//
|
|
// Checking Liquidities ...
|
|
|
|
//
|
|
// Draw Selected and Validated Bar and Selected Zone ...
|
|
if (has)
|
|
{
|
|
//
|
|
int iWidth = 1;
|
|
int iCode = 159;
|
|
color iClr = isBullish
|
|
? clrYellow
|
|
: clrDarkOrange;
|
|
ENUM_ARROW_ANCHOR iAnchor = isBullish
|
|
? ANCHOR_TOP
|
|
: ANCHOR_BOTTOM;
|
|
|
|
//
|
|
XCBoxObject *iZoneObj;
|
|
XCBarArrowObject *iPatternObj;
|
|
|
|
//
|
|
has = fima2Signaller.poiDrawer.DrawBarArrow(
|
|
bar,
|
|
iPatternObj,
|
|
iPriceType,
|
|
iCode,
|
|
iClr,
|
|
iWidth,
|
|
iAnchor,
|
|
iName,
|
|
true, // Ignore Bar Tag ...
|
|
10 // Threshold ...
|
|
);
|
|
if (has)
|
|
{
|
|
}
|
|
|
|
//
|
|
has = fima2Signaller.poiDrawer.DrawBox(
|
|
iZone,
|
|
iZoneObj,
|
|
true, // Ignore At ...
|
|
iZone.type // Name ...
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
XPOIStyle iStyle;
|
|
fima2Signaller.poiDrawer.GetBoxStyle(
|
|
iStyle,
|
|
iZone.dir //
|
|
);
|
|
iStyle.width = 2;
|
|
iStyle.clr = iClr;
|
|
fima2Signaller.poiDrawer.ApplyBoxStyle(
|
|
iZoneObj,
|
|
iStyle //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Preparing Signal ...
|
|
if (has)
|
|
{
|
|
//
|
|
iSignal.time = bar.time;
|
|
iSignal.provider = "XFima";
|
|
iSignal.symbol = bar.symbol;
|
|
iSignal.period = bar.period;
|
|
iSignal.mode = X_ORDER_MODE_MARKET;
|
|
iSignal.entry = GetEntry(bar.symbol, iDir);
|
|
iSignal.type = isBullish
|
|
? POSITION_TYPE_BUY
|
|
: POSITION_TYPE_SELL;
|
|
|
|
//
|
|
iSignal.volume = 0.01;
|
|
|
|
//
|
|
double _r2r = 2.0;
|
|
double _slDistanceInPoint = 5;
|
|
double _point = GetPoints(iSignal.symbol);
|
|
double _riskDistance = _slDistanceInPoint * _point;
|
|
double _risk = _riskDistance + MathAbs((isBullish ? iZone.lower : iZone.upper) - iSignal.entry);
|
|
double _reward = GetSpread(iSignal.symbol) + (_risk * _r2r);
|
|
|
|
//
|
|
double sl = isBullish
|
|
? iSignal.entry - _risk
|
|
: iSignal.entry + _risk;
|
|
double tp = isBullish
|
|
? iSignal.entry + _reward
|
|
: iSignal.entry - _reward;
|
|
|
|
//
|
|
iSignal.sl = sl;
|
|
iSignal.tp = tp;
|
|
|
|
//
|
|
has = iSignal.IsValid();
|
|
if (has)
|
|
{
|
|
//
|
|
XCSignalObject *iSignalObj;
|
|
has = fima2Signaller.poiDrawer.DrawSignal(
|
|
iSignal,
|
|
iSignalObj,
|
|
7 //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// For Logging ...
|
|
if (has)
|
|
{
|
|
//
|
|
ENUM_X_SIGNAL_EXECUTION_RESULT eResult;
|
|
has = eaExpert.eaTrader.ExecuteSignal(iSignal, eResult);
|
|
Print("Detect a Potential Place for Price Movement: ", ToXString(iDir), ", Time: ", bar.time);
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
iZone.Clean();
|
|
iSignal.Clean();
|
|
SpecifiedClean(supports);
|
|
SpecifiedClean(resistances);
|
|
}
|
|
|
|
//
|
|
void HandleLookupSignal(XOHCL &bar)
|
|
{
|
|
//
|
|
bool has =
|
|
bar.IsValid();
|
|
if (!has)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
XBoxZone iZone;
|
|
XSignal iSignal;
|
|
string iName = NULL;
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
int barIndex = bar.Index();
|
|
double iPrice = EMPTY_VALUE;
|
|
XFIMAConditions fimaConditions;
|
|
ENUM_X_PRICE iPriceType = X_PRICE_NONE;
|
|
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
int cIDX = 0;
|
|
int pIDX = cIDX + 1;
|
|
|
|
//
|
|
// Check for a Cross ...
|
|
|
|
//
|
|
// fima2Signaller.fimaHelper.Update(barIndex);
|
|
has = fima2Signaller.fimaHelper.GetConditions(
|
|
fimaConditions,
|
|
barIndex,
|
|
5 //
|
|
);
|
|
|
|
//
|
|
double cSlowMA = fimaConditions.maSlowBuffer[cIDX];
|
|
double pSlowMA = fimaConditions.maSlowBuffer[pIDX];
|
|
|
|
//
|
|
double cMAUpper = fimaConditions.maBandUpperBuffer[cIDX];
|
|
double cMALower = fimaConditions.maBandLowerBuffer[cIDX];
|
|
|
|
//
|
|
double pMAUpper = fimaConditions.maBandUpperBuffer[pIDX];
|
|
double pMALower = fimaConditions.maBandLowerBuffer[pIDX];
|
|
|
|
//
|
|
bool isCrossedOver = cSlowMA > cMALower &&
|
|
pSlowMA < pMALower;
|
|
|
|
//
|
|
bool isCrossedUnder = cSlowMA < cMAUpper &&
|
|
cSlowMA > pMAUpper;
|
|
|
|
//
|
|
has = isCrossedOver ||
|
|
isCrossedUnder;
|
|
if (!has)
|
|
{
|
|
//
|
|
isBullish = false;
|
|
isBearish = false;
|
|
iDir = X_DIRECTION_NONE;
|
|
}
|
|
|
|
//
|
|
if (has)
|
|
{
|
|
//
|
|
isBullish = isCrossedOver;
|
|
isBearish = isCrossedUnder;
|
|
}
|
|
|
|
//
|
|
iDir = (isBullish && !isBearish)
|
|
? X_DIRECTION_BULLISH
|
|
: (isBearish && !isBullish)
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
has = HasDirection(iDir);
|
|
if (has)
|
|
{
|
|
Print("Conditions Detected ...");
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
fimaConditions.Clean();
|
|
}
|
|
|
|
// |