Ti stai perdendo delle opportunità di trading:
- App di trading gratuite
- Oltre 8.000 segnali per il copy trading
- Notizie economiche per esplorare i mercati finanziari
Registrazione
Accedi
Accetti la politica del sito e le condizioni d’uso
Se non hai un account, registrati
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);
}
Applicazione
OrderSend(Request, Result);
Le cose sono molto più semplici. Prima di inviare un ordine, ricordava la lunghezza della storia, e dopo averlo inviato, aspettava che la lunghezza della storia aumentasse. Si dovrebbe inserire un timeout, in modo che improvvisamente non si blocchi per sempre.
Le cose sono molto più semplici. Prima di inviare un ordine, ricordava la lunghezza della storia, e dopo averlo inviato, aspettava che la lunghezza della storia aumentasse. Bisogna inserire un timeout, in modo che improvvisamente non si blocchi per sempre.
C'è un timeout. Nella tua variante, purtroppo, ci possono essere problemi se diversi OrderSend lavorano insieme (da diversi Expert Advisors).
Inoltre, non solo la storia non è sincronizzata, ma anche SL/TP di posizioni/ordini aperti, ecc. Per i mercati, la storia può aumentare prima solo con un ordine, e poi un attimo dopo con uno scambio. Ci sono anche altre situazioni. Ecco perché a prima vista sembra così ingombrante.
Qual è lo scopo del suo messaggio? Viene in OnTradeTransaction(), e allora? Significa che dobbiamo aspettare l'evento. Devi ancora aspettare. L'essenza del messaggio di fxsaber è che dopo l'esecuzione di OrderSend(), le informazioni sull'azione eseguita non appariranno immediatamente nel terminale. Ad alcuni piace aspettare OnTradeTransaction(), mentre ad altri piace vedere un ordine o un affare nella lista. Ecco la differenza rispetto a MT4, come esempio. In M4, dopo OrderSend(), l'ordine è già nella lista degli ordini, e dopo OrderClose(), è sempre nella storia.
E perché aspettare OnTradeTransaction()? Fate una coda di richieste e se c'è una risposta, fate qualcosa... almeno cancellate la richiesta dalla coda. È un peccato che SB non abbia Queue, ma è una classe semplice.
C'è un timeout. Nella tua versione, purtroppo, ci possono essere problemi se diversi OrderSend lavorano insieme (da diversi EA).
Inoltre, non solo la storia non è sincronizzata, ma anche SL/TP di posizioni/ordini aperti, ecc. Per i mercati, la storia può aumentare prima solo con un ordine, e poi un attimo dopo con uno scambio. Ci sono anche altre situazioni. Ecco perché sembra così ingombrante a prima vista.
Sì, sono d'accordo. Ma ho avuto solo un EA di questo tipo, e se non altro non ne verrà fuori nessun danno.
Sarebbe meglio scrivere una funzione separata per l'attesa, in modo da poter utilizzare anche la classe di trading standard.
Perché aspettare OnTradeTransaction()? Fare una coda di richieste, se la risposta è arrivata, fare qualcosa... almeno rimuovere la richiesta dalla coda. È un peccato che SB non abbia Queue, ma è una classe semplice.
Il punto è che OnTradeTransaction() non si attiverà immediatamente dopo OrderSend.
In breve, qui c'è solo una folla di tifosi che litigano senza entrare nel merito della discussione.
Ci sono due varianti dell'algoritmo se qualcosa deve essere fatto immediatamente dopo OrderSend():
1. Possiamo avviare un ciclo in attesa degli aggiornamenti delle liste di ordini e offerte.
2. Termina OnTick() e aspetta che OnTradeTransaction() si attivi.
3. Controlla con un segno di spunta se un nuovo ordine o affare appare nella lista.