746 lines
61 KiB
MQL5
746 lines
61 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| BSC Button.mq5 |
|
|
//| Copyright 2020, CompanyName |
|
|
//| http://www.companyname.net |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright © 2025, 4kk4"
|
|
#property link "https://www.mql5.com/en/users/4kk4"
|
|
#property version "2.2"
|
|
//---
|
|
#include <Trade\PositionInfo.mqh>
|
|
#include <Trade\Trade.mqh>
|
|
#include <Trade\SymbolInfo.mqh>
|
|
#include <Trade\AccountInfo.mqh>
|
|
#include <Trade\DealInfo.mqh>
|
|
#include <Trade\OrderInfo.mqh>
|
|
#include <Expert\Money\MoneyFixedMargin.mqh>
|
|
CPositionInfo m_position; // trade position object
|
|
CTrade m_trade; // trading object
|
|
CSymbolInfo m_symbol; // symbol info object
|
|
CAccountInfo m_account; // account info wrapper
|
|
CDealInfo m_deal; // deals object
|
|
COrderInfo m_order; // pending orders object
|
|
CMoneyFixedMargin *m_money;
|
|
CArrayLong m_arr_tickets;// array tickets
|
|
|
|
//--- input parameters
|
|
enum ENUM_CLOSE_SYMBOL
|
|
{
|
|
CLOSE_SYMBOL_CHART, // Current Chart Symbol
|
|
CLOSE_SYMBOL_ALL // All Symbols
|
|
};
|
|
|
|
enum ENUM_FONTTYPE
|
|
{
|
|
ARIAL, //Arial
|
|
ARIALBLACK, //Arial Black
|
|
VERDANA, //Verdana
|
|
TAHOMA, //Tahoma
|
|
COURIERNEW, //Courier New
|
|
LUCIDACONSOLE, //Lucida Console
|
|
BAKSOSAPI //Bakso Sapi
|
|
|
|
};
|
|
|
|
input group "Button Layout"
|
|
input ENUM_BASE_CORNER Corner = CORNER_RIGHT_UPPER; // Button Location Corner
|
|
input bool ShowButtons = true; //Show Buy Sell Buttons
|
|
input bool ShowCloseLost = false; //Show close on lost button
|
|
input int XDISTANCE = 70; // Button X position
|
|
input int YDISTANCE = 40; // Button Y position
|
|
input int XSIZE = 65; // Button width
|
|
input int YSIZE = 30; // Button height
|
|
input int fS = 10 ; // Font Size
|
|
input ENUM_FONTTYPE fName = BAKSOSAPI; // Font Name
|
|
string fN;
|
|
input group "Expert Management"
|
|
input uint RTOTAL = 5; // Retries
|
|
input uint SLEEPTIME = 500; // Sleep Time (msec)
|
|
input bool InpAsyncMode = true; // Asynchronous Mode
|
|
input bool InpDisAlgo = false; // Disable AlgoTrading Button
|
|
|
|
|
|
//--- input parameters
|
|
input group "Trades Management"
|
|
input ENUM_CLOSE_SYMBOL InpCloseSymbol = CLOSE_SYMBOL_CHART; // Symbols
|
|
|
|
input double InpLots = 0.01; //Lots
|
|
input ulong InpStopLoss = 500; //Stop Loss (1.00045-1.00055=1 pips/XAUUSD is x100)
|
|
input ulong InpTakeProfit = 4000; //Take Profit (1.00045-1.00055=1 pips/XAUUSD is x100)
|
|
input ulong InpTrailingStop = 2000; //Trail Stop (min distance from price to Stop Loss/XAUUSD x100)
|
|
input ulong InpTrailingStep = 500; //Trail Step (1.00045-1.00055=1 pips /XAUUSD x100)
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
input double closeProfitThreshold = 2000.0; //CLOSE IF PROFIT-fill with Above 0 (1.0)
|
|
input double closeLossThreshold = 0.0; //CLOSE IF LOSS-fill with Below 0 (minus : -1.0)
|
|
|
|
|
|
|
|
double ExtStopLoss=0.0;
|
|
double ExtTakeProfit=0.0;
|
|
double ExtTrailingStop=0.0;
|
|
double ExtTrailingStep=0.0;
|
|
double m_adjusted_point; // point value adjusted for 3 or 5 points
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert initialization function |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
//---
|
|
|
|
switch(fName)
|
|
|
|
{
|
|
case ARIAL:
|
|
fN = "Arial";
|
|
break;
|
|
case ARIALBLACK:
|
|
fN = "Arial Black";
|
|
break;
|
|
case VERDANA:
|
|
fN = "Verdana";
|
|
break;
|
|
case TAHOMA:
|
|
fN = "Tahoma";
|
|
break;
|
|
case COURIERNEW:
|
|
fN = "Courier New";
|
|
break;
|
|
case LUCIDACONSOLE:
|
|
fN = "Lucida Console";
|
|
break;
|
|
case BAKSOSAPI:
|
|
fN = "Bakso Sapi";
|
|
default:
|
|
fN = "Bakso Sapi";
|
|
break;
|
|
}
|
|
/*
|
|
if(InpTrailingStop!=0 && InpTrailingStep==0)
|
|
{
|
|
string err_text=(TerminalInfoString(TERMINAL_LANGUAGE)=="Indonesian")?
|
|
"Trailing Step!":
|
|
"Trailing is not possible: parameter \"Trailing Step\" is zero!";
|
|
//--- when testing, we will only output to the log about incorrect input parameters
|
|
if(MQLInfoInteger(MQL_TESTER))
|
|
{
|
|
Print(__FUNCTION__,", ERROR: ",err_text);
|
|
return(INIT_FAILED);
|
|
}
|
|
else // if the Expert Advisor is run on the chart, tell the user about the error
|
|
{
|
|
Alert(__FUNCTION__,", ERROR: ",err_text);
|
|
return(INIT_PARAMETERS_INCORRECT);
|
|
}
|
|
}
|
|
*/
|
|
//---
|
|
if(!m_symbol.Name(Symbol())) // sets symbol name
|
|
return(INIT_FAILED);
|
|
RefreshRates();
|
|
|
|
//--- tuning for 3 or 5 digits
|
|
int digits_adjust=1;
|
|
if(m_symbol.Digits()==3 || m_symbol.Digits()==5)
|
|
digits_adjust=1;
|
|
m_adjusted_point=m_symbol.Point()*digits_adjust;
|
|
|
|
ExtStopLoss = InpStopLoss * m_adjusted_point;
|
|
ExtTakeProfit = InpTakeProfit * m_adjusted_point;
|
|
ExtTrailingStop = InpTrailingStop * m_adjusted_point;
|
|
ExtTrailingStep = InpTrailingStep * m_adjusted_point;
|
|
|
|
int ydistance = YDISTANCE;
|
|
/*
|
|
if(!LabelCreate(0,"Ingat",0,XDISTANCE,ydistance,Corner, "Candle Close!",fN,fS,
|
|
clrWhite,0,ANCHOR_LEFT,clrNONE))
|
|
{
|
|
return(0);
|
|
}
|
|
*/
|
|
if(ShowButtons)
|
|
{
|
|
|
|
ydistance += YSIZE + 8;
|
|
if(!ButtonCreate(0,"OPENBUY",0,XDISTANCE,ydistance,XSIZE,YSIZE,Corner,"Buy",fN,fS, clrWhite, clrBlue))
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
ydistance += YSIZE + 5;
|
|
if(!ButtonCreate(0,"OPENSELL",0,XDISTANCE,ydistance,XSIZE,YSIZE,Corner,"Sell",fN,fS, clrWhite, clrRed))
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
ydistance = ydistance + YSIZE + 5;
|
|
if(!ButtonCreate(0,"CLOSEALL",0,XDISTANCE,ydistance,XSIZE,YSIZE,Corner,"Close",fN,fS, clrWhite, clrGreen))
|
|
{
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
if(ShowCloseLost)
|
|
{
|
|
// Button Create - Close Profitable
|
|
ydistance = ydistance + YSIZE + 5;
|
|
|
|
ObjectCreate(0, "CLOSEPROFITABLE", OBJ_BUTTON, 0, 0, 0);
|
|
ObjectSetInteger(0, "CLOSEPROFITABLE", OBJPROP_XDISTANCE, XDISTANCE); // X position
|
|
ObjectSetInteger(0, "CLOSEPROFITABLE", OBJPROP_XSIZE, YSIZE); // width
|
|
ObjectSetInteger(0, "CLOSEPROFITABLE", OBJPROP_YDISTANCE, ydistance); // Y position
|
|
ObjectSetInteger(0, "CLOSEPROFITABLE", OBJPROP_YSIZE, YSIZE); // height
|
|
ObjectSetInteger(0, "CLOSEPROFITABLE", OBJPROP_CORNER, Corner); // chart corner
|
|
ObjectSetString(0, "CLOSEPROFITABLE", OBJPROP_TEXT, "Close Profit"); // label
|
|
// Set color for Close Profit button (green)
|
|
ObjectSetInteger(0, "CLOSEPROFITABLE", OBJPROP_COLOR, clrWhite);
|
|
ObjectSetInteger(0, "CLOSEPROFITABLE", OBJPROP_BGCOLOR, clrBlack); //
|
|
|
|
// Button Create - Close Losing
|
|
ydistance = ydistance + YSIZE + 5;
|
|
ObjectCreate(0, "CLOSELOSING", OBJ_BUTTON, 0, 0, 0);
|
|
ObjectSetInteger(0, "CLOSELOSING", OBJPROP_XDISTANCE, XDISTANCE); // X position
|
|
ObjectSetInteger(0, "CLOSELOSING", OBJPROP_XSIZE, YSIZE); // width
|
|
ObjectSetInteger(0, "CLOSELOSING", OBJPROP_YDISTANCE, ydistance); // Y position
|
|
ObjectSetInteger(0, "CLOSELOSING", OBJPROP_YSIZE, YSIZE); // height
|
|
ObjectSetInteger(0, "CLOSELOSING", OBJPROP_CORNER, Corner); // chart corner
|
|
ObjectSetString(0, "CLOSELOSING", OBJPROP_TEXT, "Close Lost"); // label
|
|
// Set color for Close Loss button (red)
|
|
ObjectSetInteger(0, "CLOSELOSING", OBJPROP_COLOR, clrOrange);
|
|
ObjectSetInteger(0, "CLOSELOSING", OBJPROP_BGCOLOR, clrBlack); //
|
|
|
|
}
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert deinitialization function |
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
//---
|
|
ObjectDelete(0,"OPENBUY");
|
|
ObjectDelete(0,"OPENSELL");
|
|
ObjectDelete(0,"CLOSEALL");
|
|
ObjectDelete(0,"CLOSEPROFITABLE");
|
|
ObjectDelete(0,"CLOSELOSING");
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Expert tick function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTick()
|
|
{
|
|
/*
|
|
//--- we work only at the time of the birth of new bar
|
|
static datetime PrevBars=0;
|
|
datetime time_0=iTime(m_symbol.Name(),Period(),0);
|
|
if(time_0==PrevBars)
|
|
return;
|
|
PrevBars=time_0;
|
|
if(!RefreshRates())
|
|
{
|
|
PrevBars=0;
|
|
return;
|
|
}
|
|
*/
|
|
|
|
if(closeProfitThreshold > 0 || closeLossThreshold < 0)
|
|
{
|
|
double totalProfit = CalculateTotalProfit();
|
|
double totalLoss = CalculateTotalLoss();
|
|
if((closeProfitThreshold > 0 && totalProfit >= closeProfitThreshold) || (closeLossThreshold < 0 && totalLoss <= closeLossThreshold))
|
|
{
|
|
CloseAllPositions();
|
|
}
|
|
}
|
|
|
|
Trailing();
|
|
|
|
}
|
|
|
|
// Function to calculate the total profit of all open positions
|
|
double CalculateTotalProfit()
|
|
{
|
|
double totalProfit = 0.0;
|
|
for(int i = 0; i < PositionsTotal(); i++)
|
|
{
|
|
if(m_position.SelectByIndex(i))
|
|
{
|
|
totalProfit += m_position.Profit();
|
|
}
|
|
}
|
|
return totalProfit;
|
|
}
|
|
|
|
// Function to calculate the total loss of all open positions
|
|
double CalculateTotalLoss()
|
|
{
|
|
double totalLoss = 0.0;
|
|
for(int i = 0; i < PositionsTotal(); i++)
|
|
{
|
|
if(m_position.SelectByIndex(i))
|
|
{
|
|
totalLoss += m_position.Profit();
|
|
}
|
|
}
|
|
return totalLoss;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| TradeTransaction function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTradeTransaction(const MqlTradeTransaction &trans,
|
|
const MqlTradeRequest &request,
|
|
const MqlTradeResult &result)
|
|
{
|
|
//---
|
|
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Refreshes the symbol quotes data |
|
|
//+------------------------------------------------------------------+
|
|
bool RefreshRates(void)
|
|
{
|
|
//--- refresh rates
|
|
if(!m_symbol.RefreshRates())
|
|
{
|
|
Print("RefreshRates error");
|
|
return(false);
|
|
}
|
|
//--- protection against the return value of "zero"
|
|
if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
|
|
return(false);
|
|
//---
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Trailing |
|
|
//| InpTrailingStop: min distance from price to Stop Loss |
|
|
//+------------------------------------------------------------------+
|
|
void Trailing()
|
|
{
|
|
if(InpTrailingStop==0)
|
|
return;
|
|
for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of open positions
|
|
if(m_position.SelectByIndex(i))
|
|
if(m_position.Symbol()==m_symbol.Name()) //&& m_position.Magic()==m_magic)
|
|
{
|
|
if(m_position.PositionType()==POSITION_TYPE_BUY)
|
|
{
|
|
// Set SL if 0
|
|
if(m_position.StopLoss()==0 || m_position.TakeProfit()==0)
|
|
{
|
|
m_trade.PositionModify(m_position.Ticket(),
|
|
m_symbol.NormalizePrice(m_position.PriceOpen()-ExtStopLoss),
|
|
m_position.PriceOpen()+ExtTakeProfit);
|
|
}
|
|
if(m_position.PriceCurrent()-m_position.PriceOpen()>ExtTrailingStop+ExtTrailingStep)
|
|
{
|
|
if(m_position.StopLoss()<m_position.PriceCurrent()-(ExtTrailingStop+ExtTrailingStep))
|
|
{
|
|
if(!m_trade.PositionModify(m_position.Ticket(),
|
|
m_symbol.NormalizePrice(m_position.PriceCurrent()-ExtTrailingStop),
|
|
m_position.TakeProfit()))
|
|
Print("Modify ",m_position.Ticket(),
|
|
" Position -> false. Result Retcode: ",m_trade.ResultRetcode(),
|
|
", description of result: ",m_trade.ResultRetcodeDescription());
|
|
|
|
|
|
//RefreshRates();
|
|
m_position.SelectByIndex(i);
|
|
PrintResultModify(m_trade,m_symbol,m_position);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Set SL if 0
|
|
if(m_position.StopLoss()==0 || m_position.TakeProfit()==0)
|
|
{
|
|
m_trade.PositionModify(m_position.Ticket(),
|
|
m_symbol.NormalizePrice(m_position.PriceOpen()+ExtStopLoss),
|
|
m_position.PriceOpen()-ExtTakeProfit);
|
|
}
|
|
double open;
|
|
double current;
|
|
open = m_position.PriceOpen();
|
|
current = m_position.PriceCurrent();
|
|
if(m_position.PriceOpen()-m_position.PriceCurrent()>ExtTrailingStop+ExtTrailingStep)
|
|
{
|
|
if((m_position.StopLoss()>(m_position.PriceCurrent()+(ExtTrailingStop+ExtTrailingStep))) ||
|
|
(m_position.StopLoss()==0))
|
|
{
|
|
if(!m_trade.PositionModify(m_position.Ticket(),
|
|
m_symbol.NormalizePrice(m_position.PriceCurrent()+ExtTrailingStop),
|
|
m_position.TakeProfit()))
|
|
Print("Modify ",m_position.Ticket(),
|
|
" Position -> false. Result Retcode: ",m_trade.ResultRetcode(),
|
|
", description of result: ",m_trade.ResultRetcodeDescription());
|
|
//RefreshRates();
|
|
m_position.SelectByIndex(i);
|
|
PrintResultModify(m_trade,m_symbol,m_position);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Print CTrade result |
|
|
//+------------------------------------------------------------------+
|
|
void PrintResultModify(CTrade &trade,CSymbolInfo &symbol,CPositionInfo &position)
|
|
{
|
|
Print("File: ",__FILE__,", symbol: ",m_symbol.Name());
|
|
Print("Code of request result: "+IntegerToString(trade.ResultRetcode()));
|
|
Print("code of request result as a string: "+trade.ResultRetcodeDescription());
|
|
Print("Deal ticket: "+IntegerToString(trade.ResultDeal()));
|
|
Print("Order ticket: "+IntegerToString(trade.ResultOrder()));
|
|
Print("Volume of deal or order: "+DoubleToString(trade.ResultVolume(),2));
|
|
Print("Price, confirmed by broker: "+DoubleToString(trade.ResultPrice(),symbol.Digits()));
|
|
Print("Current bid price: "+DoubleToString(symbol.Bid(),symbol.Digits())+" (the requote): "+DoubleToString(trade.ResultBid(),symbol.Digits()));
|
|
Print("Current ask price: "+DoubleToString(symbol.Ask(),symbol.Digits())+" (the requote): "+DoubleToString(trade.ResultAsk(),symbol.Digits()));
|
|
Print("Broker comment: "+trade.ResultComment());
|
|
Print("Price of position opening: "+DoubleToString(position.PriceOpen(),symbol.Digits()));
|
|
Print("Price of position's Stop Loss: "+DoubleToString(position.StopLoss(),symbol.Digits()));
|
|
Print("Price of position's Take Profit: "+DoubleToString(position.TakeProfit(),symbol.Digits()));
|
|
Print("Current price by position: "+DoubleToString(position.PriceCurrent(),symbol.Digits()));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
// BUTTON CLICKED
|
|
void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
|
|
{
|
|
MqlTradeResult result;
|
|
MqlTradeRequest request;
|
|
ZeroMemory(request);
|
|
ZeroMemory(result);
|
|
|
|
if(ObjectGetInteger(0,"OPENBUY",OBJPROP_STATE)!=0)
|
|
{
|
|
ObjectSetInteger(0,"OPENBUY",OBJPROP_STATE,0);
|
|
OpenBuyPositions();
|
|
return;
|
|
}
|
|
else
|
|
if(ObjectGetInteger(0,"OPENSELL",OBJPROP_STATE)!=0)
|
|
{
|
|
ObjectSetInteger(0,"OPENSELL",OBJPROP_STATE,0);
|
|
OpenSellPositions();
|
|
printf("sell");
|
|
return;
|
|
}
|
|
else
|
|
if(ObjectGetInteger(0,"CLOSEALL",OBJPROP_STATE)!=0)
|
|
{
|
|
ObjectSetInteger(0,"CLOSEALL",OBJPROP_STATE,0);
|
|
CloseAllPositions();
|
|
return;
|
|
}
|
|
else
|
|
if(ObjectGetInteger(0,"CLOSEPROFITABLE",OBJPROP_STATE)!=0)
|
|
{
|
|
ObjectSetInteger(0,"CLOSEPROFITABLE",OBJPROP_STATE,0);
|
|
CloseProfitPositions();
|
|
return;
|
|
}
|
|
else
|
|
if(ObjectGetInteger(0,"CLOSELOSING",OBJPROP_STATE)!=0)
|
|
{
|
|
ObjectSetInteger(0,"CLOSELOSING",OBJPROP_STATE,0);
|
|
CloseLossPositions();
|
|
return;
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| FUNCTION CLOSE ALL |
|
|
//+------------------------------------------------------------------+
|
|
// Open buy positions
|
|
void OpenBuyPositions()
|
|
{
|
|
m_symbol.Name(Symbol());
|
|
m_symbol.RefreshRates();
|
|
|
|
double point = m_symbol.Point();
|
|
double digits = m_symbol.Digits();
|
|
//double spread = m_symbol.Spread();
|
|
|
|
//---
|
|
//+------------------------------------------------------------------+
|
|
//| get/set global variable |
|
|
//+------------------------------------------------------------------+
|
|
if(!GlobalVariableCheck("LOT"))
|
|
GlobalVariableSet("LOT",InpLots);
|
|
double Lots = GlobalVariableGet("LOT");
|
|
if(!GlobalVariableCheck("STOPLOSS"))
|
|
GlobalVariableSet("STOPLOSS", InpStopLoss);
|
|
double StopLoss = GlobalVariableGet("STOPLOSS");
|
|
if(!GlobalVariableCheck("TAKEPROFIT"))
|
|
GlobalVariableSet("TAKEPROFIT", InpTakeProfit);
|
|
double TakeProfit = GlobalVariableGet("TAKEPROFIT");
|
|
|
|
double sl = NormalizeDouble(m_symbol.Ask() - StopLoss * point, (int)digits);
|
|
double tp = NormalizeDouble(m_symbol.Ask() + TakeProfit * point, (int)digits);
|
|
m_trade.PositionOpen(_Symbol, ORDER_TYPE_BUY, Lots, SymbolInfoDouble(_Symbol, SYMBOL_ASK), sl, tp);
|
|
|
|
}
|
|
// Open Sell positions
|
|
void OpenSellPositions()
|
|
{
|
|
|
|
m_symbol.Name(Symbol());
|
|
m_symbol.RefreshRates();
|
|
|
|
double point = m_symbol.Point();
|
|
double digits = m_symbol.Digits();
|
|
//double spread = m_symbol.Spread();
|
|
|
|
if(!GlobalVariableCheck("LOT"))
|
|
GlobalVariableSet("LOT",InpLots);
|
|
double Lots = GlobalVariableGet("LOT");
|
|
if(!GlobalVariableCheck("STOPLOSS"))
|
|
GlobalVariableSet("STOPLOSS", InpStopLoss);
|
|
double StopLoss = GlobalVariableGet("STOPLOSS");
|
|
if(!GlobalVariableCheck("TAKEPROFIT"))
|
|
GlobalVariableSet("TAKEPROFIT",InpTakeProfit);
|
|
double TakeProfit = GlobalVariableGet("TAKEPROFIT");
|
|
|
|
double sl = NormalizeDouble(m_symbol.Bid() + StopLoss * point, (int)digits);
|
|
double tp = NormalizeDouble(m_symbol.Bid() - TakeProfit * point, (int)digits);
|
|
m_trade.PositionOpen(_Symbol, ORDER_TYPE_SELL, Lots, SymbolInfoDouble(_Symbol, SYMBOL_BID), sl, tp);
|
|
|
|
}
|
|
// Close all positions
|
|
void CloseAllPositions()
|
|
{
|
|
string currentSymbol = _Symbol;
|
|
for(uint retry = 0; retry < RTOTAL && !IsStopped(); retry++)
|
|
{
|
|
for(int i = PositionsTotal() - 1; i >= 0 && !IsStopped(); i--)
|
|
{
|
|
if(m_position.SelectByIndex(i))
|
|
{
|
|
string positionSymbol = PositionGetSymbol(i);
|
|
// Close position
|
|
if(positionSymbol == currentSymbol)
|
|
{
|
|
ClosePosition(m_position.Ticket());
|
|
}
|
|
|
|
}
|
|
}
|
|
Sleep(SLEEPTIME);
|
|
}
|
|
}
|
|
|
|
// Close only profitable positions
|
|
void CloseProfitPositions()
|
|
{
|
|
string currentSymbol = _Symbol;
|
|
for(uint retry = 0; retry < RTOTAL && !IsStopped(); retry++)
|
|
{
|
|
for(int i = PositionsTotal() - 1; i >= 0 && !IsStopped(); i--)
|
|
{
|
|
if(m_position.SelectByIndex(i) && (m_position.Swap() + m_position.Profit() > 0))
|
|
{
|
|
string positionSymbol = PositionGetSymbol(i);
|
|
// Close position
|
|
if(positionSymbol == currentSymbol)
|
|
{
|
|
// Close position
|
|
ClosePosition(m_position.Ticket());
|
|
}
|
|
}
|
|
}
|
|
Sleep(SLEEPTIME);
|
|
}
|
|
}
|
|
|
|
// Close only losing positions
|
|
void CloseLossPositions()
|
|
{
|
|
string currentSymbol = _Symbol;
|
|
for(uint retry = 0; retry < RTOTAL && !IsStopped(); retry++)
|
|
{
|
|
for(int i = PositionsTotal() - 1; i >= 0 && !IsStopped(); i--)
|
|
{
|
|
if(m_position.SelectByIndex(i) && (m_position.Swap() + m_position.Profit() < 0))
|
|
{
|
|
string positionSymbol = PositionGetSymbol(i);
|
|
// Close position
|
|
if(positionSymbol == currentSymbol)
|
|
{
|
|
// Close position
|
|
ClosePosition(m_position.Ticket());
|
|
}
|
|
}
|
|
}
|
|
Sleep(SLEEPTIME);
|
|
}
|
|
}
|
|
|
|
// Close a single position by ticket
|
|
void ClosePosition(ulong ticket)
|
|
{
|
|
ResetLastError();
|
|
if(m_position.SelectByTicket(ticket))
|
|
{
|
|
// Check freeze level
|
|
int freeze_level = (int)SymbolInfoInteger(m_position.Symbol(), SYMBOL_TRADE_FREEZE_LEVEL);
|
|
double point = SymbolInfoDouble(m_position.Symbol(), SYMBOL_POINT);
|
|
bool TP_check = (MathAbs(m_position.PriceCurrent() - m_position.TakeProfit()) > freeze_level * point);
|
|
bool SL_check = (MathAbs(m_position.PriceCurrent() - m_position.StopLoss()) > freeze_level * point);
|
|
|
|
if(TP_check && SL_check)
|
|
{
|
|
// Close position
|
|
if(m_trade.PositionClose(ticket))
|
|
{
|
|
PrintFormat("Position ticket #%I64u on %s has been closed.", ticket, m_position.Symbol());
|
|
}
|
|
else
|
|
{
|
|
PrintFormat("> Error: closing position ticket #%I64u on %s failed. Retcode=%u (%s)", ticket, m_position.Symbol(), m_trade.ResultRetcode(), m_trade.ResultComment());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PrintFormat("> Error: closing position ticket #%I64u on %s is prohibited. Position TP or SL is too close to activation price.", ticket, m_position.Symbol());
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool ButtonCreate(const long chart_ID=0, // chart's ID
|
|
const string name="Button", // button name
|
|
const int sub_window=0, // subwindow index
|
|
const int x=0, // X coordinate
|
|
const int y=0, // Y coordinate
|
|
const int width=50, // button width
|
|
const int height=18, // button height
|
|
const ENUM_BASE_CORNER corner=CORNER_LEFT_UPPER, // chart corner for anchoring
|
|
const string text="Button", // text
|
|
const string font="Arial", // font
|
|
const int font_size=10, // font size
|
|
const color clr=clrBlack, // text color
|
|
const color back_clr=C'236,233,216', // background color
|
|
const color border_clr=clrNONE, // border color
|
|
const bool state=false, // pressed/released
|
|
const bool back=false, // in the background
|
|
const bool selection=false, // highlight to move
|
|
const bool hidden=true, // hidden in the object list
|
|
const long z_order=0) // priority for mouse click
|
|
{
|
|
//--- reset the error value
|
|
ResetLastError();
|
|
//--- create the button
|
|
if(!ObjectCreate(chart_ID,name,OBJ_BUTTON,sub_window,0,0))
|
|
{
|
|
Print(__FUNCTION__,
|
|
": failed to create the button! Error code = ",GetLastError());
|
|
return(false);
|
|
}
|
|
//--- set button coordinates
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);
|
|
//--- set button size
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width);
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height);
|
|
//--- set the chart's corner, relative to which point coordinates are defined
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);
|
|
//--- set the text
|
|
ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
|
|
//--- set text font
|
|
ObjectSetString(chart_ID,name,OBJPROP_FONT,font);
|
|
//--- set font size
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size);
|
|
//--- set text color
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
|
|
//--- set background color
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,back_clr);
|
|
//--- set border color
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_BORDER_COLOR,border_clr);
|
|
//--- display in the foreground (false) or background (true)
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
|
|
//--- set button state
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_STATE,state);
|
|
//--- enable (true) or disable (false) the mode of moving the button by mouse
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
|
|
//--- hide (true) or display (false) graphical object name in the object list
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
|
|
//--- set the priority for receiving the event of a mouse click in the chart
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
|
|
//--- successful execution
|
|
return(true);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Create a text label |
|
|
//+------------------------------------------------------------------+
|
|
bool LabelCreate(const long chart_ID=0, // chart's ID
|
|
const string name="Label", // label name
|
|
const int sub_window=0, // subwindow index
|
|
const int x=0, // X coordinate
|
|
const int y=0, // Y coordinate
|
|
const ENUM_BASE_CORNER corner=CORNER_LEFT_UPPER, // chart corner for anchoring
|
|
const string text="Label", // text
|
|
const string font="Arial", // font
|
|
const int font_size=10, // font size
|
|
const color clr=clrRed, // color
|
|
const double angle=0.0, // text slope
|
|
const ENUM_ANCHOR_POINT anchor=ANCHOR_LEFT_UPPER, // anchor type
|
|
const bool back=false, // in the background
|
|
const bool selection=false, // highlight to move
|
|
const bool hidden=true, // hidden in the object list
|
|
const long z_order=0) // priority for mouse click
|
|
{
|
|
//--- reset the error value
|
|
ResetLastError();
|
|
//--- create a text label
|
|
if(!ObjectCreate(chart_ID,name,OBJ_LABEL,sub_window,0,0))
|
|
{
|
|
Print(__FUNCTION__,
|
|
": failed to create text label! Error code = ",GetLastError());
|
|
return(false);
|
|
}
|
|
//--- set label coordinates
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);
|
|
//--- set the chart's corner, relative to which point coordinates are defined
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);
|
|
//--- set the text
|
|
ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
|
|
//--- set text font
|
|
ObjectSetString(chart_ID,name,OBJPROP_FONT,font);
|
|
//--- set font size
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size);
|
|
//--- set the slope angle of the text
|
|
ObjectSetDouble(chart_ID,name,OBJPROP_ANGLE,angle);
|
|
//--- set anchor type
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor);
|
|
//--- set color
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
|
|
//--- display in the foreground (false) or background (true)
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
|
|
//--- enable (true) or disable (false) the mode of moving the label by mouse
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
|
|
//--- hide (true) or display (false) graphical object name in the object list
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
|
|
//--- set the priority for receiving the event of a mouse click in the chart
|
|
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
|
|
//--- successful execution
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|