Artem, diga-me qual é a função da seção de código destacada.
Como esse código pode ser executado se o cronômetro não estiver ativado?
Mas se essa seção de código for excluída, as mensagens de evento não serão impressas. Mas tudo funciona com ela.
E eu gostaria de poder obter um tíquete, preços e talvez algumas outras propriedades de posições e ordens junto com a mensagem do evento.
Acho que você alterou o comentário. Em OnTimer(), o EA é verificado, não no testador:
/************************Expert tick function************************/voidOnTick()
{
//--- Inicialização do último evento de negociaçãostatic ENUM_TRADE_EVENT last_event=WRONG_VALUE;
//--- Se estiver trabalhando no testadorif(MQLInfoInteger(MQL_TESTER))
{
engine.OnTimer();
}//--- Se o último evento de negociação foi alteradoif(engine.LastTradeEvent()!=last_event)
{
last_event=engine.LastTradeEvent();
Comment("last_event: ",EnumToString(last_event));
Print(__FUNCTION__, " last_event: ",EnumToString(last_event));
//engine.ResetLastTradeEvent();//Print("last_event: ",EnumToString(last_event));
}
}
/***************************Timer function***************************/voidOnTimer()
{
//--- Inicialização do último evento de negociaçãostatic ENUM_TRADE_EVENT last_event=WRONG_VALUE;
//--- Se o trabalho não for в тестереif(!MQLInfoInteger(MQL_TESTER))
{
engine.OnTimer();
}
}
/*******************************************************************/
E compare os dois manipuladores: em OnTick() o cronômetro da biblioteca é iniciado apenas no testador, e em OnTimer() o cronômetro da biblioteca é iniciado apenas não no testador - porque na MQL4 o cronômetro no testador não funciona, e nós trabalhamos com ticks no testador.
O comentário mudou por conta própria, não mexi nele. ))))))
Eu apenas copiei em um lugar e colei em lugares diferentes e não prestei atenção. Mas depois coloquei uma negação na forma de ! e não é importante, não mexi.
Mas a pergunta continua sem resposta: se o cronômetro não é iniciado em OnInit(), qual é o objetivo do manipulador OnTimer() e por que o código nele é executado pelo menos uma vez.
Basicamente, recebi as mensagens no registro. Resta obter as propriedades dos itens. Tipo, tíquete, preços e hora de abertura, fechamento e modificação.
E eu gostaria de poder obter tíquetes, preços e talvez algumas outras propriedades de posições e ordens junto com a mensagem do evento.
No testador, não é possível obter o tíquete da ordem do último evento em OnChartEvent() - parâmetro lparam. Em dparam, o preço é armazenado. Em sparam - símbolo.
Para obter dados no testador, você deve usar o código de evento que obtém com engine.LastTradeEvent() - porque tudo depende do evento - se for uma modificação, você precisará obter uma lista de modificações e, se for uma alteração no número de ordens, você precisará obter listas dessas novas ordens.
Precisamos adicionar o CEngine para retornar os valores necessários ao programa. Ainda não cheguei ao ponto de enviar informações ao programa - ainda estou descrevendo a preparação dos dados necessários. Em artigos futuros, chegaremos à classe que dá acesso fácil a todos os dados necessários. E agora, se precisar urgentemente, você precisa adicionar ao CEngine o retorno da lista da coleção de eventos da classe - a própria classe tem o recebimento dessa lista, aqui estão elas - todas as listas na seção pública CEventCollection:
public:
//--- Seleciona eventos da coleção com horários que variam de begin_time a end_time
CArrayObj *GetListByTime(const datetime begin_time=0,const datetime end_time=0);
//--- Retorna a lista completa da coleção de eventos "como está"
CArrayObj *GetList(void) { return &this.m_list_events; }
//--- Retorna uma lista com as propriedades selecionadas (1) integer, (2) real e (3) string que satisfazem o critério que está sendo comparado
CArrayObj *GetList(ENUM_EVENT_PROP_INTEGER property,longvalue,ENUM_COMPARER_TYPE mode=EQUAL) { return CSelect::ByEventProperty(this.GetList(),property,value,mode); }
CArrayObj *GetList(ENUM_EVENT_PROP_DOUBLE property,doublevalue,ENUM_COMPARER_TYPE mode=EQUAL) { return CSelect::ByEventProperty(this.GetList(),property,value,mode); }
CArrayObj *GetList(ENUM_EVENT_PROP_STRING property,stringvalue,ENUM_COMPARER_TYPE mode=EQUAL) { return CSelect::ByEventProperty(this.GetList(),property,value,mode); }
Todos os eventos são armazenados na lista m_list_events, e esses métodos retornam a lista completa ou filtrada por um determinado critério.
Para obter o último evento, basta criar no CEngine um retorno dessa lista para o programa e, no programa, obter o evento desejado da lista.
Tudo isso será automatizado em breve - ainda não está na fila.
Se você ainda precisar fazer uma muleta, a discussão será em particular. Isso não vale a pena aqui - não se aplica à biblioteca, pois ela está em desenvolvimento, e mais trabalho normal e adequado será feito para colocar todos e quaisquer eventos necessários no programa.
O comentário mudou por conta própria, não mexi nele. )))))
Eu apenas copiei em um lugar e colei em lugares diferentes e não prestei atenção. Mas depois coloquei uma negação na forma de ! e não mexi no que era importante.
Mas a pergunta continua sem resposta: se o cronômetro não é iniciado em OnInit(), qual é o objetivo do manipulador OnTimer() e por que o código nele é executado pelo menos uma vez.
Basicamente, recebi as mensagens no registro. Resta obter as propriedades dos itens. Tipo, tíquete, preços e hora de abertura, fechamento e modificação.
Explique o que você quer dizer? Você está falando sobre a criação de um cronômetro? Ele é criado no construtor do CEngine:
//+------------------------------------------------------------------+//| Construtor CEngine|//+------------------------------------------------------------------+
CEngine::CEngine() : m_first_start(true),m_last_trade_event(TRADE_EVENT_NO_EVENT)
{
this.m_list_counters.Sort();
this.m_list_counters.Clear();
this.CreateCounter(COLLECTION_COUNTER_ID,COLLECTION_COUNTER_STEP,COLLECTION_PAUSE);
this.m_is_hedge=#ifdef __MQL4__ true#else bool(::AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) #endif;
this.m_is_tester=::MQLInfoInteger(MQL_TESTER);
::ResetLastError();
#ifdef __MQL5__if(!::EventSetMillisecondTimer(TIMER_FREQUENCY))
::Print(DFUN,"Falha ao criar o cronômetro. Erro: ","Could not create timer. Error: ",(string)::GetLastError());
//---__MQL4__#else
if(!this.IsTester() && !::EventSetMillisecondTimer(TIMER_FREQUENCY))
::Print(DFUN,"Falha ao criar o cronômetro. Erro: ","Could not create timer. Error: ",(string)::GetLastError());
#endif }
//+------------------------------------------------------------------+
Não no testador, você pode obter o tíquete do pedido do último evento em OnChartEvent() - parâmetro lparam. Em dparam, o preço é armazenado. Em sparam - símbolo.
Eu já o encontrei, obrigado. E, ao adquirir um ingresso, você pode obter tudo o que precisa. Exceto por qual preço houve uma modificação. Ou fazer uma verdadeira muleta para saber o preço antes da modificação. Em princípio, isso ainda não é muito necessário.
Basicamente, obtive as mensagens de registro. Só preciso obter as propriedades das posições. Tipo, tíquete, preços e horário de abertura, fechamento e modificação.
No entanto, para uma solução rápida, adicione um retorno de lista de eventos à seção pública do CEngine:
public:
//--- Retorna uma lista de posições de mercado (1), (2) ordens pendentes e (3) ordens de mercado
CArrayObj* GetListMarketPosition(void);
CArrayObj* GetListMarketPendings(void);
CArrayObj* GetListMarketOrders(void);
//--- Retorna a lista de histórico de (1) ordens, (2) ordens pendentes excluídas, (3) negociações, (4) todas as ordens a mercado de uma posição por seu identificador
CArrayObj* GetListHistoryOrders(void);
CArrayObj* GetListHistoryPendings(void);
CArrayObj* GetListDeals(void);
CArrayObj* GetListAllOrdersByPosID(constulong position_id);
//--- Retorna uma lista de eventosCArrayObj* GetListAllEvents(void) { returnthis.m_events.GetList(); }//--- Reinicia o último evento de negociaçãovoid ResetLastTradeEvent(void) { this.m_events.ResetLastTradeEvent(); }
//--- Retorna (1) último evento de negociação, (2) sinalizador de conta de hedge, (3) sinalizador de operação do testador
ENUM_TRADE_EVENT LastTradeEvent(void) const { returnthis.m_last_trade_event; }
bool IsHedge(void) const { returnthis.m_is_hedge; }
bool IsTester(void) const { returnthis.m_is_tester; }
//--- Cria um contador de cronômetrovoid CreateCounter(constint id,constulong frequency,constulong pause);
//--- TemporizadorvoidOnTimer(void);
//--- Construtor/Destrutor
CEngine();
~CEngine();
};
//+------------------------------------------------------------------+
No EA, adicione este código:
//+------------------------------------------------------------------+//| Função de tique de especialista|//+------------------------------------------------------------------+voidOnTick()
{
//--- Inicialização do último evento de negociaçãostatic ENUM_TRADE_EVENT last_event=WRONG_VALUE;
//--- Se estiver trabalhando no testadorif(MQLInfoInteger(MQL_TESTER))
{
engine.OnTimer();
PressButtonsControl();
}
//--- Se o último evento de negociação foi alteradoif(engine.LastTradeEvent()!=last_event)
{
last_event=engine.LastTradeEvent();
Comment("\nlast_event: ",EnumToString(last_event));
CArrayObj* list=engine.GetListAllEvents();
if(list!=NULL)
{
if(list.Total()>0)
{
CEvent* event=list.At(list.Total()-1);
if(event!=NULL)
{
event.Print();
}
}
}
}
//--- Se o sinalizador de finalização estiver definidoif(trailing_on)
{
TrailingPositions();
TrailingOrders();
}
}
//+------------------------------------------------------------------+
Eu já encontrei isso, obrigado. E se você conseguir uma passagem, poderá obter tudo o que precisa. Exceto pelo preço da modificação. Ou faça uma muleta de verdade para saber o preço antes da modificação. Eu realmente não preciso disso ainda.
Eu já lhe dei o código - há tudo lá, e o preço antes da modificação também.
E, de repente, durante a próxima simulação, uma posição foi modificada, uma posição foi aberta e uma posição foi fechada. Mas de onde veio o registro da exclusão de uma ordem excluída há muito tempo?
Artem, diga-me qual é a função da seção de código destacada.
Como esse código pode ser executado se o cronômetro não estiver ativado?
Mas se essa seção de código for excluída, as mensagens de evento não serão impressas. Mas tudo funciona com ela.
E eu gostaria de poder obter um tíquete, preços e talvez algumas outras propriedades de posições e ordens junto com a mensagem do evento.
Acho que você alterou o comentário. Em OnTimer(), o EA é verificado, não no testador:
E compare os dois manipuladores: em OnTick() o cronômetro da biblioteca é iniciado apenas no testador, e em OnTimer() o cronômetro da biblioteca é iniciado apenas não no testador - porque na MQL4 o cronômetro no testador não funciona, e nós trabalhamos com ticks no testador.
Vou dar um exemplo agora.
Acho que você alterou o comentário.
O comentário mudou por conta própria, não mexi nele. ))))))
Eu apenas copiei em um lugar e colei em lugares diferentes e não prestei atenção. Mas depois coloquei uma negação na forma de ! e não é importante, não mexi.
Mas a pergunta continua sem resposta: se o cronômetro não é iniciado em OnInit(), qual é o objetivo do manipulador OnTimer() e por que o código nele é executado pelo menos uma vez.
Basicamente, recebi as mensagens no registro. Resta obter as propriedades dos itens. Tipo, tíquete, preços e hora de abertura, fechamento e modificação.
E eu gostaria de poder obter tíquetes, preços e talvez algumas outras propriedades de posições e ordens junto com a mensagem do evento.
No testador, não é possível obter o tíquete da ordem do último evento em OnChartEvent() - parâmetro lparam. Em dparam, o preço é armazenado. Em sparam - símbolo.
Para obter dados no testador, você deve usar o código de evento que obtém com engine.LastTradeEvent() - porque tudo depende do evento - se for uma modificação, você precisará obter uma lista de modificações e, se for uma alteração no número de ordens, você precisará obter listas dessas novas ordens.
Precisamos adicionar o CEngine para retornar os valores necessários ao programa. Ainda não cheguei ao ponto de enviar informações ao programa - ainda estou descrevendo a preparação dos dados necessários. Em artigos futuros, chegaremos à classe que dá acesso fácil a todos os dados necessários. E agora, se precisar urgentemente, você precisa adicionar ao CEngine o retorno da lista da coleção de eventos da classe - a própria classe tem o recebimento dessa lista, aqui estão elas - todas as listas na seção pública CEventCollection:
Todos os eventos são armazenados na lista m_list_events, e esses métodos retornam a lista completa ou filtrada por um determinado critério.
Para obter o último evento, basta criar no CEngine um retorno dessa lista para o programa e, no programa, obter o evento desejado da lista.
Tudo isso será automatizado em breve - ainda não está na fila.
Se você ainda precisar fazer uma muleta, a discussão será em particular. Isso não vale a pena aqui - não se aplica à biblioteca, pois ela está em desenvolvimento, e mais trabalho normal e adequado será feito para colocar todos e quaisquer eventos necessários no programa.
O comentário mudou por conta própria, não mexi nele. )))))
Eu apenas copiei em um lugar e colei em lugares diferentes e não prestei atenção. Mas depois coloquei uma negação na forma de ! e não mexi no que era importante.
Mas a pergunta continua sem resposta: se o cronômetro não é iniciado em OnInit(), qual é o objetivo do manipulador OnTimer() e por que o código nele é executado pelo menos uma vez.
Basicamente, recebi as mensagens no registro. Resta obter as propriedades dos itens. Tipo, tíquete, preços e hora de abertura, fechamento e modificação.
Explique o que você quer dizer? Você está falando sobre a criação de um cronômetro? Ele é criado no construtor do CEngine:
Não no testador, você pode obter o tíquete do pedido do último evento em OnChartEvent() - parâmetro lparam. Em dparam, o preço é armazenado. Em sparam - símbolo.
Eu já o encontrei, obrigado. E, ao adquirir um ingresso, você pode obter tudo o que precisa. Exceto por qual preço houve uma modificação. Ou fazer uma verdadeira muleta para saber o preço antes da modificação. Em princípio, isso ainda não é muito necessário.
Basicamente, obtive as mensagens de registro. Só preciso obter as propriedades das posições. Tipo, tíquete, preços e horário de abertura, fechamento e modificação.
No entanto, para uma solução rápida, adicione um retorno de lista de eventos à seção pública do CEngine:
No EA, adicione este código:
E o último evento será impresso no registro
Explique o que você quer dizer? Você está falando sobre a criação de um cronômetro? Ele é criado no construtor do CEngine:
Bem, você teve que percorrer toda a biblioteca para isso. )))
Eu já encontrei isso, obrigado. E se você conseguir uma passagem, poderá obter tudo o que precisa. Exceto pelo preço da modificação. Ou faça uma muleta de verdade para saber o preço antes da modificação. Eu realmente não preciso disso ainda.
Eu já lhe dei o código - há tudo lá, e o preço antes da modificação também.
Bem, você teve que percorrer toda a biblioteca para isso. )))
Não. Basta ler os artigos
E foi isso que aconteceu:
Enquanto eu estava executando esse código na demonstração, uma ordem de limite foi definida e excluída
E, de repente, durante a próxima simulação, uma posição foi modificada, uma posição foi aberta e uma posição foi fechada. Mas de onde veio o registro da exclusão de uma ordem excluída há muito tempo?