Orders Execution
Miscellaneous
0
Views
0
Downloads
0
Favorites
SimpleOrderPanel
//+------------------------------------------------------------------+
//| SimpleOrderPanel.mq5 |
//| Copyright 2022, Manuel Alejandro Cercós Pérez |
//| https://www.mql5.com/en/users/alexcercos |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, Manuel Alejandro Cercós Pérez"
#property link "https://www.mql5.com/en/users/alexcercos"
//#property icon "\\Images\\ProgramIcons\\simplePanelLogo.ico" //Not included
#property version "2.08"
//+------------------------------------------------------------------+
//| CHANGES NEEDED TO FIX ISSUES |
//+------------------------------------------------------------------+
// To avoid some errors, it's necessary to change code in Dialog.mqh
// file (to modify variables that are defined as private).
// Take into consideration that changes made in standard library
// files are reverted with each terminal update. To avoid errors
// when recompiling you can:
// - Track with git the changes made in the file to revert the deletion
// - Copy the file "Dialog.mqh" into another folder and change
// dependencies as needed, so it doesn't change later
//
// If you are using MT4, I recommend using the Controls classes from MT5
// To open the file, press "Alt + G" with the cursor set over the line
// "#include <Controls\Dialog.mqh>" below.
//
// The errors would appear when FIRST COMPILING or after RECOMPILING
//
//+------------------------------------------------------------------+
//| ISSUE 1: DUPLICATED OBJECTS WHEN USING TEMPLATES |
//+------------------------------------------------------------------+
#define M_NAME "12345" //Override in panel identifier
//
// Change the function "CreateInstanceId" to the one below:
//+-------------------------------------------------------------------+
// string CAppDialog::CreateInstanceId(void)
// {
// #ifdef M_NAME
// return M_NAME;
// #else
// return(IntegerToString(rand(),5,'0'));
// #endif
// }
//+-------------------------------------------------------------------+
//
// If you don't use templates and want to remove the macro M_NAME,
// delete also the following line in this file, at the beginning of
// OnInitEvent (line 1303):
//+-------------------------------------------------------------------+
// ObjectsDeleteAll(0, M_NAME);
//+-------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| ISSUE 2: HEADER FONT SIZE |
//+------------------------------------------------------------------+
// This issue is not as common (only if your PC has a different text
// size setting than default). You can modify manually the font sizes
// with the input "fontSize". If you want the header text size to
// change too:
//
// Uncomment this line (465) in CControlsDialog::Create
//+-------------------------------------------------------------------+
// CaptionFontSize(fontSize);
//+-------------------------------------------------------------------+
//
// Add the function definition to the class CDialog (in public or
// protected sections, between lines ~45-85)
//+-------------------------------------------------------------------+
// void CaptionFontSize(const int size) { m_caption.FontSize(size); }
//+-------------------------------------------------------------------+
#include <Controls\Dialog.mqh>
#include <Controls\Button.mqh>
#include <Controls\Edit.mqh>
#include <Controls\Label.mqh>
#ifdef __MQL5__
#include <Trade\PositionInfo.mqh>
#include <Trade\OrderInfo.mqh>
#include <Trade\Trade.mqh>
#define POS_TOTAL PositionsTotal()
#define ORD_TOTAL OrdersTotal()
#define ASK_PRICE SymbolInfoDouble(_Symbol, SYMBOL_ASK)
#define BID_PRICE SymbolInfoDouble(_Symbol, SYMBOL_BID)
#define POS_SELECT_BY_INDEX(i) if (!m_position.SelectByIndex(i)) continue;
#define POS_SYMBOL m_position.Symbol()
#define POS_MAGIC m_position.Magic()
#define POS_TYPE m_position.PositionType()
#define POS_OPEN m_position.PriceOpen()
#define POS_STOP m_position.StopLoss()
#define POS_TAKE_PROFIT m_position.TakeProfit()
#define POS_TICKET m_position.Ticket()
#define ORD_SELECT_BY_INDEX(i) if (!m_order.SelectByIndex(i)) continue;
#define ORD_SYMBOL m_order.Symbol()
#define ORD_MAGIC m_order.Magic()
#define ORD_TYPE m_order.OrderType()
#define ORD_OPEN m_order.PriceOpen()
#define ORD_STOP m_order.StopLoss()
#define ORD_TAKE_PROFIT m_order.TakeProfit()
#define ORD_TICKET m_order.Ticket()
#define POS_BUY(lots, price, sl, tp) m_trade.Buy(lots, _Symbol, price, sl, tp, trade_comment);
#define POS_SELL(lots, price, sl, tp) m_trade.Sell(lots, _Symbol, price, sl, tp, trade_comment);
#define ORDER_BUY_LIMIT(lots, price, sl, tp) m_trade.BuyLimit(lots, price, _Symbol, sl, tp, ORDER_TIME_GTC, 0, trade_comment);
#define ORDER_BUY_STOP(lots, price, sl, tp) m_trade.BuyStop(lots, price, _Symbol, sl, tp, ORDER_TIME_GTC, 0, trade_comment);
#define ORDER_SELL_LIMIT(lots, price, sl, tp) m_trade.SellLimit(lots, price, _Symbol, sl, tp, ORDER_TIME_GTC, 0, trade_comment);
#define ORDER_SELL_STOP(lots, price, sl, tp) m_trade.SellStop(lots, price, _Symbol, sl, tp, ORDER_TIME_GTC, 0, trade_comment);
#define POS_MODIFY(ticket, stop, take) if(!m_trade.PositionModify(ticket, stop, take)) Print("Error modyfing position: ",GetLastError());
#define POS_CLOSE(ticket) if(!m_trade.PositionClose(ticket)) Print("Error closing position, ",GetLastError());
#define POS_CLOSE_PARTIAL(ticket) if(!m_trade.PositionClosePartial(ticket, partialLots)) Print("Error closing partial position, ",GetLastError());
#define ORD_DELETE(ticket) if (!m_trade.OrderDelete(ticket)) Print("Error deleting order, ",GetLastError());
#define ORD_MODIFY(ticket, stop, take) if (!m_trade.OrderModify(ticket, ORD_OPEN, stop, take, ORDER_TIME_GTC, 0)) Print("Error modyfing order: ",GetLastError());
#define TRIM_STRING_LEFT(param) StringTrimLeft(param)
#define TRIM_STRING_RIGHT(param) StringTrimRight(param)
CTrade m_trade;
CPositionInfo m_position;
COrderInfo m_order;
#else //__MQL4__
#define POSITION_TYPE_BUY OP_BUY
#define POSITION_TYPE_SELL OP_SELL
#define POS_TOTAL OrdersTotal()
#define ORD_TOTAL OrdersTotal()
#define ASK_PRICE Ask
#define BID_PRICE Bid
#define POS_SELECT_BY_INDEX(i) if(!OrderSelect(i, SELECT_BY_POS,MODE_TRADES)) continue;
#define POS_SYMBOL OrderSymbol()
#define POS_MAGIC OrderMagicNumber()
#define POS_TYPE OrderType()
#define POS_OPEN OrderOpenPrice()
#define POS_STOP OrderStopLoss()
#define POS_TAKE_PROFIT OrderTakeProfit()
#define POS_TICKET OrderTicket()
#define ORD_SELECT_BY_INDEX(i) if(!OrderSelect(i, SELECT_BY_POS,MODE_TRADES)) continue;
#define ORD_SYMBOL OrderSymbol()
#define ORD_MAGIC OrderMagicNumber()
#define ORD_TYPE OrderType()
#define ORD_OPEN OrderOpenPrice()
#define ORD_STOP OrderStopLoss()
#define ORD_TAKE_PROFIT OrderTakeProfit()
#define ORD_TICKET OrderTicket()
#define POS_BUY(lots, price, sl, tp) OrderSend(_Symbol, OP_BUY, lots, price, expertDeviation, sl, tp, trade_comment, expertMagic, 0, clrNONE);
#define POS_SELL(lots, price, sl, tp) OrderSend(_Symbol, OP_SELL, lots, price, expertDeviation, sl, tp, trade_comment, expertMagic, 0, clrNONE);
#define ORDER_BUY_LIMIT(lots, price, sl, tp) OrderSend(_Symbol, OP_BUYLIMIT, lots, NormalizeDouble(price,_Digits), expertDeviation, sl, tp, trade_comment, expertMagic, 0, clrNONE);
#define ORDER_BUY_STOP(lots, price, sl, tp) OrderSend(_Symbol, OP_BUYSTOP, lots, NormalizeDouble(price,_Digits), expertDeviation, sl, tp, trade_comment, expertMagic, 0, clrNONE);
#define ORDER_SELL_LIMIT(lots, price, sl, tp) OrderSend(_Symbol, OP_SELLLIMIT, lots, NormalizeDouble(price,_Digits), expertDeviation, sl, tp, trade_comment, expertMagic, 0, clrNONE);
#define ORDER_SELL_STOP(lots, price, sl, tp) OrderSend(_Symbol, OP_SELLSTOP, lots, NormalizeDouble(price,_Digits), expertDeviation, sl, tp, trade_comment, expertMagic, 0, clrNONE);
#define POS_MODIFY(ticket, stop, take) if (!OrderModify(ticket, POS_OPEN, stop, take, OrderExpiration(), clrNONE)) Print("Error modyfing position: ",GetLastError());
#define POS_CLOSE(ticket) if(POS_TYPE==POSITION_TYPE_BUY) { if(!OrderClose(ticket,OrderLots(),BID_PRICE,expertDeviation)) Print("Error closing position, ",GetLastError()); } else if(POS_TYPE==POSITION_TYPE_SELL) { if(!OrderClose(ticket,OrderLots(),ASK_PRICE,expertDeviation)) Print("Error closing position, ",GetLastError()); }
#define POS_CLOSE_PARTIAL(ticket) if(POS_TYPE==POSITION_TYPE_BUY) { if(!OrderClose(ticket,MathMin(partialLots, OrderLots()),BID_PRICE,expertDeviation)) Print("Error closing partial position, ",GetLastError()); } else if(POS_TYPE==POSITION_TYPE_SELL) { if(!OrderClose(ticket,MathMin(partialLots, OrderLots()),ASK_PRICE,expertDeviation)) Print("Error closing partial position, ",GetLastError()); }
#define ORD_DELETE(ticket) if (!OrderDelete(ticket)) Print("Error deleting order, ",GetLastError());
#define ORD_MODIFY(ticket, stop, take) if (!OrderModify(ticket, ORD_OPEN, stop, take, OrderExpiration(), clrNONE)) Print("Error modyfing order: ",GetLastError());
#define TRIM_STRING_LEFT(param) param=StringTrimLeft(param)
#define TRIM_STRING_RIGHT(param) param=StringTrimRight(param)
#endif
//+------------------------------------------------------------------+
//| defines |
//+------------------------------------------------------------------+
//--- indents and gaps
#define INDENT_LEFT (11) // indent from left (with allowance for border width)
#define INDENT_TOP (11) // indent from top (with allowance for border width)
#define INDENT_RIGHT (11) // indent from right (with allowance for border width)
#define INDENT_BOTTOM (11) // indent from bottom (with allowance for border width)
#define CONTROLS_GAP_X (10) // gap by X coordinate
#define CONTROLS_GAP_Y (10) // gap by Y coordinate
//--- for buttons
#define BUTTON_WIDTH (100) // size by X coordinate
#define BUTTON_HEIGHT (25) // size by Y coordinate
#define RISK_LABEL "RISK"
#define STOP_EDIT "SL_EDIT"
#define TAKE_EDIT "TP_EDIT"
#define RISK_EDIT "R_EDIT"
#define BUY_BUTTON "BUY"
#define SELL_BUTTON "SELL"
#define BREAKEVEN_BUTTON "SL BREAKEVEN"
#define CLOSE_BUTTON "CLOSE ALL"
#define CLOSE_BUY_BUTTON "CLOSE BUYS"
#define CLOSE_SELL_BUTTON "CLOSE SELLS"
#define STOP_BUTTON "MODIFY SL"
#define TAKE_BUTTON "MODIFY TP"
#define PARTIAL_EDIT "PARTIAL_EDIT"
#define PARTIAL_BUTTON "CLOSE PARTIAL"
#define COMMENT_EDIT "COMM_EDIT"
#define BUY_PEND_BUTTON "PENDING BUY"
#define SELL_PEND_BUTTON "PENDING SELL"
#define DELETE_BUY_PEND_BUTTON "DEL BUY ORD."
#define DELETE_SELL_PEND_BUTTON "DEL SELL ORD."
#define GVAR_POSITION_X "SimplePanel_positionX"
#define GVAR_POSITION_Y "SimplePanel_positionY"
#define GVAR_RISK_NAME "SimplePanel_risk_percent"
#define GVAR_CALC_TYPE "SimplePanel_calc_mode"
#define GVAR_STOP_LOSS "SimplePanel_stop_loss"
#define GVAR_TAKE_PROFIT "SimplePanel_take_profit"
#define GVAR_PARTIAL_LOTS "SimplePanel_partial_close"
//+------------------------------------------------------------------+
//| Enumerators (for inputs) |
//+------------------------------------------------------------------+
enum RiskMode
{
BALANCE_PERCENT, //Percentage of balance
FIXED_LOTS //Fixed lots
};
enum SLTPMode
{
ST_PRICE, //Price
ST_DISTANCE //Distance to open price (>0)
};
enum BidAskMode
{
BA_NORMAL, //Bid for sell/Ask for buy
BA_INVERT, //Ask for sell/Bid for buy (inv)
BA_ONLY_ASK,//Only Ask price
BA_ONLY_BID //Only Bid price
};
//+------------------------------------------------------------------+
//| Inputs |
//+------------------------------------------------------------------+
#ifdef __MQL5__
input group "Trade Settings"
#endif
input RiskMode riskCalculation = FIXED_LOTS; //Risk calculation mode
input SLTPMode stop_takeMode = ST_DISTANCE; // SL/TP Mode
input BidAskMode bidAskReference = BA_NORMAL; //Price reference for SL and TP
input int expertDeviation = 20; // Maximum slippage
input int expertMagic = 450913; // Expert Magic number
input bool affectOtherTrades = false; // Modify external trades (not opened by the panel)
#ifdef __MQL5__
input group "Buttons"
#endif
input bool showBuySellButtons = true; // Show Buy/Sell buttons
input bool showCloseSepButtons = false; // Show Close Buy/Sell buttons
input bool showSLBECloseAllButtons = true; // Show SL to BE and Close All buttons
input bool showModifyButtons = false; // Show Modify SL/TP buttons
input bool showPartialClose = false; // Show Partial Close
input bool showPendingOrder = false; // Show Pending Orders
input bool showDeleteOrder = false; // Show Delete Pending Orders
input bool showCommentEdit = false; // Show Edit Comment
#ifdef __MQL5__
input group "Other settings"
#endif
input bool grabSLwithDrag = false; //Pick SL values with crosshair drag (Dist. mode)
input int fontSize = 10; //Font size
input double autoSetTP = 0.0; //Auto-set TP to SL ratio (0=don't use)
input bool autoSetSL = true; //Auto-set SL to ratio from TP change
#ifdef __MQL5__
input bool asyncOperations = false; //Use asynchronous orders
#endif
int lot_digits = 2;
double riskAmount = 2.0;
double stopLoss = 0.0;
double takeProfit = 0.0;
double partialLots = 1.0;
string trade_comment = NULL;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CControlsDialog : public CAppDialog
{
private:
CLabel m_label, m_stoploss_label, m_takeprofit_label;
CEdit m_edit, m_stoploss_edit, m_takeprofit_edit;
CButton m_buy_button, m_sell_button, m_breakeven_button, m_close_button, m_modify_sl_button, m_modify_tp_button;
CButton m_close_buys_button, m_close_sell_button, m_buy_order_button, m_sell_order_button, m_delete_buy_button, m_delete_sell_button;
CEdit m_partial_edit;
CButton m_partial_button;
CEdit m_comment_edit;
public:
//--- create
virtual bool Create(const string name);
//--- chart event handler
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
double GetRiskPercent();
double GetStopLoss();
double GetTakeProfit();
double GetPartialLots();
void SetStopLoss(int stop);
protected:
//--- create dependent controls
bool CreateButton(CButton &button, string name, int x1, int y1, int x2, int y2, color clr_back=clrDarkCyan);
bool CreateEdit(CEdit &edit, string name, string editText, int x1, int y1, int x2, int y2);
bool CreateLabel(CLabel &label, string name, int x1, int y1, int x2, int y2);
//--- handlers of the dependent controls events
void OnEndEditRisk(void);
void OnEndEditSL(void);
void OnEndEditTP(void);
void OnClickBuyButton(void);
void OnClickSellButton(void);
void OnClickBreakevenButton(void);
void OnClickCloseButton(void);
void OnClickCloseBuyButton(void);
void OnClickCloseSellButton(void);
void OnClickModifySLButton(void);
void OnClickModifyTPButton(void);
void OnEditPartialClose(void);
void OnClickPartialCloseButton(void);
void OnEditComment(void);
void OnClickBuyOrderButton(void);
void OnClickSellOrderButton(void);
void OnClickDeleteBuyOrders(void);
void OnClickDeleteSellOrders(void);
void WriteExpertSettings();
void RestoreExpertSettings();
void RestoreStopTakeValues();
void RestoreComment();
void SaveComment();
double NormalizeLots(double lots);
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CControlsDialog)
ON_EVENT(ON_END_EDIT, m_edit, OnEndEditRisk)
ON_EVENT(ON_END_EDIT, m_stoploss_edit, OnEndEditSL)
ON_EVENT(ON_END_EDIT, m_takeprofit_edit, OnEndEditTP)
if (showBuySellButtons)
{
ON_EVENT(ON_CLICK, m_buy_button, OnClickBuyButton)
ON_EVENT(ON_CLICK, m_sell_button, OnClickSellButton)
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
if (showCloseSepButtons)
{
ON_EVENT(ON_CLICK, m_close_buys_button, OnClickCloseBuyButton)
ON_EVENT(ON_CLICK, m_close_sell_button, OnClickCloseSellButton)
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
if (showSLBECloseAllButtons)
{
ON_EVENT(ON_CLICK, m_breakeven_button, OnClickBreakevenButton)
ON_EVENT(ON_CLICK, m_close_button, OnClickCloseButton)
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
if (showModifyButtons)
{
ON_EVENT(ON_CLICK, m_modify_sl_button, OnClickModifySLButton)
ON_EVENT(ON_CLICK, m_modify_tp_button, OnClickModifyTPButton)
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
if (showPartialClose)
{
ON_EVENT(ON_END_EDIT, m_partial_edit, OnEditPartialClose)
ON_EVENT(ON_CLICK, m_partial_button, OnClickPartialCloseButton)
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
if (showCommentEdit)
{
ON_EVENT(ON_END_EDIT, m_comment_edit, OnEditComment)
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
if (showPendingOrder)
{
ON_EVENT(ON_CLICK, m_buy_order_button, OnClickBuyOrderButton)
ON_EVENT(ON_CLICK, m_sell_order_button, OnClickSellOrderButton)
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
if (showDeleteOrder)
{
ON_EVENT(ON_CLICK, m_delete_buy_button, OnClickDeleteBuyOrders)
ON_EVENT(ON_CLICK, m_delete_sell_button, OnClickDeleteSellOrders)
}
EVENT_MAP_END(CAppDialog)
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CControlsDialog::Create(const string name)
{
stopLoss = 0.0;
takeProfit = 0.0;
partialLots = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
RestoreExpertSettings();
int rows = 3;
if (showBuySellButtons) rows++;
if (showCloseSepButtons) rows++;
if (showSLBECloseAllButtons) rows++;
if (showModifyButtons) rows++;
if (showPartialClose) rows++;
if (showCommentEdit) rows++;
if (showPendingOrder) rows++;
if (showDeleteOrder) rows++;
if (rows == 3)
{
Print("Error: no buttons are being shown");
return false;
}
//Get position
int x1 = 100;
int y1 = 40;
if (GlobalVariableCheck(GVAR_POSITION_X))
x1 = (int)GlobalVariableGet(GVAR_POSITION_X);
else
GlobalVariableSet(GVAR_POSITION_X, x1);
if (GlobalVariableCheck(GVAR_POSITION_Y))
y1 = (int)GlobalVariableGet(GVAR_POSITION_Y);
else
GlobalVariableSet(GVAR_POSITION_Y, y1);
int x2 = 8 + x1 + INDENT_LEFT + 2 * BUTTON_WIDTH + CONTROLS_GAP_X + INDENT_RIGHT;
int y2 = 30 + y1 + INDENT_TOP + rows * BUTTON_HEIGHT + (rows - 1) * CONTROLS_GAP_Y + INDENT_BOTTOM;
if(!CAppDialog::Create(0, name, 1, x1, y1, x2, y2))
return(false);
//CaptionFontSize(fontSize); //CUSTOM function defined in CDialog
int bx1=INDENT_LEFT;
int by1=INDENT_TOP;
int bx2=bx1+BUTTON_WIDTH;
int by2=by1+BUTTON_HEIGHT;
#define NEXT_COLUMN \
bx1 += (BUTTON_WIDTH+CONTROLS_GAP_X); \
bx2 += (BUTTON_WIDTH+CONTROLS_GAP_X);
#define PREV_COLUMN \
bx1 -= (BUTTON_WIDTH+CONTROLS_GAP_X); \
bx2 -= (BUTTON_WIDTH+CONTROLS_GAP_X);
#define NEXT_ROW \
by1 += (BUTTON_HEIGHT+CONTROLS_GAP_Y); \
by2 += (BUTTON_HEIGHT+CONTROLS_GAP_Y);
if(!CreateLabel(m_label, riskCalculation==BALANCE_PERCENT?"RISK %":"LOTS", bx1+BUTTON_WIDTH/2, by1, bx2, by2))
return(false);
NEXT_COLUMN
string riskText;
if (riskCalculation == BALANCE_PERCENT)
riskText = DoubleToString(riskAmount, 2) + " %";
else
riskText = DoubleToString(riskAmount, lot_digits);
if(!CreateEdit(m_edit, RISK_EDIT, riskText, bx1, by1, bx2, by2))
return(false);
PREV_COLUMN
NEXT_ROW
if(!CreateLabel(m_stoploss_label, stop_takeMode==ST_DISTANCE?"SL (points)":"SL (price)", bx1+BUTTON_WIDTH/3, by1, bx2, by2))
return(false);
NEXT_COLUMN
string sl_edit_str = stop_takeMode==ST_DISTANCE?DoubleToString(stopLoss, 0):DoubleToString(stopLoss, _Digits);
if(!CreateEdit(m_stoploss_edit, STOP_EDIT, sl_edit_str, bx1, by1, bx2, by2))
return(false);
PREV_COLUMN
NEXT_ROW
if(!CreateLabel(m_takeprofit_label, stop_takeMode==ST_DISTANCE?"TP (points)":"TP (price)", bx1+BUTTON_WIDTH/3, by1, bx2, by2))
return(false);
NEXT_COLUMN
string tp_edit_str = stop_takeMode==ST_DISTANCE?DoubleToString(takeProfit, 0):DoubleToString(takeProfit, _Digits);
if(!CreateEdit(m_takeprofit_edit, TAKE_EDIT, tp_edit_str, bx1, by1, bx2, by2))
return(false);
if (showBuySellButtons)
{
PREV_COLUMN
NEXT_ROW
if(!CreateButton(m_buy_button, BUY_BUTTON, bx1, by1, bx2, by2, clrGreen))
return(false);
NEXT_COLUMN
if(!CreateButton(m_sell_button, SELL_BUTTON, bx1, by1, bx2, by2, clrRed))
return(false);
}
if (showCloseSepButtons)
{
PREV_COLUMN
NEXT_ROW
if(!CreateButton(m_close_buys_button, CLOSE_BUY_BUTTON, bx1, by1, bx2, by2, clrDarkSlateGray))
return(false);
NEXT_COLUMN
if(!CreateButton(m_close_sell_button, CLOSE_SELL_BUTTON, bx1, by1, bx2, by2, clrDarkRed))
return(false);
}
if (showSLBECloseAllButtons)
{
PREV_COLUMN
NEXT_ROW
if(!CreateButton(m_breakeven_button, BREAKEVEN_BUTTON, bx1, by1, bx2, by2, clrGray))
return(false);
NEXT_COLUMN
if(!CreateButton(m_close_button, CLOSE_BUTTON, bx1, by1, bx2, by2, clrBlue))
return(false);
}
if (showModifyButtons)
{
PREV_COLUMN
NEXT_ROW
if(!CreateButton(m_modify_sl_button, STOP_BUTTON, bx1, by1, bx2, by2, clrIndianRed))
return(false);
NEXT_COLUMN
if(!CreateButton(m_modify_tp_button, TAKE_BUTTON, bx1, by1, bx2, by2, clrDarkCyan))
return(false);
}
if (showPartialClose)
{
PREV_COLUMN
NEXT_ROW
string partialEdit = DoubleToString(partialLots, lot_digits);
if(!CreateEdit(m_partial_edit, PARTIAL_EDIT, partialEdit, bx1, by1, bx2, by2))
return(false);
NEXT_COLUMN
if(!CreateButton(m_partial_button, PARTIAL_BUTTON, bx1, by1, bx2, by2, clrSlateBlue))
return(false);
}
if (showPendingOrder)
{
PREV_COLUMN
NEXT_ROW
if(!CreateButton(m_buy_order_button, BUY_PEND_BUTTON, bx1, by1, bx2, by2, clrLimeGreen))
return(false);
NEXT_COLUMN
if(!CreateButton(m_sell_order_button, SELL_PEND_BUTTON, bx1, by1, bx2, by2, clrOrangeRed))
return(false);
}
if (showDeleteOrder)
{
PREV_COLUMN
NEXT_ROW
if(!CreateButton(m_delete_buy_button, DELETE_BUY_PEND_BUTTON, bx1, by1, bx2, by2, clrDarkGreen))
return(false);
NEXT_COLUMN
if(!CreateButton(m_delete_sell_button, DELETE_SELL_PEND_BUTTON, bx1, by1, bx2, by2, clrMaroon))
return(false);
}
if (showCommentEdit)
{
bx1 -= (BUTTON_WIDTH+CONTROLS_GAP_X); //Keep bx2 at the end
NEXT_ROW
if(!CreateEdit(m_comment_edit, COMMENT_EDIT, trade_comment, bx1, by1, bx2, by2))
return(false);
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateButton(CButton &button, string name,int x1,int y1,int x2,int y2, color clr_back=clrDarkCyan)
{
//--- create
if(!button.Create(m_chart_id, m_name+name, m_subwin, x1, y1, x2, y2))
return(false);
if(!button.Text(name))
return(false);
if (!button.FontSize(fontSize))
return(false);
button.ColorBorder(clrBlack);
button.Color(clrWhite);
button.ColorBackground(clr_back);
if(!Add(button))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double CControlsDialog::GetRiskPercent(void)
{
if (riskCalculation == FIXED_LOTS)
return NormalizeLots(StringToDouble(m_edit.Text()));
return MathMin(MathMax(StringToDouble(m_edit.Text()), 0.0), 100.0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double CControlsDialog::GetStopLoss(void)
{
return MathMax(StringToDouble(m_stoploss_edit.Text()), 0.0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double CControlsDialog::GetTakeProfit(void)
{
return MathMax(StringToDouble(m_takeprofit_edit.Text()), 0.0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double CControlsDialog::GetPartialLots(void)
{
return NormalizeLots(StringToDouble(m_partial_edit.Text()));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateEdit(CEdit &edit, string name, string editText, int x1, int y1, int x2, int y2)
{
//--- create
if(!edit.Create(m_chart_id,m_name+name,m_subwin,x1,y1,x2,y2))
return(false);
if(!edit.ReadOnly(false))
return(false);
if(!edit.Text(editText))
return(false);
if (!edit.FontSize(fontSize))
return(false);
if(!edit.TextAlign(ALIGN_CENTER))
return(false);
if(!Add(edit))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateLabel(CLabel &label,string name,int x1,int y1,int x2,int y2)
{
//--- create
if(!label.Create(m_chart_id,m_name+name,m_subwin,x1,y1,x2,y2))
return(false);
if(!label.Text(name))
return(false);
if (!label.FontSize(fontSize))
return(false);
if(!Add(label))
return(false);
//--- succeed
return(true);
}
#define PENDING_SETLINE "SOP_setline"
//+------------------------------------------------------------------+
//| Event handler |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickBuyButton(void)
{
Print("Buy pressed");
RecalculateValues(POSITION_TYPE_BUY);
if (!CheckLots()) return;
double ask = ASK_PRICE;
double sl = 0.0;
double tp = 0.0;
if (stop_takeMode == ST_PRICE)
{
sl = stopLoss;
tp = takeProfit;
}
else
{
double ref = (bidAskReference==BA_NORMAL || bidAskReference==BA_ONLY_ASK)?ask:BID_PRICE;
if (stopLoss != 0.0)
sl = ref - stopLoss * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
if (takeProfit != 0.0)
tp = ref + takeProfit * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
}
POS_BUY(totalLots, ask, sl, tp)
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickBuyOrderButton(void)
{
Print("Pending Buy pressed");
setting_buy = true;
setting_sell = false;
CreatePendingSetLine(clrGreen, ASK_PRICE);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickSellButton(void)
{
Print("Sell pressed");
RecalculateValues(POSITION_TYPE_SELL);
if (!CheckLots()) return;
double bid = BID_PRICE;
double sl = 0.0;
double tp = 0.0;
if (stop_takeMode == ST_PRICE)
{
sl = stopLoss;
tp = takeProfit;
}
else
{
double ref = (bidAskReference==BA_NORMAL || bidAskReference==BA_ONLY_BID)?bid:ASK_PRICE;
if (stopLoss !=0.0)
sl = ref + stopLoss * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
if (takeProfit != 0.0)
tp = ref - takeProfit * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
}
POS_SELL(totalLots, bid, sl, tp)
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickSellOrderButton(void)
{
Print("Pending Sell pressed");
setting_sell = true;
setting_buy = false;
CreatePendingSetLine(clrRed, BID_PRICE);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickBreakevenButton(void)
{
Print("Breakeven pressed");
for(int i = POS_TOTAL-1; i>=0; i--)
{
POS_SELECT_BY_INDEX(i)
if(POS_SYMBOL==_Symbol && (affectOtherTrades || POS_MAGIC==expertMagic))
{
if (POS_TYPE == POSITION_TYPE_BUY)
{
double bid = BID_PRICE;
if (bid <= POS_OPEN)
{
continue;
}
}
else if (POS_TYPE == POSITION_TYPE_SELL)
{
double ask = ASK_PRICE;
if (ask >= POS_OPEN)
{
continue;
}
}
else
continue; //Pending orders
if (POS_OPEN == POS_STOP)
{
continue;
}
POS_MODIFY(POS_TICKET, POS_OPEN, POS_TAKE_PROFIT)
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickCloseButton(void)
{
Print("Close pressed");
for(int i = POS_TOTAL-1; i>=0; i--)
{
POS_SELECT_BY_INDEX(i)
if(POS_SYMBOL==_Symbol && (affectOtherTrades || POS_MAGIC==expertMagic))
{
POS_CLOSE(POS_TICKET)
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickCloseBuyButton(void)
{
Print("Close Buy pressed");
for(int i = POS_TOTAL-1; i>=0; i--)
{
POS_SELECT_BY_INDEX(i)
if (POS_TYPE == POSITION_TYPE_SELL) continue;
if(POS_SYMBOL==_Symbol && (affectOtherTrades || POS_MAGIC==expertMagic))
{
POS_CLOSE(POS_TICKET)
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickDeleteBuyOrders(void)
{
Print("Delete Pending Buys pressed");
for (int j=ORD_TOTAL-1; j>=0; j--)
{
ORD_SELECT_BY_INDEX(j)
if (ORD_TYPE != ORDER_TYPE_BUY_LIMIT && ORD_TYPE != ORDER_TYPE_BUY_STOP) continue;
if (ORD_SYMBOL==_Symbol && (affectOtherTrades || ORD_MAGIC==expertMagic))
{
ORD_DELETE(ORD_TICKET)
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickCloseSellButton(void)
{
Print("Close Sell pressed");
for(int i = POS_TOTAL-1; i>=0; i--)
{
POS_SELECT_BY_INDEX(i)
if (POS_TYPE == POSITION_TYPE_BUY) continue;
if(POS_SYMBOL==_Symbol && (affectOtherTrades || POS_MAGIC==expertMagic))
{
POS_CLOSE(POS_TICKET)
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickDeleteSellOrders(void)
{
Print("Delete Pending Sell pressed");
for (int j=ORD_TOTAL-1; j>=0; j--)
{
ORD_SELECT_BY_INDEX(j)
if (ORD_TYPE != ORDER_TYPE_SELL_LIMIT && ORD_TYPE != ORDER_TYPE_SELL_STOP) continue;
if (ORD_SYMBOL==_Symbol && (affectOtherTrades || ORD_MAGIC==expertMagic))
{
ORD_DELETE(ORD_TICKET)
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickModifySLButton(void)
{
Print("Modify Stop Loss pressed");
for(int i = POS_TOTAL-1; i>=0; i--)
{
POS_SELECT_BY_INDEX(i)
if(POS_SYMBOL==_Symbol && (affectOtherTrades || POS_MAGIC==expertMagic))
{
double sl = 0.0;
if (stop_takeMode == ST_PRICE)
{
sl = stopLoss;
}
else
{
if (stopLoss !=0.0)
{
if (POS_TYPE == POSITION_TYPE_BUY) sl = BID_PRICE - stopLoss * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
else if (POS_TYPE == POSITION_TYPE_SELL) sl = ASK_PRICE + stopLoss * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
else continue; //Pending orders
}
}
if (sl != POS_STOP)
{
POS_MODIFY(POS_TICKET, sl, POS_TAKE_PROFIT)
}
else
{
Print("Stop Loss is already " + (string)sl);
}
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickModifyTPButton(void)
{
Print("Modify Take Profit pressed");
for(int i = POS_TOTAL-1; i>=0; i--)
{
POS_SELECT_BY_INDEX(i)
if(POS_SYMBOL==_Symbol && (affectOtherTrades || POS_MAGIC==expertMagic))
{
double tp = 0.0;
if (stop_takeMode == ST_PRICE)
{
tp = takeProfit;
}
else
{
if (takeProfit !=0.0)
{
if (POS_TYPE == POSITION_TYPE_BUY) tp = ASK_PRICE + takeProfit * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
else if (POS_TYPE == POSITION_TYPE_SELL) tp = BID_PRICE - takeProfit * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
else continue;
}
}
if (tp != POS_TAKE_PROFIT)
{
POS_MODIFY(POS_TICKET, POS_STOP, tp)
}
else
{
Print("Take Profit is already " + (string)tp);
}
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickPartialCloseButton(void)
{
Print("Close Partial pressed");
for(int i = POS_TOTAL-1; i>=0; i--)
{
POS_SELECT_BY_INDEX(i)
if(POS_SYMBOL==_Symbol && (affectOtherTrades || POS_MAGIC==expertMagic))
{
POS_CLOSE_PARTIAL(POS_TICKET)
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::OnEndEditRisk(void)
{
riskAmount = GetRiskPercent();
if (riskCalculation == BALANCE_PERCENT)
m_edit.Text(DoubleToString(riskAmount, 2) + " %");
else
m_edit.Text(DoubleToString(riskAmount, lot_digits));
WriteExpertSettings();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::OnEndEditSL(void)
{
stopLoss = GetStopLoss();
if (stop_takeMode== ST_PRICE)
m_stoploss_edit.Text(DoubleToString(stopLoss, _Digits));
else
m_stoploss_edit.Text(DoubleToString(stopLoss, 0));
if (autoSetTP>0.0 && stop_takeMode==ST_DISTANCE)
{
takeProfit = MathRound(stopLoss*autoSetTP);
m_takeprofit_edit.Text(DoubleToString(takeProfit,0));
}
WriteExpertSettings();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::OnEndEditTP(void)
{
takeProfit = GetTakeProfit();
if (stop_takeMode== ST_PRICE)
m_takeprofit_edit.Text(DoubleToString(takeProfit, _Digits));
else
m_takeprofit_edit.Text(DoubleToString(takeProfit, 0));
if (autoSetSL && autoSetTP>0.0 && stop_takeMode==ST_DISTANCE)
{
stopLoss = MathRound(takeProfit/autoSetTP);
m_stoploss_edit.Text(DoubleToString(stopLoss,0));
}
WriteExpertSettings();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::OnEditPartialClose(void)
{
partialLots = GetPartialLots();
m_partial_edit.Text(DoubleToString(partialLots, lot_digits));
WriteExpertSettings();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::OnEditComment(void)
{
trade_comment = m_comment_edit.Text();
SaveComment();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::RestoreExpertSettings(void)
{
if (showCommentEdit)
RestoreComment();
else
trade_comment=NULL;
if (GlobalVariableCheck(GVAR_RISK_NAME))
{
riskAmount = GlobalVariableGet(GVAR_RISK_NAME);
if (riskCalculation==FIXED_LOTS)
riskAmount = NormalizeLots(riskAmount);
partialLots = NormalizeLots(GlobalVariableGet(GVAR_PARTIAL_LOTS));
RestoreStopTakeValues();
}
else
{
WriteExpertSettings();
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::WriteExpertSettings(void)
{
GlobalVariableSet(GVAR_RISK_NAME, riskAmount);
GlobalVariableSet(GVAR_CALC_TYPE, stop_takeMode);
GlobalVariableSet(GVAR_STOP_LOSS, stopLoss);
GlobalVariableSet(GVAR_TAKE_PROFIT, takeProfit);
GlobalVariableSet(GVAR_PARTIAL_LOTS, partialLots);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::RestoreStopTakeValues(void)
{
if (GlobalVariableCheck(GVAR_CALC_TYPE))
{
int typeCalc = (int)GlobalVariableGet(GVAR_CALC_TYPE);
if (typeCalc == stop_takeMode)
{
stopLoss = GlobalVariableGet(GVAR_STOP_LOSS);
takeProfit = GlobalVariableGet(GVAR_TAKE_PROFIT);
return;
}
}
WriteExpertSettings();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::RestoreComment(void)
{
if (!FileIsExist("SOP_SavedComment.txt"))
return;
int file = FileOpen("SOP_SavedComment.txt", FILE_READ|FILE_TXT|FILE_SHARE_READ);
if (file==INVALID_HANDLE)
{
Print("Error reading comment in file");
return;
}
trade_comment = FileReadString(file);
FileClose(file);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::SaveComment(void)
{
int file = FileOpen("SOP_SavedComment.txt", FILE_WRITE|FILE_TXT);
if (file==INVALID_HANDLE)
{
Print("Error saving comment in file");
return;
}
FileWrite(file, trade_comment);
FileClose(file);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double CControlsDialog::NormalizeLots(double lots)
{
double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
return MathMax(SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN),
MathMin(SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX),
MathFloor(lots / lotStep) * lotStep));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CControlsDialog::SetStopLoss(int stop)
{
stopLoss = stop;
m_stoploss_edit.Text(IntegerToString(stop));
if (autoSetTP>0.0 && stop_takeMode==ST_DISTANCE)
{
takeProfit = MathRound(stopLoss*autoSetTP);
m_takeprofit_edit.Text(DoubleToString(takeProfit,0));
}
ChartRedraw();
WriteExpertSettings();
}
//+------------------------------------------------------------------+
//| Global Variables |
//+------------------------------------------------------------------+
CControlsDialog ExtDialog;
double totalLots;
MqlRates currentRates[2];
bool is_tracking=false;
double recorded_price = 0.0;
bool setting_buy=false;
bool setting_sell=false;
int xysub;
double xyprice;
datetime xytime;
//+------------------------------------------------------------------+
//| Event handlers |
//+------------------------------------------------------------------+
int OnInitEvent()
{
ObjectsDeleteAll(0, M_NAME); //Remove elements in chart (for template issues)
lot_digits = int(-MathLog10(SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP)));
if(!ExtDialog.Create("Simple Panel"))
return(INIT_FAILED);
ExtDialog.Run();
#ifdef __MQL5__
m_trade.SetExpertMagicNumber(expertMagic);
m_trade.SetDeviationInPoints(expertDeviation);
if (asyncOperations) m_trade.SetAsyncMode(true);
#endif
setting_buy = false;
setting_sell = false;
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnDeinitEvent(const int reason)
{
GlobalVariableSet(GVAR_POSITION_X, ExtDialog.Left());
GlobalVariableSet(GVAR_POSITION_Y, ExtDialog.Top());
DeletePendingSetLine();
Comment("");
ExtDialog.Destroy(reason);
}
#define MASK_RIGHT_CLICK 2
#define MASK_RIGHT_MIDDLE 16
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CommonChartEvent(const int id, // event ID
const long& lparam, // event parameter of the long type
const double& dparam, // event parameter of the double type
const string& sparam) // event parameter of the string type
{
if (setting_buy || setting_sell)
{
int smask = (int)StringToInteger(sparam);
if ((id==CHARTEVENT_KEYDOWN && lparam==27) || //ESC
(id==CHARTEVENT_MOUSE_MOVE &&
((smask&MASK_RIGHT_CLICK)>0 ||
(smask&MASK_RIGHT_MIDDLE)>0)
)
)
{
DeletePendingSetLine();
setting_buy = false;
setting_sell = false;
return;
}
}
if (setting_buy)
{
if (id==CHARTEVENT_CLICK)
{
DeletePendingSetLine();
ChartXYToTimePrice(ChartID(), (int)lparam, (int)dparam, xysub, xytime, xyprice);
OpenBuyPendingOrder(xyprice);
setting_buy = false;
return;
}
if (id==CHARTEVENT_MOUSE_MOVE)
{
ChartXYToTimePrice(ChartID(), (int)lparam, (int)dparam, xysub, xytime, xyprice);
MovePendingSetLine(xyprice);
return;
}
}
if (setting_sell)
{
if (id==CHARTEVENT_CLICK)
{
DeletePendingSetLine();
ChartXYToTimePrice(ChartID(), (int)lparam, (int)dparam, xysub, xytime, xyprice);
OpenSellPendingOrder(xyprice);
setting_sell = false;
return;
}
if (id==CHARTEVENT_MOUSE_MOVE)
{
ChartXYToTimePrice(ChartID(), (int)lparam, (int)dparam, xysub, xytime, xyprice);
MovePendingSetLine(xyprice);
return;
}
}
if (!grabSLwithDrag || stop_takeMode == ST_PRICE)
return;
if (id==CHARTEVENT_CLICK)
{
if (!is_tracking) return;
if (!(recorded_price>0.0))
{
is_tracking=false;
return;
}
ChartXYToTimePrice(ChartID(), (int)lparam, (int)dparam, xysub, xytime, xyprice);
#ifdef __MQL5__
int pips = (int)MathRound(MathAbs(xyprice-recorded_price)/SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE));
#else
int pips = (int)(MathAbs(xyprice-recorded_price)/SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE));
#endif
if (pips>0)
ExtDialog.SetStopLoss(pips);
is_tracking = false;
recorded_price = 0.0;
}
if (id==CHARTEVENT_MOUSE_MOVE)
{
if (sparam!="1") return;
if (is_tracking) return;
ChartXYToTimePrice(ChartID(), (int)lparam, (int)dparam, xysub, xytime, xyprice);
if (xysub>0) return;
recorded_price = xyprice;
is_tracking = true;
}
if (id==CHARTEVENT_CHART_CHANGE || id==CHARTEVENT_CUSTOM+ON_DRAG_PROCESS) //Stop on drag panel
{
if (recorded_price>0)
recorded_price=0.0;
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CreatePendingSetLine(color clr, double line_price)
{
if (ObjectFind(ChartID(), PENDING_SETLINE)<0)
ObjectCreate(ChartID(), PENDING_SETLINE, OBJ_HLINE, 0, 0, line_price);
ObjectSetInteger(ChartID(), PENDING_SETLINE, OBJPROP_COLOR, clr);
ObjectSetInteger(ChartID(), PENDING_SETLINE, OBJPROP_SELECTABLE, false);
ObjectSetInteger(ChartID(), PENDING_SETLINE, OBJPROP_HIDDEN, false);
ObjectSetString(ChartID(), PENDING_SETLINE, OBJPROP_TOOLTIP, "\n");
ChartRedraw();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void MovePendingSetLine(double line_price)
{
ObjectSetDouble(ChartID(), PENDING_SETLINE, OBJPROP_PRICE, line_price);
ChartRedraw();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void DeletePendingSetLine()
{
ObjectDelete(ChartID(), PENDING_SETLINE);
ChartRedraw();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void RecalculateValues(int position, double price_ref=0.0)
{
if (riskCalculation == FIXED_LOTS)
{
totalLots = riskAmount;
return;
}
double riskTotal = AccountInfoDouble(ACCOUNT_BALANCE) * riskAmount / 100.0;
//Si risk es 0, puede ser por cadena invalida
double sl = 0.0;
if (stop_takeMode == ST_PRICE)
{
if (stopLoss !=0.0)
{
if (price_ref>0.0) //pending
sl = MathAbs(price_ref-stopLoss);
else
{
if (position == POSITION_TYPE_BUY) sl = ASK_PRICE - stopLoss;
else if (position == POSITION_TYPE_SELL) sl = stopLoss - BID_PRICE;
}
}
}
else
{
sl = stopLoss * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
}
if (sl == 0.0)
{
totalLots = 0.0;
Print("Stop Loss Cannot be 0 with risk percent");
return;
}
sl /= SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double lotValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE_LOSS);
double pointValue = riskTotal / sl;
if (pointValue < 0)
{
totalLots = 0.0;
Print("Invalid stop");
return;
}
double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
totalLots = MathFloor((pointValue / lotValue) / lotStep) * lotStep;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CheckLots()
{
if (totalLots < SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN))
{
Print("Risk is too small to Open a trade");
return false;
}
if (totalLots > SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX))
{
Print("Lots are too big to Open a trade");
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| Pending orders |
//+------------------------------------------------------------------+
void OpenBuyPendingOrder(double order_price)
{
Print("Open Buy pending");
RecalculateValues(POSITION_TYPE_BUY, order_price);
if (!CheckLots()) return;
double sl = 0.0;
double tp = 0.0;
if (stop_takeMode == ST_PRICE)
{
sl = stopLoss;
tp = takeProfit;
}
else
{
if (stopLoss != 0.0)
sl = order_price - stopLoss * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
if (takeProfit != 0.0)
tp = order_price + takeProfit * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
}
if (order_price>ASK_PRICE)
{
ORDER_BUY_STOP(totalLots, order_price, sl, tp)
}
else
{
ORDER_BUY_LIMIT(totalLots, order_price, sl, tp)
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OpenSellPendingOrder(double order_price)
{
Print("Open Sell pending");
RecalculateValues(POSITION_TYPE_SELL, order_price);
if (!CheckLots()) return;
double sl = 0.0;
double tp = 0.0;
if (stop_takeMode == ST_PRICE)
{
sl = stopLoss;
tp = takeProfit;
}
else
{
if (stopLoss != 0.0)
sl = order_price + stopLoss * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
if (takeProfit != 0.0)
tp = order_price - takeProfit * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
}
if (order_price<BID_PRICE)
{
ORDER_SELL_STOP(totalLots, order_price, sl, tp)
}
else
{
ORDER_SELL_LIMIT(totalLots, order_price, sl, tp)
}
}
//+------------------------------------------------------------------+
int OnInit()
{
return OnInitEvent();
}
void OnDeinit(const int reason)
{
OnDeinitEvent(reason);
}
void OnChartEvent(const int id, // event ID
const long& lparam, // event parameter of the long type
const double& dparam, // event parameter of the double type
const string& sparam) // event parameter of the string type
{
ExtDialog.ChartEvent(id,lparam,dparam,sparam);
CommonChartEvent(id,lparam,dparam,sparam);
}
Comments
Markdown Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

`code`
```
code block
```
> blockquote
- Item 1
- Item 2
1. First item
2. Second item
---