Como codificar? - página 299

 

Entrada de tempo personalizada na MQL4

É possível escrever um código com MQL4 que possa traçar uma linha horizontal a partir de uma barra definida pelo usuário até o final do gráfico?

Aqui está o mesmo código com Metastock

{Customer Inputs}

Dy:=Input("Day",1,31,1);

Mn:=Input("Month",1,12,1);

Yr:=Input("Year",2000,2012,2010);

{Time Calculation}

Time:=Dy=DayOfMonth() AND Mn=Month() AND Yr=Year();

{Formula}

Start:= ValueWhen(1,Time,CLOSE);

{Output}

Start;

E aqui está o resultado

Eu espero fazer a mesma coisa com a MQL4

 

Tente assim :

#property indicator_chart_window

extern string startFrom = "2012.07.06 00:00";

int init() { return(0); }

int deinit() { ObjectDelete("hLine"); return(0); }

int start()

{

string name = "hLine";

int barShift = iBarShift(NULL,0,StrToTime(startFrom));

ObjectCreate(name,OBJ_TREND,0,0,0,0,0);

ObjectSet(name,OBJPROP_PRICE1,Close);

ObjectSet(name,OBJPROP_PRICE2,Close);

ObjectSet(name,OBJPROP_TIME1,Time);

ObjectSet(name,OBJPROP_TIME2,Time[0]);

return (0);

}

Basta copiar e colar em algum indicador (é um indicador que já está funcionando) e anexá-lo ao gráfico.

kappari:
É possível escrever um código com MQL4 que possa traçar uma linha horizontal a partir de uma barra definida pelo usuário até o final do gráfico?

Aqui está o mesmo código com o Metastock

{Customer Inputs}

Dy:=Input("Day",1,31,1);

Mn:=Input("Month",1,12,1);

Yr:=Input("Year",2000,2012,2010);

{Time Calculation}

Time:=Dy=DayOfMonth() AND Mn=Month() AND Yr=Year();

{Formula}

Start:= ValueWhen(1,Time,CLOSE);

{Output}

Start;

E aqui está o resultado

Eu espero fazer a mesma coisa com a MQL4
 
mladen:
Tente assim :
#property indicator_chart_window

extern string startFrom = "2012.07.06 00:00";

int init() { return(0); }

int deinit() { ObjectDelete("hLine"); return(0); }

int start()

{

string name = "hLine";

int barShift = iBarShift(NULL,0,StrToTime(startFrom));

ObjectCreate(name,OBJ_TREND,0,0,0,0,0);

ObjectSet(name,OBJPROP_PRICE1,Close);

ObjectSet(name,OBJPROP_PRICE2,Close);

ObjectSet(name,OBJPROP_TIME1,Time);

ObjectSet(name,OBJPROP_TIME2,Time[0]);

return (0);

}
Basta copiar e colar em algum indicador (é um indicador que já está funcionando) e anexá-lo ao gráfico.

Você é o melhor, muito obrigado.

 

Olá, Mladen,

Você pode me dizer mais sobre a razão de ser das funções aqui? Eu ainda não entendi bem. Obrigado

Terrance

mladen:
Tente esta função :
int countOpenedOrders(int type)

{

int openedOrders = 0;

for(int i=0; i < OrdersTotal(); i++)

{

if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) break;

if(OrderSymbol() != Symbol()) continue;

if(OrderMagicNumber() != MagicNumber) continue;

if(OrderType() == type) openedOrders++;

}

return(openedOrders);

}

[/PHP]

To count opened buy orders, call it like this :

int openedBuys = countOpened(OP_BUY);

to count opened sell orders, call it like this :

[PHP]int openedSells = countOpened(OP_SELL);
e então você pode verificar
:se openBuys==0 open buyif

openSells==0 open sell

 

tkuan77

Você queria limitar os pedidos a 1 compra e 1 venda de cada vez.

Assim, se você chamar o contador de ordens abertas antes de abrir qualquer uma das posições, você pode controlar quantas compras ou vendas abertas você tem.

um exemplo :

int openedBuys = countOpened(OP_BUY); if (openedBuys==0) code for open a buy order

se openBuys uis qualquer coisa menos 0, você não abre uma nova ordem de compra. A mesma lógica se aplica à venda (este é o segundo exemplo nesse post)

tkuan77:
Olá, Mladen,

Você pode me dizer mais sobre a razão de ser das funções aqui? Eu ainda não entendi bem. Obrigado

Terrance
 

Olá, Mladen,

Talvez eu tenha me apresentado erroneamente. O que estou tentando realizar é que quando meu critério de compra for atendido, isso desencadeará uma compra e se outro critério de compra for atendido novamente, isso desencadeará outra compra OU venda se o critério de venda for atendido. Entretanto, o comércio máximo que eu terei a qualquer momento será 2.

Eu tentei seu método anteriormente e ainda estou encontrando o sistema abrindo 2 negociações ao mesmo tempo, por isso tentei limitá-lo com a função de Barras com a mesma questão de ter a EA abrindo 2 negociações ao mesmo tempo.

Qual poderia ser a causa possível aqui? Tem algo a ver com minha lógica?

Cumprimentos

Terrance

mladen:
tkuan77

Você queria limitar os pedidos a 1 compra e 1 venda de cada vez.

Assim, se você chamar o contador de ordens abertas antes de abrir qualquer uma das posições, você pode controlar quantas compras ou vendas abertas você tem.

um exemplo :

int openedBuys = countOpened(OP_BUY); if (openedBuys==0) code for open a buy order
se openBuys uis qualquer coisa menos 0 você não abre uma nova ordem de compra. A mesma lógica se aplica à venda (este é o segundo exemplo nesse post)
 

Você pode adicionar verificação se um pedido de algum tipo já foi aberto em um bar atual e assim você evitará a abertura de um novo pedido em um próximo tick. Se sim (houve uma ordem aberta em um bar atual), então não será possível abrir uma nova ordem. Se não, você pode abrir um novo pedido. Aqui está uma função que pode contar as ordens de tipo rewuired abertas em um bar atual

int countOpenedOnACurrentBar(int type)

{

int openedAtBar = 0;

datetime startTime = Time[0];

datetime endTime = Time[0]+Period()*60;

for(int i=0; i < OrdersTotal(); i++)

{

if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) break;

if(OrderMagicNumber() != MagicNumber) continue;

if(OrderSymbol() != Symbol()) continue;

if(OrderType() != type) continue;

if(OrderOpenTime()=endTime) continue;

openedAtBar++;

break;

}

return(openedAtBar);

}

tkuan77:
Olá, Mladen,

Talvez eu tenha me apresentado erroneamente. O que estou tentando realizar é que quando meu critério de compra for atendido, isso desencadeará uma compra e se outro critério de compra for atendido novamente, isso desencadeará outra compra OU venda se o critério de venda for atendido. Entretanto, o comércio máximo que eu terei a qualquer momento será 2.

Eu tentei seu método anteriormente e ainda estou encontrando o sistema abrindo 2 negociações ao mesmo tempo, por isso tentei limitá-lo com a função de Barras com a mesma questão de ter a EA abrindo 2 negociações ao mesmo tempo.

Qual poderia ser a causa possível aqui? Tem algo a ver com minha lógica?

Cumprimentos

Terrance
 
tkuan77:
Olá Mladen,

Talvez eu tenha me apresentado erroneamente. O que estou tentando realizar é que quando meu critério de compra for atendido, isso desencadeará uma compra e se outro critério de compra for atendido novamente, isso desencadeará outra compra OU venda se o critério de venda for atendido. Entretanto, o comércio máximo que eu terei a qualquer momento será 2.

Eu tentei seu método anteriormente e ainda estou encontrando o sistema abrindo 2 negociações ao mesmo tempo, por isso tentei limitá-lo com a função de Barras com a mesma questão de ter a EA abrindo 2 negociações ao mesmo tempo.

Qual poderia ser a causa possível aqui? Tem algo a ver com minha lógica?

Cumprimentos

Terrance

isto porque você não especificou como você quer que a segunda profissão seja diferente da primeira. A diferenciação poderia ser na forma de x nº de barras ou preço longe do FirstBuyPrice.

 

Obrigado Mladen pela ajuda, entretanto eu só quero verificar com você, eu coloco o código antes da minha função longa/curta, no meio ou em outro lugar? Porque parece que continua aparecendo erro e eu não consigo encontrar a origem do mesmo. E o MagicNumber deve ser um número inteiro?

Terrance

total = EncomendasTotal();

if(total < 2)

