O básico de codificação de um Expert Advisor de cobertura
Eu fornecerei uma ideia de um simples expert advisor de cobertura. A vantagem do EA básico de cobertura.
Cobertura (finanças) (Da Wikipédia, a enciclopédia livre)
(Redirecionado de Cobertura)
Em finanças, uma cobertura é um investimento que é retirado especificamente para reduzir ou anular o risco em outro investimento. Cobertura é uma estratégia projetada para minimizar a exposição a riscos indesejados do negócio, enquanto ainda permite que a empresa se beneficie de uma atividade de investimento. Normalmente, uma cobertura pode ser investida em um título que, acredita-se, estar subvalorizada em relação ao seu "valor justo" (por exemplo, um empréstimo hipotecário), e combina isso com uma venda a descoberto de um título ou títulos relacionados. Assim, o investidor não se importa se o mercado como um todo vai subir ou baixar o valor, ele se preocupa unicamente com o título subvalorizado. Holbrook Working, um pioneiro na teoria de cobertura, chamou essa estratégia de "especulação na base",[1] onde a base é a diferença entre o valor teórico de cobertura e seu valor real (ou entre os dois e os preços futuros do tempo de Working).
Alguma forma de tomada de risco é inerente a qualquer atividade de negócios. Alguns riscos são considerados "naturais" em negócios específicos, assim como o risco do preço do petróleo aumentar ou baixar para empresas d perfuração ou refino de petróleo. Outras formas de risco não são desejadas, mas não podem ser evitadas sem cobertura. Alguém que tem uma loja, por exemplo, pode cuidar de riscos naturais tais como o risco de concorrência, de produtos ruins ou impopulares, e assim por diante. O risco de estoque do lojista ser destruído pelo fogo é indesejado, no entanto, pode ser coberto por um contrato de seguro de incêndio. Nem todas as coberturas são instrumentos financeiros: um produtor que exporta para outro país, por exemplo, pode cobrir seu risco de moeda ao vender ligando suas despesas com a moeda desejada.
leia mais aquiTodas as coisas que precisamos a partir do servidor devem ser chamadas pela função MarketInfo (símbolo string, tipo int). Esta função permite-nos chamar quaisquer dados além dos dados que aparecem na janela do gráfico ativo. Isso também nos permite enviar qualquer tipo de ordem de qualquer símbolo além do símbolo exibido ativamente na janela do gráfico ativo. E isso pode deixar-nos cobrir o símbolo 2 facilmente. Graças a Deus e aos membros da equipe MT4, isto ajuda muito.
Uma coisa necessária na cobertura é a correlação entre os 2 símbolos de monitoramento que podem encontrar-se com algumas pequenas funções que serão mostradas abaixo.
Correlação, no mundo financeiro, é a medida estatística da relação entre dois títulos. O coeficiente de correlação varia entre -1 e +1. A correlação de +1 implica que os dois pares de moedas irão se mover no mesmo sentido 100% do tempo. A correlação de -1 implica que os dois pares de moedas irão se mover em posição oposta 100% do tempo. A correlação de zero implica que a relação entre os pares de moedas será completamente aleatória. leia mais aqui
Todo que está acima são coisas simples que quem faz cobertura no mercado Forex utilizando Expert Advisor MT4 precisa saber. Agora podemos começar a fazer um EA de cobertura.
Código do EA de cobertura passo a passo
Etapa 1: Os parâmetros de entradaEm primeiro lugar, antes de começar a escrever o EA de cobertura, precisamos escolher 2 símbolos correlatos, ou seja:
- GBPUSD e EURUSD que sempre se movem da mesma maneira;
- EURUSD & USDCHF que sempre se movem de formas opostas;
- * etc.
Neste artigo, escolherei meu próprio par de cobertura favorito que é EURJPY e GBPJPY. Ele sempre se move da mesma maneira,sendo assim, mais fácil definir o tipo de ordem de cobertura. Vamos começar. Para começar a fazer o EA de cobertura, vamos conhecer abaixo as variáveis de entrada.
// this is to block the order sending function but // not to block the close function. extern bool BlockOpening = false; extern string BaseSymbol = "EURJPY";//the 1st symbol extern string H_Symbol = "GBPJPY";//the 2nd symbol extern bool MoveSameWay = true;//they move the same way or not extern int CorPeriod = 5;//your favorite correlation period extern double BaseLotSize = 1.5;//1st symbol lotsize extern double H_LotsSize = 1.0;//2nd symbol lotsize extern double ExpectProfit$ = 137;//your expect profit in USD //your acceptable loss in USD in case any error occurred extern double AcceptableLoss$ = -77; extern string ExpectCor = "______";//your expect correlation to hedge //this is the upper expect cor value and has to be greater than "And" extern double Between = 1.05; extern double And = 0.9;//this is the lower expect cor level extern string MISC = "______";//some thing more extern int MagicNo = 318;//your favorite magic number extern bool ShowStatus = true;//to show the present hedging status //to play sound when SendH and CloseH function done extern bool PlayAudio = false;
Etapa 2: A declaração da variável
A seguir estão as variáveis utilizadas neste EA e eu explicarei somente a variável necessária para entender como funciona o EA.
int BSP // the spread of base symbol , HSP // the spread of hedge symbol , gsp , BOP = -1 // base symbol order type , HOP = -1 // hedge symbol order type , up = 0 , Hcnt = 0 , u = 0 , d = 0 , day = 0 , sent=0 , firstopen , expire; double Lot , BaseOpen // base symbol order open price , HOpen // hedge symbol order open price , BPt // base symbol Point value , HPt // hedge symbol Point value , BSwapL // base symbol swap long value , BSwapS // base symbol swap short value , HSwapL // hedge symbol swap long value , HSwapS; // hedge symbol swap short value bool SResult = false, BResult = false, H1.profitswap, H2.profitswap, H3.profitswap; bool SwapMode = true, allmeetcor = false, BlockOpen = false, buy,sell,cleared = false; string H1.string = "", H2.string = "", H3.string = "", OrdComment = "", candletxt,tdstxt = "";
Etapa 3: Obtenha todos os parâmetros estáticos necessários
Agora vamos especificar alguns valores estáticos que serão declarados na parte do init().
//+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---- BSP = MarketInfo(BaseSymbol,MODE_SPREAD); HSP = MarketInfo(H_Symbol ,MODE_SPREAD); BPt = MarketInfo(BaseSymbol,MODE_POINT); HPt = MarketInfo(H_Symbol ,MODE_POINT); BSwapL = MarketInfo(BaseSymbol,MODE_SWAPLONG); BSwapS = MarketInfo(BaseSymbol,MODE_SWAPSHORT); HSwapL = MarketInfo(H_Symbol,MODE_SWAPLONG); HSwapS = MarketInfo(H_Symbol,MODE_SWAPSHORT); //---- return(0); }
Etapa 4: As Funções Úteis
Antes de entrar na parte mais engraçada, estamos aguardando a função "start ()", vamos começar com as funções utilizadas neste EA. Mas, por favor, observe que todas as funções vão ficar fora da função start().
1. A função de correlação
Primeiro, precisamos começar com as funções de cálculo de correlação. As funções a seguir são aplicadas por um homem fornecendo o indicador livre de correlação (igorad2004@list.ru) e eu os modifiquei para facilitar o uso neste EA, sendo assim, não será mais preciso chamar o valor de correlação do indicador de fora. Boa ideia?
//+------------------------------------------------------------------+ //| CORRELATION | //+------------------------------------------------------------------+ double symboldif(string symbol, int shift) { return(iClose(symbol, 1440, shift) - iMA(symbol, 1440, CorPeriod, 0, MODE_SMA, PRICE_CLOSE, shift)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double powdif(double val) { return(MathPow(val, 2)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double u(double val1,double val2) { return((val1*val2)); } //+------------------------------------------------------------------+ //| The real correlation function to call is here. | //+------------------------------------------------------------------+ double Cor(string base, string hedge) { double u1=0,l1=0,s1=0; for(int i = CorPeriod - 1; i >= 0; i--) { u1 += u(symboldif(base, i), symboldif(hedge, i)); l1 += powdif(symboldif(base, i)); s1 += powdif(symboldif(hedge, i)); } if(l1*s1 > 0) return(u1 / MathSqrt(l1*s1)); } //+------------------------------------------------------------------+
A variável CorPeriod será externa como uma variável de entrada para permitir-nos configurá-la. Quando você quiser calcular a correlação entre 2 símbolos, basta chamar a função Cor(base da string, cobertura da string) como esta Cor (EURJPY, GBPJPY). É fácil, não é?
2. A função de envio de cobertura
Eu acho que é mais fácil gerenciar como podemos enviar as ordens de cobertura criando uma função SendH abaixo.
//+------------------------------------------------------------------+ //| SEND HEDGE | //+------------------------------------------------------------------+ bool SendH(string symbol, int op, double lots, double price, int sp, string comment, int magic) { if(OrderSend(symbol , op , lots , price , sp , 0 , 0 , comment , magic , 0 , CLR_NONE) > 0) { return(true); if(PlayAudio) PlaySound("expert.wav"); } else { Print(symbol, ": ", magic, " : " , ErrorDescription(GetLastError())); return(false); } } //+------------------------------------------------------------------+
Você pode ler mais sobre a função OrderSend aqui.
Esta função ErrorDescription(GetLastError()) acima permite que nosso EA nos diga o erro que ocorreu quando a função de trading estava trabalhando para nós. Para usá-la, precisamos incluir o arquivo "stdlib.mqh" colocando o código da seguinte maneira:
//+------------------------------------------------------------------+ //| MyHedge.mq4 | //| myHedge | //| http://dailyh.blogspot.com/ | //+------------------------------------------------------------------+ #property copyright "myHedge" #property link "http://dailyh.blogspot.com/" #include <stdlib.mqh> //+-------
E para usá-la, basta chamar a função "ErrorDescription()" como mostrado acima.
3. A função do fechamento da cobertura
Além de enviar as ordens, precisamos também de uma função para fechar todas as ordens de cobertura quando elas alcançam o lucro esperado. Lá vai:
//+------------------------------------------------------------------+ //| CLOSE HEDGE | //+------------------------------------------------------------------+ bool CloseHedge(int magic) { for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == magic) { if(OrderClose(OrderTicket() , OrderLots() , OrderClosePrice() , MarketInfo(OrderSymbol(), MODE_SPREAD) , CLR_NONE)) SResult = true; } } if(SResult) { return(true); if(PlayAudio) { PlaySound("ok.wav"); } } else Print("CloseHedge Error: ", ErrorDescription(GetLastError())); RefreshRates(); // return(0); } //+------------------------------------------------------------------+
Esta função só fechará as ordens com o mesmo número mágico, o que significa que não irá interferir nas ordens de cobertura com outros números mágicos. Não é uma coisa para se preocupar. Antes de usar essa função de fechamento, precisamos definir "o quanto nós temos agora", usando a função abaixo.
4. A função de encontrar o lucro total
//+------------------------------------------------------------------+ //| TOTAL PROFIT | //+------------------------------------------------------------------+ double TotalCurProfit(int magic) { double MyCurrentProfit = 0; for(int cnt = 0 ; cnt < OrdersTotal() ; cnt++) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if(OrderMagicNumber() == magic) { MyCurrentProfit += (OrderProfit() + OrderSwap()); } } return(MyCurrentProfit); } //+------------------------------------------------------------------+
Como na função de fechamento, para saber o lucro da cobertura precisamos monitorar apenas as decisões com o mesmo número mágico, para fechá-las corretamente. Para usá-las, apenas configure os códigos da seguinte forma:
if(TotalCurProfit(318) > 100) CloseHedge(318);
Todos os valores de lucro são calculados em USD. A partir da linha anterior, quando o lucro geral de ordens com o número mágico 318 for maior do que $100, elas serão fechadas. É isso. Para abrir as ordens de cobertura, precisamos saber que não há outra ordem com o mesmo símbolo e número mágico flutuando no momento que precisarmos enviar a cobertura. Isto pode ser definido por esta função.
5. Obter a quantidade de posições existentes
//+------------------------------------------------------------------+ //| EXISTING POSITIONS | //+------------------------------------------------------------------+ int ExistPositions(string symbol, int magic) { int NumPos = 0; for(int i = 0; i < OrdersTotal(); i++) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderSymbol() == symbol && OrderMagicNumber() == magic) { NumPos++; } } return(NumPos); } //+------------------------------------------------------------------+
Pode ser usado da seguinte forma:
ExistPositions("GBPJPY",318)
Esta função nos retornará "quantas ordens de abertura de GBPJPY com número mágico de 318 estão flutuando" no momento. Mais uma função para definir o tipo de ordem flutuante.
6. Encontrar o tipo de ordem de posição específicas existentes
//+------------------------------------------------------------------+ //| EXISTING OP POSITION | //+------------------------------------------------------------------+ int ExistOP(string symbol, int magic) { int NumPos = -1; for(int i = 0; i < OrdersTotal(); i++) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderSymbol() == symbol && OrderMagicNumber() == magic) { NumPos = OrderType(); } } return(NumPos); } //+------------------------------------------------------------------+
Esta função retorna o valor inteiro do tipo de ordem para o símbolo e o número mágico especificado que estão flutuando no momento. Se o número de flutuação do GBPJPY for OP_BUY, o valor de retorno é "0". Esta função não trabalha somente em conjunto com a função de trading. Ela também funciona com uma função para mostrar o estado atual da cobertura. Esta função chama-se "OP2Str".
7. Mostrando o estado do trading
//+------------------------------------------------------------------+ //| Transform OP Value To string | //+------------------------------------------------------------------+ string OP2Str(int op) { switch(op) { case OP_BUY : return("BUY"); case OP_SELL: return("SELL"); default : return("~~"); } } //+------------------------------------------------------------------+
Não há muito a dizer, acho que o nome já mostra como funciona.
8. Fechamento de todos os tipos específicos de ordens
Mais uma função para fechar qualquer ordem única diretamente, no caso de um erro, ao enviar ou fechar a cobertura.
//+------------------------------------------------------------------+ //| CLOSE SCRAP | //+------------------------------------------------------------------+ bool CloseScrap(string sym, int op, int magic) { for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && amp; OrderMagicNumber() == magic && OrderSymbol() == sym && OrderType() == op) { if(OrderClose(OrderTicket() , OrderLots() , OrderClosePrice() , MarketInfo(OrderSymbol(), MODE_SPREAD) , CLR_NONE)) BResult = true; } } if(BResult) { return(true); if(PlayAudio) { PlaySound("ok.wav"); } } else Print("CloseScrap Error: ", ErrorDescription(GetLastError())); RefreshRates(); // return(0); }
CloseScrap("GBPJPY",OP_BUY,318) : isto irá fechar apenas o flutuação prolongada "GBPJPY" que possui o número mágico de 318. É fácil. Há mais uma função.
9. Mostrar qualquer estado booleano que você desejar
//+------------------------------------------------------------------+ //| Translate bool to string | //+------------------------------------------------------------------+ string bool2str( bool boolval) { if(boolval == true) return("Yes"); if(boolval == false) return("No"); } //+------------------------------------------------------------------+
Nada de especial, esta função mostrará o estado booleano de alguns parâmetros, tais como o valor BlockOpening. Quando você defini-la como verdadeira, esta função irá retornar "Sim" na tela. Ela irá retornar "Não" quando você defini-la como falsa. Isto é tudo sobre as funções que precisamos. Agora vamos aproveitar o processo de codificação da cobertura.
Etapa 5: O núcleo do Expert Advisor
Primeiramente, comece com isto:
//+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() {
Em seguida, especifique o intervalo de correlação.
if(Cor(BaseSymbol, H_Symbol) > Between || Cor(BaseSymbol, H_Symbol) < And) // Block opening when the correlation is out of // expected range. BlockOpen = true; else BlockOpen = false;
Depois, defina a forma da cobertura (este é apenas um exemplo), neste artigo vou selecionar o estilo de trading pelo valor de troca, então, só irei realizar o trade de maneira que eu posso ganhar com a troca todos os dias.
// if they move the same way we will open long & short if(MoveSameWay) { if(((BSwapL*BaseLotSize) + (HSwapS*H_LotSize)) > 0) { BOP = OP_BUY; HOP = OP_SELL; } else if(((BSwapS*BaseLotSize) + (HSwapL*H_LotSize)) > 0) { BOP = OP_SELL; HOP = OP_BUY; } } // end MoveSameWay // if the move the opposite way we will open short & short or long & long else { if(((BSwapL*BaseLotSize) + (HSwapL*H_LotSize)) > 0) { BOP = OP_BUY; HOP = OP_BUY; } else if(((BSwapS*BaseLotSize) + (HSwapS*H_LotSize)) > 0) { BOP = OP_SELL; HOP = OP_SELL; } }
Agora é o momento de enviar a cobertura:
// if they meet the correlation range and // you're not blocking them if(!BlockOpen && !BlockOpening) { if(BOP == OP_BUY) // define the opening price BaseOpen = MarketInfo(BaseSymbol, MODE_ASK); else BaseOpen = MarketInfo(BaseSymbol, MODE_BID); if(HOP == OP_BUY) HOpen = MarketInfo(H_Symbol, MODE_ASK); else HOpen = MarketInfo(H_Symbol, MODE_BID); // In case there is no any swap condition to gain // from BOP & HOP will be -1. if(BOP >= 0 && HOP >= 0) { if(ExistPositions(BaseSymbol, MagicNo) == 0 && ExistPositions(H_Symbol, MagicNo) == 0) { SendH(BaseSymbol, BOP, BaseLotSize, BaseOpen, BSP, "COR : " + DoubleToStr(Cor(BaseSymbol, H_Symbol), 2), MagicNo); SendH(H_Symbol, HOP, H_LotsSize, HOpen, HSP, "COR : " + DoubleToStr(Cor(BaseSymbol, H_Symbol), 2), MagicNo); } else // in case ping failed or requote { if(ExistPositions(BaseSymbol, MagicNo) == 1&& TotalCurProfit(MagicNo)>AcceptableLoss$) { CloseScrap(BaseSymbol, ExistOP(BaseSymbol, MagicNo), MagicNo); } else if(ExistPositions(H_Symbol, MagicNo) == 1&& TotalCurProfit(MagicNo) > AcceptableLoss$) { CloseScrap(H_Symbol, ExistOP(H_Symbol, MagicNo), MagicNo); } } } else // if one of BOP and HOP is less than 0 { string swaptxt = "No Swap Condition To Gain From :" + "pls modify one or more input parameter(s)."; } }
Em seguida, feche-os quando atingirem o lucro esperado
if((TotalCurProfit(MagicNo) > ExpectProfit$) { CloseHedge(MagicNo); }
E algo mais engraçado: A parte de exibição do status.
if(ShowStatus) { Comment("\nCorrel: " + DoubleToStr(Cor(BaseSymbol , H_Symbol), 2) , "\nBlockOpen : " + bool2str(BlockOpen || BlockOpening) , "\n" + swaptxt , "\n~~~~~~~" , "\nB/H [sp] : " + BaseSymbol + " [" + BSP + "]" + " / " + H_Symbol+" ["+HSP+"]" , "\nCurOp [Lots]: " + OP2Str(ExistOP(BaseSymbol, MagicNo)) + " [" + DoubleToStr(BaseLotSize, 2) + "]" + " ~ " + OP2Str(ExistOP(H_Symbol, MagicNo)) + " [" + DoubleToStr(H_LotsRatio*BaseLotSize, 2) + "]" , "\nCurPF [Expect]: $" + DoubleToStr(TotalCurProfit(MagicNo), 2) + " [$"+DoubleToStr(ExpectProfit$, 2) + "]"); } else Comment("");
Finalize com o fim de cada EA.
return(0); }
Etapa 6: Reunir todos eles
Aqui você pode ver como o myHedge.mq4 parece.
//+------------------------------------------------------------------+ //| MyHedge.mq4 | //| myHedge | //| http://dailyh.blogspot.com/ | //+------------------------------------------------------------------+ #property copyright "myHedge" #property link "http://dailyh.blogspot.com/" //---- #include <stdlib.mqh> // this is to block the order sending function but not to block the // close function. extern bool BlockOpening = false; extern string BaseSymbol = "EURJPY"; // the 1st symbol extern string H_Symbol = "GBPJPY"; // the 2nd symbol extern bool MoveSameWay = true; // they move the same way or not extern int CorPeriod = 5; // your favorite correlation period extern double BaseLotSize = 1.5; // 1st symbol lotsize extern double H_LotSize = 1.0; // 2nd symbol lotsize extern double ExpectProfit$ = 137; // your expect profit in USD // your acceptable loss in USD in case any error occurred extern double AcceptableLoss$ = -77; extern string ExpectCor = "______"; // your expect correlation to // hedge this is the upper expect cor value and has to be greater // than "And" extern double Between = 1.05; extern double And = 0.9; // this is the lower expect cor level extern string MISC = "______"; // some thing more extern int MagicNo = 318; // your favorite magic number extern bool ShowStatus = true; // to show the present hedging status // to play sound when SendH and CloseH function done extern bool PlayAudio = false; //---- int BSP // the spread of base symbol ,HSP // the spread of hedge symbol ,gsp ,BOP = -1 // base symbol order type ,HOP = -1 // hedge symbol order type ,up = 0 ,Hcnt = 0 ,u = 0 ,d = 0 ,day = 0 ,sent = 0 ,firstopen ,expire; double Lot ,BaseOpen // base symbol order open price ,HOpen // hedge symbol order open price ,BPt // base symbol Point value ,HPt // hedge symbol Point value ,BSwapL // base symbol swap long value ,BSwapS // base symbol swap short value ,HSwapL // hedge symbol swap long value ,HSwapS; // hedge symbol swap short value bool SResult = false, BResult = false, H1.profitswap, H2.profitswap, H3.profitswap; bool SwapMode = true, allmeetcor = false, BlockOpen = false, buy, sell, cleared = false; string H1.string = "", H2.string = "", H3.string = "", OrdComment = "", candletxt,tdstxt = ""; //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { BSP = MarketInfo(BaseSymbol, MODE_SPREAD); HSP = MarketInfo(H_Symbol, MODE_SPREAD); //---- BPt = MarketInfo(BaseSymbol, MODE_POINT); HPt = MarketInfo(H_Symbol, MODE_POINT); //---- BSwapL = MarketInfo(BaseSymbol, MODE_SWAPLONG); BSwapS = MarketInfo(BaseSymbol, MODE_SWAPSHORT); //---- HSwapL = MarketInfo(H_Symbol, MODE_SWAPLONG); HSwapS = MarketInfo(H_Symbol, MODE_SWAPSHORT); //---- return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { if(Cor(BaseSymbol, H_Symbol) > Between || Cor(BaseSymbol, H_Symbol) < And) // Block opening when the correlation is out of expected range. BlockOpen = true; else BlockOpen = false; //---- if(MoveSameWay) { if((BSwapL*BaseLotSize) + (HSwapS*H_LotSize) > 0) { BOP = OP_BUY; HOP = OP_SELL; } else if((BSwapS*BaseLotSize) + (HSwapL*H_LotSize) > 0) { BOP = OP_SELL; HOP = OP_BUY; } } else { if((BSwapL*BaseLotSize) + (HSwapL*H_LotSize) > 0) { BOP = OP_BUY; HOP = OP_BUY; } else if((BSwapS*BaseLotSize) + (HSwapS*H_LotSize) > 0) { BOP = OP_SELL; HOP = OP_SELL; } } if(!BlockOpen && !BlockOpening) { if(BOP == OP_BUY) BaseOpen = MarketInfo(BaseSymbol, MODE_ASK); else BaseOpen = MarketInfo(BaseSymbol, MODE_BID); if(HOP == OP_BUY) HOpen = MarketInfo(H_Symbol, MODE_ASK); else HOpen = MarketInfo(H_Symbol, MODE_BID); // In case there is no any swap condition that we can gain from. if(BOP >= 0 && HOP >= 0) { if(ExistPositions(BaseSymbol, MagicNo) == 0 && ExistPositions(H_Symbol,MagicNo) == 0) { SendH(BaseSymbol, BOP, BaseLotSize, BaseOpen, BSP, "COR : " + DoubleToStr(Cor(BaseSymbol, H_Symbol), 2), MagicNo); SendH(H_Symbol, HOP, H_LotSize, HOpen, HSP, "COR : " + DoubleToStr(Cor(BaseSymbol, H_Symbol), 2), MagicNo); } else // in case ping failed or requote { if(ExistPositions(BaseSymbol, MagicNo) == 1 && TotalCurProfit(MagicNo) > AcceptableLoss$) { CloseScrap(BaseSymbol, ExistOP(BaseSymbol, MagicNo), MagicNo); } else if(ExistPositions(H_Symbol, MagicNo) == 1 && TotalCurProfit(MagicNo) > AcceptableLoss$) { CloseScrap(H_Symbol, ExistOP(H_Symbol, MagicNo), MagicNo); } } } else { string swaptxt = "No Swap Condition To Gain From : pls " + "modify one or more input parameter(s)."; } } if(TotalCurProfit(MagicNo) > ExpectProfit$) { CloseHedge(MagicNo); } if(ShowStatus) { Comment("\nCorrel: "+DoubleToStr(Cor(BaseSymbol, H_Symbol), 2) , "\nBlockOpen : " + bool2str(BlockOpen || BlockOpening) , "\n" + swaptxt , "\n~~~~~~~" , "\nB/H [sp] : " + BaseSymbol + " [" + BSP + "]" + " / " + H_Symbol + " [" + HSP + "]" , "\nCurOp [Lots]: " + OP2Str(ExistOP(BaseSymbol, MagicNo)) + " [" + DoubleToStr(BaseLotSize, 2) + "]" + " ~ " + OP2Str(ExistOP(H_Symbol, MagicNo)) + " [" + DoubleToStr(H_LotSize, 2) + "]" , "\nCurPF [Expect]: $" + DoubleToStr(TotalCurProfit(MagicNo), 2) + " [$" + DoubleToStr(ExpectProfit$, 2) + "]"); } else Comment(""); return(0); } //+------------------------------------------------------------------+ //| CORRELATION | //+------------------------------------------------------------------+ double symboldif(string symbol, int shift) { return(iClose(symbol, 1440, shift) - iMA(symbol, 1440, CorPeriod, 0, MODE_SMA, PRICE_CLOSE, shift)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double powdif(double val) { return(MathPow(val, 2)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double u(double val1, double val2) { return((val1*val2)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double Cor(string base, string hedge) { double u1 = 0, l1 = 0, s1 = 0; for(int i = CorPeriod - 1; i >= 0; i--) { u1 += u(symboldif(base, i), symboldif(hedge, i)); l1 += powdif(symboldif(base, i)); s1 += powdif(symboldif(hedge, i)); } if(l1*s1 > 0) return(u1 / MathSqrt(l1*s1)); } //+------------------------------------------------------------------+ //| SEND HEDGE | //+------------------------------------------------------------------+ bool SendH(string symbol, int op, double lots, double price, int sp, string comment, int magic) { if(OrderSend(symbol ,op ,lots ,price ,sp ,0 ,0 ,comment ,magic ,0 ,CLR_NONE) >0) { return(true); if(PlayAudio) PlaySound("expert.wav"); } else { Print(symbol, ": ", magic, " : " ,ErrorDescription(GetLastError())); return(false); } } //+------------------------------------------------------------------+ //| CLOSE HEDGE | //+------------------------------------------------------------------+ bool CloseHedge(int magic) { for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == magic) { if(OrderClose(OrderTicket() , OrderLots() , OrderClosePrice() , MarketInfo(OrderSymbol(), MODE_SPREAD) , CLR_NONE)) SResult = true; } } if(SResult) { return(true); if(PlayAudio) { PlaySound("ok.wav"); } } else Print("CloseHedge Error: ", ErrorDescription(GetLastError())); RefreshRates(); // return(0); } //+------------------------------------------------------------------+ //| TOTAL PROFIT | //+------------------------------------------------------------------+ double TotalCurProfit(int magic) { double MyCurrentProfit = 0; for(int cnt = 0; cnt < OrdersTotal(); cnt++) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if(OrderMagicNumber() == magic) { MyCurrentProfit += (OrderProfit() + OrderSwap()); } } return(MyCurrentProfit); } //+------------------------------------------------------------------+ //| EXISTING POSITION | //+------------------------------------------------------------------+ int ExistPositions(string symbol,int magic) { int NumPos = 0; for(int i = 0; i < OrdersTotal(); i++) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderSymbol() == symbol && OrderMagicNumber() == magic) { NumPos++; } } return(NumPos); } //+------------------------------------------------------------------+ //| EXISTING OP POSITION | //+------------------------------------------------------------------+ int ExistOP(string symbol,int magic) { int NumPos = -1; for(int i = 0; i < OrdersTotal(); i++) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderSymbol() == symbol && OrderMagicNumber() == magic) { NumPos = OrderType(); } } return(NumPos); } //+------------------------------------------------------------------+ //| Transform OP Value To string | //+------------------------------------------------------------------+ string OP2Str(int op) { switch(op) { case OP_BUY : return("BUY"); case OP_SELL: return("SELL"); default : return("~~"); } } //+------------------------------------------------------------------+ //| CLOSE SCRAP | //+------------------------------------------------------------------+ bool CloseScrap(string sym,int op,int magic) { for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == magic && OrderSymbol() == sym && OrderType() == op) { if(OrderClose(OrderTicket() , OrderLots() , OrderClosePrice() , MarketInfo(OrderSymbol(), MODE_SPREAD) , CLR_NONE)) BResult = true; } } if(SResult || BResult) { return(true); if(PlayAudio) { PlaySound("ok.wav"); } } else Print("CloseScrap Error: ", ErrorDescription(GetLastError())); RefreshRates(); // return(0); } //+------------------------------------------------------------------+ //| Translate bool to string | //+------------------------------------------------------------------+ string bool2str(bool boolval) { if(boolval == true) return("Yes"); if(boolval == false) return("No"); } //+------------------------------------------------------------------+
Conclusão
Este é apenas um exemplo de uma Expert Advisors de cobertura simples. Você precisa modificá-lo para encaixar seu próprio estilo de cobertura. Estou certo de que existem muitos estilos de cobertura por aí. E, por favor, observe que este tipo de EA não pode ser testado pelo Strategy Tester devido seu próprio limite. Você precisa testá-lo apenas ao vivo. Abaixo está o resultado da amostra de uma EA de cobertura.
E a função ShowStatus será assim:
Espero que você aproveite meu artigo e que ele ajude-o a criar seu próprio EA de cobertura.
Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/1479
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso