last works on XBackTester ...
This commit is contained in:
@@ -0,0 +1,338 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Class Library
|
||||
// --------------------------------------
|
||||
// Name: XCChartHelper
|
||||
// Description: Chart Helper Tools ...
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../Classes/x-saherelm.base.class.mq5"
|
||||
|
||||
//
|
||||
// Implementation ...
|
||||
class XCChartHelper : public XCBase
|
||||
{
|
||||
//
|
||||
// Public ...
|
||||
public:
|
||||
//
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XCChartHelper(ulong _chartId = 0)
|
||||
{
|
||||
//
|
||||
// Normalize Chart ID ...
|
||||
mChartID = NormalizeChartId(_chartId);
|
||||
}
|
||||
|
||||
//
|
||||
// Desconstructor ...
|
||||
~XCChartHelper()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Actioins ...
|
||||
|
||||
/**
|
||||
* Redraw Specified Chart ...
|
||||
*/
|
||||
void Redraw()
|
||||
{
|
||||
ChartRedraw(mChartID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Chart Navigation ...
|
||||
*
|
||||
* @param position: ENUM_CHART_POSITION
|
||||
* @param shift: int
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool Navigate(
|
||||
const ENUM_CHART_POSITION position,
|
||||
const int shift //
|
||||
)
|
||||
{
|
||||
return (ChartNavigate(mChartID, position, shift));
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a Template to Chart ...
|
||||
*
|
||||
* @param filename: string file path ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool ApplyTemplate(const string filename) const
|
||||
{
|
||||
return (ChartApplyTemplate(mChartID, filename));
|
||||
}
|
||||
|
||||
/**
|
||||
* Take an Screenshot of Chart ...
|
||||
*
|
||||
* @param filename: string file path ...
|
||||
* @param width: int ...
|
||||
* @param height: int ...
|
||||
* @param align_mode: ENUM_ALIGN_MODE ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool ScreenShot(
|
||||
const string filename,
|
||||
const int width,
|
||||
const int height,
|
||||
const ENUM_ALIGN_MODE align_mode //
|
||||
) const
|
||||
{
|
||||
return (ChartScreenShot(mChartID, filename, width, height, align_mode));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writing parameters of chart to file ...
|
||||
**/
|
||||
bool Save(const int file_handle)
|
||||
{
|
||||
//
|
||||
string work_str;
|
||||
int work_int;
|
||||
//--- check
|
||||
if (file_handle == INVALID_HANDLE || mChartID == -1)
|
||||
return (false);
|
||||
//--- write start marker - 0xFFFFFFFFFFFFFFFF
|
||||
if (FileWriteLong(file_handle, -1) != sizeof(long))
|
||||
return (false);
|
||||
//--- write chart type
|
||||
if (FileWriteInteger(file_handle, Type(), INT_VALUE) != INT_VALUE)
|
||||
return (false);
|
||||
//--- write chart symbol
|
||||
work_str = Symbol();
|
||||
work_int = StringLen(work_str);
|
||||
if (FileWriteInteger(file_handle, work_int, INT_VALUE) != INT_VALUE)
|
||||
return (false);
|
||||
if (work_int != 0)
|
||||
if (FileWriteString(file_handle, work_str, work_int) != work_int)
|
||||
return (false);
|
||||
//--- write period of chart
|
||||
if (FileWriteInteger(file_handle, Period(), INT_VALUE) != sizeof(int))
|
||||
return (false);
|
||||
//--- write value of the "Mode" property
|
||||
if (FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_MODE), INT_VALUE) != sizeof(int))
|
||||
return (false);
|
||||
//--- write value of the "Foreground" property
|
||||
if (FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_FOREGROUND), CHAR_VALUE) != sizeof(char))
|
||||
return (false);
|
||||
//--- write value of the "Shift" property
|
||||
if (FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHIFT), CHAR_VALUE) != sizeof(char))
|
||||
return (false);
|
||||
//--- write value of the "ShiftSize" property
|
||||
if (FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHIFT), INT_VALUE) != sizeof(int))
|
||||
return (false);
|
||||
//--- write value of the "AutoScroll" property
|
||||
if (FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_AUTOSCROLL), CHAR_VALUE) != sizeof(char))
|
||||
return (false);
|
||||
//--- write value of the "Scale" property
|
||||
if (FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SCALE), INT_VALUE) != sizeof(int))
|
||||
return (false);
|
||||
//--- write value of the "ScaleFix" property
|
||||
if (FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SCALEFIX), CHAR_VALUE) != sizeof(char))
|
||||
return (false);
|
||||
//--- write value of the "ScaleFix_11" property
|
||||
if (FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SCALEFIX_11), CHAR_VALUE) != sizeof(char))
|
||||
return (false);
|
||||
//--- write value of the "FixedMax" property
|
||||
if (FileWriteDouble(file_handle, ChartGetDouble(mChartID, CHART_FIXED_MAX)) != sizeof(double))
|
||||
return (false);
|
||||
//--- write value of the "FixedMin" property
|
||||
if (FileWriteDouble(file_handle, ChartGetDouble(mChartID, CHART_FIXED_MIN)) != sizeof(double))
|
||||
return (false);
|
||||
//--- write the "ScalePPB" property
|
||||
if (FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SCALE_PT_PER_BAR), CHAR_VALUE) != sizeof(char))
|
||||
return (false);
|
||||
//--- write value of the "PointsPerBar" property
|
||||
if (FileWriteDouble(file_handle, ChartGetDouble(mChartID, CHART_POINTS_PER_BAR)) != sizeof(double))
|
||||
return (false);
|
||||
//--- write value of the "ShowOHLC" property
|
||||
if (FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_OHLC), CHAR_VALUE) != sizeof(char))
|
||||
return (false);
|
||||
//--- write value of the "ShowLineBid" property
|
||||
if (FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_BID_LINE), CHAR_VALUE) != sizeof(char))
|
||||
return (false);
|
||||
//--- write value of the "ShowLineAsk" property
|
||||
if (FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_ASK_LINE), CHAR_VALUE) != sizeof(char))
|
||||
return (false);
|
||||
//--- write value of the "ShowLastLine" property
|
||||
if (FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_LAST_LINE), CHAR_VALUE) != sizeof(char))
|
||||
return (false);
|
||||
//--- write value of the "ShowPeriodSep" property
|
||||
if (FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_PERIOD_SEP), CHAR_VALUE) != sizeof(char))
|
||||
return (false);
|
||||
//--- write value of the "ShowGrid" property
|
||||
if (FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_GRID), CHAR_VALUE) != sizeof(char))
|
||||
return (false);
|
||||
//--- write value of the "ShowVolumes" property
|
||||
if (FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_VOLUMES), INT_VALUE) != sizeof(int))
|
||||
return (false);
|
||||
//--- write value of the "ShowObjectDescr" property
|
||||
if (FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_OBJECT_DESCR), CHAR_VALUE) != sizeof(char))
|
||||
return (false);
|
||||
//--- successful
|
||||
return (true);
|
||||
}
|
||||
|
||||
//
|
||||
// Properties ...
|
||||
|
||||
/**
|
||||
* Get Chart ID ...
|
||||
*
|
||||
* @return ( ulong )
|
||||
*/
|
||||
ulong ChartId()
|
||||
{
|
||||
return mChartID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object Type ...
|
||||
*
|
||||
* @return ( int )
|
||||
**/
|
||||
int Type() const
|
||||
{
|
||||
return (0x1111);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Chart Mode ...
|
||||
*
|
||||
* @return ( ENUM_CHART_MODE )
|
||||
**/
|
||||
ENUM_CHART_MODE Mode()
|
||||
{
|
||||
return ((ENUM_CHART_MODE)ChartGetInteger(mChartID, CHART_MODE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Chart Symbol ...
|
||||
*
|
||||
* @return ( string )
|
||||
*/
|
||||
string Symbol()
|
||||
{
|
||||
return (ChartSymbol(mChartID));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Chart Period ...
|
||||
*
|
||||
* @return ( ENUM_TIMEFRAMES )
|
||||
*/
|
||||
ENUM_TIMEFRAMES Period()
|
||||
{
|
||||
return (ChartPeriod(mChartID));
|
||||
}
|
||||
|
||||
/**
|
||||
* Count Chart Visible Bars ...
|
||||
*
|
||||
* @return ( int )
|
||||
*/
|
||||
int VisibleBars()
|
||||
{
|
||||
return ((int)ChartGetInteger(mChartID, CHART_WIDTH_IN_BARS));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Chart First Visible Bars Index ...
|
||||
*
|
||||
* @return ( int )
|
||||
*/
|
||||
int FirstVisibleBar()
|
||||
{
|
||||
return ((int)ChartGetInteger(mChartID, CHART_FIRST_VISIBLE_BAR));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Chart Last Visible Bars Index ...
|
||||
*
|
||||
* @return ( int )
|
||||
*/
|
||||
int LastVisibleBar()
|
||||
{
|
||||
//
|
||||
int first = FirstVisibleBar();
|
||||
int count = VisibleBars();
|
||||
int result = first + count;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Chart's Specified SubWindows Minimum Price ...
|
||||
*
|
||||
* @param subWindow: int
|
||||
* @return ( double )
|
||||
*/
|
||||
double PriceMin(int subWindow = 0)
|
||||
{
|
||||
//
|
||||
// Normalize Subwindow ...
|
||||
if (subWindow <= 0)
|
||||
{
|
||||
subWindow = 0;
|
||||
}
|
||||
|
||||
//
|
||||
return (ChartGetDouble(mChartID, CHART_PRICE_MIN, subWindow));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Chart's Specified SubWindows Maximum Price ...
|
||||
*
|
||||
* @param subWindow: int
|
||||
* @return ( double )
|
||||
*/
|
||||
double PriceMax(int subWindow = 0)
|
||||
{
|
||||
//
|
||||
// Normalize Subwindow ...
|
||||
if (subWindow <= 0)
|
||||
{
|
||||
subWindow = 0;
|
||||
}
|
||||
|
||||
//
|
||||
return (ChartGetDouble(mChartID, CHART_PRICE_MAX, subWindow));
|
||||
}
|
||||
|
||||
//
|
||||
// Protected ...
|
||||
protected:
|
||||
//
|
||||
// Private ...
|
||||
private:
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
ulong mChartID; // Chart ID ...
|
||||
};
|
||||
|
||||
//
|
||||
@@ -0,0 +1,646 @@
|
||||
|
||||
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);
|
||||
// }
|
||||
@@ -24,9 +24,26 @@
|
||||
//
|
||||
// Imports ...
|
||||
#include "../Classes/x-saherelm.x-alert.class.mq5"
|
||||
#include "../Classes/x-saherelm.x-rm.panel.class.mq5"
|
||||
#include "../Classes/x-saherelm.x-chart.helper.class.mq5"
|
||||
#include "../Classes/x-saherelm.x-trade.class.mq5"
|
||||
|
||||
//
|
||||
// Import Chart Objects ...
|
||||
#include <Arrays/ArrayObj.mqh>
|
||||
#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>
|
||||
#include <Controls/Button.mqh>
|
||||
#include <Controls/Edit.mqh>
|
||||
#include <Controls/Label.mqh>
|
||||
|
||||
//
|
||||
// Definitions ...
|
||||
|
||||
//
|
||||
// Inputs ...
|
||||
|
||||
@@ -54,7 +71,32 @@ input bool eATerminalAlerts = false; // Terminal Alerts
|
||||
string eaLogTag; // EA Log Prefix ...
|
||||
XCAlert *eaAlert; // Alert Provider for Expert Adviser ...
|
||||
XCTrade *eaTrader; // Trader of Expert Adviser ...
|
||||
XCRMPanel eaMainWindow; // Main Window ...
|
||||
XCChartHelper *mChartHelper; // Chart Helper Class ...
|
||||
|
||||
//
|
||||
// Object Props ...
|
||||
|
||||
//
|
||||
string objSuffix;
|
||||
|
||||
//
|
||||
CButton btnBuy;
|
||||
CButton btnSell;
|
||||
CButton btnClose;
|
||||
CButton btnCloseAll;
|
||||
CButton btnSelectedPosInfo;
|
||||
|
||||
//
|
||||
CEdit lblPositionId;
|
||||
int lblPositionIdSizeX = 0;
|
||||
int lblPositionIdSizeY = 0;
|
||||
int lblPositionIdStartX = 0;
|
||||
int lblPositionIdStartY = 0;
|
||||
ulong selectedPositionID = 0;
|
||||
|
||||
//
|
||||
// Position Arrays ...
|
||||
CArrayObj posArray;
|
||||
|
||||
//
|
||||
// Event Handlers ...
|
||||
@@ -148,6 +190,7 @@ void OnTick()
|
||||
// Handle On Trade Event ...
|
||||
void OnTrade()
|
||||
{
|
||||
//
|
||||
eaTrader.HandleOnTrade();
|
||||
}
|
||||
|
||||
@@ -168,9 +211,6 @@ void OnChartEvent(
|
||||
const string &sparam //
|
||||
)
|
||||
{
|
||||
//
|
||||
// Apply Chart Event on Main Window ...
|
||||
eaMainWindow.ChartEvent(id, lparam, dparam, sparam);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -285,7 +325,19 @@ bool InitEA()
|
||||
eaSlippage,
|
||||
eaMagicNumber //
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// Attach Event Handlers ...
|
||||
eaTrader.AddOnDealsChangedEventHandler(OnDealsChanged);
|
||||
eaTrader.AddOnStopLossEventHandler(OnStopLossTriggered);
|
||||
eaTrader.AddOnOrdersChangedEventHandler(OnOrdersChanged);
|
||||
eaTrader.AddOnTakeProfitEventHandler(OnTakeProfitTriggered);
|
||||
eaTrader.AddOnModifyPositionEventHandler(OnPositionModified);
|
||||
eaTrader.AddOnPositionsChangedEventHandler(OnPositionsChanged);
|
||||
eaTrader.AddOnTradeStateChangedEventHandler(OnTradeStateChanged);
|
||||
eaTrader.AddOnForceClosePositionEventHandler(OnPositionForceClosed);
|
||||
eaTrader.AddOnPartialClosePositionEventHandler(OnPositionPartialClosed);
|
||||
|
||||
//
|
||||
// TODO: Fix This ...
|
||||
result = true;
|
||||
@@ -317,24 +369,155 @@ bool InitGUI()
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Initialize Application Main Window ...
|
||||
result = eaMainWindow.Create(
|
||||
ChartID(),
|
||||
ShortName, // Dialog Name ...
|
||||
0, // SubWindow ...
|
||||
10, // X1 ...
|
||||
35, // Y1 ...
|
||||
300, // X2 ...
|
||||
200 // Y2 ...
|
||||
);
|
||||
int subWindow = 0;
|
||||
ulong chartId = ChartID();
|
||||
objSuffix = ShortName + "_";
|
||||
|
||||
//
|
||||
// Try To Run Main Window ...
|
||||
// Initial Chart Class Instance ...
|
||||
mChartHelper = new XCChartHelper(chartId);
|
||||
|
||||
//
|
||||
int startX = 5;
|
||||
int startY = 25;
|
||||
|
||||
//
|
||||
// Buy ...
|
||||
int btnBuyStartX = startX;
|
||||
int btnBuySizeX = startX + 100;
|
||||
int btnBuyStartY = startY;
|
||||
int btnBuySizeY = startY + 50;
|
||||
string btnBuyName = objSuffix + "BTN_BUY";
|
||||
result = btnBuy.Create(
|
||||
chartId,
|
||||
btnBuyName,
|
||||
subWindow,
|
||||
btnBuyStartX,
|
||||
btnBuyStartY,
|
||||
btnBuySizeX,
|
||||
btnBuySizeY //
|
||||
);
|
||||
if (result)
|
||||
{
|
||||
eaMainWindow.Run();
|
||||
//
|
||||
// Apply Buy Button Style ...
|
||||
|
||||
//
|
||||
btnBuy.Text("Buy");
|
||||
btnBuy.Color(clrYellow);
|
||||
btnBuy.ColorBackground(clrGreen);
|
||||
}
|
||||
|
||||
//
|
||||
// Sell ...
|
||||
int btnSellStartX = btnBuyStartX + btnBuySizeX;
|
||||
int btnSellSizeX = btnSellStartX + 100;
|
||||
int btnSellStartY = btnBuyStartY;
|
||||
int btnSellSizeY = btnBuySizeY;
|
||||
string btnSellName = objSuffix + "BTN_SELL";
|
||||
result = btnSell.Create(
|
||||
chartId,
|
||||
btnSellName,
|
||||
subWindow,
|
||||
btnSellStartX,
|
||||
btnSellStartY,
|
||||
btnSellSizeX,
|
||||
btnSellSizeY //
|
||||
);
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
// Apply Sell Button Style ...
|
||||
|
||||
//
|
||||
btnSell.Text("Sell");
|
||||
btnSell.Color(clrYellow);
|
||||
btnSell.ColorBackground(clrDarkRed);
|
||||
}
|
||||
|
||||
//
|
||||
// LABEL Position ID ...
|
||||
lblPositionIdStartX = btnBuyStartX;
|
||||
lblPositionIdSizeX = lblPositionIdStartX + 100;
|
||||
lblPositionIdStartY = btnSellSizeY + 5;
|
||||
lblPositionIdSizeY = lblPositionIdStartY + 50;
|
||||
string lblPositionIdName = objSuffix + "LBL_POS_ID";
|
||||
result = lblPositionId.Create(
|
||||
chartId,
|
||||
lblPositionIdName,
|
||||
subWindow,
|
||||
lblPositionIdStartX,
|
||||
lblPositionIdStartY,
|
||||
lblPositionIdSizeX,
|
||||
lblPositionIdSizeY //
|
||||
);
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
// Apply Label Position ID Style ...
|
||||
lblPositionId.ReadOnly(true);
|
||||
lblPositionId.Text("Pos ID: ");
|
||||
lblPositionId.Color(clrYellow);
|
||||
lblPositionId.ColorBackground(clrDarkGray);
|
||||
}
|
||||
|
||||
//
|
||||
// Close ...
|
||||
int btnCloseStartX = startX;
|
||||
int btnCloseSizeX = btnCloseStartX + 100;
|
||||
int btnCloseStartY = lblPositionIdSizeY + 5;
|
||||
int btnCloseSizeY = lblPositionIdSizeY + 50;
|
||||
string btnCloseName = objSuffix + "BTN_CLOSE";
|
||||
result = btnClose.Create(
|
||||
chartId,
|
||||
btnCloseName,
|
||||
subWindow,
|
||||
btnCloseStartX,
|
||||
btnCloseStartY,
|
||||
btnCloseSizeX,
|
||||
btnCloseSizeY //
|
||||
);
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
// Apply Close Button Style ...
|
||||
|
||||
//
|
||||
btnClose.Text("Close");
|
||||
btnClose.Color(clrYellow);
|
||||
btnClose.ColorBackground(clrDarkOrange);
|
||||
}
|
||||
|
||||
//
|
||||
// Close All ...
|
||||
int btnCloseAllStartX = btnCloseSizeX + 5;
|
||||
int btnCloseAllSizeX = btnCloseAllStartX + 100;
|
||||
int btnCloseAllStartY = lblPositionIdSizeY + 5;
|
||||
int btnCloseAllSizeY = lblPositionIdSizeY + 50;
|
||||
string btnCloseAllName = objSuffix + "BTN_CLOSE_ALL";
|
||||
result = btnCloseAll.Create(
|
||||
chartId,
|
||||
btnCloseAllName,
|
||||
subWindow,
|
||||
btnCloseAllStartX,
|
||||
btnCloseAllStartY,
|
||||
btnCloseAllSizeX,
|
||||
btnCloseAllSizeY //
|
||||
);
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
// Apply Close Button Style ...
|
||||
|
||||
//
|
||||
btnCloseAll.Text("Close All");
|
||||
btnCloseAll.Color(clrYellow);
|
||||
btnCloseAll.ColorBackground(clrDarkRed);
|
||||
}
|
||||
|
||||
//
|
||||
UpdateGUIState();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
@@ -345,7 +528,94 @@ bool InitGUI()
|
||||
void UpdateGUI()
|
||||
{
|
||||
//
|
||||
eaMainWindow.UpdateState();
|
||||
UpdateGUIState();
|
||||
|
||||
//
|
||||
// Buy Button Pressed ...
|
||||
if (btnBuy.Pressed())
|
||||
{
|
||||
//
|
||||
HandleBuyTrade();
|
||||
btnBuy.Pressed(false);
|
||||
}
|
||||
|
||||
//
|
||||
// Sell Button Pressed ...
|
||||
if (btnSell.Pressed())
|
||||
{
|
||||
//
|
||||
HandleSellTrade();
|
||||
btnSell.Pressed(false);
|
||||
}
|
||||
|
||||
//
|
||||
// Close Button Pressed ...
|
||||
if (btnClose.Pressed())
|
||||
{
|
||||
//
|
||||
if (btnClose.IsEnabled())
|
||||
{
|
||||
//
|
||||
if (selectedPositionID > 0)
|
||||
{
|
||||
HandleCloseTrade(selectedPositionID);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
btnClose.Pressed(false);
|
||||
}
|
||||
|
||||
//
|
||||
// Close All Button Pressed ...
|
||||
if (btnCloseAll.Pressed())
|
||||
{
|
||||
//
|
||||
if (btnCloseAll.IsEnabled())
|
||||
{
|
||||
HandleCloseTrade(0);
|
||||
}
|
||||
|
||||
//
|
||||
btnCloseAll.Pressed(false);
|
||||
}
|
||||
|
||||
//
|
||||
// Check Positions Buttons ...
|
||||
int posCount = posArray.Total();
|
||||
bool has = IsValidSize(posCount);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
for (int i = 0; i < posCount; i++)
|
||||
{
|
||||
//
|
||||
CButton *iBtn = (CButton *)posArray.At(i);
|
||||
|
||||
//
|
||||
if (iBtn.Pressed())
|
||||
{
|
||||
//
|
||||
if (iBtn.IsEnabled())
|
||||
{
|
||||
//
|
||||
ulong posID = ExtractPositionIDFromButtonName(iBtn.Name());
|
||||
if (posID > 0 && selectedPositionID != posID)
|
||||
{
|
||||
selectedPositionID = posID;
|
||||
UpdateGUIState();
|
||||
Print("Changed Selected Pos ID: ", selectedPositionID);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
iBtn.Pressed(false);
|
||||
}
|
||||
|
||||
//
|
||||
ZeroMemory(iBtn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -354,5 +624,448 @@ void UpdateGUI()
|
||||
void DestroyGUI()
|
||||
{
|
||||
//
|
||||
eaMainWindow.Destroy();
|
||||
delete mChartHelper;
|
||||
ZeroMemory(mChartHelper);
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
//
|
||||
// Trade Event Handlers ...
|
||||
|
||||
/**
|
||||
* Handle StopLoss Triggered Positions ...
|
||||
*
|
||||
* @param deal: XDeal instance ...
|
||||
*/
|
||||
void OnStopLossTriggered(const XDeal &deal)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Take Profit Triggered Positions ...
|
||||
*
|
||||
* @param deal: XDeal instance ...
|
||||
*/
|
||||
void OnTakeProfitTriggered(const XDeal &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 //
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Deals Changes ...
|
||||
*
|
||||
* @param count: Integer, Number of Changes ...
|
||||
*/
|
||||
void OnDealsChanged(int count)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Orders Changes ...
|
||||
*
|
||||
* @param count: Integer, Number of Changes ...
|
||||
*/
|
||||
void OnOrdersChanged(int count)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Positions Changes ...
|
||||
*
|
||||
* @param count: Integer, Number of Changes ...
|
||||
*/
|
||||
void OnPositionsChanged(int count)
|
||||
{
|
||||
//
|
||||
// Update Position Buttons ...
|
||||
UpdatePositionButtons();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 //
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 //
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Trade State Changed ...
|
||||
*
|
||||
* @param state: XOnTradeHandlerState instance ...
|
||||
*/
|
||||
void OnTradeStateChanged(const XOnTradeHandlerState &state)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// GUI Event Handlers and Helpers ...
|
||||
|
||||
//
|
||||
void HandleBuyTrade()
|
||||
{
|
||||
HandleTrade(X_DIRECTION_BULLISH);
|
||||
}
|
||||
|
||||
//
|
||||
void HandleSellTrade()
|
||||
{
|
||||
HandleTrade(X_DIRECTION_BEARISH);
|
||||
}
|
||||
|
||||
//
|
||||
void HandleTrade(ENUM_X_DIRECTION dir)
|
||||
{
|
||||
//
|
||||
if (!HasDirection(dir))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
string symbol = mChartHelper.Symbol();
|
||||
ENUM_TIMEFRAMES period = mChartHelper.Period();
|
||||
|
||||
//
|
||||
bool isBullish = IsSpecifiedBullish(dir);
|
||||
|
||||
//
|
||||
double r2r = 1.5;
|
||||
double volume = 0.01;
|
||||
double riskInPoints = 100;
|
||||
double point = GetPoints(symbol);
|
||||
double entry = GetEntry(symbol, dir);
|
||||
|
||||
//
|
||||
double risk = riskInPoints * point;
|
||||
double reward = risk * r2r;
|
||||
|
||||
//
|
||||
double sl = isBullish
|
||||
? entry - risk
|
||||
: entry + risk;
|
||||
double tp = isBullish
|
||||
? entry + reward
|
||||
: entry - reward;
|
||||
|
||||
//
|
||||
string comment = ShortName + "_POS_" + ToXString(dir);
|
||||
|
||||
//
|
||||
if (isBullish)
|
||||
{
|
||||
//
|
||||
eaTrader.Buy(
|
||||
symbol,
|
||||
period,
|
||||
volume,
|
||||
entry,
|
||||
sl,
|
||||
tp,
|
||||
comment //
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
eaTrader.Sell(
|
||||
symbol,
|
||||
period,
|
||||
volume,
|
||||
entry,
|
||||
sl,
|
||||
tp,
|
||||
comment //
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void HandleCloseTrade(ulong positionID)
|
||||
{
|
||||
//
|
||||
if (positionID == 0)
|
||||
{
|
||||
//
|
||||
// Force Close All ...
|
||||
Print("Close All Positions ...");
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Close Specified Position ...
|
||||
Print("Close Position: ", positionID);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
ulong ExtractPositionIDFromButtonName(string name)
|
||||
{
|
||||
//
|
||||
ulong result = 0;
|
||||
|
||||
//
|
||||
string nameParts[];
|
||||
int namePartsCount = SplitContent(nameParts, name, "_");
|
||||
bool has = IsValidSize(namePartsCount);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
string lastPart = nameParts[namePartsCount - 1];
|
||||
StringReplace(lastPart, "_", "");
|
||||
result = (long)lastPart;
|
||||
}
|
||||
|
||||
//
|
||||
SpecifiedClean(nameParts);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
void UpdatePositionButtons()
|
||||
{
|
||||
//
|
||||
// Retrieve Positions ...
|
||||
XPosition positions[];
|
||||
int count = eaTrader.GetPositions(
|
||||
positions //
|
||||
);
|
||||
bool has = IsValidSize(count);
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
posArray.Clear();
|
||||
selectedPositionID = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
posArray.Clear();
|
||||
|
||||
//
|
||||
// Selected Position ID ...
|
||||
if (selectedPositionID == 0)
|
||||
{
|
||||
//
|
||||
XPosition youngest;
|
||||
int youngestIDX = GetXYoungest(youngest, positions);
|
||||
bool hasYoungest = IsValidIndex(youngestIDX) &&
|
||||
youngest.IsValid();
|
||||
if (hasYoungest)
|
||||
{
|
||||
selectedPositionID = youngest.ticket;
|
||||
}
|
||||
|
||||
//
|
||||
youngest.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
int subWindow = 0;
|
||||
ulong chartId = mChartHelper.ChartId();
|
||||
|
||||
//
|
||||
int btnWidth = 25;
|
||||
|
||||
//
|
||||
int lastX = lblPositionIdSizeX + 5;
|
||||
int lastSizeX = lastX + btnWidth;
|
||||
|
||||
//
|
||||
int lastY = lblPositionIdStartY;
|
||||
int lastSizeY = lblPositionIdSizeY;
|
||||
|
||||
//
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
XPosition iPos = positions[i];
|
||||
|
||||
//
|
||||
string posTypeStr = IsLong(iPos.type)
|
||||
? "LONG"
|
||||
: "SHORT";
|
||||
|
||||
//
|
||||
int iPosBtnX = lastX;
|
||||
int iPosBtnSizeX = iPosBtnX + btnWidth;
|
||||
string iPosBtnName = objSuffix + "_" + posTypeStr + "_POS_SELECT_BTN_" + ToXString(iPos.ticket);
|
||||
|
||||
//
|
||||
CButton *iPosBtn = new CButton();
|
||||
has = iPosBtn.Create(
|
||||
chartId,
|
||||
iPosBtnName,
|
||||
subWindow,
|
||||
iPosBtnX,
|
||||
lastY,
|
||||
iPosBtnSizeX,
|
||||
lastSizeY //
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
// Apply Styles ...
|
||||
string iPosBtnText = ToXString(iPos.ticket);
|
||||
|
||||
//
|
||||
iPosBtn.Text(iPosBtnText);
|
||||
iPosBtn.Color(clrWhite);
|
||||
|
||||
//
|
||||
color iPosBtnBG = IsLong(iPos.type)
|
||||
? clrGreen
|
||||
: clrDarkRed;
|
||||
iPosBtn.ColorBackground(iPosBtnBG);
|
||||
|
||||
//
|
||||
lastX = iPosBtnSizeX + 5;
|
||||
|
||||
//
|
||||
if (selectedPositionID == iPos.ticket)
|
||||
{
|
||||
iPosBtn.Disable();
|
||||
}
|
||||
|
||||
//
|
||||
posArray.Add(iPosBtn);
|
||||
}
|
||||
|
||||
//
|
||||
iPos.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
SpecifiedClean(positions);
|
||||
UpdateGUIState();
|
||||
}
|
||||
|
||||
//
|
||||
void UpdateGUIState()
|
||||
{
|
||||
//
|
||||
// Update States Of Position Select Buttons ...
|
||||
int count = posArray.Total();
|
||||
bool has = IsValidSize(count) && selectedPositionID > 0;
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
CButton *iBtn = (CButton *)posArray.At(i);
|
||||
|
||||
//
|
||||
ulong posID = ExtractPositionIDFromButtonName(iBtn.Name());
|
||||
|
||||
//
|
||||
// Select Position ...
|
||||
XPosition iPos;
|
||||
bool hasPosition = eaTrader.GetPosition(
|
||||
posID,
|
||||
iPos //
|
||||
);
|
||||
string iTooltip =
|
||||
!hasPosition
|
||||
? ""
|
||||
: IsLong(iPos.type)
|
||||
? "Long"
|
||||
: "Short";
|
||||
|
||||
//
|
||||
if (posID == selectedPositionID)
|
||||
{
|
||||
//
|
||||
iBtn.Disable();
|
||||
iBtn.ColorBackground(clrDarkGray);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
iBtn.Enable();
|
||||
|
||||
//
|
||||
color iBtnBG = IsLong(iPos.type)
|
||||
? clrGreen
|
||||
: clrDarkRed;
|
||||
|
||||
//
|
||||
iBtn.ColorBackground(iBtnBG);
|
||||
}
|
||||
|
||||
//
|
||||
ZeroMemory(iBtn);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Update State of Close All ...
|
||||
if (has && count > 1)
|
||||
{
|
||||
//
|
||||
btnCloseAll.Enable();
|
||||
btnCloseAll.ColorBackground(clrDarkRed);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
btnCloseAll.Disable();
|
||||
btnCloseAll.ColorBackground(clrDarkGray);
|
||||
}
|
||||
|
||||
//
|
||||
// Update State of BtnClose and BtnClose All ...
|
||||
if (selectedPositionID == 0)
|
||||
{
|
||||
//
|
||||
btnClose.Disable();
|
||||
btnClose.ColorBackground(clrDarkGray);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
btnClose.Enable();
|
||||
btnClose.ColorBackground(clrDarkOrange);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
@@ -570,6 +570,25 @@ double NormalizePrice(
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize Chart Id ...
|
||||
*
|
||||
* @param _chartId: ulong
|
||||
*
|
||||
* @return ( ulong )
|
||||
*/
|
||||
ulong NormalizeChartId(ulong _chartId = 0)
|
||||
{
|
||||
//
|
||||
if (_chartId <= 0)
|
||||
{
|
||||
_chartId = ChartID();
|
||||
}
|
||||
|
||||
//
|
||||
return _chartId;
|
||||
}
|
||||
|
||||
//
|
||||
// END Normalizations ...
|
||||
//
|
||||
|
||||
@@ -4248,7 +4248,7 @@ int GetYoungest(
|
||||
|
||||
//
|
||||
int iAge = GetAge(iItem);
|
||||
if (iAge > 0 &&
|
||||
if (iAge >= 0 &&
|
||||
(tmpAge == 0 || tmpAge > iAge))
|
||||
{
|
||||
//
|
||||
@@ -4258,7 +4258,7 @@ int GetYoungest(
|
||||
}
|
||||
|
||||
//
|
||||
if (tmpAge > 0)
|
||||
if (tmpAge >= 0)
|
||||
{
|
||||
//
|
||||
result = tmpAge;
|
||||
|
||||
Reference in New Issue
Block a user