{

int contagemOpenedOnACurrentBar(int tipo)

{

int abertoNa barra = 0;

data/hora de inícioTempo = Hora[0];

data/hora finalTempo = Hora[0]+Periodo()*60;

for(int i=0; i < OrdensTotal(); i++)

{

if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == falso) break;

if(OrderMagicNumber() != MagicNumber) continua;

if(OrderSymbol() != Symbol()) continua;

if(OrderType() != type) continue;

if(OrderOpenTime()=endTime) continua; if(OrderOpenTime()=endTime) continua;

openAtBar++;

quebrar;

}

retorno(aberto na barra);

}

if(isCrossed == 1 && shortEma > mainshortEma && longEma > mainshortEma)

{

ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,1,Ask-StopLoss*Point,Ask+TakeProfit*Point,

"Minha EA",12345,0,Verde);

if(bilhete>0)

{

if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))

Imprimir("Pedido aberto : ",OrderOpenPrice());

}

else Print("Erro na abertura do pedido de compra : ",GetLastError());

retornar(0);

}

if(isCrossed == 2 && shortEma < mainshortEma && longEma < mainshortEma)

{

ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,1,Bid+StopLoss*Point,Bid-TakeProfit*Point,

"Minha EA",12345,0,Vermelho);

if(bilhete>0)

{

if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))

Imprimir("Pedido de venda aberto : ",OrderOpenPrice());

}

else Print("Erro na abertura do pedido de VENDA : ",GetLastError());

retornar(0);

}

retorno(0);

}

mladen:
Você pode adicionar verificação se um pedido de algum tipo já foi aberto em um bar atual e assim você evitará a abertura de um novo pedido em um próximo tick. Se sim (houve uma ordem aberta em um bar atual), então não será possível abrir uma nova ordem. Se não, você pode abrir um novo pedido. Aqui está uma função que pode contar as ordens de tipo rewuired abertas em um bar atual
int countOpenedOnACurrentBar(int type)

{

int openedAtBar = 0;

datetime startTime = Time[0];

datetime endTime = Time[0]+Period()*60;

for(int i=0; i < OrdersTotal(); i++)

{

if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) break;

if(OrderMagicNumber() != MagicNumber) continue;

if(OrderSymbol() != Symbol()) continue;

if(OrderType() != type) continue;

if(OrderOpenTime()=endTime) continue;

openedAtBar++;

break;

}

return(openedAtBar);

}

 

...

... Terrance

Essa é uma função. Coloque-a no final de sua EA e coloque chamadas a ela onde você achar apropriado verificar se um pedido já está aberto em um bar atual.

tkuan77:
Obrigado Mladen pela ajuda, entretanto eu só quero verificar com você, eu coloco o código antes da minha função longa/curta, no meio ou em outro lugar? Porque parece que continua aparecendo erro e eu não consigo encontrar a fonte do mesmo. E o MagicNumber deve ser um número inteiro?

Terrance

total = EncomendasTotal();

if(total < 2)

{

int contagemOpenedOnACurrentBar(int tipo)

{

int abertoNa barra = 0;

data/hora de inícioTempo = Hora[0];

data/hora finalTempo = Hora[0]+Periodo()*60;

for(int i=0; i < OrdensTotal(); i++)

{

if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == falso) break;

if(OrderMagicNumber() != MagicNumber) continua;

if(OrderSymbol() != Symbol()) continua;

if(OrderType() != type) continue;

if(OrderOpenTime()=endTime) continua; if(OrderOpenTime()=endTime) continua;

openAtBar++;

quebrar;

}

retorno(aberto na barra);

}

if(isCrossed == 1 && shortEma > mainshortEma && longEma > mainshortEma)

{

ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,1,Ask-StopLoss*Point,Ask+TakeProfit*Point,

"Minha EA",12345,0,Verde);

if(bilhete>0)

{

if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))

Imprimir("Pedido aberto : ",OrderOpenPrice());

}

else Print("Erro na abertura do pedido de compra : ",GetLastError());

retornar(0);

}

if(isCrossed == 2 && shortEma < mainshortEma && longEma < mainshortEma)

{

ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,1,Bid+StopLoss*Point,Bid-TakeProfit*Point,

"Minha EA",12345,0,Vermelho);

if(bilhete>0)

{

if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))

Imprimir("Pedido de venda aberto : ",OrderOpenPrice());

}

else Print("Erro na abertura do pedido de VENDA : ",GetLastError());

retornar(0);

}

retorno(0);

}