Files
MT5-EA-Sniper-Strategy/Experts/Nkanven/MidNightAngel.mq5
T

416 lines
26 KiB
Plaintext

//+------------------------------------------------------------------+
//| MidNightAngel.mq5 |
//| Copyright 2022, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#include <Nkanven\MidNightAngel\Parameters.mqh> // EA paramters
#include <Nkanven\MidNightAngel\LotSizeCal.mqh> // Lot size calculator
ulong ticket=0;
double profit;
datetime time;
string symbol;
long type;
long entry;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
//---
datetime ht = TimeCurrent();
TimeToStruct(ht, dt);
SymbolInfoTick(_Symbol,last_tick);
/*storeEquity();
HasTodayClosingPosition();
if(FileIsExist(filename))
{
//Compare stored balance and actual balance
if(getStoredBalance() > AccountInfoDouble(ACCOUNT_BALANCE))
{
IsLosing=true;
}
else
{
IsLosing=false;
}
}
else
{
storeEquity();
}*/
CheckSpread();
if(dt.hour == 0)
{
Print("It's trading time. History sum ", checkHistory());
for(int i=0; i<ArraySize(gStandardRisk); i++)
{
if(checkHistory() == gStandardRisk[i])
{
gBuyPositioning = STANDARD_BUY;
break;
}
}
for(int i=0; i<ArraySize(gOneSL); i++)
{
if(checkHistory() == gOneSL[i])
{
gBuyPositioning = TWO_SL_BUY;
break;
}
}
if(gTwoSL == checkHistory())
{
gBuyPositioning = THREE_SL_BUY;
}
if(checkHistory()==0)
{
gBuyPositioning = STANDARD_BUY;
}
Print("Verify buy ", PositionsTotal()==0 && HasTodayClosingPosition());
//if(PositionsTotal()==0 && !HasTodayClosingPosition())
if(PositionsTotal()==0 && !HasTodayClosingPosition() && IsSpreadOK)
{
switch(gBuyPositioning)
{
case STANDARD_BUY:
Print("Buy standard entry");
ExecuteEntry(InpDefaultSize);
break;
case TWO_SL_BUY:
Print("Buy One SL entry");
ExecuteEntry(InpOneSlSize);
break;
case THREE_SL_BUY:
Print("Buy Two SL entry");
ExecuteEntry(InpTwoSlSize);
break;
default:
break;
}
}
}
Comment("Hour ", dt.hour, " Hour is true", " Balance is actually = ", AccountInfoInteger(ACCOUNT_LOGIN), " File ", FileIsExist(filename));
}
//+------------------------------------------------------------------+
//Check and return if the spread is not too high
void CheckSpread()
{
//Get the current spread in points, the (int) transforms the double coming from MarketInfo into an integer to avoid a warning when compiling
long SpreadCurr=(int)Spread;
Print("Spread ", Spread);
if(SpreadCurr<=InpMaxSpread)
{
IsSpreadOK=true;
}
else
{
IsSpreadOK=false;
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void storeEquity()
{
string terminal_data_path=TerminalInfoString(TERMINAL_DATA_PATH);
printf(" terminal_data_path ", terminal_data_path);
int filehandle=FileOpen(filename,FILE_WRITE|FILE_TXT,",");
if(filehandle!=INVALID_HANDLE)
{
FileWrite(filehandle,DoubleToString(AccountInfoDouble(ACCOUNT_BALANCE)));
FileClose(filehandle);
//Print("The file must be created in the folder "+terminal_data_path+"\\"+subfolder);
}
else
Print("File open failed, error ",GetLastError());
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double getStoredBalance()
{
int balance;
struct Table
{
int line;
datetime date;
string symbol;
double price;
};
Table table[];
int i=0;
short delimiter=',';
int fileHandle = FileOpen(filename,FILE_READ|FILE_ANSI,delimiter);
if(fileHandle==INVALID_HANDLE)
Alert("could not open file, error: "+(string)GetLastError());
if(fileHandle!=INVALID_HANDLE)
{
while(FileIsEnding(fileHandle) == false)
{
ArrayResize(table,ArraySize(table) +1);
table[i].line = (int) FileReadNumber(fileHandle);
/* table[i].date = FileReadDatetime(fileHandle);
table[i].symbol = FileReadString(fileHandle);
table[i].price = FileReadNumber(fileHandle);*/
i++;
}
FileClose(fileHandle);
}
for(i=0; i<ArraySize(table); i++)
{
balance = table[i].line;
}
return balance;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool HasTodayClosingPosition()
{
datetime timeStart = TimeCurrent() - PeriodSeconds(PERIOD_D1);
time =(datetime)HistoryDealGetInteger(ticket,DEAL_TIME);
int totalClosed = 0;
printf(TimeToString(timeStart));
HistorySelect(timeStart,TimeCurrent());
uint total=HistoryDealsTotal();
for(uint i=0; i<total; i++)
{
//--- essaye de récuperer le ticket des transactions
if((ticket=HistoryDealGetTicket(i))>0)
{
if(TimeToString(time, TIME_DATE) == TimeToString(TimeCurrent(), TIME_DATE))
{
totalClosed += 1;
}
Print("TIMES ", TimeToString(time, TIME_DATE)," ", TimeToString(TimeCurrent(), TIME_DATE));
}
}
Print("Total closed today ", totalClosed);
if(totalClosed > 0)
{
return true;
}
else
{
return false;
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int checkHistory()
{
uint total=HistoryDealsTotal();
int outCount=0;
int j=1;
for(uint i=total; i>0; i--)
{
//--- essaye de récuperer le ticket des transactions
if((ticket=HistoryDealGetTicket(i))>0)
{
//--- récupère les propriétés des transactions
time =(datetime)HistoryDealGetInteger(ticket,DEAL_TIME);
symbol=HistoryDealGetString(ticket,DEAL_SYMBOL);
type =HistoryDealGetInteger(ticket,DEAL_TYPE);
entry =HistoryDealGetInteger(ticket,DEAL_ENTRY);
profit=HistoryDealGetDouble(ticket,DEAL_PROFIT);
if(entry == DEAL_ENTRY_OUT)
{
if(j==1)
{
if(profit > 0)
{
outCount+= 1;
}
else
{
outCount-= 1;
}
}
if(j==2)
{
if(profit > 0)
{
outCount+= 1;
}
else
{
outCount-= 2;
}
}
if(j==3)
{
if(profit > 0)
{
outCount+= 1;
}
else
{
outCount-= 3;
}
}
j+=1;
Print("date ", TimeToString(time), " type ", entry, " profit ", profit);
}
}
}
return outCount;
}
//+------------------------------------------------------------------+
//Execute entry if there is an entry signal
void ExecuteEntry(double LotMultiplier)
{
int Operation;
double OpenPrice=0;
double StopLossPrice=0;
double TakeProfitPrice=0;
Print("In buy execution");
Operation=ORDER_TYPE_BUY; //Set the operation to BUY
OpenPrice=last_tick.ask; //Set the open price to Ask price
//If the Stop Loss is fixed and the default stop loss is set
if(InpStopLossMode==SL_FIXED && InpDefaultStopLoss>0)
{
StopLossPrice=OpenPrice-InpDefaultStopLoss*Point();
}
//If the Stop Loss is automatic
if(InpStopLossMode==SL_AUTO)
{
//Set the Stop Loss to the custom stop loss price
//StopLossPrice=last_tick.ask-((last_tick.ask-sell_level));
StopLossPrice=iLow(Symb, PERIOD_CURRENT, 3);
}
//If the Take Profix price is fixed and defined
if(InpTakeProfitMode==TP_FIXED && InpDefaultTakeProfit>0)
{
TakeProfitPrice=OpenPrice+InpDefaultTakeProfit*Point();
}
//If the Take Profit is automatic
if(InpTakeProfitMode==TP_AUTO)
{
//Set the Take Profit to the custom take profit price
TakeProfitPrice=OpenPrice+((OpenPrice-StopLossPrice)*InpTakeProfitPercent);
}
//Normalize the digits for the float numbers
OpenPrice=NormalizeDouble(OpenPrice,Digits());
StopLossPrice=NormalizeDouble(StopLossPrice,Digits());
TakeProfitPrice=NormalizeDouble(TakeProfitPrice,Digits());
//Submit the order
SendOrder(Operation,Symbol(),OpenPrice,StopLossPrice,TakeProfitPrice, LotMultiplier);
}
//+------------------------------------------------------------------+
//Send Order Function adjusted to handle errors and retry multiple times
void SendOrder(int Command, string Instrument, double OpenPrice, double SLPrice, double TPPrice, double Multiplier)
{
MqlTradeRequest request= {};
MqlTradeResult result= {};
//Calculate the position size, if the lot size is zero then exit the function
double SLPoints=0;
Print("Stop loss ", SLPrice, " Open price ", OpenPrice);
//If the Stop Loss price is set then find the points of distance between open price and stop loss price, and round it
if(SLPrice>0)
SLPoints=MathCeil(MathAbs(OpenPrice-SLPrice)/_Point);
//Call the function to calculate the position size
Print("Stop loss en point ", SLPoints, " Point ", _Point);
LotSizeCalculate(SLPoints);
//If the position size is zero then exit and don't submit any orderInit
Print("Stop loss en point ", SLPoints);
if(LotSize==0)
return;
if(gBuyPositioning == TWO_SL_BUY || gBuyPositioning == THREE_SL_BUY)
{
SLPrice=SLPrice-InpDefaultTakeProfit*Point();
}
request.action =TRADE_ACTION_DEAL; // type de l'opération de trading
request.symbol =Instrument; // symbole
request.volume =LotSize*Multiplier; // volume de 0.1 lot
request.type =Command; // type de l'ordre
request.price =SYMBOL_TRADE_EXECUTION_MARKET; // prix d'ouverture
request.sl =NormalizeDouble(SLPrice,Digits());
request.tp =NormalizeDouble(TPPrice,Digits());
request.type_filling =ORDER_FILLING_FOK;
request.deviation =InpSlippage; // déviation du prix autorisée
//Submit the order
if(!OrderSend(request,result))
PrintFormat("OrderSend erreur %d",GetLastError()); // en cas d'erreur d'envoi de la demande, affiche le code d'erreur
//--- informations de l'opération
PrintFormat("retcode=%u transaction=%I64u ordre=%I64u",result.retcode,result.deal,result.order);
if(result.retcode == TRADE_RETCODE_DONE && result.deal != 0)
return;
}
//+------------------------------------------------------------------+