Files
MQL5Data/Classes/x-saherelm.x-rm.panel.class.mq5
T
2025-03-12 09:08:01 +03:30

1162 lines
22 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// --------------------------------------
// Name: XCRMPanel
// Description: provides all based classes for use ...
//
//
// 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.x-app-dialog.class.mq5"
#include "../Classes/x-saherelm.x-trade.class.mq5"
//
#include <ChartObjects/ChartObjectsArrows.mqh>
#include <ChartObjects/ChartObjectsFibo.mqh>
#include <ChartObjects/ChartObjectsLines.mqh>
#include <ChartObjects/ChartObjectsShapes.mqh>
#include <Controls/Button.mqh>
#include <Controls/Edit.mqh>
//
// Implementation ...
//
class XCRMPanel : public XCAppDialog
{
//
public:
//
// Event Binding ...
// EVENT_MAP_BEGIN(XCRMPanel)
// ON_EVENT(ON_CLICK, btnBuy, HandleBtnBuyClicked)
// ON_EVENT(ON_CLICK, btnSell, HandleBtnSellClicked)
// EVENT_MAP_END(XCRMPanel)
//
// Constructor(s) ...
void XCRMPanel()
{
//
Default();
}
//
// Deconstructor ...
void ~XCRMPanel()
{
//
HandleRemoveObjects();
//
ZeroMemory(mTrader);
}
//
// Props ...
//
int SubWindow()
{
return subWindow;
}
//
void SubWindow(int value)
{
//
if (value < 0)
{
value = 0;
}
//
subWindow = value;
}
//
// BUY ...
//
string BtnBuyLabel()
{
return buyLabelStr;
}
//
void BtnBuyLabel(string value)
{
buyLabelStr = value;
}
//
color BtnBuyBGColor()
{
return btnBuyBGColor;
}
//
void BtnBuyBGColor(color value)
{
btnBuyBGColor = value;
}
//
// SELL ...
//
string BtnSellLabel()
{
return sellLabelStr;
}
//
void BtnSellLabel(string value)
{
sellLabelStr = value;
}
//
color BtnSellBGColor()
{
return btnSellBGColor;
}
//
void BtnSellBGColor(color value)
{
btnSellBGColor = value;
}
//
double RiskPercent()
{
return riskPercent;
}
//
void RiskPercent(double value)
{
//
if (value < minAllowedRiskPercent)
{
value = minAllowedRiskPercent;
}
//
if (value > maxAllowedRiskPercent)
{
value = maxAllowedRiskPercent;
}
//
riskPercent = value;
//
tbRisk.Text((string)value);
}
//
//
//
bool HasSL()
{
return slLine != NULL;
}
double ReadSL()
{
//
double result = 0;
//
if (HasSL())
{
//
result = slLine.GetDouble(OBJPROP_PRICE);
result = NormalizePrice(result, _Symbol);
}
//
return result;
}
bool HasTP()
{
return tpLine != NULL;
}
double ReadTP()
{
//
double result = 0;
//
if (HasTP())
{
//
result = tpLine.GetDouble(OBJPROP_PRICE);
result = NormalizePrice(result, _Symbol);
}
//
return result;
}
bool HasEntry()
{
return entryLine != NULL;
}
double ReadEntry()
{
//
double result = 0;
//
if (HasEntry())
{
//
result = entryLine.GetDouble(OBJPROP_PRICE);
result = NormalizePrice(result, _Symbol);
}
//
return result;
}
bool GetDirection(ENUM_X_DIRECTION &dir)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
//
result = HasTP() &&
HasSL() &&
HasEntry();
//
if (!result)
{
return result;
}
//
double sl = ReadSL();
double tp = ReadTP();
double entry = ReadEntry();
//
result = sl > 0 &&
tp > 0 &&
entry > 0;
if (!result)
{
return result;
}
//
bool isBullish =
tp > entry &&
tp > sl &&
entry > sl;
bool isBearish =
tp < entry &&
tp < sl &&
entry < sl;
result = isBullish ||
isBearish;
if (!result)
{
return result;
}
//
dir = isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
return result;
}
//
// Tools ...
//
void Default()
{
//
string prefix = CreateInstanceId();
//
defaultR2R = 2;
riskPercent = 1;
defaultRisk = 50;
minAllowedRiskPercent = 0.5;
maxAllowedRiskPercent = 10.0;
//
disabledBtnColor = clrLightGray;
disabledBtnBGColor = clrGray;
//
tbRiskID = prefix + "_RiskTB";
//
buyLabelStr = "Buy";
btnBuyBGColor = clrLime;
btnBuyColor = clrDarkBlue;
btnBuyID = prefix + "_" + buyLabelStr;
//
sellLabelStr = "Sell";
btnSellBGColor = clrRed;
btnSellColor = clrDarkBlue;
btnSellID = prefix + "_" + sellLabelStr;
//
slLine = NULL;
slColor = clrMagenta;
slID = prefix + "_SL";
//
tpLine = NULL;
tpColor = clrAqua;
tpID = prefix + "_TP";
//
entryLine = NULL;
entryColor = clrYellow;
entryID = prefix + "_Entry";
//
btnDrawRemoveID = prefix + "_DrawRemove";
drawLabelStr = "Draw";
removeLabelStr = "Remove";
btnDrawColor = clrWhite;
btnDrawBGColor = clrDarkBlue;
btnRemoveColor = clrYellow;
btnRemoveBGColor = clrDarkRed;
//
slippage = 10;
magicNumber = 1694056;
//
// Create Trader Instance and Configure it ...
mTrader = new XCTrade(
slippage,
magicNumber //
);
}
//
void UpdateState()
{
//
bool canEnable = HasSL() &&
HasTP() &&
HasEntry();
//
if (canEnable)
{
SetRemoveMode();
}
else
{
SetDrawMode();
}
//
double entry = GetBid(_Symbol);
ENUM_X_DIRECTION dir;
if (GetDirection(dir))
{
entry = GetEntry(_Symbol, dir);
}
//
if (HasEntry())
{
double iEntry = ReadEntry();
if (iEntry != entry)
{
SetEntry(entry);
}
}
}
//
// Handlers ...
/**
* Handle Btn Buy Clicked ...
*/
void HandleBtnBuyClicked()
{
//
ENUM_X_DIRECTION dir;
bool has = GetDirection(dir);
bool isBullish = has &
IsBullish(dir);
if (!has || !isBullish)
{
return;
}
//
double tp = ReadTP();
double sl = ReadSL();
double entry = ReadEntry();
//
mTrader.Buy(
_Symbol,
_Period,
volume,
entry,
sl,
tp //
);
}
/**
* Handle Btn Sell Clicked ...
*/
void HandleBtnSellClicked()
{
//
ENUM_X_DIRECTION dir;
bool has = GetDirection(dir);
bool isBearish = has &
IsBearish(dir);
if (!has || !isBearish)
{
return;
}
//
double tp = ReadTP();
double sl = ReadSL();
double entry = ReadEntry();
//
mTrader.Sell(
_Symbol,
_Period,
volume,
entry,
sl,
tp //
);
}
/**
* Handle Draw Remove Position ...
*/
void HandleBtnDrawRemoveClicked()
{
//
string btnText = btnDrawRemove.Text();
if (btnText == drawLabelStr)
{
HandleDrawObjects();
}
else if (btnText == removeLabelStr)
{
HandleRemoveObjects();
}
}
/**
* Handle Risk Percent Changed ...
*/
void HandleOnRiskPercentChanged()
{
//
string tbRiskStr = tbRisk.Text();
//
double tbNewRisk = (double)tbRiskStr;
RiskPercent(tbNewRisk);
}
//
// Virtuals ...
//
virtual bool OnEvent(
const int id,
const long &lparam,
const double &dparam,
const string &sparam //
)
{
//
bool result = false;
//
XCAppDialog::OnEvent(id, lparam, dparam, sparam);
//
// Check if the event is a button click
if (id == ON_CLICK + CHARTEVENT_CUSTOM)
{
//
// Verify if the clicked object is this button
if (lparam == btnBuy.Id())
{
//
HandleBtnBuyClicked();
result = true;
}
else if (lparam == btnSell.Id())
{
//
HandleBtnSellClicked();
result = true;
}
else if (lparam == btnDrawRemove.Id())
{
//
HandleBtnDrawRemoveClicked();
result = true;
}
}
else if (id == ON_END_EDIT + CHARTEVENT_CUSTOM)
{
//
if (lparam == tbRisk.Id())
{
//
HandleOnRiskPercentChanged();
result = true;
}
}
else if (id == CHARTEVENT_OBJECT_DRAG)
{
//
if (sparam == entryLine.Name())
{
//
CalculateData();
result = true;
}
else if (sparam == tpLine.Name())
{
//
CalculateData();
result = true;
}
else if (sparam == slLine.Name())
{
//
CalculateData();
result = true;
}
}
//
return result;
}
//
// Overrides ...
//
bool Create(
const long chart,
const string name,
const int subwin,
const int x1,
const int y1,
const int x2,
const int y2 //
)
{
//
bool result = false;
//
// Create App Dialog instance it Self ...
result = XCAppDialog::Create(
chart,
name,
subwin,
x1,
y1,
x2,
y2 //
);
if (!result)
{
return result;
}
//
chartId = chart;
subWindow = subwin;
//
// Configure Dialog ...
BackgroundColor(clrBlack);
//
int top = Top();
int left = Left();
int right = Right();
int bottom = Bottom();
//
int width = Width();
int height = Height();
//
int desiredWidth = width - left;
int desiredHeight = height - top;
//
int btnWidth = desiredWidth / 2;
int btnHeight = desiredHeight / 3;
//
// Risk Edit ...
int tbRiskX1 = 0;
int tbRiskY1 = 0;
int tbRiskX2 = tbRiskX1 + (btnWidth * 2);
int tbRiskY2 = tbRiskY1 + btnHeight;
result = tbRisk.Create(
chart,
tbRiskID,
subWindow,
tbRiskX1,
tbRiskY1,
tbRiskX2,
tbRiskY2 //
);
if (!result)
{
return result;
}
//
result = tbRisk.Text((string)riskPercent);
result = tbRisk.TextAlign(ALIGN_CENTER);
//
result = Add(tbRisk);
//
// Create Draw/Remove Button ...
int btnDrawX1 = 0;
int btnDrawY1 = desiredHeight - (btnHeight * 2);
int btnDrawX2 = btnDrawX1 + (btnWidth * 2);
int btnDrawY2 = btnDrawY1 + btnHeight;
result = btnDrawRemove.Create(
chart,
btnDrawRemoveID,
subWindow,
btnDrawX1,
btnDrawY1,
btnDrawX2,
btnDrawY2 //
);
if (!result)
{
return result;
}
//
result = btnDrawRemove.Text(drawLabelStr);
result = btnDrawRemove.Color(btnDrawColor);
result = btnDrawRemove.ColorBackground(btnDrawBGColor);
//
result = Add(btnDrawRemove);
//
// Create Buy Button ...
int btnBuyX1 = 0;
int btnBuyY1 = desiredHeight - btnHeight;
int btnBuyX2 = btnBuyX1 + btnWidth;
int btnBuyY2 = btnBuyY1 + btnHeight;
result = btnBuy.Create(
chart,
btnBuyID,
subWindow,
btnBuyX1,
btnBuyY1,
btnBuyX2,
btnBuyY2 //
);
if (!result)
{
return result;
}
//
result = btnBuy.Text(buyLabelStr);
result = btnBuy.Color(btnBuyColor);
result = btnBuy.ColorBackground(btnBuyBGColor);
//
result = Add(btnBuy);
//
// Create Sell Button ...
int btnSellX1 = btnBuyX2;
int btnSellY1 = btnBuyY1;
int btnSellX2 = btnSellX1 + btnWidth;
int btnSellY2 = btnSellY1 + btnHeight;
result = btnSell.Create(
chart,
btnSellID,
subWindow,
btnSellX1,
btnSellY1,
btnSellX2,
btnSellY2 //
);
if (!result)
{
return result;
}
//
result = btnSell.Text(sellLabelStr);
result = btnSell.Color(btnSellColor);
result = btnSell.ColorBackground(btnSellBGColor);
//
result = Add(btnSell);
//
if (result)
{
//
UpdateState();
CalculateData();
}
//
return result;
}
//
protected:
//
XCTrade *mTrader;
int slippage;
long magicNumber;
//
long chartId;
int subWindow;
//
string slID;
color slColor;
CChartObjectHLine *slLine;
//
string tpID;
color tpColor;
CChartObjectHLine *tpLine;
//
string entryID;
color entryColor;
CChartObjectHLine *entryLine;
//
double riskPercent;
double minAllowedRiskPercent;
double maxAllowedRiskPercent;
//
double volume;
//
double defaultR2R;
double defaultRisk;
//
color disabledBtnColor;
color disabledBtnBGColor;
//
// Risk Percent Edit ...
CEdit tbRisk;
string tbRiskID;
//
// BUY Button ...
CButton btnBuy;
string btnBuyID;
string buyLabelStr;
color btnBuyColor;
color btnBuyBGColor;
//
// SELL Button ...
CButton btnSell;
string btnSellID;
string sellLabelStr;
color btnSellColor;
color btnSellBGColor;
//
// DRAW / REMOVE Button ...
CButton btnDrawRemove;
string btnDrawRemoveID;
string drawLabelStr;
string removeLabelStr;
color btnDrawColor;
color btnDrawBGColor;
color btnRemoveColor;
color btnRemoveBGColor;
//
private:
//
bool EnableBuy(bool value)
{
//
bool result = false;
//
btnBuy.Locking(!value);
btnSell.Pressed(value);
if (!value)
{
//
// Disabled ...
btnBuy.Color(disabledBtnColor);
btnBuy.ColorBackground(disabledBtnBGColor);
}
else
{
//
// Enable ...
btnBuy.Color(btnBuyColor);
btnBuy.ColorBackground(btnBuyBGColor);
}
//
return result;
}
bool EnableSell(bool value)
{
//
bool result = false;
//
btnSell.Locking(!value);
btnSell.Pressed(value);
if (!value)
{
//
// Disabled ...
btnSell.Color(disabledBtnColor);
btnSell.ColorBackground(disabledBtnBGColor);
}
else
{
//
// Enable ...
btnSell.Color(btnSellColor);
btnSell.ColorBackground(btnSellBGColor);
}
//
return result;
}
bool SetDrawMode()
{
//
bool result = false;
//
result = btnDrawRemove.Text(drawLabelStr);
result = btnDrawRemove.Color(btnDrawColor);
result = btnDrawRemove.ColorBackground(btnDrawBGColor);
//
return result;
}
bool SetRemoveMode()
{
//
bool result = false;
//
result = btnDrawRemove.Text(removeLabelStr);
result = btnDrawRemove.Color(btnRemoveColor);
result = btnDrawRemove.ColorBackground(btnRemoveBGColor);
//
return result;
}
void HandleDrawObjects()
{
//
double entry = GetBid(_Symbol);
double points = GetPoints(_Symbol);
double riskRatio = defaultRisk * points;
double rewardRatio = riskRatio * defaultR2R;
double sl = entry - riskRatio;
double tp = entry + rewardRatio;
//
datetime rectTime1 = iTime(
_Symbol,
_Period,
20 //
);
datetime rectTime2 = iTime(
_Symbol,
_Period,
19 //
);
//
bool has = false;
//
// Create Entry Line ...
entryLine = new CChartObjectHLine();
has = entryLine.Create(
chartId,
entryID,
subWindow,
entry //
);
if (!has)
{
//
HandleRemoveObjects();
return;
}
entryLine.Selectable(false);
entryLine.Color(entryColor);
//
// Create SL Line ...
slLine = new CChartObjectHLine();
has = slLine.Create(
chartId,
slID,
subWindow,
sl //
);
if (!has)
{
//
HandleRemoveObjects();
return;
}
slLine.Color(slColor);
slLine.Selectable(true);
//
// Create TP Line ...
tpLine = new CChartObjectHLine();
has = tpLine.Create(
chartId,
tpID,
subWindow,
tp //
);
if (!has)
{
//
HandleRemoveObjects();
return;
}
tpLine.Color(tpColor);
tpLine.Selectable(true);
//
CalculateData();
}
void HandleRemoveObjects()
{
//
if (HasSL())
{
//
slLine.Delete();
slLine.Detach();
ZeroMemory(slLine);
}
//
if (HasTP())
{
//
tpLine.Delete();
tpLine.Detach();
ZeroMemory(tpLine);
}
//
if (HasEntry())
{
//
entryLine.Delete();
entryLine.Detach();
ZeroMemory(entryLine);
}
//
UpdateState();
CalculateData();
}
void CalculateData()
{
//
EnableBuy(false);
EnableSell(false);
//
ENUM_X_DIRECTION dir;
bool has = GetDirection(dir);
if (!has)
{
return;
}
//
bool isBullish = IsBullish(dir);
bool isBearish = IsBearish(dir);
//
if (isBullish)
{
//
EnableBuy(true);
EnableSell(false);
}
else if (isBearish)
{
//
EnableSell(true);
EnableBuy(false);
}
//
double sl = ReadSL();
double tp = ReadTP();
double entry = ReadEntry();
double points = GetPoints(_Symbol);
//
double risk = MathAbs(entry - sl);
int riskPoints = (int)(risk / points);
double riskRewardRatio = MathAbs(tp - entry) / risk;
riskRewardRatio = NormalizeDouble(riskRewardRatio, 2);
//
double balance = GetBalance();
//
double riskAmount = riskPercent * (balance / 100);
riskAmount = NormalizePrice(riskAmount, _Symbol);
//
double rewardAmount = riskAmount * riskRewardRatio;
rewardAmount = NormalizePrice(rewardAmount, _Symbol);
//
string currency = mTrader.mAccount.GetCurrency();
//
volume = mTrader
.mAccount
.CalculateVolume(
_Symbol,
riskAmount,
riskPoints //
);
volume = NormalizeVolume(volume, _Symbol);
//
string slDesc = "SL: " + ToString(sl) +
", Risk: " + ToString(riskPoints) + " pt (" + ToString(riskPercent) + "%)" +
", Amount: " + ToString(riskAmount) + currency;
slLine.Tooltip(slDesc);
slLine.Description(slDesc);
//
string tpDesc = "TP: " + ToString(tp) + " (" + ToString(rewardAmount) + " " + currency + ")" +
", R2R: 1:" + ToString(riskRewardRatio);
tpLine.Tooltip(tpDesc);
tpLine.Description(tpDesc);
//
string entryDesc = "Entry: " + ToString(entry) +
", Volume: " + ToString(volume);
entryLine.Tooltip(entryDesc);
entryLine.Description(entryDesc);
//
}
void SetEntry(double value)
{
//
if (value <= 0 ||
!HasEntry())
{
return;
}
//
bool has = entryLine
.SetDouble(OBJPROP_PRICE, value);
}
double GetBalance()
{
//
double result = 0;
//
// TODO: Change This ...
return mTrader.mAccount.GetBalance();
//
return result;
}
//
};
//