![MQL5 - Langage des stratégies de trading intégré au terminal client MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
Vous manquez des opportunités de trading :
- Applications de trading gratuites
- Plus de 8 000 signaux à copier
- Actualités économiques pour explorer les marchés financiers
Inscription
Se connecter
Vous acceptez la politique du site Web et les conditions d'utilisation
Si vous n'avez pas de compte, veuillez vous inscrire
ENUM_ORDER_TYPE_FILLING GetFilling( const string Symb, const uint Type = ORDER_FILLING_FOK )
{
const ENUM_SYMBOL_TRADE_EXECUTION ExeMode = (ENUM_SYMBOL_TRADE_EXECUTION)::SymbolInfoInteger(Symb, SYMBOL_TRADE_EXEMODE);
const int FillingMode = (int)::SymbolInfoInteger(Symb, SYMBOL_FILLING_MODE);
return((FillingMode == 0 || (Type >= ORDER_FILLING_RETURN) || ((FillingMode & (Type + 1)) != Type + 1)) ?
(((ExeMode == SYMBOL_TRADE_EXECUTION_EXCHANGE) || (ExeMode == SYMBOL_TRADE_EXECUTION_INSTANT)) ?
ORDER_FILLING_RETURN : ((FillingMode == SYMBOL_FILLING_IOC) ? ORDER_FILLING_IOC : ORDER_FILLING_FOK)) :
(ENUM_ORDER_TYPE_FILLING)Type);
}
ENUM_ORDER_TYPE_TIME GetExpirationType( const string Symb, uint Expiration = ORDER_TIME_GTC )
{
const int ExpirationMode = (int)::SymbolInfoInteger(Symb, SYMBOL_EXPIRATION_MODE);
if ((Expiration > ORDER_TIME_SPECIFIED_DAY) || (((ExpirationMode >> Expiration) & 1) == 0))
{
if ((Expiration < ORDER_TIME_SPECIFIED) || (ExpirationMode < SYMBOL_EXPIRATION_SPECIFIED))
Expiration = ORDER_TIME_GTC;
else if (Expiration > ORDER_TIME_DAY)
Expiration = ORDER_TIME_SPECIFIED;
uint i = 1 << Expiration;
while ((Expiration <= ORDER_TIME_SPECIFIED_DAY) && ((ExpirationMode & i) != i))
{
i <<= 1;
Expiration++;
}
}
return((ENUM_ORDER_TYPE_TIME)Expiration);
}
if (Expiration > ORDER_TIME_DAY)
Request.expiration = Expiration;
#define TOSTRING2(A) #A + " = " + EnumToString(A) + " (" + (string)(A) + ")\n"
string ToString( const MqlTradeTransaction &Trans )
{
return(TOSTRING(Trans.deal) + TOSTRING(Trans.order) + TOSTRING(Trans.symbol) +
TOSTRING2(Trans.type) + TOSTRING2(Trans.order_type) + TOSTRING2(Trans.order_state) +
TOSTRING2(Trans.deal_type) + TOSTRING2(Trans.time_type) +
TOSTRING(Trans.time_expiration) + TOSTRING(Trans.price) + TOSTRING(Trans.price_trigger) +
TOSTRING(Trans.price_sl) + TOSTRING(Trans.price_tp) + TOSTRING(Trans.volume) +
TOSTRING(Trans.position) + TOSTRING(Trans.position_by));
}
string ToString( const MqlTradeRequest &Request )
{
return(TOSTRING2(Request.action) + TOSTRING(Request.magic) + TOSTRING(Request.order) +
TOSTRING(Request.symbol) + TOSTRING(Request.volume) + TOSTRING(Request.price) +
TOSTRING(Request.stoplimit) + TOSTRING(Request.sl) + TOSTRING(Request.tp) +
TOSTRING(Request.deviation) + TOSTRING2(Request.type) + TOSTRING2(Request.type_filling) +
TOSTRING2(Request.type_time) + TOSTRING(Request.expiration) + TOSTRING(Request.comment) +
TOSTRING(Request.position) + TOSTRING(Request.position_by));
}
string ToString( const MqlTradeResult &Result )
{
return(TOSTRING(Result.retcode) + TOSTRING(Result.deal) + TOSTRING(Result.order) +
TOSTRING(Result.volume) + TOSTRING(Result.price) + TOSTRING(Result.bid) +
TOSTRING(Result.ask) + TOSTRING(Result.comment) + TOSTRING(Result.request_id) +
TOSTRING(Result.retcode_external));
}
#undef TOSTRING
#undef TOSTRING2
{
Print(ToString(Trans) + ToString(Request) + ToString(Result));
}
void OnTradeTransaction ( const MqlTradeTransaction &Trans, const MqlTradeRequest &Request, const MqlTradeResult &Result )
{
if ((Trans.type == TRADE_TRANSACTION_ORDER_ADD) &&
PositionSelectByTicket(Trans.position) && OrderSelect(Trans.order) &&
(PositionGetInteger(POSITION_TYPE) == 1 - OrderGetInteger(ORDER_TYPE)))
{
const double Price = OrderGetDouble(ORDER_PRICE_OPEN);
if (Price == PositionGetDouble(POSITION_TP))
Print("Position #" + (string)Trans.position + " - triggered TP.");
else if (Price == PositionGetDouble(POSITION_SL))
Print("Position #" + (string)Trans.position + " - triggered SL.");
}
}
{
MqlDateTime sTime = {0};
::TimeToStruct(time, sTime);
return((ENUM_DAY_OF_WEEK)sTime.day_of_week);
}
// true - находимся в торговой сессии
bool SessionTrade( const string Symb )
{
datetime TimeNow = ::TimeTradeServer();
const ENUM_DAY_OF_WEEK DayOfWeek = GetDayOfWeek(TimeNow);
TimeNow %= 24 * 60 * 60;
bool Res = false;
datetime From, To;
for (int i = 0; (!Res) && ::SymbolInfoSessionTrade(Symb, DayOfWeek, i, From, To); i++)
Res = ((From <= TimeNow) && (TimeNow < To));
return(Res);
}
// Возвращает true, если символ торгуемый. Иначе - false.
bool SymbolTrade( const string Symb )
{
MqlTick Tick;
return(::SymbolInfoTick(Symb, Tick) ? ((Tick.bid != 0) && (Tick.ask != 0) && SessionTrade(Symb) /* &&
((ENUM_SYMBOL_TRADE_MODE)::SymbolInfoInteger(Symb, SYMBOL_TRADE_MODE) == SYMBOL_TRADE_MODE_FULL) */) : false);
}
Application
OrderSend(Request, Result);
Les choses sont beaucoup plus simples. Avant d'envoyer un ordre, on se souvient de la longueur de l'historique, et après l'avoir envoyé, on attend que la longueur de l'historique augmente. Il convient d'introduire un délai d'attente, afin que l'opération ne reste pas bloquée pour toujours.
Les choses sont beaucoup plus simples. Avant d'envoyer un ordre, on se souvient de la longueur de l'historique, et après l'avoir envoyé, on attend que la longueur de l'historique augmente. Un délai d'attente doit être saisi, afin d'éviter que l'opération ne reste bloquée pour toujours.
Il y a un délai d'attente. Dans votre variante, malheureusement, il peut y avoir des problèmes si plusieurs OrderSends fonctionnent ensemble (à partir de différents Expert Advisors).
En outre, non seulement l'historique n'est pas synchronisé, mais aussi les SL/TP des positions/ordres ouverts, etc. Pour les marchés, l'historique peut s'accroître d'abord seulement par un ordre, puis un instant plus tard par une transaction. Il existe également d'autres situations. C'est pourquoi il semble si encombrant à première vue.
Quel est le but de votre message ? Il arrive dans OnTradeTransaction(), et alors ? Ça veut dire qu'on doit attendre l'événement. Vous devez encore attendre. L'essence du message de fxsaber est qu'après l'exécution de OrderSend(), les informations concernant l'action effectuée n'apparaîtront pas immédiatement dans le terminal. Certaines personnes aiment attendre la fonction OnTradeTransaction(), tandis que d'autres aiment voir un ordre ou une transaction dans la liste. Voici la différence avec MT4, à titre d'exemple. Dans M4, après OrderSend(), l'ordre est déjà dans la liste des ordres, et après OrderClose(), il est toujours dans l'historique.
Et pourquoi attendre OnTradeTransaction()? Faites une file d'attente des demandes et s'il y a une réponse, faites quelque chose... au moins supprimez la demande de la file d'attente. C'est dommage que SB n'ait pas de Queue, mais c'est une classe simple.
Il y a un délai d'attente. Dans votre version, malheureusement, il peut y avoir des problèmes si plusieurs OrderSends fonctionnent ensemble (à partir de différents EAs).
En outre, non seulement l'historique n'est pas synchronisé, mais aussi les SL/TP des positions/ordres ouverts, etc. Pour les marchés, l'historique peut augmenter d'abord seulement par un ordre, puis un instant plus tard par une transaction. Il existe également d'autres situations. C'est pourquoi il semble si lourd à première vue.
Oui, je suis d'accord. Mais je n'ai eu qu'une seule évaluation environnementale de ce type, et il n'y aura aucun mal à cela.
Il serait préférable d'écrire une fonction distincte pour l'attente, de sorte que la classe de négociation standard puisse également être utilisée.
Pourquoi attendre OnTradeTransaction()? Faites une file d'attente de demandes, si la réponse est venue, faites quelque chose... au moins retirez la demande de la file d'attente. C'est dommage que SB n'ait pas de Queue, mais c'est une classe simple.
Le fait est que OnTradeTransaction() ne se déclenchera pas immédiatement après OrderSend.
En bref, il y a juste une foule de fans qui se disputent ici sans entrer dans le sujet de la dispute.
Il existe deux variantes de l'algorithme si quelque chose doit être fait immédiatement après OrderSend() :
1. Nous pouvons démarrer une boucle en attendant les mises à jour des listes de commandes et d'offres.
2. Terminez OnTick() et attendez le déclenchement de OnTradeTransaction().
3. Vérifiez par cochage si une nouvelle commande ou une nouvelle affaire apparaît dans la liste.