文章 "轻松快捷开发 MetaTrader 程序的函数库(第八部分):订单和持仓修改事件" - 页 2 1234 新评论 BmC 2020.05.07 11:57 #11 Artem,再次感谢! 方法"void CEventsCollection::CreateNewEvent(COrderControl*order)"用于根据订单变化的类型创建交易事件,即创建与任何订单变化相关的事件..... 而订单变化的原因被发送到创建的事件是相同的:EVENT_REASON_STOPLIMIT_TRIGGERED。 //--- 创建一个事件 if(event!=NULL) { event.SetProperty(EVENT_PROP_TIME_EVENT,order.Time()); // 活动时间 event.SetProperty(EVENT_PROP_REASON_EVENT,EVENT_REASON_STOPLIMIT_TRIGGERED); // 事件原因(来自 ENUM_EVENT_REASON 枚举) 如果我是对的,请更正;如果不对,请解释我没有看到的地方。 非常感谢您提供的库,您多次简化了我的工作,,尤其是在主要工作与编程无关的情况下。 Artyom Trishkin 2020.05.07 18:50 #12 BmC:Artem,再次感谢! 方法"void CEventsCollection::CreateNewEvent(COrderControl*order)"用于根据订单更改类型创建交易事件,即创建与任何订单更改相关的事件.....,而订单更改的原因被发送到创建的事件是相同的:EVENT_REASON_STOPLIMIT_TRIGGERED。如果我是对的,请更正;如果不对,请解释我没有看到的地方。非常感谢您提供的库,您多次简化了我的工作,,尤其是在主要工作与编程无关的情况下。 在没有链接到引用行的确切位置的情况下,我无法理解您到底在说什么--我只是通过搜索(Shift+Ctrl+F)在所有库文件中都找不到这样的代码...... event.SetProperty(EVENT_PROP_REASON_EVENT,EVENT_REASON_STOPLIMIT_TRIGGERED); 它的位置在哪里? BmC 2020.05.07 19:30 #13 以下是本文开头部分的说明和文章末尾的代码: //+------------------------------------------------------------------+ //|| 根据订单更改类型创建交易事件 //+------------------------------------------------------------------+ void CEventsCollection::CreateNewEvent(COrderControl* order) { if(!::SymbolInfoTick(order.Symbol(),this.m_tick)) { Print(DFUN,TextByLanguage("按事件符号检索当前价格失败","Failed to get current prices by event symbol "),order.Symbol()); return; } CEvent* event=NULL; //--- 已触发挂单限价止损指令 if(order.GetChangeType()==CHANGE_TYPE_ORDER_TYPE) { this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_PLASED; event=new CEventOrderPlased(this.m_trade_event_code,order.Ticket()); } //--- 修改 else { //--- 修改挂单价格 if(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE) this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE; //--- 修改挂单价格及其止损值 else if(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE_STOP_LOSS) this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE+TRADE_EVENT_FLAG_SL; //--- 修改挂单价格及其止盈 else if(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE_TAKE_PROFIT) this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE+TRADE_EVENT_FLAG_TP; //--- 修改挂单的价格、止损和止盈 else if(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE_STOP_LOSS_TAKE_PROFIT) this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE+TRADE_EVENT_FLAG_SL+TRADE_EVENT_FLAG_TP; //--- 修改挂单止损 else if(order.GetChangeType()==CHANGE_TYPE_ORDER_STOP_LOSS) this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_SL; //--- 修改挂单的 TakeProfit else if(order.GetChangeType()==CHANGE_TYPE_ORDER_TAKE_PROFIT) this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_TP; //--- 修改挂单的止损和止盈 else if(order.GetChangeType()==CHANGE_TYPE_ORDER_STOP_LOSS_TAKE_PROFIT) this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_SL+TRADE_EVENT_FLAG_TP; //--- 修改止损位置 else if(order.GetChangeType()==CHANGE_TYPE_POSITION_STOP_LOSS) this.m_trade_event_code=TRADE_EVENT_FLAG_POSITION_MODIFY+TRADE_EVENT_FLAG_SL; //--- 修改止盈位置 else if(order.GetChangeType()==CHANGE_TYPE_POSITION_TAKE_PROFIT) this.m_trade_event_code=TRADE_EVENT_FLAG_POSITION_MODIFY+TRADE_EVENT_FLAG_TP; //--- 修改仓位的止损和止盈 else if(order.GetChangeType()==CHANGE_TYPE_POSITION_STOP_LOSS_TAKE_PROFIT) this.m_trade_event_code=TRADE_EVENT_FLAG_POSITION_MODIFY+TRADE_EVENT_FLAG_SL+TRADE_EVENT_FLAG_TP; //--- 创建修改事件 event=new CEventModify(this.m_trade_event_code,order.Ticket()); } //--- 创建一个事件 if(event!=NULL) { event.SetProperty(EVENT_PROP_TIME_EVENT,order.Time()); // 活动时间 event.SetProperty(EVENT_PROP_REASON_EVENT,EVENT_REASON_STOPLIMIT_TRIGGERED); // 事件原因(来自 ENUM_EVENT_REASON 枚举) event.SetProperty(EVENT_PROP_TYPE_DEAL_EVENT,PositionTypeByOrderType((ENUM_ORDER_TYPE)order.TypeOrderPrev())); // 订单类型,触发该类型会导致事件发生 event.SetProperty(EVENT_PROP_TICKET_DEAL_EVENT,order.Ticket()); // 触发事件的订单票号 event.SetProperty(EVENT_PROP_TYPE_ORDER_EVENT,order.TypeOrder()); // 活动订单类型 event.SetProperty(EVENT_PROP_TICKET_ORDER_EVENT,order.Ticket()); // 活动订购单 event.SetProperty(EVENT_PROP_TYPE_ORDER_POSITION,order.TypeOrder()); // 第一个位置顺序的类型 event.SetProperty(EVENT_PROP_TICKET_ORDER_POSITION,order.Ticket()); // 第一位置顺序票 event.SetProperty(EVENT_PROP_POSITION_ID,order.PositionID()); // 位置标识符 event.SetProperty(EVENT_PROP_POSITION_BY_ID,0); // 计数器位置标识符 event.SetProperty(EVENT_PROP_MAGIC_BY_ID,0); // 计数器位置的神奇数字 event.SetProperty(EVENT_PROP_TYPE_ORD_POS_BEFORE,order.TypeOrderPrev()); // 改变方向前的位置命令类型 event.SetProperty(EVENT_PROP_TICKET_ORD_POS_BEFORE,order.Ticket()); // 更改方向前的订单票位置 event.SetProperty(EVENT_PROP_TYPE_ORD_POS_CURRENT,order.TypeOrder()); // 当前位置的订单类型 event.SetProperty(EVENT_PROP_TICKET_ORD_POS_CURRENT,order.Ticket()); // 当前位置的阶次票 event.SetProperty(EVENT_PROP_PRICE_OPEN_BEFORE,order.PricePrev()); // 修改前的订单设置价格 event.SetProperty(EVENT_PROP_PRICE_SL_BEFORE,order.StopLossPrev()); // 修改前的止损价格 event.SetProperty(EVENT_PROP_PRICE_TP_BEFORE,order.TakeProfitPrev()); // 修改前的获利价格 event.SetProperty(EVENT_PROP_PRICE_EVENT_ASK,this.m_tick.ask); // 活动时的询问价格 event.SetProperty(EVENT_PROP_PRICE_EVENT_BID,this.m_tick.bid); // 活动时的竞标价格 event.SetProperty(EVENT_PROP_MAGIC_ORDER,order.Magic()); // 神奇订单号 event.SetProperty(EVENT_PROP_TIME_ORDER_POSITION,order.TimePrev()); // 第一个位置订单的时间 event.SetProperty(EVENT_PROP_PRICE_EVENT,order.PricePrev()); // 事件发生时的价格 event.SetProperty(EVENT_PROP_PRICE_OPEN,order.Price()); // 订单设置价格 event.SetProperty(EVENT_PROP_PRICE_CLOSE,order.Price()); // 订单收盘价 event.SetProperty(EVENT_PROP_PRICE_SL,order.StopLoss()); // 止损订单价格 event.SetProperty(EVENT_PROP_PRICE_TP,order.TakeProfit()); // 止盈订单的价格 event.SetProperty(EVENT_PROP_VOLUME_ORDER_INITIAL,order.Volume()); // 申请订单量 event.SetProperty(EVENT_PROP_VOLUME_ORDER_EXECUTED,0); // 已执行的订单量 event.SetProperty(EVENT_PROP_VOLUME_ORDER_CURRENT,order.Volume()); // 剩余(未执行)订单量 event.SetProperty(EVENT_PROP_VOLUME_POSITION_EXECUTED,0); // 执行位置音量 event.SetProperty(EVENT_PROP_PROFIT,0); // 利润 event.SetProperty(EVENT_PROP_SYMBOL,order.Symbol()); // 订购符号 event.SetProperty(EVENT_PROP_SYMBOL_BY_ID,order.Symbol()); // 计数器位置符号 //--- 设置控制程序的计划标识符,解码事件代码并设置事件类型 event.SetChartID(this.m_chart_id); event.SetTypeEvent(); //--- 如果事件对象不在列表中,则添加它 if(!this.IsPresentEventInList(event)) { this.m_list_trade_events.InsertSort(event); //--- 发送事件消息并设置上次交易事件的值 event.SendEvent(); this.m_trade_event=event.TradeEvent(); } //--- 如果该事件已在列表中,则删除新事件对象并显示调试信息 else { ::Print(DFUN_ERR_LINE,TextByLanguage("这样的活动已经列入清单"。,"This event is already in the list.")); delete event; } } } 下划线! BmC 2020.05.07 19:36 #14 Artyom Trishkin:在没有链接到引用行的确切位置的情况下,我无法理解您到底在说什么--仅通过搜索(Shift+Ctrl+F),我无法在所有库文件中找到这样的代码它的位置在哪里? 也许您已经在程序库说明的下几章中解决了这个问题?对我来说,您的程序库非常适合我的策略,而且我对它的理解非常透彻,因为除了程序库之外,您还提供了正确编程的方法。 Artyom Trishkin 2020.05.07 19:42 #15 BmC: 以下是本文第一部分描述中的几行,以及文章末尾的代码:在这一行下划线! 目前,在当前版本的库中,该方法看起来是这样的: //+------------------------------------------------------------------+ //|| 根据订单更改类型创建交易事件 //+------------------------------------------------------------------+ void CEventsCollection::CreateNewEvent(COrderControl* order) { ENUM_EVENT_REASON reason=WRONG_VALUE; if(!::SymbolInfoTick(order.Symbol(),this.m_tick)) { ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_NOT_GET_CURR_PRICES),order.Symbol()); return; } CEvent* event=NULL; //--- 已触发挂单限价止损指令 if(order.GetChangeType()==CHANGE_TYPE_ORDER_TYPE) { reason=EVENT_REASON_STOPLIMIT_TRIGGERED; this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_PLASED; event=new CEventOrderPlased(this.m_trade_event_code,order.Ticket()); } //--- 修改 else { //--- 修改挂单价格 if(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE) this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE; //--- 修改挂单价格及其止损值 else if(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE_STOP_LOSS) this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE+TRADE_EVENT_FLAG_SL; //--- 修改挂单价格及其止盈 else if(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE_TAKE_PROFIT) this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE+TRADE_EVENT_FLAG_TP; //--- 修改挂单的价格、止损和止盈 else if(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE_STOP_LOSS_TAKE_PROFIT) this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE+TRADE_EVENT_FLAG_SL+TRADE_EVENT_FLAG_TP; //--- 修改挂单止损 else if(order.GetChangeType()==CHANGE_TYPE_ORDER_STOP_LOSS) this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_SL; //--- 修改挂单的 TakeProfit else if(order.GetChangeType()==CHANGE_TYPE_ORDER_TAKE_PROFIT) this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_TP; //--- 修改挂单的止损和止盈 else if(order.GetChangeType()==CHANGE_TYPE_ORDER_STOP_LOSS_TAKE_PROFIT) this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_SL+TRADE_EVENT_FLAG_TP; //--- 修改止损位置 else if(order.GetChangeType()==CHANGE_TYPE_POSITION_STOP_LOSS) this.m_trade_event_code=TRADE_EVENT_FLAG_POSITION_MODIFY+TRADE_EVENT_FLAG_SL; //--- 修改止盈位置 else if(order.GetChangeType()==CHANGE_TYPE_POSITION_TAKE_PROFIT) this.m_trade_event_code=TRADE_EVENT_FLAG_POSITION_MODIFY+TRADE_EVENT_FLAG_TP; //--- 修改仓位的止损和止盈 else if(order.GetChangeType()==CHANGE_TYPE_POSITION_STOP_LOSS_TAKE_PROFIT) this.m_trade_event_code=TRADE_EVENT_FLAG_POSITION_MODIFY+TRADE_EVENT_FLAG_SL+TRADE_EVENT_FLAG_TP; //--- 创建修改事件 reason=EVENT_REASON_MODIFY; event=new CEventModify(this.m_trade_event_code,order.Ticket()); } //--- 创建一个事件 if(event!=NULL) { event.SetProperty(EVENT_PROP_TIME_EVENT,order.Time()); // 活动时间 event.SetProperty(EVENT_PROP_REASON_EVENT,reason); // 事件原因(来自 ENUM_EVENT_REASON 枚举) event.SetProperty(EVENT_PROP_TYPE_DEAL_EVENT,PositionTypeByOrderType((ENUM_ORDER_TYPE)order.TypeOrderPrev())); // 订单类型,触发该类型会导致事件发生 event.SetProperty(EVENT_PROP_TICKET_DEAL_EVENT,order.Ticket()); // 触发事件的订单票号 event.SetProperty(EVENT_PROP_TYPE_ORDER_EVENT,order.TypeOrder()); // 活动订单类型 event.SetProperty(EVENT_PROP_TICKET_ORDER_EVENT,order.Ticket()); // 活动订购单 event.SetProperty(EVENT_PROP_TYPE_ORDER_POSITION,order.TypeOrder()); // 第一个位置顺序的类型 event.SetProperty(EVENT_PROP_TICKET_ORDER_POSITION,order.Ticket()); // 第一位置顺序票 event.SetProperty(EVENT_PROP_POSITION_ID,order.PositionID()); // 位置标识符 event.SetProperty(EVENT_PROP_POSITION_BY_ID,0); // 计数器位置标识符 event.SetProperty(EVENT_PROP_MAGIC_BY_ID,0); // 计数器位置的神奇数字 event.SetProperty(EVENT_PROP_TYPE_ORD_POS_BEFORE,order.TypeOrderPrev()); // 改变方向前的位置命令类型 event.SetProperty(EVENT_PROP_TICKET_ORD_POS_BEFORE,order.Ticket()); // 更改方向前的订单票位置 event.SetProperty(EVENT_PROP_TYPE_ORD_POS_CURRENT,order.TypeOrder()); // 当前位置的订单类型 event.SetProperty(EVENT_PROP_TICKET_ORD_POS_CURRENT,order.Ticket()); // 当前位置的阶次票 event.SetProperty(EVENT_PROP_PRICE_OPEN_BEFORE,order.PricePrev()); // 修改前的订单设置价格 event.SetProperty(EVENT_PROP_PRICE_SL_BEFORE,order.StopLossPrev()); // 修改前的止损价格 event.SetProperty(EVENT_PROP_PRICE_TP_BEFORE,order.TakeProfitPrev()); // 修改前的获利价格 event.SetProperty(EVENT_PROP_PRICE_EVENT_ASK,this.m_tick.ask); // 活动时的询问价格 event.SetProperty(EVENT_PROP_PRICE_EVENT_BID,this.m_tick.bid); // 活动时的竞标价格 event.SetProperty(EVENT_PROP_MAGIC_ORDER,order.Magic()); // 神奇订单号 event.SetProperty(EVENT_PROP_TIME_ORDER_POSITION,order.TimePrev()); // 第一个位置订单的时间 event.SetProperty(EVENT_PROP_PRICE_EVENT,order.PricePrev()); // 事件发生时的价格 event.SetProperty(EVENT_PROP_PRICE_OPEN,order.Price()); // 订单设置价格 event.SetProperty(EVENT_PROP_PRICE_CLOSE,order.Price()); // 订单收盘价 event.SetProperty(EVENT_PROP_PRICE_SL,order.StopLoss()); // 止损订单价格 event.SetProperty(EVENT_PROP_PRICE_TP,order.TakeProfit()); // 止盈订单的价格 event.SetProperty(EVENT_PROP_VOLUME_ORDER_INITIAL,order.Volume()); // 申请订单量 event.SetProperty(EVENT_PROP_VOLUME_ORDER_EXECUTED,0); // 已执行的订单量 event.SetProperty(EVENT_PROP_VOLUME_ORDER_CURRENT,order.Volume()); // 剩余(未执行)订单量 event.SetProperty(EVENT_PROP_VOLUME_POSITION_EXECUTED,0); // 执行位置音量 event.SetProperty(EVENT_PROP_PROFIT,0); // 利润 event.SetProperty(EVENT_PROP_SYMBOL,order.Symbol()); // 订购符号 event.SetProperty(EVENT_PROP_SYMBOL_BY_ID,order.Symbol()); // 计数器位置符号 //--- 解码事件代码并设置事件类型 event.SetTypeEvent(); //--- 如果事件对象不在列表中,则添加它 if(!this.IsPresentEventInList(event)) { this.m_list_trade_events.InsertSort(event); //--- 发送事件消息并设置上次交易事件的值 this.m_trade_event=event.TradeEvent(); this.m_is_event=true; event.SendEvent(); CBaseObjExt::EventAdd(this.m_trade_event,order.Ticket(),order.Price(),order.Symbol()); } //--- 如果该事件已在列表中,则删除新事件对象并显示调试信息 else { ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_EVENT_ALREADY_IN_LIST)); delete event; } } } //+------------------------------------------------------------------+ 因此,要么这是一个错误,而且早就被修复了,要么在讨论的版本库中它并不重要。我不记得具体是怎样的了.... BmC 2020.05.11 16:02 #16 Artyom Trishkin:目前,在当前版本的程序库中,该方法如下所示:所以,要么这是一个错误,而且早就被修复了,要么在讨论的版本库中它并不重要。我不记得具体是怎么回事了... 这一点非常重要,从作者的角度来看更是如此。如果你没有放弃你最初的想法。帮助像我这样的程序员新手 完成工作。当你是一个初学者(学生),刚刚学习一门编程语言或一般编程时,在研究你的作品(库)时会有很多疑惑和问题。在这种情况下,我直到最后一刻才确定这到底是一个错误还是你的本意。我不止一次地阅读您的代码。对我来说,这一点非常重要:"要么我没有理解作者的意思,要么这只是作者在他的大项目中的一个错字。" 你怎么能说这不是关键呢?你这样说是不对的,你我都是在混淆读者的视听。谁会像我一样在你的图书馆里学习呢? Artyom Trishkin 2020.05.11 17:16 #17 BmC: 这一点非常重要,从作者的角度来看,这一点更为重要。如果你还没有放弃你最初的想法。帮助像我这样的程序员新手 完成工作。当你是一个初学者(学生),刚刚学习一门编程语言或一般编程时,在研究你的作品(库)时会有很多疑惑和问题。在这种情况下,我直到最后一刻才确定这到底是一个错误还是你的本意。我不止一次地阅读您的代码。对我来说,这一点非常重要:"要么我没有理解作者的意思,要么这只是作者在他的大项目中的一个错字。" 那你怎么说这不是关键呢?你这样做是不对的,因此你和我只是在混淆读者的视听。谁会像我一样在你的图书馆里学习呢? :) 我给你看了代码,用颜色标出了更正。把它们放到本文所附的版本库中。 当然,我不记得这是否是我的错误,或者在这个版本中它并不重要,因此在调试过程中被我忽略了。毕竟,这已经是四十多篇文章了,而这篇文章已经过去很久了。很有可能是一个错误,在后续的文章中得到了修正--库中的很多东西都是即时创建的。当然,库中也有测试版本,而且不止一个。但是,自从开始描述其创建过程以来,又有许多内容被修改和添加。这就是为什么这一系列文章被定位为对程序库创建过程的描述。通过这种方式,我试图让读者参与到图书馆的创建过程中。通过试验和错误,以及如何解决这些问题的指导--让整个过程清晰可见--可以说是揭示 "创作的所有痛苦":):) 因此,如果您在理解上有任何困惑,我深表歉意.....。 请按照上面的建议进行修改。或者留到文章中再修改。 Andrii Miknevich 2021.01.17 13:06 #18 我想获得最后一个事件的符号、票据和类型(打开、关闭、修改),如何正确操作? Alexey Viktorov 2021.01.18 20:22 #19 Andrii Miknevich: 我想获得最后一个事件的符号、票据和类型(打开、关闭、修改),如何正确操作? 我发现 Artyom 忙得根本不在论坛上露面。))))))))也许我可以给你一个提示,我曾经用他的库做过实验。今天,我通过这些实验找到了这样一个函数。评论中说,该函数可以获取所有空缺职位 的列表。 void OrderActivated() { Print(__FUNCTION__, "***", ENUM_TRADE_EVENT(engine.LastTradeEvent())); //---获取所有空缺职位列表 CArrayObj* list = engine.GetListMarketPosition(); if(list == NULL || list.Total() == 0) return; int index = CSelect::FindOrderMax(list, ORDER_PROP_TIME_OPEN); COrder *pos = list.At(index); if(pos == NULL) return; pos.Print(); }/*******************************************************************/ 不幸的是,我无法解释它的用途,我已经忘得一干二净了,但也许你能想出来....。 好吧......如果你不能,那就等等。Artem 会抽出时间回复您的。 leonerd 2021.02.06 15:58 #20 当收到一个 tick 时,挂单 被设置并同时激活(触发)(我用 Buy Stop 测试过),您的引擎不会记录所有事件...收到 TRADE_EVENT_PENDING_ORDER_PLASED 事件,但没有收到 TRADE_EVENT_PENDING_ORDER_ACTIVATED。我的代码如下//+------------------------------------------------------------------+ //| 处理贸易事件| //+------------------------------------------------------------------+ void ProcessTradeEvents(void) { static ENUM_TRADE_EVENT last_event=WRONG_VALUE; static CEvent *last_processed=NULL; if(engine.LastTradeEvent()!=last_event) { if(last_event==TRADE_EVENT_NO_EVENT) return; CArrayObj *list=engine.GetListAllOrdersEvents(); if(list==NULL) return; list=CSelect::ByEventProperty(list,EVENT_PROP_SYMBOL,Symbol(),EQUAL); if(list==NULL || list.Total()<=0) return; last_event=engine.LastTradeEvent(); //--- 获取旧事件的索引 int index_of_old_event=0; if(last_processed==NULL) index_of_old_event=-1; else { for(int i=list.Total()-1;i>=0;i--) { CEvent *event=list.At(i); if(event==NULL) return; ENUM_TRADE_EVENT event_type=event.TypeEvent(); if(last_processed!=NULL && event.IsEqual(last_processed)) { index_of_old_event=i; break; } } } //--- 检查所有新事件 for(int i=index_of_old_event+1;i<list.Total();i++) { CEvent *event=list.At(i); if(event==NULL) break; if(last_processed!=NULL && event.IsEqual(last_processed)) break; Print(__FUNCTION__+": event : ",event.TypeEventDescription()); switch(event.TypeEvent()) { case TRADE_EVENT_PENDING_ORDER_PLASED: { // 一些代码 } break; case TRADE_EVENT_PENDING_ORDER_REMOVED: { // 一些代码 } break; case TRADE_EVENT_PENDING_ORDER_ACTIVATED: { // 一些代码 } break; case TRADE_EVENT_POSITION_CLOSED: { // 一些代码 } break; case TRADE_EVENT_POSITION_CLOSED_BY_SL: { // 一些代码 } break; case TRADE_EVENT_POSITION_CLOSED_BY_TP: { // 一些代码 } break; case TRADE_EVENT_MODIFY_ORDER_PRICE: { // 一些代码 } break; case TRADE_EVENT_MODIFY_POSITION_SL: { // 一些代码 } break; case TRADE_EVENT_MODIFY_POSITION_TP: { // 一些代码 } break; } } last_processed=list.At(list.Total()-1); Comment("\nLast trade event: ",last_processed.TypeEventDescription()); } }我首先在循环中找到旧(已处理)事件的索引,然后从该索引开始,循环处理所有新事件,直到结束。因此,如果在一个刻度上设置了限价订单,而 striggeren 收到了一个关于设置的事件,那么......请发表评论。 我在 engine.OnTick(rates_data) 之后的 OnTick() 中调用 ProcessTradeEvents()。 Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Свойства ордеров www.mql5.com Свойства ордеров - Торговые константы - Константы, перечисления и структуры - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5 1234 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
Artem,再次感谢!
方法"void CEventsCollection::CreateNewEvent(COrderControl*order)"用于根据订单变化的类型创建交易事件,即创建与任何订单变化相关的事件.....
而订单变化的原因被发送到创建的事件是相同的:EVENT_REASON_STOPLIMIT_TRIGGERED。
如果我是对的,请更正;如果不对,请解释我没有看到的地方。
非常感谢您提供的库,您多次简化了我的工作,
,尤其是在主要工作与编程无关的情况下。
Artem,再次感谢!
方法"void CEventsCollection::CreateNewEvent(COrderControl*order)"用于根据订单更改类型创建交易事件,即创建与任何订单更改相关的事件.....
,而订单更改的原因被发送到创建的事件是相同的:EVENT_REASON_STOPLIMIT_TRIGGERED。
如果我是对的,请更正;如果不对,请解释我没有看到的地方。
非常感谢您提供的库,您多次简化了我的工作,
,尤其是在主要工作与编程无关的情况下。
在没有链接到引用行的确切位置的情况下,我无法理解您到底在说什么--我只是通过搜索(Shift+Ctrl+F)在所有库文件中都找不到这样的代码......
event.SetProperty(EVENT_PROP_REASON_EVENT,EVENT_REASON_STOPLIMIT_TRIGGERED);它的位置在哪里?
在没有链接到引用行的确切位置的情况下,我无法理解您到底在说什么--仅通过搜索(Shift+Ctrl+F),我无法在所有库文件中找到这样的代码
它的位置在哪里?
以下是本文第一部分描述中的几行,以及文章末尾的代码:在这一行下划线!
目前,在当前版本的库中,该方法看起来是这样的:
因此,要么这是一个错误,而且早就被修复了,要么在讨论的版本库中它并不重要。我不记得具体是怎样的了....
目前,在当前版本的程序库中,该方法如下所示:
所以,要么这是一个错误,而且早就被修复了,要么在讨论的版本库中它并不重要。我不记得具体是怎么回事了...
这一点非常重要,从作者的角度来看更是如此。如果你没有放弃你最初的想法。帮助像我这样的程序员新手 完成工作。当你是一个初学者(学生),刚刚学习一门编程语言或一般编程时,在研究你的作品(库)时会有很多疑惑和问题。在这种情况下,我直到最后一刻才确定这到底是一个错误还是你的本意。我不止一次地阅读您的代码。对我来说,这一点非常重要:"要么我没有理解作者的意思,要么这只是作者在他的大项目中的一个错字。"
你怎么能说这不是关键呢?你这样说是不对的,你我都是在混淆读者的视听。谁会像我一样在你的图书馆里学习呢?
这一点非常重要,从作者的角度来看,这一点更为重要。如果你还没有放弃你最初的想法。帮助像我这样的程序员新手 完成工作。当你是一个初学者(学生),刚刚学习一门编程语言或一般编程时,在研究你的作品(库)时会有很多疑惑和问题。在这种情况下,我直到最后一刻才确定这到底是一个错误还是你的本意。我不止一次地阅读您的代码。对我来说,这一点非常重要:"要么我没有理解作者的意思,要么这只是作者在他的大项目中的一个错字。"
那你怎么说这不是关键呢?你这样做是不对的,因此你和我只是在混淆读者的视听。谁会像我一样在你的图书馆里学习呢?
:)
我给你看了代码,用颜色标出了更正。把它们放到本文所附的版本库中。
当然,我不记得这是否是我的错误,或者在这个版本中它并不重要,因此在调试过程中被我忽略了。毕竟,这已经是四十多篇文章了,而这篇文章已经过去很久了。很有可能是一个错误,在后续的文章中得到了修正--库中的很多东西都是即时创建的。当然,库中也有测试版本,而且不止一个。但是,自从开始描述其创建过程以来,又有许多内容被修改和添加。这就是为什么这一系列文章被定位为对程序库创建过程的描述。通过这种方式,我试图让读者参与到图书馆的创建过程中。通过试验和错误,以及如何解决这些问题的指导--让整个过程清晰可见--可以说是揭示 "创作的所有痛苦":):)
因此,如果您在理解上有任何困惑,我深表歉意.....。
请按照上面的建议进行修改。或者留到文章中再修改。
我想获得最后一个事件的符号、票据和类型(打开、关闭、修改),如何正确操作?
我发现 Artyom 忙得根本不在论坛上露面。))))))))也许我可以给你一个提示,我曾经用他的库做过实验。今天,我通过这些实验找到了这样一个函数。评论中说,该函数可以获取所有空缺职位 的列表。
不幸的是,我无法解释它的用途,我已经忘得一干二净了,但也许你能想出来....。
好吧......如果你不能,那就等等。Artem 会抽出时间回复您的。
当收到一个 tick 时,挂单 被设置并同时激活(触发)(我用 Buy Stop 测试过),您的引擎不会记录所有事件...
收到 TRADE_EVENT_PENDING_ORDER_PLASED 事件,但没有收到 TRADE_EVENT_PENDING_ORDER_ACTIVATED。
我的代码如下
我首先在循环中找到旧(已处理)事件的索引,然后从该索引开始,循环处理所有新事件,直到结束。因此,如果在一个刻度上设置了限价订单,而 striggeren 收到了一个关于设置的事件,那么......请发表评论。
我在 engine.OnTick(rates_data) 之后的 OnTick() 中调用 ProcessTradeEvents()。