Eu comecei a investigar porque o verdadeiro estava se chocando.
Parece que eles atualizaram o servidor durante o fim de semana. Milissegundos. Pode haver mais surpresas.
Aparentemente, a funçãoOnTradeTransaction funciona independentemente do registro da transação.
Acho que este comportamento da função é razoável - não há necessidade de retardar o fluxo de operações e esperar até que o registro seja escrito e tudo seja calculado.
No seu caso, provavelmente é melhor usar oOnTrade,
ou esperar e verificar periodicamente com uma pausa mínima quando o negócio aparece no histórico.
Parece que eles atualizaram o servidor no fim de semana. Milissegundos apareceram. Pode haver mais surpresas.
Aparentemente, a funçãoOnTradeTransaction funciona independentemente do registro de operação.
Acho que este comportamento da função é justificado - não há necessidade de retardar o fluxo de operações e esperar até que tudo seja registrado e contado no diário.
No seu caso, provavelmente é melhor usar oOnTrade,
ou esperar e verificar periodicamente com uma pausa mínima quando o negócio aparece no histórico.
Oi Sergei!
Sim, fizemos, mas não no fim de semana, mas na quinta-feira após a sessão noturna (perguntou meu corretor).
Não posso usar o evento Trade() e esperar que os dados sejam atualizados no terminal.
O Expert Advisor foi escrito há muito tempo e até recentemente funcionava "como um relógio" (talvez eu tenha tido sorte e o eventoTRADE_TRANSACTION_DEAL_ADD foisempre o primeiro a chegar).
É importante que o Expert Advisor execute uma negociação recíproca o mais rápido possível, por isso o modo assíncrono e a OnTradeTransaction().
Agora, o Expert Advisor (às vezes) envia ordens duplicadas para abrir e fechar posições.
Você: "Eu acho que este comportamento da função é justificado. Não há necessidade de retardar o fluxo de operações e esperar que tudo seja escrito e contado no diário".
De qualquer forma, tudo está sendo escrito e contado após a chegada doTRADE_TRANSACTION_DEAL_ADDD :)
A questão é queTRADE_TRANSACTION_DEAL_ADD pode se perder eTRADE_TRANSACTION_HISTORY_ADD pode vir e então o terminal terá dados de posição desatualizados.:(,
o que realmente acontece.
É estranho que os desenvolvedores não tenham pensado sobre isso.
TRADE_TRANSACTION_HISTORY_HISTORY_ADD só vem se a ordem tiver sido executada ou apagada (cancelada), portanto
se o estado do pedido mudar (respectivamente, a posição pode mudar), o terminal deve receber as informações sobre a mudança de posição,
Por favor, peça aos "professores" e aos "sabichões" que falem sobre o conteúdo,
e não apenas para colocar o pé no poste para fazer um ponto de vista.
Antes de se exibir diante de pessoas que querem ajudá-lo, você deve formular sua pergunta corretamente. O que o envio assíncrono de um pedido tem a ver com ele, se o fechamento parcial é realizado pela função OrderSend()? Sobre o que você está perguntando?
Dmitry Fedoseev: Antes de se exibir para as pessoas que querem ajudá-lo, você deve formular sua pergunta normalmente. O que o envio assíncrono de um pedido tem a ver com ele, se o fechamento parcial é realizado pela função OrderSend()? Sobre o que você está fazendo perguntas?
Ótimo!
Isso deve ser visto como uma ajuda?
Бред. Какая связь между кэшем, где сохраняются данные о запрашиваемой позиции, и транзакциями?
prostotrader, у Вас там с логикой алгоритма наверное что-то не то. Хотел было покопаться в чужом коде, но влом... потом тип исполнения тут:
request.type_filling=ORDER_FILLING_IOC; // разве так?
request.type_filling=ORDER_FILLING_RETURN; // а может так?
И вообще в каких университетах так учат кодировать?
E Karputov não tem nada a ver com isso, é que quando escrevi meu post ele já havia postado o dele e eu não o vi.
Inicialmente, a questão foi colocada da seguinte forma (caso você seja preguiçoso demais para lê-la primeiro)
Como construir um registro para mostrar o erro aos desenvolvedores?
Por que, eu mesmo fiz isso e os registros mostram claramente que
prostotrader, Dimitri lhe diz corretamente que fechamentos parciais (e totais) não são assíncronos em seu código, mas síncronos... o que significa que o programa está à espera de uma resposta do servidor.
É provável que a OnTradeTransaction seja acionada mais rapidamente do que a própria posição muda.
Depois, aqui:
//+------------------------------------------------------------------+//| TradeTransaction function |//+------------------------------------------------------------------+voidOnTradeTransaction(constMqlTradeTransaction &trans,
constMqlTradeRequest &request,
constMqlTradeResult &result)
{
bool is_select=false;
ENUM_POSITION_TYPE pos_type=NULL;
long volume=0;
switch(trans.type)
{
caseTRADE_TRANSACTION_REQUEST: if((request_id!=0) && (result.request_id==request_id))
{
order_ticket=result.order;
request_id=0;
Print(__FUNCTION__,": Order resived #",result.order);
}
break;
caseTRADE_TRANSACTION_HISTORY_ADD: if((order_ticket!=0) && (trans.order==order_ticket))
{
Print(__FUNCTION__,": Order #",order_ticket," add to history.");
ORDER_DATA order_data;
ENUM_ORD_SELECT order_select=OrderRealSelect(order_ticket,order_data,false);
switch(order_select)
{
case SELECT_TRUE: if(PositionSelect(Symbol()))
{
pos_type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
volume=(long)PositionGetDouble(POSITION_VOLUME);
is_select=true;
}
elsePrint(__FUNCTION__,": Position not exist.");
break;
case SELECT_FALSE: if(PositionSelect(Symbol()))
{
pos_type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
volume=(long)PositionGetDouble(POSITION_VOLUME);
is_select=true;
}
elsePrint(__FUNCTION__,": Position not exist.");
break;
}
if(is_select)
{
Print(__FUNCTION__,": Position exists");
Print(__FUNCTION__,": Position type: ",EnumToString(pos_type));
Print(__FUNCTION__,": Position volume: ",volume);
}
tr_cnt++;
exp_busy=false;
}
break;
}
}
você poderia tentar fazer o looping da verificação de posição. Talvez isso ajude....
É algo parecido com isto:
//+------------------------------------------------------------------+//| TradeTransaction function |//+------------------------------------------------------------------+voidOnTradeTransaction(constMqlTradeTransaction &trans,
constMqlTradeRequest &request,
constMqlTradeResult &result)
{
bool is_select=false;
ENUM_POSITION_TYPE pos_type=NULL;
long volume=0;
switch(trans.type)
{
caseTRADE_TRANSACTION_REQUEST:
{
if((request_id!=0) && (result.request_id==request_id))
{
order_ticket=result.order;
request_id=0;
Print(__FUNCTION__,": Order resived #",result.order);
}
break;
}
caseTRADE_TRANSACTION_HISTORY_ADD:
{
if((order_ticket!=0) && (trans.order==order_ticket))
{
Print(__FUNCTION__,": Order #",order_ticket," add to history.");
ORDER_DATA order_data;
ENUM_ORD_SELECT order_select=OrderRealSelect(order_ticket,order_data,false);
bool is_position=false;
//--- 5 попыток на проверку наличия позицииfor(int attempt_idx=0;attempt_idx<5;attempt_idx++)
{
is_position=PositionSelect(Symbol());
if(is_position)
break;
Sleep(25);
}//---if((order_select==SELECT_TRUE) || (order_select==SELECT_FALSE))
{
if(is_position)
{
pos_type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
volume=(long)PositionGetDouble(POSITION_VOLUME);
is_select=true;
}
elsePrint(__FUNCTION__,": Position not exist.");
}
if(is_select)
{
Print(__FUNCTION__,": Position exists");
Print(__FUNCTION__,": Position type: ",EnumToString(pos_type));
Print(__FUNCTION__,": Position volume: ",volume);
}
tr_cnt++;
exp_busy=false;
}
break;
}
}
}
Sem conhecer o algoritmo exato(O QUE você precisa do programa), é difícil avaliar a correção de sua implementação...
1. >Sem conhecer o algoritmo exato (O QUE você precisa do programa), é difícil avaliar se ele foi implementado corretamente...
Pensei que não era difícil entender o que o programa faz, bem, se não está claro, então
Um Expert Advisor abre uma posição no mercado FORTS com um volume de 2 contratos; se a posição for aberta, ela é parcialmente fechada com um volume de 1 contrato,
então a posição será completamente fechada. Repita este procedimento até o contador tr_cnt<50
2. Você pode "correr" PositionSelect() um milhão de vezes - não vai mudar nada, porque
o eventoTRADE_TRANSACTION_DEAL_ADD não será recebido até que você esteja no loop, e portanto, o terminal não será atualizado
Eu disse acima - não se deixe levar pelas ordens: veja as transações. Aqui está um código curto que mostra quando o volume da posição muda e que tipo de transação é:
Você pode ver claramente que, assim que um evento com o tipo de transação comercialTRADE_TRANSACTION_DEAL_ADDD passa, os dados de posição no terminal são atualizados.
Karputov Vladimir E simplificar a OnTradeTransaction()- considere apenas acrescentar uma operação à história - sem ordens
Você ficará bem, não se preocupe em escrevê-lo (não perca seu tempo).
Eu comecei a investigar porque o verdadeiro estava se chocando.
Parece que eles atualizaram o servidor durante o fim de semana. Milissegundos. Pode haver mais surpresas.
Aparentemente, a funçãoOnTradeTransaction funciona independentemente do registro da transação.
Acho que este comportamento da função é razoável - não há necessidade de retardar o fluxo de operações e esperar até que o registro seja escrito e tudo seja calculado.
No seu caso, provavelmente é melhor usar oOnTrade,
ou esperar e verificar periodicamente com uma pausa mínima quando o negócio aparece no histórico.
Parece que eles atualizaram o servidor no fim de semana. Milissegundos apareceram. Pode haver mais surpresas.
Aparentemente, a funçãoOnTradeTransaction funciona independentemente do registro de operação.
Acho que este comportamento da função é justificado - não há necessidade de retardar o fluxo de operações e esperar até que tudo seja registrado e contado no diário.
No seu caso, provavelmente é melhor usar oOnTrade,
ou esperar e verificar periodicamente com uma pausa mínima quando o negócio aparece no histórico.
Oi Sergei!
Sim, fizemos, mas não no fim de semana, mas na quinta-feira após a sessão noturna (perguntou meu corretor).
Não posso usar o evento Trade() e esperar que os dados sejam atualizados no terminal.
O Expert Advisor foi escrito há muito tempo e até recentemente funcionava "como um relógio" (talvez eu tenha tido sorte e o eventoTRADE_TRANSACTION_DEAL_ADD foisempre o primeiro a chegar).
É importante que o Expert Advisor execute uma negociação recíproca o mais rápido possível, por isso o modo assíncrono e a OnTradeTransaction().
Agora, o Expert Advisor (às vezes) envia ordens duplicadas para abrir e fechar posições.
Você: "Eu acho que este comportamento da função é justificado. Não há necessidade de retardar o fluxo de operações e esperar que tudo seja escrito e contado no diário".
De qualquer forma, tudo está sendo escrito e contado após a chegada doTRADE_TRANSACTION_DEAL_ADDD :)
A questão é queTRADE_TRANSACTION_DEAL_ADD pode se perder eTRADE_TRANSACTION_HISTORY_ADD pode vir e então o terminal terá dados de posição desatualizados.:(,
o que realmente acontece.
É estranho que os desenvolvedores não tenham pensado sobre isso.
TRADE_TRANSACTION_HISTORY_HISTORY_ADD só vem se a ordem tiver sido executada ou apagada (cancelada), portanto
se o estado do pedido mudar (respectivamente, a posição pode mudar), o terminal deve receber as informações sobre a mudança de posição,
mesmo queTRADE_TRANSACTION_DEAL_ADD seja perdido
Vamos ver o que os desenvolvedores têm a dizer.
Karputov Vladimir E simplificar a OnTradeTransaction() - considere apenas acrescentar uma operação à história - sem ordens
Você ficará bem, não se preocupe em escrevê-lo (não perca seu tempo).
Por favor, peça aos "professores" e aos "sabichões" que falem sobre o conteúdo,
e não apenas para colocar o pé no poste para fazer um ponto de vista.
Antes de se exibir para as pessoas que querem ajudá-lo, você deve formular sua pergunta normalmente. O que o envio assíncrono de um pedido tem a ver com ele, se o fechamento parcial é realizado pela função OrderSend()? Sobre o que você está fazendo perguntas?
Ótimo!
Isso deve ser visto como uma ajuda?
E Karputov não tem nada a ver com isso, é que quando escrevi meu post ele já havia postado o dele e eu não o vi.
Inicialmente, a questão foi colocada da seguinte forma (caso você seja preguiçoso demais para lê-la primeiro)
Como construir um registro para mostrar o erro aos desenvolvedores?
Por que, eu mesmo fiz isso e os registros mostram claramente que
apósTRADE_TRANSACTION_HISTORY_ADD (antes deTRADE_TRANSACTION_DEAL_ADD)
o terminal não atualiza as informações de posição.
prostotrader, Dimitri lhe diz corretamente que fechamentos parciais (e totais) não são assíncronos em seu código, mas síncronos... o que significa que o programa está à espera de uma resposta do servidor.
É provável que a OnTradeTransaction seja acionada mais rapidamente do que a própria posição muda.
Depois, aqui:
você poderia tentar fazer o looping da verificação de posição. Talvez isso ajude....
É algo parecido com isto:
Sem conhecer o algoritmo exato(O QUE você precisa do programa), é difícil avaliar a correção de sua implementação...
Alterado completamente para o modo assíncrono
Mas nada mudou
Era óbvio, mas "por uma questão de pureza" do experimento...
Logs completos no porão
1. >Sem conhecer o algoritmo exato (O QUE você precisa do programa), é difícil avaliar se ele foi implementado corretamente...
Pensei que não era difícil entender o que o programa faz, bem, se não está claro, então
Um Expert Advisor abre uma posição no mercado FORTS com um volume de 2 contratos; se a posição for aberta, ela é parcialmente fechada com um volume de 1 contrato,
então a posição será completamente fechada. Repita este procedimento até o contador tr_cnt<50
2. Você pode "correr" PositionSelect() um milhão de vezes - não vai mudar nada, porque
o eventoTRADE_TRANSACTION_DEAL_ADD não será recebido até que você esteja no loop, e portanto, o terminal não será atualizado
informações sobre a posição
...
Eu disse acima - não se deixe levar pelas ordens: veja as transações. Aqui está um código curto que mostra quando o volume da posição muda e que tipo de transação é:
E aqui estão as impressões, no fechamento parcial:
Você pode ver claramente que, assim que um evento com o tipo de transação comercialTRADE_TRANSACTION_DEAL_ADDD passa, os dados de posição no terminal são atualizados.