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 ...
|
// Imports ...
|
||||||
#include "../Classes/x-saherelm.x-alert.class.mq5"
|
#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"
|
#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 ...
|
// Inputs ...
|
||||||
|
|
||||||
@@ -54,7 +71,32 @@ input bool eATerminalAlerts = false; // Terminal Alerts
|
|||||||
string eaLogTag; // EA Log Prefix ...
|
string eaLogTag; // EA Log Prefix ...
|
||||||
XCAlert *eaAlert; // Alert Provider for Expert Adviser ...
|
XCAlert *eaAlert; // Alert Provider for Expert Adviser ...
|
||||||
XCTrade *eaTrader; // Trader of 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 ...
|
// Event Handlers ...
|
||||||
@@ -148,6 +190,7 @@ void OnTick()
|
|||||||
// Handle On Trade Event ...
|
// Handle On Trade Event ...
|
||||||
void OnTrade()
|
void OnTrade()
|
||||||
{
|
{
|
||||||
|
//
|
||||||
eaTrader.HandleOnTrade();
|
eaTrader.HandleOnTrade();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,9 +211,6 @@ void OnChartEvent(
|
|||||||
const string &sparam //
|
const string &sparam //
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//
|
|
||||||
// Apply Chart Event on Main Window ...
|
|
||||||
eaMainWindow.ChartEvent(id, lparam, dparam, sparam);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -285,7 +325,19 @@ bool InitEA()
|
|||||||
eaSlippage,
|
eaSlippage,
|
||||||
eaMagicNumber //
|
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 ...
|
// TODO: Fix This ...
|
||||||
result = true;
|
result = true;
|
||||||
@@ -317,24 +369,155 @@ bool InitGUI()
|
|||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initialize Application Main Window ...
|
int subWindow = 0;
|
||||||
result = eaMainWindow.Create(
|
ulong chartId = ChartID();
|
||||||
ChartID(),
|
objSuffix = ShortName + "_";
|
||||||
ShortName, // Dialog Name ...
|
|
||||||
0, // SubWindow ...
|
|
||||||
10, // X1 ...
|
|
||||||
35, // Y1 ...
|
|
||||||
300, // X2 ...
|
|
||||||
200 // Y2 ...
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// 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)
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -345,7 +528,94 @@ bool InitGUI()
|
|||||||
void UpdateGUI()
|
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()
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize Chart Id ...
|
||||||
|
*
|
||||||
|
* @param _chartId: ulong
|
||||||
|
*
|
||||||
|
* @return ( ulong )
|
||||||
|
*/
|
||||||
|
ulong NormalizeChartId(ulong _chartId = 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (_chartId <= 0)
|
||||||
|
{
|
||||||
|
_chartId = ChartID();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return _chartId;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// END Normalizations ...
|
// END Normalizations ...
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -4248,7 +4248,7 @@ int GetYoungest(
|
|||||||
|
|
||||||
//
|
//
|
||||||
int iAge = GetAge(iItem);
|
int iAge = GetAge(iItem);
|
||||||
if (iAge > 0 &&
|
if (iAge >= 0 &&
|
||||||
(tmpAge == 0 || tmpAge > iAge))
|
(tmpAge == 0 || tmpAge > iAge))
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@@ -4258,7 +4258,7 @@ int GetYoungest(
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
if (tmpAge > 0)
|
if (tmpAge >= 0)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
result = tmpAge;
|
result = tmpAge;
|
||||||
|
|||||||
Reference in New Issue
Block a user