Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
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);
}
Применение
OrderSend(Request, Result);
Дела на много проще. Перед отправкой ордера запоминал длину истории, а после отправки ждал, когда длина истории увеличится. Таймаут надо ввести, что бы вдруг не застряло на вечно.
Дела на много проще. Перед отправкой ордера запоминал длину истории, а после отправки ждал, когда длина истории увеличится. Таймаут надо ввести, что бы вдруг не застряло на вечно.
Таймаут есть. В Вашем варианте, к сожалению, могут быть проблемы, если несколько OrderSend отрабатывают вместе (из разных советников).
Так же, не синхронизирована не только история, но и SL/TP открытых позиций/ордеров и т.д. Для маркетов может история увеличиться сначала только на ордер, а спустя мгновение - на сделку. Есть и другие ситуации. Поэтому так громоздко выглядит на первый взгляд.
А смысл вашего сообщения? Ну придет в OnTradeTransaction(), ну и что? Это значит что надо ждать события. Все равно ждать. Смысл сообщения fxsaber в что, что после выполнения OrderSend() информация о выполненном действия появляется в терминале не сразу. Кому то нравится ждать OnTradeTransaction(), кому-то появления ордера или сделка в списке. Для примера - отличие от МТ4. В М4, после OrderSend() ордер уже есть в списке ордеров, а после OrderClose() всегда есть в истории.
А зачем ждать OnTradeTransaction()?. Сделать очередь запросов, если пришел ответ, что-то делать... как минунмум, удалить запрос из очереди. Жаль, в СБ нет Queue, но это простой класс.
Таймаут есть. В Вашем варианте, к сожалению, могут быть проблемы, если несколько OrderSend отрабатывают вместе (из разных советников).
Так же, не синхронизирована не только история, но и SL/TP открытых позиций/ордеров и т.д. Для маркетов может история увеличиться сначала только на ордер, а спустя мгновение - на сделку. Есть и другие ситуации. Поэтому так громоздко выглядит на первый взгляд.
Да, согласен. Но у только один такой советник был, и если что ничего страшного не произойдет.
Лучше бы написать отдельную функцию для ожидания, что бы и стандартным торговым классом можно было пользоваться.
А зачем ждать OnTradeTransaction()?. Сделать очередь запросов, если пришел ответ, что-то делать... как минунмум, удалить запрос из очереди. Жаль, в СБ нет Queue, но это простой класс.
Смысл том, что в OnTradeTransaction() сработает не сразу после OrderSend.
Короче, здесь просто толпа любителей поспорить не вникнув в предмет спора.
Есть два варианта алгоритма, если после OrderSend() надо сразу что-то делать:
1. Врубить цикл ожидания обновления списков ордеров и сделок.
2. Завершить работу OnTick() и ждать срабатывания OnTradeTransaction().
3. По тикам проверять, появился ли новый ордер или сделка в списке.