250 lines
17 KiB
MQL5
250 lines
17 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| EA simples.mq5 |
|
|
//| Copyright 2018, Romeu Bertho. |
|
|
//| https://www.mql5.com/pt/users/c4b3l3r4 |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2018, Romeu Bertho."
|
|
#property link "https://www.mql5.com/pt/users/c4b3l3r4"
|
|
#property version "1.00"
|
|
//--- input parameters
|
|
input string op0="-------------- Parâmetros de Entrada --------------"; // -------------- Parâmetros de Entrada --------------
|
|
input double Volume=1; // Quantidade
|
|
input int TakeProfit=100; // TakeProfit
|
|
input int StopLoss=100; // Stoploss
|
|
input string op2="-------------- Média Móvel --------------"; // -------------- Média Móvel --------------
|
|
input int MA_period=5; // Período
|
|
input int MA_shift=0; // Deslocamento
|
|
input ENUM_MA_METHOD MA_method=MODE_EMA; // Tipo da média
|
|
input ENUM_APPLIED_PRICE MA_applied_price=PRICE_CLOSE; // Tipo do preço
|
|
int h_MA;
|
|
int Magic=12345;
|
|
ENUM_ORDER_TYPE_FILLING type_filling=ORDER_FILLING_RETURN;
|
|
ENUM_ORDER_TYPE_TIME expiration=ORDER_TIME_GTC;
|
|
//+------------------------------------------------------------------+
|
|
//| Expert initialization function |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
//---
|
|
h_MA=iMA(NULL,_Period,MA_period,MA_shift,MA_method,MA_applied_price);
|
|
if(h_MA<0)
|
|
{
|
|
Print("ERRO na criação do indicador, "+(string)GetLastError()+"!!");
|
|
return(INIT_FAILED);
|
|
}
|
|
//---
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Expert deinitialization function |
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
//---
|
|
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Expert tick function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTick()
|
|
{
|
|
//---
|
|
if(isNewBar())
|
|
{
|
|
int signal=GetSignal(); //Busca o sinal
|
|
if(PositionSelect(_Symbol)) //Se está posicionado
|
|
{
|
|
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) //Se a posição é comprada
|
|
{
|
|
if(signal==-1) //Se o sinal gerado é de venda
|
|
{
|
|
if(ClosePosition(_Symbol)) //Encerra a posição
|
|
{
|
|
if(Sell(_Symbol,0,Volume,TakeProfit,StopLoss,"Sell")) //Opera vendido
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
else //Caso contrário, temos uma posição vendida
|
|
{
|
|
if(signal==1) //Se o sinal gerado é de compra
|
|
{
|
|
if(ClosePosition(_Symbol)) //Encerra a posição
|
|
{
|
|
if(Buy(_Symbol,0,Volume,TakeProfit,StopLoss,"Buy")) //Opera comprado
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else //Caso contrário, não há posição
|
|
{
|
|
if(signal==1) //Se o sinal gerado é de compra
|
|
{
|
|
if(Buy(_Symbol,0,Volume,TakeProfit,StopLoss,"Buy")) //Opera comprado
|
|
return;
|
|
}
|
|
if(signal==-1) //Se o sinal gerado é de venda
|
|
{
|
|
if(Sell(_Symbol,0,Volume,TakeProfit,StopLoss,"Sell")) //Opera vendido
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool Buy(string symbol,double price,double volume,int takeProfit_,int stopLoss_,string comment)
|
|
{
|
|
MqlTradeRequest request={0};
|
|
MqlTradeResult result={0};
|
|
double SL=0;
|
|
double TP=0;
|
|
if(price==0)
|
|
price=SymbolInfoDouble(symbol,SYMBOL_ASK);
|
|
if(stopLoss_>0)
|
|
SL=NormalizeDouble(price-stopLoss_*_Point,_Digits); //--- Calcula SL
|
|
else
|
|
SL=0;
|
|
if(takeProfit_>0)
|
|
TP=NormalizeDouble(price+takeProfit_*_Point,_Digits); //--- Calcula TP
|
|
else
|
|
TP=0;
|
|
if(comment==NULL)
|
|
comment=StringFormat("Long %s %G lotes ",symbol,volume);
|
|
//--- Preenchimento da estrutura
|
|
request.action=TRADE_ACTION_DEAL;
|
|
request.symbol=symbol;
|
|
request.volume=volume;
|
|
request.type=ORDER_TYPE_BUY;
|
|
request.price=price;
|
|
request.tp=TP;
|
|
request.sl=SL;
|
|
request.deviation=10;
|
|
request.magic=Magic;
|
|
request.type_filling=type_filling;
|
|
request.expiration=expiration;
|
|
request.comment=comment;
|
|
//--- Envio da ordem
|
|
if(!OrderSend(request,result))
|
|
{
|
|
//--- Falha na ordem
|
|
Print("Ordem de compra falhou. Código de retorno=",result.retcode);
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
Print("Ordem de compra executada com sucesso. Código de retorno=",result.retcode);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool Sell(string symbol,double price,double volume,int takeProfit,int stopLoss,string comment)
|
|
{
|
|
MqlTradeRequest request={0};
|
|
MqlTradeResult result={0};
|
|
double SL=0;
|
|
double TP=0;
|
|
if(price==0)
|
|
price=SymbolInfoDouble(symbol,SYMBOL_BID);
|
|
if(stopLoss>0)
|
|
SL=NormalizeDouble(price+stopLoss*_Point,_Digits);
|
|
if(takeProfit>0)
|
|
TP=NormalizeDouble(price-takeProfit*_Point,_Digits);
|
|
if(comment==NULL)
|
|
comment=StringFormat("Short %s %G lotes ",symbol,volume);
|
|
//--- Preenchimento da estrutura
|
|
request.action=TRADE_ACTION_DEAL;
|
|
request.symbol=symbol;
|
|
request.volume=volume;
|
|
request.type=ORDER_TYPE_SELL;
|
|
request.price=price;
|
|
request.tp=TP;
|
|
request.sl=SL;
|
|
request.deviation=10;
|
|
request.magic=Magic;
|
|
request.type_filling=type_filling;
|
|
request.expiration=expiration;
|
|
request.comment=comment;
|
|
//--- Envio da ordem
|
|
if(!OrderSend(request,result))
|
|
{
|
|
//--- Falha na ordem
|
|
Print("Ordem de venda falhou. Código de retorno=",result.retcode);
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
Print("Ordem de venda executada com sucesso. Código de retorno=",result.retcode);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool ClosePosition(string symbol)
|
|
{
|
|
ENUM_POSITION_TYPE direction;
|
|
double volume=0;
|
|
if(!PositionSelect(symbol))
|
|
{
|
|
Print("Posição não encontrada!");
|
|
return false;
|
|
}
|
|
direction=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
|
|
volume=PositionGetDouble(POSITION_VOLUME);
|
|
if(direction==POSITION_TYPE_BUY)
|
|
if(Sell(symbol,0,volume,0,0,"Closing Buy Position"))
|
|
return true;
|
|
if(direction==POSITION_TYPE_SELL)
|
|
if(Buy(symbol,0,volume,0,0,"Closing Sell Position"))
|
|
return true;
|
|
return false;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
int GetSignal()
|
|
{
|
|
MqlRates rates[];
|
|
double MA[];
|
|
int to_copy=2;
|
|
ArraySetAsSeries(rates,true);
|
|
ArraySetAsSeries(MA,true);
|
|
int copied_rates=CopyRates(_Symbol,_Period,1,to_copy,rates);
|
|
if(copied_rates<to_copy)
|
|
return 0;
|
|
int copied_MA=CopyBuffer(h_MA,0,1,to_copy,MA);
|
|
if(copied_MA<to_copy)
|
|
return 0;
|
|
if(rates[0].close>MA[0] && rates[1].close<MA[1])
|
|
return 1;
|
|
if(rates[0].close<MA[0] && rates[1].close>MA[1])
|
|
return -1;
|
|
return 0;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool isNewBar()
|
|
{
|
|
static datetime last_time=0;
|
|
datetime lastbar_time=(datetime)SeriesInfoInteger(Symbol(),Period(),SERIES_LASTBAR_DATE);
|
|
if(last_time==0)
|
|
{
|
|
last_time=lastbar_time;
|
|
return(true);
|
|
}
|
|
if(last_time<lastbar_time)
|
|
{
|
|
last_time=lastbar_time;
|
|
return(true);
|
|
}
|
|
return(false);
|
|
}
|
|
//+------------------------------------------------------------------+
|