1390 lines
28 KiB
Plaintext
1390 lines
28 KiB
Plaintext
|
|
void UpdateMainPanel()
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (mChartHelper == NULL ||
|
|
mainPanel == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
bool has = false;
|
|
|
|
//
|
|
// Update Main Panel Position ...
|
|
XObjPosition mainPanelPosition;
|
|
CalculateMainPanelPosition(mainPanelPosition);
|
|
if (mainPanelPosition.IsValidForRectangle())
|
|
{
|
|
//
|
|
has = mainPanel.ShiftPoint(1, mainPanelPosition.fromTime, mainPanelPosition.fromPrice);
|
|
if (has)
|
|
{
|
|
has = mainPanel.ShiftPoint(2, mainPanelPosition.toTime, mainPanelPosition.toPrice);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Calculate Main Window Position ...
|
|
*
|
|
* @param position: XObjPosition
|
|
*/
|
|
void CalculateMainPanelPosition(XObjPosition &position)
|
|
{
|
|
//
|
|
position.Clean();
|
|
|
|
//
|
|
// Reading Chart Helper Requirements ...
|
|
|
|
//
|
|
string mChartSymbol = mChartHelper.Symbol();
|
|
double mPoint = GetPoints(mChartSymbol);
|
|
|
|
//
|
|
ENUM_TIMEFRAMES mChartPeriod = mChartHelper.Period();
|
|
int mChartPeriodSeconds = PeriodSeconds(mChartPeriod);
|
|
|
|
//
|
|
double mChartMinPrice = mChartHelper.PriceMin();
|
|
double mChartMaxPrice = mChartHelper.PriceMax();
|
|
int mChartVisibleBarsCount = mChartHelper.VisibleBars();
|
|
int mChartFirstBarIndex = mChartHelper.FirstVisibleBar();
|
|
|
|
//
|
|
datetime mChartFirstBarTime = GetBarTime(
|
|
mChartSymbol,
|
|
mChartPeriod,
|
|
mChartFirstBarIndex //
|
|
);
|
|
|
|
//
|
|
position.fromTime = mChartFirstBarTime + (mChartPeriodSeconds);
|
|
position.fromPrice = mChartMaxPrice - (10 * mPoint);
|
|
|
|
//
|
|
position.toTime = position.fromTime + (40 * mChartPeriodSeconds);
|
|
position.toPrice = position.fromPrice - (20 * mPoint);
|
|
|
|
//
|
|
Print(" ");
|
|
|
|
//
|
|
Print("From Time: ", position.fromTime);
|
|
Print("To Time: ", position.toTime);
|
|
|
|
//
|
|
Print(" ");
|
|
|
|
//
|
|
Print("From Price: ", position.fromPrice);
|
|
Print("To Price: ", position.toPrice);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////
|
|
//
|
|
// 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 strict
|
|
|
|
//
|
|
#define ShortName "XBackTester"
|
|
|
|
//
|
|
// Imports ...
|
|
#include "../Classes/x-saherelm.x-alert.class.mq5"
|
|
#include "../Classes/x-saherelm.x-chart.helper.class.mq5"
|
|
#include "../Classes/x-saherelm.x-trade.class.mq5"
|
|
|
|
//
|
|
// Import Chart Objects ...
|
|
#include <ChartObjects/ChartObject.mqh>
|
|
#include <ChartObjects/ChartObjectsArrows.mqh>
|
|
#include <ChartObjects/ChartObjectsFibo.mqh>
|
|
#include <ChartObjects/ChartObjectsLines.mqh>
|
|
#include <ChartObjects/ChartObjectsShapes.mqh>
|
|
#include <ChartObjects/ChartObjectsTxtControls.mqh>
|
|
#include <Charts/Chart.mqh>
|
|
|
|
//
|
|
// Definitions ...
|
|
struct XObjPosition
|
|
{
|
|
//
|
|
// Props ...
|
|
datetime fromTime;
|
|
double fromPrice;
|
|
datetime toTime;
|
|
double toPrice;
|
|
|
|
//
|
|
// Constructor ...
|
|
XObjPosition()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
//
|
|
// Cleanup ...
|
|
void Clean()
|
|
{
|
|
//
|
|
toPrice = 0;
|
|
fromPrice = 0;
|
|
|
|
//
|
|
toTime = NULL;
|
|
fromTime = NULL;
|
|
}
|
|
|
|
//
|
|
// Validate XWindowPosition for Rectangle ...
|
|
bool IsValidForRectangle()
|
|
{
|
|
//
|
|
bool result =
|
|
//
|
|
toPrice > 0 &&
|
|
fromPrice > 0 &&
|
|
IsSpecifiedValid(toTime) &&
|
|
IsSpecifiedValid(fromTime) &&
|
|
fromTime < toTime
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
};
|
|
|
|
//
|
|
// 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
|
|
//
|
|
// Define Local Variables ...
|
|
|
|
//
|
|
string eaLogTag; // EA Log Prefix ...
|
|
XCAlert *eaAlert; // Alert Provider for Expert Adviser ...
|
|
XCTrade *eaTrader; // Trader of Expert Adviser ...
|
|
|
|
//
|
|
// Chart Objects and Properties ...
|
|
XCChartHelper *mChartHelper;
|
|
|
|
//
|
|
// Chart Object Class ...
|
|
|
|
//
|
|
string objSuffix;
|
|
|
|
//
|
|
// Main Panel ...
|
|
string mainPanelName;
|
|
CChartObjectRectLabel *mainPanel; // Main Panel ...
|
|
string buyButtonName;
|
|
CChartObjectButton *buyButton; // Buy Button ...
|
|
string sellButtonName;
|
|
CChartObjectButton *sellButton; // Sell Button ...
|
|
|
|
//
|
|
// Event Handlers ...
|
|
|
|
//
|
|
// Initialization ...
|
|
int OnInit()
|
|
{
|
|
//
|
|
// Validate Inputs and Required Parameters
|
|
// for EA to Works fine ...
|
|
if (!ValidateInputs())
|
|
{
|
|
return INIT_PARAMETERS_INCORRECT;
|
|
}
|
|
|
|
//
|
|
// Initialize Timer ...
|
|
if (!InitTimer())
|
|
{
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
//
|
|
// Initialize all Requirements ...
|
|
if (!InitEA())
|
|
{
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
//
|
|
// Initialize all GUI Objects and Classes ...
|
|
if (!InitGUI())
|
|
{
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
//
|
|
// Alert Initialization ...
|
|
string msg = "Initialized Successfully ...";
|
|
eaAlert.SendAlert(msg);
|
|
|
|
//
|
|
// Init Succeed ...
|
|
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 ...
|
|
DestroyTimer();
|
|
|
|
//
|
|
// Destroy all GUI Requirements ...
|
|
DestroyGUI();
|
|
|
|
//
|
|
// Alert De Initialization Succeeded ...
|
|
string msg = "De Initialized Successfully ...";
|
|
eaAlert.SendAlert(msg);
|
|
|
|
//
|
|
// Destroy all EA Requirements ...
|
|
DestroyEA();
|
|
}
|
|
|
|
//
|
|
// On Tick Handler ...
|
|
void OnTick()
|
|
{
|
|
//
|
|
UpdateGUI();
|
|
}
|
|
|
|
//
|
|
// Handle On Trade Event ...
|
|
void OnTrade()
|
|
{
|
|
eaTrader.HandleOnTrade();
|
|
}
|
|
|
|
//
|
|
// On Timer ...
|
|
void OnTimer()
|
|
{
|
|
//
|
|
// TODO: Implement Time Based Functionalities ...
|
|
}
|
|
|
|
//
|
|
// Chart Event Handler ...
|
|
void OnChartEvent(
|
|
const int id,
|
|
const long &lparam,
|
|
const double &dparam,
|
|
const string &sparam //
|
|
)
|
|
{
|
|
//
|
|
// Apply Chart Event on Main Window ...
|
|
if (id == CHARTEVENT_OBJECT_CLICK)
|
|
{
|
|
//
|
|
if (mainPanel != NULL && sparam == mainPanelName)
|
|
{
|
|
//
|
|
Print("Main Panel Clicked ...");
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Custom Functions ...
|
|
|
|
/**
|
|
* Validate all Inputs of Expert Adviser ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool ValidateInputs()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
string errMessage = "";
|
|
|
|
//
|
|
bool isCommonValid = (
|
|
//
|
|
eaSlippage > 0 &&
|
|
eaMagicNumber > 0
|
|
//
|
|
);
|
|
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();
|
|
}
|
|
|
|
/**
|
|
* Initialize all Requirements for Working Fine ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool InitEA()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Locally Apply Changes on Prefix ...
|
|
eaLogTag = ShortName + ">" + eaLogSuffix;
|
|
|
|
//
|
|
// Create Instance of Alert Class and Configure it ...
|
|
eaAlert = new XCAlert();
|
|
eaAlert.SetPrefix(eaLogTag);
|
|
eaAlert.SetLogAlerts(eALogAlerts);
|
|
eaAlert.SetMailAlerts(eAMailAlerts);
|
|
eaAlert.SetPushAlerts(eAPushAlerts);
|
|
eaAlert.SetEnableAlerts(eAEnableAlerts);
|
|
eaAlert.SetTerminalAlerts(eATerminalAlerts);
|
|
|
|
//
|
|
// Create Trader Instance and Configure it ...
|
|
eaTrader = new XCTrade(
|
|
eaSlippage,
|
|
eaMagicNumber //
|
|
);
|
|
|
|
//
|
|
// TODO: Fix This ...
|
|
result = true;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Destroy all Initialized EA Requirements ...
|
|
*/
|
|
void DestroyEA()
|
|
{
|
|
//
|
|
delete eaAlert;
|
|
}
|
|
|
|
//
|
|
// GUI Events ...
|
|
|
|
/**
|
|
* Initialize all GUI Requirements for EA ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool InitGUI()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
int subWindow = 0;
|
|
ulong chartId = ChartID();
|
|
objSuffix = ShortName + "_";
|
|
|
|
//
|
|
// Initial Chart Class Instance ...
|
|
mChartHelper = new XCChartHelper(chartId);
|
|
|
|
//
|
|
// Create Main Panel ...
|
|
result = CreateMainPanel();
|
|
|
|
//
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Update GUI based on Each Ticks ...
|
|
*/
|
|
void UpdateGUI()
|
|
{
|
|
//
|
|
// UpdateMainPanel();
|
|
}
|
|
|
|
/**
|
|
* Destroy all Initialized GUi Requirements ...
|
|
*/
|
|
void DestroyGUI()
|
|
{
|
|
//
|
|
delete mChartHelper;
|
|
ZeroMemory(mChartHelper);
|
|
|
|
//
|
|
delete mainPanel;
|
|
ZeroMemory(mainPanel);
|
|
}
|
|
|
|
//
|
|
// Custom Helper Functions ...
|
|
|
|
bool CreateMainPanel()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (mChartHelper == NULL)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int subWindow = 0;
|
|
|
|
//
|
|
mainPanelName = objSuffix + "Main_Panel";
|
|
mainPanel = new CChartObjectRectLabel();
|
|
result = mainPanel.Create(
|
|
mChartHelper.ChartId(),
|
|
mainPanelName,
|
|
subWindow,
|
|
10,
|
|
25,
|
|
400,
|
|
200 //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Styling Main Panel ...
|
|
mainPanel.BackColor(clrDarkGray);
|
|
mainPanel.Tooltip(mainPanelName);
|
|
|
|
//
|
|
// Create Buttons ...
|
|
buyButtonName = objSuffix + "BTN_BUY";
|
|
buyButton = new CChartObjectButton();
|
|
result = buyButton.Create(
|
|
mChartHelper.ChartId(),
|
|
buyButtonName,
|
|
subWindow,
|
|
10,
|
|
25,
|
|
200,
|
|
100 //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Apply Style of Buy Button ...
|
|
|
|
if (result)
|
|
{
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
//
|
|
// class XCEdit : public CEdit {
|
|
// //
|
|
// public:
|
|
// //
|
|
// string mValue;
|
|
|
|
// //
|
|
// bool OnSetText() {
|
|
// //
|
|
// Print("Object Edit End ...");
|
|
// return true;
|
|
// }
|
|
// };
|
|
|
|
// CEdit edtPositionId;
|
|
|
|
// //
|
|
// // EDIT Position ID ...
|
|
// int edtPositionIdStartX = btnSellStartX;
|
|
// int edtPositionIdSizeX = edtPositionIdStartX + 100;
|
|
// int edtPositionIdStartY = btnSellSizeY + 5;
|
|
// int edtPositionIdSizeY = edtPositionIdStartY + 50;
|
|
// string edtPositionIdName = objSuffix + "EDT_POS_ID";
|
|
// result = edtPositionId.Create(
|
|
// chartId,
|
|
// edtPositionIdName,
|
|
// subWindow,
|
|
// edtPositionIdStartX,
|
|
// edtPositionIdStartY,
|
|
// edtPositionIdSizeX,
|
|
// edtPositionIdSizeY //
|
|
// );
|
|
// if (result)
|
|
// {
|
|
// //
|
|
// // Apply Edit Position ID Style ...
|
|
// edtPositionId.Text(ToXString(selectedPositionID));
|
|
// edtPositionId.TextAlign(ALIGN_LEFT);
|
|
// }
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
CButton btnPauseReplay;
|
|
bool isVisualTesterPaused = false;
|
|
|
|
//
|
|
// Initial Btn Pause Play ...
|
|
int subWindow = 0;
|
|
int defaultGap = 5;
|
|
int defaultWidth = 100;
|
|
int defaultHeight = 30;
|
|
ulong chartId = eaExpert.eaChartHelper.ChartId();
|
|
|
|
//
|
|
int btnPauseReplayX1 = defaultGap;
|
|
int btnPauseReplayX2 = btnPauseReplayX1 + defaultWidth;
|
|
int btnPauseReplayY1 = eaExpert.eaChartHelper.Height() - defaultHeight - defaultGap;
|
|
int btnPauseReplayY2 = btnPauseReplayY1 + defaultHeight;
|
|
|
|
//
|
|
string btnPauseReplayName = ShortName + "BTN_PAUSE_REPLAY";
|
|
|
|
//
|
|
isInited = btnPauseReplay.Create(
|
|
chartId,
|
|
btnPauseReplayName,
|
|
subWindow,
|
|
btnPauseReplayX1,
|
|
btnPauseReplayY1,
|
|
btnPauseReplayX2,
|
|
btnPauseReplayY2 //
|
|
);
|
|
if (isInited)
|
|
{
|
|
//
|
|
// Apply Style ...
|
|
string btnPauseReplayText =
|
|
isVisualTesterPaused
|
|
? "Play"
|
|
: "Pause";
|
|
btnPauseReplay.Text(btnPauseReplayText);
|
|
btnPauseReplay.Color(clrAzure);
|
|
btnPauseReplay.ColorBackground(clrBlack);
|
|
}
|
|
|
|
//
|
|
//
|
|
// Update btn Pause Replay ...
|
|
string btnPauseReplayText =
|
|
isVisualTesterPaused
|
|
? "Play"
|
|
: "Pause";
|
|
btnPauseReplay.Text(btnPauseReplayText);
|
|
if (IsRunningeOnTestVisualMode())
|
|
{
|
|
//
|
|
btnPauseReplay.Show();
|
|
btnPauseReplay.Enable();
|
|
}
|
|
else
|
|
{
|
|
//
|
|
btnPauseReplay.Hide();
|
|
btnPauseReplay.Enable();
|
|
}
|
|
if (btnPauseReplay.Pressed())
|
|
{
|
|
//
|
|
if (btnPauseReplay.IsEnabled())
|
|
{
|
|
//
|
|
HandlePauseStrategyTester();
|
|
|
|
//
|
|
btnPauseReplayText =
|
|
isVisualTesterPaused
|
|
? "Play"
|
|
: "Pause";
|
|
btnPauseReplay.Text(btnPauseReplayText);
|
|
}
|
|
|
|
//
|
|
btnPauseReplay.Pressed(false);
|
|
}
|
|
|
|
void HandlePauseStrategyTester()
|
|
{
|
|
//
|
|
isVisualTesterPaused = !isVisualTesterPaused;
|
|
|
|
//
|
|
// DebugBreak();
|
|
|
|
keybd_event(VK_SPACE, 0, 0, 0);
|
|
keybd_event(VK_SPACE, 0, KEYEVENTF_KEYUP, 0);
|
|
}
|
|
|
|
///////////////////////////
|
|
/// XFIMA ...
|
|
///////////////////////////
|
|
|
|
//
|
|
// ZIGZAG Pattern ...
|
|
// if (detectZIGZAGPatterns)
|
|
// {
|
|
// //
|
|
// // Detect Market Analysis ...
|
|
// XZigZagAnalysis zAnalysis;
|
|
// has = fima2Signaller.fimaPOIDetector.AnalyseMarketUsingZigZag(
|
|
// cBar,
|
|
// cBar.period,
|
|
// fima2Signaller.fimaHelper,
|
|
// zAnalysis,
|
|
// 15 //
|
|
// );
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// Print(ShortName + zAnalysis.GetMessage());
|
|
|
|
// //
|
|
// XCZigZagAnalysisObject *iObj;
|
|
// has = fima2Signaller.fimaPOIDrawer.DrawZigZagMarketAnalysisByPV(
|
|
// iObj,
|
|
// zAnalysis //
|
|
// );
|
|
// if (has)
|
|
// {
|
|
// draws.Add(iObj);
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
//
|
|
// Reading Pivots ...
|
|
double iLows[];
|
|
double iHighs[];
|
|
double lowTo = 0;
|
|
double highTo = 0;
|
|
double lowFrom = 0;
|
|
double highFrom = 0;
|
|
datetime lowToTime = NULL;
|
|
datetime highToTime = NULL;
|
|
datetime lowFromTime = NULL;
|
|
datetime highFromTime = NULL;
|
|
double lowsSlope = EMPTY_VALUE;
|
|
double highsSlope = EMPTY_VALUE;
|
|
double lowsIntercept = EMPTY_VALUE;
|
|
double highsIntercept = EMPTY_VALUE;
|
|
|
|
//
|
|
int iLoopbackLength = 50;
|
|
for (int i = 0; i < iLoopbackLength; i++)
|
|
{
|
|
//
|
|
double iLowPrice = iLow(_Symbol, _Period, i);
|
|
double iHighPrice = iHigh(_Symbol, _Period, i);
|
|
|
|
//
|
|
Add(
|
|
iLowPrice,
|
|
iLows //
|
|
);
|
|
Add(
|
|
iHighPrice,
|
|
iHighs //
|
|
);
|
|
}
|
|
has = CalculateLinearRegression(
|
|
lowsSlope,
|
|
lowsIntercept,
|
|
iLows,
|
|
0,
|
|
0 //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
lowToTime = GetBarTime(
|
|
_Symbol,
|
|
_Period,
|
|
0 //
|
|
);
|
|
lowTo = CalculateValueBySlopeIntercept(
|
|
lowsSlope,
|
|
lowsIntercept,
|
|
0 //
|
|
);
|
|
|
|
//
|
|
lowFromTime = GetBarTime(
|
|
_Symbol,
|
|
_Period,
|
|
iLoopbackLength //
|
|
);
|
|
lowFrom = CalculateValueBySlopeIntercept(
|
|
lowsSlope,
|
|
lowsIntercept,
|
|
iLoopbackLength //
|
|
);
|
|
}
|
|
|
|
//
|
|
has = CalculateLinearRegression(
|
|
highsSlope,
|
|
highsIntercept,
|
|
iHighs,
|
|
0,
|
|
0 //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
highToTime = GetBarTime(
|
|
_Symbol,
|
|
_Period,
|
|
0 //
|
|
);
|
|
highTo = CalculateValueBySlopeIntercept(
|
|
highsSlope,
|
|
highsIntercept,
|
|
0 //
|
|
);
|
|
|
|
//
|
|
highFromTime = GetBarTime(
|
|
_Symbol,
|
|
_Period,
|
|
iLoopbackLength //
|
|
);
|
|
highFrom = CalculateValueBySlopeIntercept(
|
|
highsSlope,
|
|
highsIntercept,
|
|
iLoopbackLength //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Try to Draw ...
|
|
|
|
//
|
|
// Low ...
|
|
CChartObjectTrend *iLowTrend;
|
|
has = fima2Signaller.fimaPOIDrawer.DrawTrendLine(
|
|
lowFrom,
|
|
lowFromTime,
|
|
lowTo,
|
|
lowToTime,
|
|
iLowTrend,
|
|
"LOW_TREMD",
|
|
true // Ray Right ...
|
|
);
|
|
if (has)
|
|
{
|
|
draws.Add(iLowTrend);
|
|
}
|
|
|
|
//
|
|
// High ...
|
|
CChartObjectTrend *iHighTrend;
|
|
has = fima2Signaller.fimaPOIDrawer.DrawTrendLine(
|
|
highFrom,
|
|
highFromTime,
|
|
highTo,
|
|
highToTime,
|
|
iHighTrend,
|
|
"HIGH_TREMD",
|
|
true // Ray Right ...
|
|
);
|
|
if (has)
|
|
{
|
|
draws.Add(iHighTrend);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// if (HasDirection(marketStructure.signalKeyBarPatternDir))
|
|
// {
|
|
// Print("Detected ...");
|
|
// }
|
|
// if (marketStructure.ob.IsValid() && marketStructure.fvg.IsValid())
|
|
// {
|
|
// Print("Detected ...");
|
|
// }
|
|
// if (marketStructure.support.IsValid() || marketStructure.resistance.IsValid())
|
|
// {
|
|
// //
|
|
// XOHCL pBar;
|
|
// XOHCL p2Bar;
|
|
// bool has = cBar.GetPreviousBar(pBar);
|
|
// has = has &&
|
|
// pBar.GetPreviousBar(p2Bar);
|
|
// if (!has)
|
|
// {
|
|
// //
|
|
// pBar.Clean();
|
|
// p2Bar.Clean();
|
|
// return;
|
|
// }
|
|
|
|
// //
|
|
// // Check For PrevZoneExistanse ...
|
|
// has = marketStructure.prevZone.IsValid();
|
|
// if (has) {
|
|
// //
|
|
// // Draw Prev Zone ...
|
|
// XCBoxObject *iPrevZoneObj;
|
|
// marketStructure.prevZone.to = pBar.time;
|
|
// has = fima2Signaller.poiDrawer.DrawBox(
|
|
// marketStructure.prevZone,
|
|
// iPrevZoneObj //
|
|
// );
|
|
// if (has)
|
|
// {
|
|
// //
|
|
// XPOIStyle style;
|
|
// fima2Signaller.poiDrawer.GetBoxStyle(
|
|
// style,
|
|
// marketStructure.prevZone.dir //
|
|
// );
|
|
// style.clr = clrYellow;
|
|
// fima2Signaller.poiDrawer.ApplyBoxStyle(
|
|
// iPrevZoneObj,
|
|
// style //
|
|
// );
|
|
|
|
// //
|
|
// style.Clean();
|
|
// eaDraws.Add(iPrevZoneObj);
|
|
// }
|
|
// }
|
|
|
|
// //
|
|
// if (has)
|
|
// {
|
|
// Print("Detected ...");
|
|
// }
|
|
|
|
// //
|
|
// // Cleanup Resources ...
|
|
// pBar.Clean();
|
|
// p2Bar.Clean();
|
|
// }
|
|
|
|
//////////////////////////////////////////////////////////
|
|
|
|
//
|
|
XOHCL pBar;
|
|
bool has = cBar.GetPreviousBar(pBar);
|
|
if (marketStructure.isPTest)
|
|
{
|
|
//
|
|
// Check For PrevZoneExistanse ...
|
|
has = marketStructure.pTestedZone.IsValid();
|
|
if (has)
|
|
{
|
|
//
|
|
// Draw Prev Zone ...
|
|
XCBoxObject *iPrevZoneObj;
|
|
marketStructure.pTestedZone.to = pBar.time;
|
|
has = fima2Signaller.poiDrawer.DrawBox(
|
|
marketStructure.pTestedZone,
|
|
iPrevZoneObj //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
XPOIStyle style;
|
|
fima2Signaller.poiDrawer.GetBoxStyle(
|
|
style,
|
|
marketStructure.pTestedZone.dir //
|
|
);
|
|
style.clr = clrYellow;
|
|
fima2Signaller.poiDrawer.ApplyBoxStyle(
|
|
iPrevZoneObj,
|
|
style //
|
|
);
|
|
|
|
//
|
|
style.Clean();
|
|
eaDraws.Add(iPrevZoneObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
Print("Previous Tested ...");
|
|
}
|
|
pBar.Clean();
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// Previous Bar must Has Support or Resistance ...
|
|
|
|
//
|
|
// Check Supports ...
|
|
idx = GetYoungestBefore(
|
|
pForBar.time,
|
|
supports //
|
|
);
|
|
has =
|
|
pForBar.IsValid() &&
|
|
IsValidIndex(idx);
|
|
if (has)
|
|
{
|
|
pSupport = supports[idx];
|
|
}
|
|
|
|
//
|
|
// Check Resistances ...
|
|
idx = GetYoungestBefore(
|
|
pForBar.time,
|
|
resistances //
|
|
);
|
|
has =
|
|
pForBar.IsValid() &&
|
|
IsValidIndex(idx);
|
|
if (has)
|
|
{
|
|
pResistance = resistances[idx];
|
|
}
|
|
|
|
//
|
|
bool isPSupportTouched =
|
|
pSupport.IsValid() &&
|
|
pForBar.low < pSupport.upper;
|
|
|
|
//
|
|
bool isPResistanceTouched =
|
|
pResistance.IsValid() &&
|
|
pForBar.high > pResistance.lower;
|
|
|
|
//
|
|
has =
|
|
isPSupportTouched ||
|
|
isPResistanceTouched;
|
|
structure.isPTest = has;
|
|
if (has)
|
|
{
|
|
//
|
|
if (isPSupportTouched)
|
|
{
|
|
//
|
|
// Validate Previously Tested Zone Price ...
|
|
structure.pTestedZone = pSupport;
|
|
}
|
|
else if (isPResistanceTouched)
|
|
{
|
|
//
|
|
// Validate Previously Tested Zone Price ...
|
|
structure.pTestedZone = pResistance;
|
|
}
|
|
|
|
//
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
|
|
// //
|
|
// // Here We Apply Custom Detecting ...
|
|
// detectorConfig.OffDetectors();
|
|
// detectorConfig.detectSupport = true;
|
|
// detectorConfig.detectResistance= true;
|
|
// detectorConfig.detectSignalKeyBarPattern = true;
|
|
|
|
// //
|
|
// // Initial Bar for Analysis ...
|
|
// // at Signal Time ...
|
|
// XOHCL signalBar;
|
|
// bool isInited = signalBar.Init(
|
|
// signal.symbol,
|
|
// signal.period,
|
|
// signal.time //
|
|
// );
|
|
|
|
// //
|
|
// // Analyse Market ...
|
|
// fima1Signaller.poiDetector.AnalyseMarket(
|
|
// signalBar,
|
|
// marketStructure,
|
|
// detectorConfig //
|
|
// );
|
|
// CArrayObj *iObjects;
|
|
// int drawnsCount = fima2Signaller.poiDrawer.DrawMarketStructure(
|
|
// marketStructure,
|
|
// marketStructureDrawerConfig,
|
|
// iObjects //
|
|
// );
|
|
// if (IsValidSize(drawnsCount))
|
|
// {
|
|
// //
|
|
// AddObjects(
|
|
// iObjects,
|
|
// eaDraws //
|
|
// );
|
|
// }
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// On Tick Handler ...
|
|
void OnTick()
|
|
{
|
|
//
|
|
eaIsNewBar = eaBarTracker.IsNewBar();
|
|
bool canProcess = eaProcessAllTicks
|
|
? true
|
|
: eaIsNewBar;
|
|
//
|
|
eaExpert.HandleOnTick();
|
|
|
|
//
|
|
if (!canProcess)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
fima1Signaller.OnTick();
|
|
fima2Signaller.OnTick();
|
|
|
|
//
|
|
// Initial Bar for Analysis ...
|
|
XOHCL cBar;
|
|
bool isInited = cBar.Init(
|
|
_Symbol,
|
|
_Period,
|
|
0 //
|
|
);
|
|
|
|
//
|
|
// Here We Apply Custom Detecting ...
|
|
detectorConfig.OffDetectors();
|
|
detectorConfig.detectSupport = true;
|
|
detectorConfig.detectResistance = true;
|
|
detectorConfig.detectSignalKeyBarPattern = false;
|
|
detectorConfig.supportAndResistanceValidationLength = 21;
|
|
|
|
//
|
|
// Analyse Market ...
|
|
fima2Signaller.poiDetector.AnalyseMarket(
|
|
cBar,
|
|
marketStructure,
|
|
detectorConfig //
|
|
);
|
|
CArrayObj *iObjects;
|
|
int drawnsCount = fima2Signaller.poiDrawer.DrawMarketStructure(
|
|
marketStructure,
|
|
marketStructureDrawerConfig,
|
|
iObjects //
|
|
);
|
|
if (IsValidSize(drawnsCount))
|
|
{
|
|
//
|
|
AddObjects(
|
|
iObjects,
|
|
eaDraws //
|
|
);
|
|
}
|
|
|
|
//
|
|
// TODO: Remove this ...
|
|
XOHCL pBar;
|
|
bool has = cBar.GetPreviousBar(pBar);
|
|
if (marketStructure.fakeBreakedZone.IsValid())
|
|
{
|
|
//
|
|
// Check For PrevZoneExistanse ...
|
|
has = marketStructure.fakeBreakedZone.IsValid();
|
|
if (has)
|
|
{
|
|
//
|
|
// Draw Prev Zone ...
|
|
XCBoxObject *iPrevZoneObj;
|
|
marketStructure.fakeBreakedZone.to = pBar.time;
|
|
has = fima2Signaller.poiDrawer.DrawBox(
|
|
marketStructure.fakeBreakedZone,
|
|
iPrevZoneObj //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
XPOIStyle style;
|
|
fima2Signaller.poiDrawer.GetBoxStyle(
|
|
style,
|
|
marketStructure.fakeBreakedZone.dir //
|
|
);
|
|
style.clr = clrYellow;
|
|
fima2Signaller.poiDrawer.ApplyBoxStyle(
|
|
iPrevZoneObj,
|
|
style //
|
|
);
|
|
|
|
//
|
|
style.Clean();
|
|
eaDraws.Add(iPrevZoneObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
Print("Fake Breaked Detection ...");
|
|
}
|
|
if (HasChild(marketStructure.recentlyTestedZones))
|
|
{
|
|
//
|
|
int idx = GetYoungest(marketStructure.recentlyTestedZones);
|
|
bool has = IsValidIndex(idx);
|
|
if (has)
|
|
{
|
|
//
|
|
has = IsTested(
|
|
pBar,
|
|
marketStructure.recentlyTestedZones[idx] //
|
|
);
|
|
}
|
|
|
|
//
|
|
if (has)
|
|
{
|
|
Print("PrevZone Exists ...");
|
|
}
|
|
}
|
|
pBar.Clean();
|
|
|
|
//
|
|
cBar.Clean();
|
|
}
|
|
|
|
//
|
|
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.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.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 //
|
|
);
|
|
|
|
//
|
|
bar.Clean();
|
|
}
|