Discussão do artigo "Biblioteca para criação simples e rápida de programas para MetaTrader (Parte XXVI): trabalho com ordens de negociação pendentes - primeira implementação (abertura de posições)"
As ordens de mercado são abertas, mas todas as ordens pendentes não são.
Símbolos de câmbio, corretor Otkritie, versão 5.00 build 2190.
As ordens são abertas, mas todas as ordens pendentes não são.
Símbolos de câmbio, corretor Otkritie, versão 5.00 build 2190.
Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação
Artyom Trishkin, 2019.11.28 09:39
Nesta versão da biblioteca, bem como na próxima, não verifiquei os tipos de preenchimento de ordens e os tipos de expiração de ordens. Haverá correções no próximo artigo (27).
Por enquanto, posso sugerir que você especifique explicitamente o tipo de expiração ao enviar uma solicitação de negociação. Por exemplo, para colocar uma ordem pendente Sell Limit, você precisa adicioná-la no Expert Advisor de teste:
//--- Se o botão BUTT_SELL_LIMIT for pressionado: Definir SellLimit else if(button==EnumToString(BUTT_SELL_LIMIT)) { //--- Definir ordem SellLimit engine.PlaceSellLimit(lot,Symbol(),distance_pending,stoploss,takeprofit,magic,TextByLanguage("Pending SellLimit" (Limite de venda pendente),"Pending order SellLimit"),0,ORDER_TIME_DAY); }
E fazer o mesmo em todas as linhas que contêm a chamada de métodos para definir ordens pendentes.
//--- Localização dos dados no valor do número mágico int //----------------------------------------------------------- // bit 32|31 24|2316|15 8|7 0| //----------------------------------------------------------- // byte | 3 | 2| 1 | 0 | //----------------------------------------------------------- // dados | uchar | uchar | ushort | //----------------------------------------------------------- // descr |pend req id| id2 | id1 | magic | //----------------------------------------------------------- //--- Retorna (1) o número mágico especificado, a ID do (2) primeiro grupo, (3) segundo grupo, (4) solicitação pendente do valor do número mágico ushort GetMagicID(void) const { return ushort(this.Magic() & 0xFFFF); } uchar GetGroupID1(void) const { return uchar(this.Magic()>>16) & 0x0F; } uchar GetGroupID2(void) const { return uchar((this.Magic()>>16) & 0xF0)>>4; } uchar GetPendReqID(void) const { return uchar(this.Magic()>>24) & 0xFF; }
Existe uma função conveniente para extrair bits de um número.
//--- extrair bits cnt na posição do k-ésimo bit uint _getBits(const uint number,uint pos,uint cnt=1) const { return (number >> pos) & ((1 << cnt) - 1); } ushort GetMagicID(void) const { return ushort(_getBits(this.Magic(),0,16)); } uchar GetGroupID1(void) const { return uchar(_getBits(this.Magic(),16,4)); } uchar GetGroupID2(void) const { return uchar(_getBits(this.Magic(),20,4)); } uchar GetPendReqID(void) const { return uchar(_getBits(this.Magic(),24,8)); }
Você poderia me dizer, por favor, onde exatamente, em que método, você decodifica a mágica codificada na solicitação pendente?
Após um erro ao abrir uma posição(fundos insuficientes) e acionar uma solicitação pendente, tenho uma posição criada com uma mágica completamente diferente (aparentemente, a que foi codificada).
Onde você a decodifica? Quero uma mágica nativa, não uma nova.
void CTradingControl::OnPReqByErrCodeHandler()
É aqui que você deve chamar o método que retorna a mágica original. E que método é esse? GetMagicID()?
//+------------------------------------------------------------------+ //| Retorna o lucro da ordem em pips| //+------------------------------------------------------------------+ int COrder::ProfitInPoints(void) const { MqlTick tick={0}; string symbol=this.Symbol(); if(!::SymbolInfoTick(symbol,tick)) return 0; ENUM_ORDER_TYPE type=(ENUM_ORDER_TYPE)this.TypeOrder(); double point=::SymbolInfoDouble(symbol,SYMBOL_POINT); if(type==ORDER_TYPE_CLOSE_BY || point==0) return 0; if(this.Status()==ORDER_STATUS_HISTORY_ORDER) return int(type==ORDER_TYPE_BUY ? (this.PriceClose()-this.PriceOpen())/point : type==ORDER_TYPE_SELL ? (this.PriceOpen()-this.PriceClose())/point : 0); else if(this.Status()==ORDER_STATUS_MARKET_POSITION) { if(type==ORDER_TYPE_BUY) return int((tick.bid-this.PriceOpen())/point); else if(type==ORDER_TYPE_SELL) return int((this.PriceOpen()-tick.ask)/point); } else if(this.Status()==ORDER_STATUS_MARKET_PENDING) { if(type==ORDER_TYPE_BUY_LIMIT || type==ORDER_TYPE_BUY_STOP || type==ORDER_TYPE_BUY_STOP_LIMIT) return (int)fabs((tick.bid-this.PriceOpen())/point); else if(type==ORDER_TYPE_SELL_LIMIT || type==ORDER_TYPE_SELL_STOP || type==ORDER_TYPE_SELL_STOP_LIMIT) return (int)fabs((this.PriceOpen()-tick.ask)/point); } return 0; }
Por que não há cálculo aqui para o tipo ORDER_STATUS_DEAL?
Em geral, não está claro como obter o lucro em pontos de uma negociação ou posição fechada...
E é sempre 0:
deal_profit_pts=(int)deal.GetProperty(ORDER_PROP_PROFIT_PT)

- 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
Novo artigo Biblioteca para criação simples e rápida de programas para MetaTrader (Parte XXVI): trabalho com ordens de negociação pendentes - primeira implementação (abertura de posições) foi publicado:
No artigo, abordaremos o armazenamento de alguns dados no valor do número mágico de ordens e posições, e implementaremos ordens pendentes. Para examinar a ideia, criaremos a primeira ordem pendente de teste para abrir posições a mercado quando recebermos um erro do servidor requerendo aguardar e enviar uma segunda solicitação.
Compilamos e iniciamos o EA. Desligamos a Internet de qualquer forma e aguardamos tal ícone no canto inferior direito do terminal:
Após desconectar a Internet e clicar no botão Sell, o servidor de negociação retorna um erro e no log são exibidas as seguintes entradas:
Após receber desse erro, a biblioteca cria uma ordem pendente com os parâmetros existentes no momento da tentativa sem êxito de abrir uma posição curta.
A ordem pendente também contém o número de tentativas e um tempo de espera de 20 segundos.
Em seguida, conectamos a Internet, restaurando assim a comunicação com o servidor de negociação:
Assim que a conexão é restaurada, a biblioteca começa a processar a ordem pendente, enviando-a para o servidor. Como resultado, temos uma posição aberta com entradas no log:
Como se pode ver no log, após reconectar ao servidor de negociação, a permissão de negociação para a conta atual não foi ativada imediatamente.
Mas, seja como for, a ordem pendente fez o que devia fazer...
Também no log vemos o número mágico real 17629307, atrás dele entre parênteses vemos o magic definido nas configurações do EA (123), além de uma entrada G1: 13, que nos diz que o identificador do primeiro grupo é 13 e o identificador do segundo grupo não existe, pois seu valor acabou sendo zero, portanto, não foi gerao o segundo registro com os identificadores do segundo grupo G2: XX
Autor: Artyom Trishkin