Стесняюсь спросить, а откуда такая уверенность, что ошибка есть? Или Вы полагаете, что разработчики такие дремучие как таёжный лес? ;-)
Читайте матчасть про асинхронные операции.
Стесняюсь спросить, а откуда такая уверенность, что ошибка есть? Или Вы полагаете, что разработчики такие дремучие как таёжный лес? ;-)
Читайте матчасть про асинхронные операции.
Уважаемый, рекомендую Вам почитать начало сообщения.
Я спросил как построить доказательую базу для разработчикав, а не как пользоваться
ассинхронной функцией!
В педыдущих билдах (до хеджирования) этой ошибки небыло.
Написал тестового эксперта
//+------------------------------------------------------------------+ //| Test_Pos_selct.mq5 | //| Copyright 2016, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2016, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" input uint TrCount=50; //Кол-во транзакций uint tr_cnt; ulong order_ticket; ulong request_id; ulong Magic=1234567890; #define ERR_ZERO_TICKET -11; bool exp_busy; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum ENUM_ORD_SELECT { SELECT_ERROR = 0, SELECT_FALSE = 1, SELECT_TRUE = 2, SELECT_BUSY = 3 }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum ENUM_ORD_REAL_STATE { ORD_NOT_SPECIFIED = 0, //Состояние ордера не определено ORD_NONE_CANCELED = 1, //Ордера нет, отменён пользователем ORD_NONE_PARTIAL_CANCELED = 2, //Ордера нет, исполнился частично (не был залит вторым объёмом) ORD_NONE_PARTIAL = 3, //Ордера нет, исполнился частично ORD_NONE_EXPIRED = 4, //Ордера нет, удалён по сроку ORD_NONE_FILLED = 5, //Ордера нет, исполнился полностью ORD_NONE_REJECTED = 6, //Ордера нет, отклонён брокером(биржей) ORD_BUSY = 7, //Ордер находится в переходном состоянии ORD_EXIST = 8, //Ордер выставлен на биржу, возможны действия над ним ORD_EXIST_PARTIAL = 9 //Ордер выставлен на биржу, частично исполнился, возможны действия над ним }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ struct ORDER_DATA { int error_code; datetime time_setup; ENUM_ORDER_TYPE type; ENUM_ORDER_STATE state; ENUM_ORD_REAL_STATE real_state; datetime expiration; datetime time_done; long t_set_msc; long t_done_msc; ENUM_ORDER_TYPE_FILLING type_filling; ENUM_ORDER_TYPE_TIME type_time; long magic; long pos_id; double vol_init; double vol_cur; double price_open; double sl; double tp; double price_cur; double price_stlim; string symbol; string comment; }; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- Print(__FUNCTION__, ": Start testing: ",TimeTradeServer()); tr_cnt=0; order_ticket=0; request_id=0; exp_busy=false; if(!MarketBookAdd(Symbol())){return(INIT_FAILED);} //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- MarketBookRelease(Symbol()); } //+------------------------------------------------------------------+ //| TradeTransaction function | //+------------------------------------------------------------------+ void OnTradeTransaction(const MqlTradeTransaction &trans, const MqlTradeRequest &request, const MqlTradeResult &result) { bool is_select=false; ENUM_POSITION_TYPE pos_type=NULL; long volume=0; switch(trans.type) { case TRADE_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; case TRADE_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; } else Print(__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; } else Print(__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; } } //+------------------------------------------------------------------+ //| BookEvent function | //+------------------------------------------------------------------+ void OnBookEvent(const string &symbol) { //--- if(symbol==Symbol()&&(!exp_busy)) { if(tr_cnt>=TrCount) { if(PositionSelect(Symbol())) { order_ticket=0; ENUM_POSITION_TYPE pos_type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); long vol=(long)PositionGetDouble(POSITION_VOLUME); ClosePosition(pos_type,vol); Print(__FUNCTION__, ": End testing: ",TimeTradeServer()); if(order_ticket>0) ExpertRemove(); } else { Print(__FUNCTION__, ": End testing: ",TimeTradeServer()); ExpertRemove(); } } else { if(PositionSelect(Symbol())) { ENUM_POSITION_TYPE pos_type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); long vol=(long)PositionGetDouble(POSITION_VOLUME); Print(__FUNCTION__, ": Position exists"); Print(__FUNCTION__, ": Position type: ", EnumToString(pos_type)); Print(__FUNCTION__, ": Position volume: ", vol); switch(int(vol)) { case 1: ClosePosition(pos_type,vol); break; default: PartClosePos(pos_type); break; } } else { Print(__FUNCTION__, ": Try open position..."); OpenPosition(); } } } } // void ClosePosition(ENUM_POSITION_TYPE p_type,const long volume) { MqlTradeRequest request={0}; MqlTradeResult result={0}; switch(p_type) { case POSITION_TYPE_BUY: request.type=ORDER_TYPE_SELL; break; case POSITION_TYPE_SELL: request.type=ORDER_TYPE_BUY; break; } order_ticket=0; request.magic=Magic; request.symbol=Symbol(); request.volume=(double)volume; request.type_filling=ORDER_FILLING_IOC; request.type_time=ORDER_TIME_DAY; request.action=TRADE_ACTION_DEAL; request.comment=""; request.price=0; if(OrderSend(request,result)) { if(result.retcode==TRADE_RETCODE_PLACED) { //order_ticket=result.order; exp_busy=false; tr_cnt++; Print(__FUNCTION__, ": Position slosed."); } } else {Print(__FUNCTION__, ": Order not sent for close position!");} } //+------------------------------------------------------------------+ void PartClosePos(ENUM_POSITION_TYPE p_type) { MqlTradeRequest request={0}; MqlTradeResult result={0}; switch(p_type) { case POSITION_TYPE_BUY: request.type=ORDER_TYPE_SELL; break; case POSITION_TYPE_SELL: request.type=ORDER_TYPE_BUY; break; } order_ticket=0; request.magic=Magic; request.symbol=Symbol(); request.volume=1; request.type_filling=ORDER_FILLING_IOC; request.type_time=ORDER_TIME_DAY; request.action=TRADE_ACTION_DEAL; request.comment=""; request.price=0; if(OrderSend(request,result)) { if(result.retcode==TRADE_RETCODE_PLACED) { order_ticket=result.order; exp_busy=true; tr_cnt++; Print(__FUNCTION__, ": Order sent for part close position."); } } else {Print(__FUNCTION__, ": Order not sent for part close position!");} } //+------------------------------------------------------------------+ void OpenPosition() { MqlTradeRequest request={0}; MqlTradeResult result={0}; request_id=0; order_ticket=0; request.magic=Magic; request.symbol=Symbol(); request.volume=2; request.type_filling=ORDER_FILLING_IOC; request.type_time=ORDER_TIME_DAY; request.action=TRADE_ACTION_DEAL; request.comment=""; request.price=0; request.type=ORDER_TYPE_BUY; if(OrderSendAsync(request,result)) { if(result.retcode==TRADE_RETCODE_PLACED) { request_id=result.request_id; exp_busy=true; Print(__FUNCTION__, ": Order sent successfully for open position"); } } else Print(__FUNCTION__, ": Order not sent for open position!"); } ENUM_ORD_SELECT OrderRealSelect(const ulong ticket,ORDER_DATA &ord_data,const bool get_data) { double init_vol= 0; double cur_vol = 0; ZeroMemory(ord_data); ord_data.real_state = ORD_NOT_SPECIFIED; ord_data.error_code = ERR_SUCCESS; ResetLastError(); //--- if(ticket>0) { if(HistoryOrderSelect(ticket)) { if(get_data) { ord_data.comment=HistoryOrderGetString(ticket,ORDER_COMMENT); ord_data.expiration=datetime(HistoryOrderGetInteger(ticket,ORDER_TIME_EXPIRATION)); ord_data.magic=HistoryOrderGetInteger(ticket,ORDER_MAGIC); ord_data.pos_id=HistoryOrderGetInteger(ticket,ORDER_POSITION_ID); ord_data.price_cur=HistoryOrderGetDouble(ticket,ORDER_PRICE_CURRENT); ord_data.price_open=HistoryOrderGetDouble(ticket,ORDER_PRICE_OPEN); ord_data.price_stlim=HistoryOrderGetDouble(ticket,ORDER_PRICE_STOPLIMIT); ord_data.sl=HistoryOrderGetDouble(ticket,ORDER_SL); ord_data.state=ENUM_ORDER_STATE(HistoryOrderGetInteger(ticket,ORDER_STATE)); ord_data.symbol=HistoryOrderGetString(ticket,ORDER_SYMBOL); ord_data.t_done_msc=datetime(HistoryOrderGetInteger(ticket,ORDER_TIME_DONE_MSC)); ord_data.t_set_msc =datetime( HistoryOrderGetInteger(ticket, ORDER_TIME_SETUP_MSC)); ord_data.time_done =datetime( HistoryOrderGetInteger( ticket, ORDER_TIME_DONE)); ord_data.time_setup=datetime(HistoryOrderGetInteger(ticket,ORDER_TIME_SETUP)); ord_data.tp=HistoryOrderGetDouble(ticket,ORDER_TP); ord_data.type=ENUM_ORDER_TYPE(HistoryOrderGetInteger(ticket,ORDER_TYPE)); ord_data.type_filling=ENUM_ORDER_TYPE_FILLING(HistoryOrderGetInteger(ticket,ORDER_TYPE_FILLING)); ord_data.type_time=ENUM_ORDER_TYPE_TIME(HistoryOrderGetInteger(ticket,ORDER_TYPE_TIME)); ord_data.vol_cur=HistoryOrderGetDouble(ticket,ORDER_VOLUME_CURRENT); ord_data.vol_init=HistoryOrderGetDouble(ticket,ORDER_VOLUME_INITIAL); } else { ord_data.state=ENUM_ORDER_STATE(HistoryOrderGetInteger(ticket,ORDER_STATE)); cur_vol=HistoryOrderGetDouble(ticket,ORDER_VOLUME_CURRENT); init_vol=HistoryOrderGetDouble(ticket,ORDER_VOLUME_INITIAL); } //--- switch(ord_data.state) { case ORDER_STATE_CANCELED: if(get_data) { if(ord_data.vol_init==ord_data.vol_cur) { ord_data.real_state=ORD_NONE_CANCELED; } else { ord_data.real_state=ORD_NONE_PARTIAL_CANCELED; } } else { if(init_vol==cur_vol) { ord_data.real_state=ORD_NONE_CANCELED; } else { ord_data.real_state=ORD_NONE_PARTIAL_CANCELED; } } break; case ORDER_STATE_PARTIAL: ord_data.real_state=ORD_NONE_PARTIAL; break; case ORDER_STATE_EXPIRED: ord_data.real_state=ORD_NONE_EXPIRED; break; case ORDER_STATE_FILLED: ord_data.real_state=ORD_NONE_FILLED; break; case ORDER_STATE_REJECTED: ord_data.real_state=ORD_NONE_REJECTED; break; } } else if(OrderSelect(ticket)) { if(get_data) { ord_data.comment=OrderGetString(ORDER_COMMENT); ord_data.expiration=datetime(OrderGetInteger(ORDER_TIME_EXPIRATION)); ord_data.magic=OrderGetInteger(ORDER_MAGIC); ord_data.pos_id=OrderGetInteger(ORDER_POSITION_ID); ord_data.price_cur=OrderGetDouble(ORDER_PRICE_CURRENT); ord_data.price_open=OrderGetDouble(ORDER_PRICE_OPEN); ord_data.price_stlim=OrderGetDouble(ORDER_PRICE_STOPLIMIT); ord_data.sl=OrderGetDouble(ORDER_SL); ord_data.state=ENUM_ORDER_STATE(OrderGetInteger(ORDER_STATE)); ord_data.symbol=OrderGetString(ORDER_SYMBOL); ord_data.t_done_msc=datetime(OrderGetInteger(ORDER_TIME_DONE_MSC)); ord_data.t_set_msc =datetime( OrderGetInteger(ORDER_TIME_SETUP_MSC)); ord_data.time_done =datetime( OrderGetInteger(ORDER_TIME_DONE )); ord_data.time_setup=datetime(OrderGetInteger(ORDER_TIME_SETUP)); ord_data.tp=OrderGetDouble(ORDER_TP); ord_data.type=ENUM_ORDER_TYPE(OrderGetInteger(ORDER_TYPE)); ord_data.type_filling=ENUM_ORDER_TYPE_FILLING(OrderGetInteger(ORDER_TYPE_FILLING)); ord_data.type_time=ENUM_ORDER_TYPE_TIME(OrderGetInteger(ORDER_TYPE_TIME)); ord_data.vol_cur=OrderGetDouble(ORDER_VOLUME_CURRENT); ord_data.vol_init=OrderGetDouble(ORDER_VOLUME_INITIAL); } else { ord_data.state=ENUM_ORDER_STATE(OrderGetInteger(ORDER_STATE)); } //--- switch(ord_data.state) { case ORDER_STATE_STARTED: case ORDER_STATE_REQUEST_ADD: case ORDER_STATE_REQUEST_MODIFY: case ORDER_STATE_REQUEST_CANCEL: ord_data.real_state=ORD_BUSY; break; case ORDER_STATE_PARTIAL: ord_data.real_state=ORD_EXIST_PARTIAL; break; case ORDER_STATE_PLACED: ord_data.real_state=ORD_EXIST; break; } } else { ord_data.error_code=GetLastError(); } //--- if(( ord_data.error_code!=ERR_SUCCESS) || (ord_data.real_state==ORD_NOT_SPECIFIED)) { return(SELECT_ERROR); } else { switch(ord_data.real_state) { case ORD_BUSY: return(SELECT_BUSY); break; case ORD_EXIST: case ORD_EXIST_PARTIAL: return(SELECT_TRUE); break; default: return(SELECT_FALSE); break; } } } else { ord_data.error_code=ERR_ZERO_TICKET; return(SELECT_ERROR); } } //+------------------------------------------------------------------+
Запустил на Демо в Открытии, я считаю, что это ошибка, то что ордер уже в истории, а терминал "не знает", что
позиция открыта 2016.08.02 17:52:34.427 Test_Pos_selct (GAZR-9.16,M1) OnTradeTransaction: Position not exist.
2016.08.02 17:52:34.403 Test_Pos_selct (GAZR-9.16,M1) OnBookEvent: Try open position... 2016.08.02 17:52:34.403 Test_Pos_selct (GAZR-9.16,M1) OpenPosition: Order sent successfully for open position 2016.08.02 17:52:34.409 Test_Pos_selct (GAZR-9.16,M1) OnTradeTransaction: Order resived #50224643 2016.08.02 17:52:34.427 Test_Pos_selct (GAZR-9.16,M1) OnTradeTransaction: Order #50224643 add to history. 2016.08.02 17:52:34.427 Test_Pos_selct (GAZR-9.16,M1) OnTradeTransaction: Position not exist. 2016.08.02 17:52:34.437 Test_Pos_selct (GAZR-9.16,M1) OnBookEvent: Position exists
Полные логи прикреплены
Заявка в сервисдеск отправлена
Необработана, Начата: 2016.08.02 17:20, #1529580
Неужели никто раньше не обращал внимание на этоту багу?
Расширил логирование функции OnTradeTransaction
void OnTradeTransaction(const MqlTradeTransaction &trans, const MqlTradeRequest &request, const MqlTradeResult &result) { bool is_select=false; ENUM_POSITION_TYPE pos_type=NULL; long volume=0; switch(trans.type) { case TRADE_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; case TRADE_TRANSACTION_DEAL_ADD: if((order_ticket!=0) && (trans.order==order_ticket)) { Print(__FUNCTION__, ": Deal, based on order #", order_ticket, " done."); if(PositionSelect(Symbol())) { Print(__FUNCTION__, ": Position exists."); pos_type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); volume=(long)PositionGetDouble(POSITION_VOLUME); Print(__FUNCTION__, ": Position type: ", EnumToString(pos_type)); Print(__FUNCTION__, ": Position volume: ", volume); } else Print(__FUNCTION__, ": Position not exist."); } break; case TRADE_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; } else Print(__FUNCTION__, ": Position not exist."); Print(__FUNCTION__, ": Order #",trans.order," exists."); break; case SELECT_FALSE: if(PositionSelect(Symbol())) { pos_type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); volume=(long)PositionGetDouble(POSITION_VOLUME); is_select=true; } else Print(__FUNCTION__, ": Position not exist."); Print(__FUNCTION__, ": Order #",trans.order," not found."); 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; } }
Несмотря на то, что события TRADE_TRANSACTION_DEAL_ADD и TRADE_TRANSACTION_HISTORY_ADD
не имеют очерёдности, но терминал-то должен знать состоянии позиции, при любом из этих
приходящих событий, иначе получается просто лажа. Вот пример, когда событие TRADE_TRANSACTION_HISTORY_ADD
приходит первым (ордер в истории, сделка совершена, а в терминале так и "болтается" позиция с объёмом равным 2, а не 1)
2016.08.02 19:28:02.259 Test_Pos_selct (GAZR-9.16,M1) OnBookEvent: Position exists 2016.08.02 19:28:02.259 Test_Pos_selct (GAZR-9.16,M1) OnBookEvent: Position type: POSITION_TYPE_BUY 2016.08.02 19:28:02.259 Test_Pos_selct (GAZR-9.16,M1) OnBookEvent: Position volume: 2 2016.08.02 19:28:02.288 Test_Pos_selct (GAZR-9.16,M1) PartClosePos: Order sent for part close position. 2016.08.02 19:28:02.288 Test_Pos_selct (GAZR-9.16,M1) OnTradeTransaction: Order #50232966 add to history. 2016.08.02 19:28:02.288 Test_Pos_selct (GAZR-9.16,M1) OnTradeTransaction: Order #50232966 not found. 2016.08.02 19:28:02.288 Test_Pos_selct (GAZR-9.16,M1) OnTradeTransaction: Position exists 2016.08.02 19:28:02.288 Test_Pos_selct (GAZR-9.16,M1) OnTradeTransaction: Position type: POSITION_TYPE_BUY 2016.08.02 19:28:02.288 Test_Pos_selct (GAZR-9.16,M1) OnTradeTransaction: Position volume: 2 2016.08.02 19:28:02.288 Test_Pos_selct (GAZR-9.16,M1) OnTradeTransaction: Deal, based on order #50232966 done. 2016.08.02 19:28:02.288 Test_Pos_selct (GAZR-9.16,M1) OnTradeTransaction: Position exists. 2016.08.02 19:28:02.288 Test_Pos_selct (GAZR-9.16,M1) OnTradeTransaction: Position type: POSITION_TYPE_BUY 2016.08.02 19:28:02.288 Test_Pos_selct (GAZR-9.16,M1) OnTradeTransaction: Position volume: 1
Из справки MQL5
Один торговый запрос, отправленный из терминала вручную или через торговые функции OrderSend()/OrderSendAsync(), может порождать на торговом сервере несколько последовательных торговых транзакций. При этом очередность поступления этих транзакций в терминал не гарантирована, поэтому нельзя свой торговый алгоритм строить на ожидании поступления одних торговых транзакций после прихода других. Кроме того, транзакции могут потеряться при доставке от сервера к терминалу.
Всё бы ничего, если бы не последняя фраза.
Если событие TRADE_TRANSACTION_HISTORY_ADD пришло первым, а событие TRADE_TRANSACTION_DEAL_ADD
потерялось :(, то в терминале так и будут "висеть" предыдущие данные о позизиции!
Из справки MQL5
Всё бы ничего, если бы не последняя фраза.
Если событие TRADE_TRANSACTION_HISTORY_ADD пришло первым, а событие TRADE_TRANSACTION_DEAL_ADD
потерялось :(, то в терминале так и будут "висеть" предыдущие данные о позизии!
Бред. Какая связь между кэшем, где сохраняются данные о запрашиваемой позиции, и транзакциями?
prostotrader, у Вас там с логикой алгоритма наверное что-то не то. Хотел было покопаться в чужом коде, но влом... потом тип исполнения тут:
request.type_filling=ORDER_FILLING_IOC; // разве так? request.type_filling=ORDER_FILLING_RETURN; // а может так?
И вообще в каких университетах так учат кодировать?
switch(trans.type) { case TRADE_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; case TRADE_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; } else Print(__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; } else Print(__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; }
Бред. Какая связь между кэшем, где сохраняются данные о запрашиваемой позиции, и транзакциями?
prostotrader, у Вас там с логикой алгоритма наверное что-то не то. Хотел было покопаться в чужом коде, но влом... потом тип исполнения тут:
И вообще в каких университетах так учат кодировать?
Вы сами-то читали, что написали?
Обязательно находится "учитель", который сам ничего не умеет, но
регулярно пишет...
Увидит знакомое слово (ORDER_FILLING_IOC) и начинает изголятся.
Для Вас, всезнайка
ORDER_FILLING_IOC
Означает согласие совершить сделку по максимально доступному на рынке объему в пределах указанного в ордере.
В случае невозможности полного исполнения ордер будет исполнен на доступный объем, а неисполненный объем ордера будет отменен.
Вы сами-то читали, что написали?
Обязательно находится "учитель", который сам ничего не умеет, но
регулярно пишет...
Увилит знакомое слово (ORDER_FILLING_IOC) и начинает изголятся.
Нужно (только завтра) сделать два примера - синхронную отправку и асинхронную. И упростить OnTradeTransaction() - рассматривать только добавление сделки в историю - никаких ордеров, чтобы не было и близко. Но я буду делать исключительно через стандартный класс CTrade.
Кстати, на каком торговом сервере Вы экспериментируете?
Просьба к "учителям" и "всезнайкам" выступать по существу,
а не просто ногу задирать у столба, чтобы отметится.
Нужно (только завтра) сделать два примера - синхронную отправку и асинхронную. И упростить OnTradeTransaction() - рассматривать только добавление сделки в историю - никаких ордеров, чтобы не было и близко. Но я буду делать исключительно через стандартный класс CTrade.
Кстати, на каком торговом сервере Вы экспериментируете?
В сообщениях было определённо написано Демо.
А начал разбираться с этим вопросом, потому что на реале сбои пошли.

- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Привет!
Ситуация следующая МТ5, билд 1375
Робот, в своей работе, при торговле фьючерсами, использует фунцию OrderSendAsync()
Допустим, что есть открытая позиция объёмом 2 контракта.
Посылается ордер на частичное закрытие позиции (объём 1), получая ответ от сервера
в функции OnTradeTransaction(), проверяется позиция PositionSelect(Symbol()) и берутся данные
о позиции. Так вот, достаточно часто, при исполнении ордера о частичном закрытии
позиции, при получении данных о позиции, в данных содержится информация, что
позиция не изменена (объём остаётся равнм 2).
Как построить логирование, чтобы показать разработчикам наличие ошибки?