Ho iniziato a guardarci dentro perché quello vero si stava bloccando.
Sembra che abbiano aggiornato il server durante il fine settimana. Sono arrivati i millisecondi. Potrebbero esserci altre sorprese.
Apparentemente, la funzioneOnTradeTransaction funziona indipendentemente dal registro delle transazioni.
Penso che questo comportamento della funzione sia ragionevole - non c'è bisogno di rallentare il flusso delle operazioni e aspettare che il registro sia scritto e tutto sia calcolato.
Nel tuo caso, è probabilmente meglio usareOnTrade,
o aspettare e controllare periodicamente con una pausa minima quando l'affare appare nella storia.
Sembra che abbiano aggiornato il server nel fine settimana. Sono apparsi dei millisecondi. Potrebbero esserci altre sorprese.
Apparentemente la funzioneOnTradeTransaction funziona indipendentemente dal registro delle operazioni.
Penso che questo comportamento della funzione sia giustificato - non c'è bisogno di rallentare il flusso delle operazioni e aspettare che tutto sia registrato e contato nel giornale.
Nel tuo caso, è probabilmente meglio usareOnTrade,
o aspettare e controllare periodicamente con una pausa minima quando l'affare appare nella storia.
Ciao Sergei!
Sì, ma non nel fine settimana, ma il giovedì dopo la sessione serale (chiesto al mio broker).
Non posso usare l'evento Trade() e aspettare che i dati si aggiornino nel terminale.
L'Expert Advisor è stato scritto molto tempo fa e fino a poco tempo fa funzionava "come un orologio" (forse sono stato fortunato e l'eventoTRADE_TRANSACTION_DEAL_ADD erasempre il primo ad arrivare).
È importante che l'Expert Advisor esegua un trade reciproco il più presto possibile, ecco perché la modalità asincrona e OnTradeTransaction().
Ora, l'Expert Advisor (a volte) invia ordini duplicati per aprire e chiudere posizioni.
Tu: "Penso che questo comportamento della funzione sia giustificato. Non c'è bisogno di rallentare il flusso delle operazioni e aspettare che tutto sia scritto e contato nel giornale".
Comunque, tutto viene scritto e contato dopo l'arrivo diTRADE_TRANSACTION_DEAL_ADD :)
Il fatto è cheTRADE_TRANSACTION_DEAL_ADD può essere perso eTRADE_TRANSACTION_HISTORY_ADD può arrivare e quindi il terminale avrà dati di posizione non aggiornati.:(,
cosa che accade realmente.
È strano che gli sviluppatori non ci abbiano pensato.
TRADE_TRANSACTION_HISTORY_ADD arriva solo se l'ordine è stato eseguito o cancellato (cancellato), quindi
se lo stato dell'ordine cambia (rispettivamente, la posizione può cambiare), il terminale dovrebbe ricevere le informazioni sul cambiamento di posizione,
Per favore, chiedete agli "insegnanti" e ai "sapientoni" di parlare sulla sostanza,
e non solo per mettere il piede sul palo per fare un punto.
Prima di mostrarsi di fronte a persone che vogliono aiutarvi, dovreste formulare la vostra domanda in modo corretto. Cosa c'entra l'invio asincrono di un ordine, se la chiusura parziale viene eseguita dalla funzione OrderSend()? Cosa stai chiedendo?
Dmitry Fedoseev: Prima di mostrarsi alle persone che vogliono aiutarvi, dovreste formulare normalmente la vostra domanda. Cosa c'entra l'invio asincrono di un ordine, se la chiusura parziale viene eseguita dalla funzione OrderSend()? Su cosa fai domande?
Grande!
Questo dovrebbe essere visto come un aiuto?
Бред. Какая связь между кэшем, где сохраняются данные о запрашиваемой позиции, и транзакциями?
prostotrader, у Вас там с логикой алгоритма наверное что-то не то. Хотел было покопаться в чужом коде, но влом... потом тип исполнения тут:
request.type_filling=ORDER_FILLING_IOC; // разве так?
request.type_filling=ORDER_FILLING_RETURN; // а может так?
И вообще в каких университетах так учат кодировать?
E Karputov non c'entra niente, è solo che quando ho scritto il mio post lui aveva già pubblicato il suo e non l'ho visto.
Inizialmente, la domanda è stata posta come segue (nel caso siate troppo pigri per leggerla prima)
Come costruire il log per mostrare agli sviluppatori l'errore?
Perché, l'ho fatto io stesso e i registri mostrano chiaramente che
prostotrader, Dimitri ti dice correttamente che le chiusure parziali (e complete) non sono asincrone nel tuo codice, ma sincrone... il che significa che il programma sta aspettando una risposta dal server...
È probabile che OnTradeTransaction si attivi più velocemente di quanto la posizione stessa cambi.
Allora qui:
//+------------------------------------------------------------------+//| 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;
}
}
potreste provare a mettere in loop il controllo della posizione. Forse sarà d'aiuto....
È qualcosa del genere:
//+------------------------------------------------------------------+//| 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;
}
}
}
Senza conoscere l'algoritmo esatto(quello che ti serve dal programma), è difficile valutare la correttezza della sua implementazione...
1. >Senza conoscere l'algoritmo esatto (quello che ti serve dal programma), è difficile valutare se è implementato correttamente...
Pensavo che non fosse difficile capire cosa fa il programma, beh, se non è chiaro, allora
Un Expert Advisor apre una posizione nel mercato FORTS con un volume di 2 contratti; se la posizione viene aperta, viene chiusa parzialmente con un volume di 1 contratto,
allora la posizione sarà chiusa completamente. Ripetere questa procedura finché il contatore tr_cnt<50
2. Potete "eseguire" PositionSelect() un milione di volte - non cambierà nulla, perché
l'eventoTRADE_TRANSACTION_DEAL_ADD non sarà ricevuto finché non sarete nel ciclo, e quindi il terminale non aggiornerà
Ho detto sopra - non lasciatevi trasportare dagli ordini: guardate le transazioni. Ecco un breve codice che mostra QUANDO il volume della posizione cambia e che tipo di transazione è:
Potete vedere chiaramente che non appena un evento con il tipo di transazione commercialeTRADE_TRANSACTION_DEAL_ADD è passato, ecco che i dati di posizione nel terminale vengono aggiornati.
Karputov Vladimir E semplificare OnTradeTransaction()- considerare solo l'aggiunta di una transazione alla storia - nessun ordine
Starai bene, non preoccuparti nemmeno di scriverlo (non perdere tempo).
Ho iniziato a guardarci dentro perché quello vero si stava bloccando.
Sembra che abbiano aggiornato il server durante il fine settimana. Sono arrivati i millisecondi. Potrebbero esserci altre sorprese.
Apparentemente, la funzioneOnTradeTransaction funziona indipendentemente dal registro delle transazioni.
Penso che questo comportamento della funzione sia ragionevole - non c'è bisogno di rallentare il flusso delle operazioni e aspettare che il registro sia scritto e tutto sia calcolato.
Nel tuo caso, è probabilmente meglio usareOnTrade,
o aspettare e controllare periodicamente con una pausa minima quando l'affare appare nella storia.
Sembra che abbiano aggiornato il server nel fine settimana. Sono apparsi dei millisecondi. Potrebbero esserci altre sorprese.
Apparentemente la funzioneOnTradeTransaction funziona indipendentemente dal registro delle operazioni.
Penso che questo comportamento della funzione sia giustificato - non c'è bisogno di rallentare il flusso delle operazioni e aspettare che tutto sia registrato e contato nel giornale.
Nel tuo caso, è probabilmente meglio usareOnTrade,
o aspettare e controllare periodicamente con una pausa minima quando l'affare appare nella storia.
Ciao Sergei!
Sì, ma non nel fine settimana, ma il giovedì dopo la sessione serale (chiesto al mio broker).
Non posso usare l'evento Trade() e aspettare che i dati si aggiornino nel terminale.
L'Expert Advisor è stato scritto molto tempo fa e fino a poco tempo fa funzionava "come un orologio" (forse sono stato fortunato e l'eventoTRADE_TRANSACTION_DEAL_ADD erasempre il primo ad arrivare).
È importante che l'Expert Advisor esegua un trade reciproco il più presto possibile, ecco perché la modalità asincrona e OnTradeTransaction().
Ora, l'Expert Advisor (a volte) invia ordini duplicati per aprire e chiudere posizioni.
Tu: "Penso che questo comportamento della funzione sia giustificato. Non c'è bisogno di rallentare il flusso delle operazioni e aspettare che tutto sia scritto e contato nel giornale".
Comunque, tutto viene scritto e contato dopo l'arrivo diTRADE_TRANSACTION_DEAL_ADD :)
Il fatto è cheTRADE_TRANSACTION_DEAL_ADD può essere perso eTRADE_TRANSACTION_HISTORY_ADD può arrivare e quindi il terminale avrà dati di posizione non aggiornati.:(,
cosa che accade realmente.
È strano che gli sviluppatori non ci abbiano pensato.
TRADE_TRANSACTION_HISTORY_ADD arriva solo se l'ordine è stato eseguito o cancellato (cancellato), quindi
se lo stato dell'ordine cambia (rispettivamente, la posizione può cambiare), il terminale dovrebbe ricevere le informazioni sul cambiamento di posizione,
anche seTRADE_TRANSACTION_DEAL_ADD è perso
Vediamo cosa hanno da dire gli sviluppatori.
Karputov Vladimir E semplificare OnTradeTransaction() - considerare solo l'aggiunta di una transazione alla storia - nessun ordine
Starai bene, non preoccuparti nemmeno di scriverlo (non perdere tempo).
Per favore, chiedete agli "insegnanti" e ai "sapientoni" di parlare sulla sostanza,
e non solo per mettere il piede sul palo per fare un punto.
Prima di mostrarsi alle persone che vogliono aiutarvi, dovreste formulare normalmente la vostra domanda. Cosa c'entra l'invio asincrono di un ordine, se la chiusura parziale viene eseguita dalla funzione OrderSend()? Su cosa fai domande?
Grande!
Questo dovrebbe essere visto come un aiuto?
E Karputov non c'entra niente, è solo che quando ho scritto il mio post lui aveva già pubblicato il suo e non l'ho visto.
Inizialmente, la domanda è stata posta come segue (nel caso siate troppo pigri per leggerla prima)
Come costruire il log per mostrare agli sviluppatori l'errore?
Perché, l'ho fatto io stesso e i registri mostrano chiaramente che
dopoTRADE_TRANSACTION_HISTORY_ADD (prima diTRADE_TRANSACTION_DEAL_ADD)
il terminale non aggiorna le informazioni sulla posizione.
prostotrader, Dimitri ti dice correttamente che le chiusure parziali (e complete) non sono asincrone nel tuo codice, ma sincrone... il che significa che il programma sta aspettando una risposta dal server...
È probabile che OnTradeTransaction si attivi più velocemente di quanto la posizione stessa cambi.
Allora qui:
potreste provare a mettere in loop il controllo della posizione. Forse sarà d'aiuto....
È qualcosa del genere:
Senza conoscere l'algoritmo esatto(quello che ti serve dal programma), è difficile valutare la correttezza della sua implementazione...
Cambiato completamente in modalità asincrona
Ma nulla è cambiato
Era ovvio, ma "per amore della purezza" dell'esperimento...
Tronchi pieni nel seminterrato
1. >Senza conoscere l'algoritmo esatto (quello che ti serve dal programma), è difficile valutare se è implementato correttamente...
Pensavo che non fosse difficile capire cosa fa il programma, beh, se non è chiaro, allora
Un Expert Advisor apre una posizione nel mercato FORTS con un volume di 2 contratti; se la posizione viene aperta, viene chiusa parzialmente con un volume di 1 contratto,
allora la posizione sarà chiusa completamente. Ripetere questa procedura finché il contatore tr_cnt<50
2. Potete "eseguire" PositionSelect() un milione di volte - non cambierà nulla, perché
l'eventoTRADE_TRANSACTION_DEAL_ADD non sarà ricevuto finché non sarete nel ciclo, e quindi il terminale non aggiornerà
informazioni sulla posizione
...
Ho detto sopra - non lasciatevi trasportare dagli ordini: guardate le transazioni. Ecco un breve codice che mostra QUANDO il volume della posizione cambia e che tipo di transazione è:
Ed ecco le stampe, a chiusura parziale:
Potete vedere chiaramente che non appena un evento con il tipo di transazione commercialeTRADE_TRANSACTION_DEAL_ADD è passato, ecco che i dati di posizione nel terminale vengono aggiornati.