Celebra/Celebra V_v5.0.4.mq5

370 lines
33 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 14:45:57 +02:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| ExampleV.mq5 |
//| Copyright 2017, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//
enum wdr_period { none=-3, days=-2, weeks=-1, months=1, quarters=3, halfyears=6, years=12 };
//--- input parameters
double InpLots =SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN); // Lots
bool DescriptionModeFull=false; // 568< 45B0;L=>3> 2K2>40
input double kLots =1.6; // kMLots * prior Lots = next Lots Martin
input int PipsStep =100; // PipsStep [pips] step for open next order
input double kPips =0.94; // kPips * prior Pips = next Pips
input int TimeStep =0; // TimeStep [sec] step sec for open next order
input int MaxTrades =14; // MaxTrades max count orders
input int TakeProfit =100; // TakeProfit [pips] if==0:PipsStep
input double kTP =1.1; // kTP * prior TP = next TP
//
input double MarginLevel =100.0; // Freez Margin Level [%]
input int Delay =20; // Delay [min]
//
input wdr_period WDR_Period =months; // WDR_Period: none days weeks months quarters halfyears years
//
double WDR_Balance; // =0G0;L=K9 10;0=A 745AL =5 8=8F80;878@>20BL
double _wdr_summa =0;
int _wdr_day_of_year_last =0;
int _wdr_mon_last =0;
int _wdr_year_last =0;
int MagicNumber =0; // 45=B8D8:0B>@ M:A?5@B0
int MinPipsStep =50;
int MinTakeProfit =40;
datetime _dtForbiden =0;
int _CountDelay =0;
int _TimeStep;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
Comment(setupRobot);
WDR_Balance = AccountInfoDouble(ACCOUNT_BALANCE);
int curr_positions=PositionsTotal();
int curr_orders=OrdersTotal();
if( OrdersTotal()>0||PositionsTotal()>0 ) {Print("*** WARNING Erroe OnInit. Order is opens"); return(INIT_FAILED); }
if(TimeStep==0)_TimeStep=1; else _TimeStep=TimeStep;
OnZero();
return(INIT_SUCCEEDED);
}
//------------------------------------------------------------------ OnDeinit
void OnDeinit(const int reason)
{
EventKillTimer();
Print("*** WARNING >;8G5AB2> 7045@65: = ",_CountDelay,", !=OB> 2A53> = ",_wdr_summa);
}
//------------------------------------------------------------------ OnTick
void OnTick()
{
if(CheckTradeDelay()) return;
if(AccountInfoDouble(ACCOUNT_MARGIN_LEVEL)>0.0 && AccountInfoDouble(ACCOUNT_MARGIN_LEVEL)<=MarginLevel) { SetTtradeDelay(); return; }
return;
}
//+------------------------------------------------------------------+
//| SetTtradeDelay |
//+------------------------------------------------------------------+
bool SetTtradeDelay()
{
datetime dt;
dt=TimeLocal(); // loacal 7=0G8B :852A:>5 2@5<O !!!
_dtForbiden=dt+Delay*60;
Remove();
Close();
_CountDelay++;
Print("*** WARNING date ",TimeToString(_dtForbiden,TIME_DATE)," Close all orders and trade forbiden CountDelay=",_CountDelay);
return true;
}
//+------------------------------------------------------------------+
//| CheckTradeDelay |
//+------------------------------------------------------------------+
bool CheckTradeDelay()
{
if(_dtForbiden==0) return false;
datetime dt=TimeLocal(); // loacal 7=0G8B :852A:>5 2@5<O !!!
if(dt<_dtForbiden) return true;
OnZero();
_dtForbiden=0;
Print("*** WARNING date ",TimeToString(dt,TIME_DATE)," trade allowed");
return false;
}
//+------------------------------------------------------------------+
//| Trade function |
//+------------------------------------------------------------------+
void OnTrade()
{
static int prev_positions=0,prev_orders=0;
//
int curr_positions=PositionsTotal();
int curr_orders=OrdersTotal();
bool OnClose=false, OnExec=false;
if(prev_positions>curr_positions)OnClose=true;// GB>-B> 70:@K;>AL!
if(prev_positions<curr_positions)OnExec=true; //GB>-B> ?>H;> =0 8A?>;=5=85!
prev_positions=curr_positions;
prev_orders=curr_orders;
//---
if(OnClose) { prev_positions=0; OnTP(); }
if(OnExec) { Remove(); EventSetTimer(_TimeStep); }// B>;L:> >48= @07!!
//
TimeOfWithDrawal();
}
//+------------------------------------------------------------------+
//| OnTP function |
//+------------------------------------------------------------------+
void OnTP()
{
Close();
Remove();
OnZero();
}
//+------------------------------------------------------------------+
//| OnZero function |
//+------------------------------------------------------------------+
void OnZero()
{
MagicNumber=0;
BuyAsync(MagicNumber);
SellAsync(MagicNumber);
}
//------------------------------------------------------------------ OnTimer
void OnTimer()
{
EventKillTimer();
OnTimerExec();
return;
}
//+------------------------------------------------------------------+
//| OnTimerExec() function |
//+------------------------------------------------------------------+
void OnTimerExec()
{
MagicNumber=PositionsTotal(); // :>;8G5AB2> >B:@KBKE ?>78F89 =5O2=> MagicNumber++ !!!!!!!
if(MagicNumber>=MaxTrades) return;
ulong ticket = PositionGetTicket(MagicNumber-1); // =04> 2A5340 4;O 8=8F80;870F88
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) BuyAsync(MagicNumber);
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL) SellAsync(MagicNumber);
return;
}
//+------------------------------------------------------------------+
//| PipsOptimized |
//+------------------------------------------------------------------+
int PipsOptimized(int count)
{
int pips = PipsStep;
for(int i=0;i<count;i++)
{ pips=int(NormalizeDouble(pips*kPips,0)); }
if(pips<MinPipsStep) pips=MinPipsStep;
return(pips);
}
//+------------------------------------------------------------------+
//| LotsOptimized |
//+------------------------------------------------------------------+
double LotsOptimized(int count)
{
double lot=InpLots;
for(int i=0;i<count;i++) { lot=lot*kLots; }
lot=NormalizeDouble(lot,2);
double maxlot=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
if(lot>maxlot) lot=maxlot;
double minlot=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
if(lot<minlot) lot=minlot;
return(lot);
}
//+------------------------------------------------------------------+
//| TPOptimized |
//+------------------------------------------------------------------+
int TPOptimized(int count )
{
int pips = TakeProfit; if(pips==0) pips=PipsStep;
for(int i=0;i<count;i++)
{ pips=int(NormalizeDouble(pips*kTP,0)); }
if(pips<MinTakeProfit) pips=MinTakeProfit;
return(pips);
}
//+------------------------------------------------------------------+
//| >:C?:0 G5@57 0A8=E@>==CN DC=:F8N OrderSendAsync() |
//+------------------------------------------------------------------+
void BuyAsync(int count)
{
//--- ?>43>B>28< 70?@>A
int pips = PipsOptimized(count);
double vol = LotsOptimized(count);
int tp = TPOptimized(count);
double OpenPrice=0.0;
ulong ticket=0;
MqlTradeRequest req={0};
if(count==0) {
OpenPrice = NormalizeDouble(SymbolInfoDouble(Symbol(),SYMBOL_ASK)-pips*_Point,_Digits);// ?@>B82 @K=:0 !
req.action= TRADE_ACTION_PENDING; // CAB0=>2:0 >B;>65==>3> >@45@0 ;
req.type = ORDER_TYPE_BUY_LIMIT;
}
if(count>0) {
ticket = PositionGetTicket(MagicNumber-1); // =04> 2A5340 4;O 8=8F80;870F88
OpenPrice = NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN)-pips*_Point,_Digits); // ?@>B82 @K=:0 !
if(OpenPrice<SymbolInfoDouble(Symbol(),SYMBOL_ASK)) {
req.action= TRADE_ACTION_PENDING; // CAB0=>2:0 >B;>65==>3> >@45@0
req.type = ORDER_TYPE_BUY_LIMIT;
} else {
OpenPrice = SymbolInfoDouble(Symbol(),SYMBOL_ASK);
req.action= TRADE_ACTION_DEAL;; // =5<54;5==>5 2K?>;=5=85 >@45@0
req.type = ORDER_TYPE_BUY;
}
}
req.symbol =_Symbol;
req.magic =MagicNumber;
req.volume =vol;
req.price =OpenPrice;
req.tp =NormalizeDouble(req.price+tp*_Point,_Digits);
req.deviation =10;
req.comment ="Magic = "+DoubleToString(MagicNumber,0);
MqlTradeResult res={0};
if(!OrderSendAsync(req,res)) { Print(__FUNCTION__,": >H81:0 ",GetLastError(),", retcode = ",res.retcode); }
//---
}
//+------------------------------------------------------------------+
//| @>4060 G5@57 0A8=E@>==CN DC=:F8N OrderSendAsync() |
//+------------------------------------------------------------------+
void SellAsync(int count)
{
//--- ?>43>B>28< 70?@>A
int pips = PipsOptimized(count);
double vol = LotsOptimized(count);
int tp = TPOptimized(count);
double OpenPrice=0.0;
ulong ticket=0;
MqlTradeRequest req={0};
if(count==0) {
OpenPrice = NormalizeDouble(SymbolInfoDouble(Symbol(),SYMBOL_BID)+pips*_Point,_Digits);// ?@>B82 @K=:0 !
req.action= TRADE_ACTION_PENDING; // CAB0=>2:0 >B;>65==>3> >@45@0 ;
req.type = ORDER_TYPE_SELL_LIMIT;
}
if(count>0) {
ticket = PositionGetTicket(MagicNumber-1); // =04> 2A5340 4;O 8=8F80;870F88
OpenPrice = NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN)+pips*_Point,_Digits); // ?@>B82 @K=:0 !
if(OpenPrice>SymbolInfoDouble(Symbol(),SYMBOL_BID)) {
req.action= TRADE_ACTION_PENDING; // CAB0=>2:0 >B;>65==>3> >@45@0
req.type = ORDER_TYPE_SELL_LIMIT;
} else {
OpenPrice = SymbolInfoDouble(Symbol(),SYMBOL_BID);
req.action= TRADE_ACTION_DEAL;; // =5<54;5==>5 2K?>;=5=85 >@45@0
req.type = ORDER_TYPE_SELL;
}
}
req.symbol =_Symbol;
req.magic =MagicNumber;
req.volume =vol;
req.price =OpenPrice;
req.tp =NormalizeDouble(req.price-tp*_Point,_Digits);
req.deviation =10;
req.comment ="Magic = "+DoubleToString(MagicNumber,0);
MqlTradeResult res={0};
if(!OrderSendAsync(req,res)) { Print(__FUNCTION__,": >H81:0 ",GetLastError(),", retcode = ",res.retcode); }
//---
}
//+------------------------------------------------------------------+
//| Check for close order -1 close all >G8AB8BL ?5@5<5==K5 F5?>G:8 |
//+------------------------------------------------------------------+
void Close(ENUM_POSITION_TYPE _type=-1) // -1 close all
{
MqlTradeRequest request;
MqlTradeResult result;
int total=PositionsTotal(); // :>;8G5AB2> >B:@KBKE ?>78F89
//--- ?5@51>@ 2A5E >B:@KBKE ?>78F89
for(int i=total-1; i>=0; i--)
{
ulong ticket = PositionGetTicket(i); // =04> 2A5340 4;O 8=8F80;870F88
ZeroMemory(request);
ZeroMemory(result);
//--- CAB0=>2:0 ?0@0<5B@>2 >?5@0F88
request.action =TRADE_ACTION_DEAL; // B8? B>@3>2>9 >?5@0F88
request.position =PositionGetTicket(i); // B8:5B ?>78F88
request.symbol =PositionGetString(POSITION_SYMBOL);// A8<2>;
if(request.symbol!=Symbol()) continue;//////////////////////////////////>>
request.volume =PositionGetDouble(POSITION_VOLUME);// >1J5< ?>78F88
request.deviation=20; // 4>?CAB8<>5 >B:;>=5=85 >B F5=K
//--- CAB0=>2:0 F5=K 8 B8?0 >@45@0 2 7028A8<>AB8 >B B8?0 ?>78F88
ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); // B8? ?>78F88
if(_type != -1 && _type != type) continue;
if(type==POSITION_TYPE_BUY){
request.price=SymbolInfoDouble(request.symbol,SYMBOL_BID);
request.type =ORDER_TYPE_SELL;
}else if(type==POSITION_TYPE_SELL){
request.price=SymbolInfoDouble(request.symbol,SYMBOL_ASK);
request.type =ORDER_TYPE_BUY;
}
//PrintFormat(__FUNCTION__," Close #%I64d type=%s magic=[%I64d]",request.position,EnumToString(type),request.magic);
if(!OrderSend(request,result)) PrintFormat(__FUNCTION__," Close error %d",GetLastError()); // 5A;8 >B?@028BL 70?@>A =5 C40;>AL, 2K25AB8 :>4 >H81:8
//Sleep(120);
/// PrintFormat(__FUNCTION__," Close retcode=%u deal=%I64u order=%I64u ticket_position=%I64u",result.retcode,result.deal,result.order,ticket);
}
}
//+------------------------------------------------------------------+
//| #40;O5B 2A5 >B;>65==K5 >@45@0 |
//+------------------------------------------------------------------+
void Remove()
{
ulong order_ticket;
for(int i=OrdersTotal()-1;i>=0;i--)
{
if((order_ticket=OrderGetTicket(i))>0) //--- ?@>945< ?> 2A5< >B;>65==K< >@45@0<
{
MqlTradeResult result={0};
MqlTradeRequest request={0};
request.order=order_ticket;
request.action=TRADE_ACTION_REMOVE;
if(!OrderSend(request,result)) Print(__FUNCTION__," Error: ",result.comment," :>4 >B25B0 ",result.retcode);
else Print(__FUNCTION__," Succes: ",result.comment," :>4 >B25B0 ",result.retcode);
}
}
//---
}
//+------------------------------------------------------------------+
//--- K2>4 8=D>@<0F88 > B5AB8@>20=88 |
//+------------------------------------------------------------------+
double OnTester(void)
{
double Equity=AccountInfoDouble(ACCOUNT_BALANCE) - WDR_Balance;
if(Equity>=0.0) return (_wdr_summa); else return Equity;
}
//+------------------------------------------------------------------+
int _iVspread; //*** Anton ***
string setupRobot=DoubleToString(kLots,1)+" / "+DoubleToString(PipsStep,0)+
" / "+DoubleToString(kPips,2)+" / "+DoubleToString(TimeStep,0)+" / "+DoubleToString(MaxTrades,0)+" / "+DoubleToString(TakeProfit,0)+
" / "+DoubleToString(kTP,2)+" / "+DoubleToString(MarginLevel,0)+" / "+DoubleToString(Delay,0);
//+------------------------------------------------------------------+
//--- $C=:F8O A=OB8O A@54AB2 A> AG5B0 |
//+------------------------------------------------------------------+
void TimeOfWithDrawal()
{
MqlDateTime dt_struct; // ?5@5<5==0O B8?0 AB@C:BC@K
//
if(WDR_Period == none ) return; // 2KE>4, 5A;8 A=OB85 A@54AB2 70?@5I5=>
TimeCurrent (dt_struct);
switch(WDR_Period) // WDR_Period days -2 weeks -1 months 1 quarters 3 halfyears 6 none -3
{
case days: if(_wdr_day_of_year_last != dt_struct.day_of_year) _wdr_day_of_year_last = dt_struct.day_of_year; else return;
break;
case weeks: if(dt_struct.day_of_week != 1) return;
if(_wdr_day_of_year_last == dt_struct.day_of_year) return;
break;
case months: if(_wdr_mon_last != dt_struct.mon) _wdr_mon_last = dt_struct.mon; else return;
break;
case years: if(_wdr_year_last != dt_struct.year) _wdr_year_last = dt_struct.year; else return;
break;
default: if(dt_struct.mon % WDR_Period != 1) return;
if(_wdr_mon_last != dt_struct.mon) _wdr_mon_last = dt_struct.mon; else return;
}
_wdr_day_of_year_last = dt_struct.day_of_year;
double wdr_value = AccountInfoDouble(ACCOUNT_EQUITY) - WDR_Balance-1;///////////////-1
if(wdr_value<0.0) return; // 2KE>4, 5A;8 =5G53> A=8<0BL
if(TesterWithdrawal(wdr_value))
{
_wdr_summa = _wdr_summa + wdr_value;
Print("*** TesterWithdrawal wdr_value = ",wdr_value," _wdr_summa =",_wdr_summa," CountDelay=",_CountDelay);
}
return;
}
//+------------------------------------------------------------------+