内容提要
- 概述
- COrder
- CStop
- CStops
- COrderStop
- COrderStops
- 停止位的图表表达
- 检查订单停止位
- 示例
- 结束语
- 文章中使用的程序
- 文章中列出的类文件
概述
如前一篇文章中所讨论的那样, 对于跨平台智能交易系统, 我们已创建了一个订单管理器 (COrderManager), 它负责处理 MQL4 和 MQL5 之间交易入场和离场的大部分差异。在两个版本中, 智能交易系统通过创建 COrder 的实例将交易信息保存在内存中。这些类对象实例的动态指针容器也可作为 COrderManager 的类成员 (当前和历史交易均可)。
订单管理器能够直接处理每笔交易的停止价位。但是, 这样做会有一些限制:
- COrderManager 有很大可能需要扩展, 以便能够定制如何处理每笔交易的停止价位。
- COrderManager 的现有方法只能处理主要交易的入场。
可以扩展 COrderManager, 以便它可以自行处理每笔交易的停止价位。不过, 这不仅限于实际价位的设置, 还涉及有关停止位监控的其它任务, 诸如修改和检查行情是否已触及预定价位。这些功能将致 COrderManager 更复杂, 而目前并未提及如何拆分实现它。
订单管理器仅处理主要交易的入场, 而 EA 执行其它交易操作时会需要一些停止价位, 例如放置挂单, 以及真实仓位的平仓。虽然订单管理器可以自行处理它, 但最好将其重点放在主要交易的入场上, 并让另一个类对象处理停止价位。
在本文中, 我们将研讨具体实现, 其中 COrderManager 将专门处理主要交易 (目前为止) 的入场和离场, 然后由另一个单独的类对象 (CStop) 处理停止价位的实施。
COrder
正如我们从前一篇文章 (参见 跨平台智能交易系统: 订单) 中了解到的那样, 在交易操作 (入场) 成功之后创建了一个 COrder 实例。对于 MetaTrader 4 和 MetaTrader 5, 关于止损和止盈的信息可以从经纪商的后台获取并保存。然而, 如果要对经纪商隐藏停止位或涉及多个停止位的情况下, 关于这些停止位的更多信息就应该被保存在本地。因此, 在后一种情况下, 在仓位成功入场后, 应首先创建 COrder 实例, 随后是代表其止损和止盈价位的对象实例。在早前的文章中, 我们已演示了如何在创建时将 COrder 实例添加到订单管理器中, 正如下图所示:
停止价位以相同的方式添加。为此, 我们只需要在创建新的 COrder 实例之后, 并在将其添加到进行中交易列表 (COrders) 之前插入该方法。因此, 我们只需稍微修改以上示意图, 如下图所示:
创建停止价位的一般操作如下图所示:
如前面两个流程图所示, 一旦交易成功入场, 将会创建一个新的 COrder 实例来表示它。此后, 将为每个已定义的止损和止盈价位创建 COrderStop 的实例。如果在智能交易系统的初始化中没有声明 CStop 实例, 则会跳过这一特定过程。另一方面, 如果创建了 COrderStop 的实例, 那么这些实例的指针将被存储在早前创建的 COrder 实例中。我们可以在 COrder 的 Init 方法中找到这个操作:
bool COrderBase::Init(COrders *orders,CStops *stops) { if(CheckPointer(orders)) SetContainer(GetPointer(orders)); if(CheckPointer(stops)) CreateStops(GetPointer(stops)); m_order_stops.SetContainer(GetPointer(this)); return true; }
为了给 COrder 实例创建停止价位, 我们可以看到它调用了自身的 CreateStops 方法, 如下所示:
void COrderBase::CreateStops(CStops *stops) { if(!CheckPointer(stops)) return; if(stops.Total()>0) { for(int i=0;i<stops.Total();i++) { CStop *stop=stops.At(i); if(CheckPointer(stop)==POINTER_INVALID) continue; m_order_stops.NewOrderStop(GetPointer(this),stop); } } }该方法遍历 CStop 的所有可用实例, 该实例代表每对止损和止盈价位。这些 CStop 实例中的每一个都传递给 COrderStops 的实例, 其中 COrderStops 只是所有给定顺序的停止价位的容器。然后, 我们可以如下构造类对象的层次结构:
对于 COrder 的每个实例, 都有一个类型为 COrderStops 的成员。这个 COrderStops 实例是一个容器 (CArrayObj 的扩展), 它包含指向 COrderStop 实例的指针。每个 COrderStop 实例代表该特定交易 (COrder 实例) 的停止价位 (CStop)。
CStop
如前所述, 我们希望有一定的自由度来定制每笔交易的停止价位如何处理, 而无需修改订单管理器的源代码。这主要是由 CStop 类完成的。当中这个类的职责是:
- 定义止损和止盈价位
- 执行计算停止价位所需的计算
- 主要交易的止损和止盈价位实现
- 检查是否已触发停止价位
- 调整 MQL4 和 MQL5 之间实现止损和止盈价位的差异
- 定义如何随时间处理停止位 (例如, 盈亏平衡, 尾随等)
指针 #1-#5 将在本文中讨论, 而 #6 将在单独一篇文章中讨论。
类型
本文将讨论三种类型的停止位:
- 经纪商端停止位 – 停止位与交易请求一起发送给经纪商
- 挂单停止位 – 使用挂单作为停止位将令主仓位部分平仓或全部反向对冲平仓 (MetaTrader 4, MetaTrader 5 的对冲模式), 或从主仓位中相减 (MetaTrader 5 净持模式)。
- 虚拟停止位 (隐形停止位) – 对经纪商隐藏停止位, 由智能交易系统在本地进行管理。
在 MetaTrader 4 中, 经纪商端停止位是交易者最熟悉的止损和止盈。这些价格或停止价位与主要交易一起发送给经纪商。MetaTrader 5 版本的对冲模式使用与 MetaTrader 4 版本相同的机制。另一方面, 对于净持模式, 由于止损和止盈与 MT4 不同 (应用于品种或金融工具的整体持仓), 因此 CStop 将使用挂单停止位。
挂单停止位使用挂单以某种方式模拟经纪商端停止位。一旦挂单执行, EA 将执行交易操作 (OrderCloseBy) 以便用刚触发的挂单交易量来为主仓位平仓。对于 MetaTrader 4 和 MetaTrader 5 版本的对冲模式, 这是正确的。对于 MetaTrader 5 版本的净持模式, 主仓位的部分或全部仓量自动完成离场, 因为每个品种在任何给定时间只能保留一笔持仓。
主要停止位
主要停止位是触发整体仓位退出的停止价位。通常, 这是经纪商端的停止位。当经纪商端的止损或止盈触发时, 整体持仓离场, 无论 EA 是否打算为此进一步操作。然而, 如果有多个停止价位, 且无经纪商端的停止位, 那么让 EA 决定哪个是主要停止位可能是一个坏主意。在这种情况下, 程序员必须选择哪个 CStop 实例是交易的主要停止位。这对于某些依赖仓位的主要停止位的功能和特性尤为有用, 例如资金管理。由于主要停止位的止损会导致整体持仓的离场, 它代表入场交易的最大风险。已知主要停止位的实例, EA 将能够相应地计算手数。
值得注意的是, 当一个停止位被指定为主要停止位时, 其交易量将始终等于主要交易的初始交易量。对于经纪商端和虚拟停止位这将工作良好, 但不适用在基于挂单的停止位。有两个关联的问题会引出这种方法。
第一个原因是在 MetaTrader 4 中, 在挂单尚未触发前可以修改入场价格。在 MetaTrader 5 中, 这是不可能的, 因为必须维护交易操作的清晰足迹。必须放出新的挂单, 如果成功, 应删除旧订单, 然后智能交易系统应使用新挂单作为新的停止价位。
第二个问题是给经纪商发送替换挂单时, 旧的挂单可能被同时触发。由于 EA 对触发挂单没有控制权 (只有经纪商可以), 这会导致诸如孤立交易或一个停止价位超预期将更多持仓平仓等问题。
为了避免这些问题, 更简单的方法是在交易创建时分配挂单的交易量, 而非在主要交易的整个生存期内动态调整挂单的交易量。不过, 这就要求如果主停止位为挂单类型, 则不应有其它挂单停止位。
交易量
对于主停止位, 无需分配从主持仓扣除的手数, 一旦触发, 整体持仓应平仓。然而, 对于其它类型的停止价位, 必须考虑交易量, 因为它们通常仅用于主持仓的部分平仓。分配划分为四种不同类型:
- 固定 – 固定手数
- 剩余百分比 – 主要交易的剩余手数百分比
- 总体百分比 – 主要交易总手数 (初始交易量) 的百分比
- 剩余 – 主要交易的剩余交易量。
固定手数是最简单的交易量分配形式。然而, 如果智能交易系统为每笔仓位使用某种形式的动态手数计算, 那么这就不是最优操作。仅当智能交易系统在整个操作期间使用固定手数时, 才是理想的。
剩余百分比和剩余最好在主停止位为虚拟时使用。剩余将防止 EA 创建孤立交易, 譬如依据未平仓交易量或执行平仓的交易量大于主交易剩余交易量时。另一方面, 当智能交易系统并非基于初始交易量, 而是根据主交易当前剩余交易量进行平仓时, 使用剩余百分比。
总计百分比可用于经纪商端, 虚拟和挂单停止位。使用此方法计算是基于主要交易的初始交易量。
一键取消其它 (OCO)
CStop 始终表达为一对数值, 每个数值表示止损或止盈。然而, 若其中任一值置为零, 可以实现单侧价位 (有止盈无止损, 反之亦然)。省缺情况下, 一个停止价位在被触发时, 关闭其它。唯一的例外是当 CStop 实例是主要停止位。
基类
CStop (CStopBase) 的基类显示在以下代码中:
class CStopBase : public CObject { protected: //--- 停止订单参数 bool m_active; bool m_main; string m_name; bool m_oco; double m_stoploss; string m_stoploss_name; ENUM_STOP_TYPE m_stop_type; double m_takeprofit; string m_takeprofit_name; int m_delay; //--- 停止订单交易参数 ENUM_VOLUME_TYPE m_volume_type; double m_volume; int m_magic; int m_deviation; string m_comment; //--- 停止订单对象参数 bool m_entry_visible; bool m_stoploss_visible; bool m_takeprofit_visible; color m_entry_color; color m_stoploss_color; color m_takeprofit_color; ENUM_LINE_STYLE m_entry_style; ENUM_LINE_STYLE m_stoploss_style; ENUM_LINE_STYLE m_takeprofit_style; //--- 对象 CSymbolManager *m_symbol_man; CSymbolInfo *m_symbol; CAccountInfo *m_account; CTradeManager m_trade_man; CExpertTradeX *m_trade; CTrails *m_trails; CEventAggregator *m_event_man; CStops *m_stops; public: CStopBase(void); ~CStopBase(void); virtual int Type(void) const {return CLASS_TYPE_STOP;} //--- 初始化 virtual bool Init(CSymbolManager*,CAccountInfo*,CEventAggregator*); virtual bool InitAccount(CAccountInfo*); virtual bool InitEvent(CEventAggregator*); virtual bool InitSymbol(CSymbolManager*); virtual bool InitTrade(void); virtual CStops *GetContainer(void); virtual void SetContainer(CStops*); virtual bool Validate(void) const; //--- 取值和赋值 bool Active(void); void Active(const bool); bool Broker(void) const; void Comment(const string); string Comment(void) const; void Delay(int delay); int Delay(void) const; void SetDeviation(const int); int SetDeviation(void) const; void EntryColor(const color clr); void EntryStyle(const ENUM_LINE_STYLE); void EntryVisible(const bool); bool EntryVisible(void) const; void Magic(const int); int Magic(void) const; void Main(const bool); bool Main(void) const; void Name(const string); string Name(void) const; void OCO(const bool oco); bool OCO(void) const; bool Pending(void) const; void StopLoss(const double); double StopLoss(void) const; void StopLossColor(const color); bool StopLossCustom(void); void StopLossName(const string); string StopLossName(void) const; void StopLossVisible(const bool); bool StopLossVisible(void) const; void StopLossStyle(const ENUM_LINE_STYLE); void StopType(const ENUM_STOP_TYPE); ENUM_STOP_TYPE StopType(void) const; string SymbolName(void); void TakeProfit(const double); double TakeProfit(void) const; void TakeProfitColor(const color); bool TakeProfitCustom(void); void TakeProfitName(const string); string TakeProfitName(void) const; void TakeProfitStyle(const ENUM_LINE_STYLE); void TakeProfitVisible(const bool); bool TakeProfitVisible(void) const; bool Virtual(void) const; void Volume(double); double Volume(void) const; void VolumeType(const ENUM_VOLUME_TYPE); ENUM_VOLUME_TYPE VolumeType(void) const; //--- 停止订单检查 virtual bool CheckStopLoss(COrder*,COrderStop*); virtual bool CheckTakeProfit(COrder*,COrderStop*); virtual bool CheckStopOrder(ENUM_STOP_MODE,COrder*,COrderStop*)=0; virtual bool DeleteStopOrder(const ulong)=0; virtual bool DeleteMarketStop(const ulong)=0; virtual bool OrderModify(const ulong,const double); //--- 停止订单对象创建 virtual CStopLine *CreateEntryObject(const long,const string,const int,const double); virtual CStopLine *CreateStopLossObject(const long,const string,const int,const double); virtual CStopLine *CreateTakeProfitObject(const long,const string,const int,const double); //--- 停止订单价格计算 virtual bool Refresh(const string); virtual double StopLossCalculate(const string,const ENUM_ORDER_TYPE,const double); virtual double StopLossCustom(const string,const ENUM_ORDER_TYPE,const double); virtual double StopLossPrice(COrder*,COrderStop*); virtual double StopLossTicks(const ENUM_ORDER_TYPE,const double); virtual double TakeProfitCalculate(const string,const ENUM_ORDER_TYPE,const double); virtual double TakeProfitCustom(const string,const ENUM_ORDER_TYPE,const double); virtual double TakeProfitPrice(COrder*,COrderStop*); virtual double TakeProfitTicks(const ENUM_ORDER_TYPE,const double); //--- 尾随 virtual bool Add(CTrails*); virtual double CheckTrailing(const string,const ENUM_ORDER_TYPE,const double,const double,const ENUM_TRAIL_TARGET); protected: //--- 对象创建 virtual CStopLine *CreateObject(const long,const string,const int,const double); //--- 停止订单价格计算 virtual double LotSizeCalculate(COrder*,COrderStop*); //--- 停止订单入场 virtual bool GetClosePrice(const string,const ENUM_ORDER_TYPE,double&); //--- 停止订单离场 virtual bool CloseStop(COrder*,COrderStop*,const double)=0; //--- 逆初始化 virtual void Deinit(void); virtual void DeinitSymbol(void); virtual void DeinitTrade(void); virtual void DeinitTrails(void); };
对于基于点值或点数的止损和止盈价位, 至少需要记住四个类方法:
- 停止位类型 (经纪商端, 挂单或虚拟), 使用 StopType 方法
- 所用的交易量计算类型, 使用 VolumeType 方法
- 以点数为止损价位 (每当需要时), 使用 StopLoss 方法
- 以点数为止盈价位 (每当需要时), 使用 TakeProfit 方法
所有这些仅仅是类成员的赋值器, 所以没有必要详细说明这些方法。其余的大部分方法仅在类的内部计算中才需要。这些受保护方法当中最重要的是 StopLossCalculate 和 TakeProfitCalculate 方法, 其代码如下所示:
double CStopBase::StopLossCalculate(const string symbol,const ENUM_ORDER_TYPE type,const double price) { if(!Refresh(symbol)) return 0; if(type==ORDER_TYPE_BUY || type==ORDER_TYPE_BUY_STOP || type==ORDER_TYPE_BUY_LIMIT) return price-m_stoploss*m_symbol.Point(); else if(type==ORDER_TYPE_SELL || type==ORDER_TYPE_SELL_STOP || type==ORDER_TYPE_SELL_LIMIT) return price+m_stoploss*m_symbol.Point(); return 0; } double CStopBase::TakeProfitCalculate(const string symbol,const ENUM_ORDER_TYPE type,const double price) { if(!Refresh(symbol)) return 0; if(type==ORDER_TYPE_BUY || type==ORDER_TYPE_BUY_STOP || type==ORDER_TYPE_BUY_LIMIT) return price+m_takeprofit*m_symbol.Point(); else if(type==ORDER_TYPE_SELL || type==ORDER_TYPE_SELL_STOP || type==ORDER_TYPE_SELL_LIMIT) return price-m_takeprofit*m_symbol.Point(); return 0; }
这两种方法都取三个参数, 所有这些都与主要交易有关。该方法首先通过 Refresh 方法刷新品种, 该方法简单地更新要用到的品种管理器。一旦品种被刷新, 它将基于初始化期间提供给类实例的点数值返回止损或止盈价位。
CStops
CStops 类将作为 CStop 实例的容器。该类的实例必须作为其成员之一动态添加到订单管理器。以下代码显示了 CStopsBase, 它是 CStops 的基类:
class CStopsBase : public CArrayObj { protected: bool m_active; CEventAggregator *m_event_man; CObject *m_container; public: CStopsBase(void); ~CStopsBase(void); virtual int Type(void) const {return CLASS_TYPE_STOPS;} //--- 初始化 virtual bool Init(CSymbolManager*,CAccountInfo*,CEventAggregator*); virtual CObject *GetContainer(void); virtual void SetContainer(CObject*); virtual bool Validate(void) const; //--- 赋值和取值 virtual bool Active(void) const; virtual void Active(const bool); virtual CStop *Main(void); //--- 复原 virtual bool CreateElement(const int); };
这个类与本文中迄今为止描述的其它容器非常相似。
COrderStop
COrderStop 表示特定交易的 CStop 的实现。对于给定的仓位, CStop 最多可以创建一个 COrderStop。但是, 任意数量的 COrderStop 实例可以共享相同的 CStop 实例。因此, 如果智能交易系统有 3 个不同的 CStop 实例, 通常我们希望每个COrder 实例具有相同数量的 COrderStop 实例。如果智能交易系统已经进行了 1000 笔交易, 则创建的 COrderStop 实例数量将为 1000 * 3 = 3000, 而创建的 CStop 实例数仍为 3。
COrderStop 基于 COrderStopBase 的定义如下所示:
class COrderStopBase : public CObject { protected: bool m_active; //--- 停止位参数 double m_volume; CArrayDouble m_stoploss; CArrayDouble m_takeprofit; ulong m_stoploss_ticket; ulong m_takeprofit_ticket; bool m_stoploss_closed; bool m_takeprofit_closed; bool m_closed; ENUM_STOP_TYPE m_stop_type; string m_stop_name; //--- 主订单对象 COrder *m_order; //--- 停止位对象 CStop *m_stop; CStopLine *m_objentry; CStopLine *m_objsl; CStopLine *m_objtp; COrderStops *m_order_stops; public: COrderStopBase(void); ~COrderStopBase(void); virtual int Type(void) const {return CLASS_TYPE_ORDERSTOP;} //--- 初始化 virtual void Init(COrder*,CStop*,COrderStops*); virtual COrderStops *GetContainer(void); virtual void SetContainer(COrderStops*); virtual void Show(bool); //--- 取值和赋值 bool Active(void) const; void Active(bool active); string EntryName(void) const; ulong MainMagic(void) const; ulong MainTicket(void) const; double MainTicketPrice(void) const; ENUM_ORDER_TYPE MainTicketType(void) const; COrder *Order(void); void Order(COrder*); CStop *Stop(void); void Stop(CStop*); bool StopLoss(const double); double StopLoss(void) const; double StopLoss(const int); void StopLossClosed(const bool); bool StopLossClosed(void); double StopLossLast(void) const; string StopLossName(void) const; void StopLossTicket(const ulong); ulong StopLossTicket(void) const; void StopName(const string); string StopName(void) const; bool TakeProfit(const double); double TakeProfit(void) const; double TakeProfit(const int); void TakeProfitClosed(const bool); bool TakeProfitClosed(void); double TakeProfitLast(void) const; string TakeProfitName(void) const; void TakeProfitTicket(const ulong); ulong TakeProfitTicket(void) const; void Volume(const double); double Volume(void) const; //--- 检查 virtual void Check(double&)=0; virtual bool Close(void); virtual bool CheckTrailing(void); virtual bool DeleteChartObject(const string); virtual bool DeleteEntry(void); virtual bool DeleteStopLines(void); virtual bool DeleteStopLoss(void); virtual bool DeleteTakeProfit(void); virtual bool IsClosed(void); virtual bool Update(void) {return true;} virtual void UpdateVolume(double) {} //--- 逆初始化 virtual void Deinit(void); //--- 复原 virtual bool Save(const int); virtual bool Load(const int); virtual void Recreate(void); protected: virtual bool IsStopLossValid(const double) const; virtual bool IsTakeProfitValid(const double) const; virtual bool Modify(const double,const double); virtual bool ModifyStops(const double,const double); virtual bool ModifyStopLoss(const double) {return true;} virtual bool ModifyTakeProfit(const double){return true;} virtual bool UpdateOrderStop(const double,const double){return true;} virtual bool MoveStopLoss(const double); virtual bool MoveTakeProfit(const double); };
COrderStop 包含在 COrderStops 中 (将在下一节中讨论), COrderStop 则由 COrder 包含。在 EA 的实际开发中, 不需要再声明一个 COrderStop 的实例。这是由 COrder 根据 CStop 的特定实例自动创建的。
COrderStops
class COrderStopsBase : public CArrayObj { protected: bool m_active; CArrayInt m_types; COrder *m_order; public: COrderStopsBase(void); ~COrderStopsBase(void); virtual int Type(void) const {return CLASS_TYPE_ORDERSTOPS;} void Active(bool); bool Active(void) const; //--- 初始化 virtual CObject *GetContainer(void); virtual void SetContainer(COrder*); virtual bool NewOrderStop(COrder*,CStop*)=0; //--- 检查 virtual void Check(double &volume); virtual bool CheckNewTicket(COrderStop*); virtual bool Close(void); virtual void UpdateVolume(const double) {} //--- 隐藏和显示停止位指示线 virtual void Show(const bool); //--- 复原 virtual bool CreateElement(const int); virtual bool Save(const int); virtual bool Load(const int); };
就像 CStop, 这看起来只是一个典型的容器。不过, 它包含了一些方法来镜像对象方法, 其指针用于存储 (COrderStop)。
停止位的图表表达
CStopLine 是 CStop 的类成员, 其主要职责是在图表上表述停止价位的图形。在智能交易系统中有三个核心函数:
- 在 COrder 实例初始化时显示停止价位
- 在更改其中一个或两个停止价位的情况下在事件中更新停止价位
- 一旦主要交易离场, 立即删除停止位指示线
所有这些函数都通过 CStop 类实现。
作为 CStopLine 基类的 CStopLineBase 定义如下所示:
class CStopLineBase : public CChartObjectHLine { protected: bool m_active; CStop *m_stop; public: CStopLineBase(void); ~CStopLineBase(void); virtual int Type(void) const {return CLASS_TYPE_STOPLINE;} virtual void SetContainer(CStop*); virtual CStop *GetContainer(void); bool Active(void) const; void Active(const bool); virtual bool ChartObjectExists(void) const; virtual double GetPrice(const int); virtual bool Move(const double); virtual bool SetStyle(const ENUM_LINE_STYLE); virtual bool SetColor(const color); };
在旧版本的 MetaTrader 4 中, 止损和止盈价位不能通过拖动进行修改。这些价位必须通过订单窗口或通过智能交易系统和脚本进行修改。然而, 显示这些价位的图形表述可能仍然有用, 特别是在处理虚拟停止位时。
检查订单停止位
对于给定仓位成功创建停止价位之后, 下一步将是检查行情是否达到给定的停止价位。对于经纪商端的停止位, 该过程不是必需的, 因为平仓操作在服务器端完成。然而, 对于虚拟和挂单停止位, 在大多数情况下, 由智能交易系统自身执行平仓操作。
对于虚拟停止位, 智能交易系统完全负责监控行情走势, 并检查行情是否达到给定停止价位。以下示意图展现了一般操作。一旦行情触及停止价位, 智能交易系统就会执行相应的平仓操作。
对于挂单停止位, 该过程稍微复杂一点。被触发的停止价位将导致挂单被触发, 即变为一笔持仓。这在经纪商一端自动完成。因此, 智能交易系统有责任检测给定的挂单是否仍在等待或已经入场。如果挂单已经被触发, 那么智能交易系统负责按照刚触发的挂单交易量将主要仓位平仓 - 一笔交易通过操作平仓。
在所有情况下, 一旦给定的订单停止价位被触发, 停止价位被标记为关闭。这是为了防止给定的停止价位被执行一次以上。
示例
示例 #1: 使用 Heiken Ashi 和移动平均线的 EA, 具有单一停止价位 (主要停止位)
在大多数智能交易系统中, 一个止损和一个止盈通常就足够了。我们现在将扩展前一篇文章中的示例 (请参阅 跨平台智能交易系统: 时间过滤器), 在源代码当中添加止损和止盈。为此, 我们首先创建一个新的容器实例 (CStops)。然后创建一个 CStop 的实例, 然后将其指针添加到容器。之后, 最终将指向容器的指针添加到订单管理器中。代码如下所示:
int OnInit() { //--- 其它代码 CStops *stops=new CStops(); CStop *main=new CStop("main"); main.StopType(stop_type_main); main.VolumeType(VOLUME_TYPE_PERCENT_TOTAL); main.Main(true); main.StopLoss(stop_loss); main.TakeProfit(take_profit); stops.Add(GetPointer(main)); order_manager.AddStops(GetPointer(stops)); //--- 其它代码 }
在 MetaTrader 4 上测试经纪商端停止位, 结果如下表所示。这就是交易者通常期望的由平台上的智能交易系统执行的交易。
# | 时间 | 类型 | 订单 | 手数 | 价格 | 止损 | 止盈 | 盈利 | 余额 |
1 | 2017.01.03 10:00 | sell | 1 | 0.30 | 1.04597 | 1.05097 | 1.04097 | ||
2 | 2017.01.03 11:34 | t/p | 1 | 0.30 | 1.04097 | 1.05097 | 1.04097 | 150.00 | 3150.00 |
3 | 2017.01.05 11:00 | sell | 2 | 0.30 | 1.05149 | 1.05649 | 1.04649 | ||
4 | 2017.01.05 17:28 | s/l | 2 | 0.30 | 1.05649 | 1.05649 | 1.04649 | -150.00 | 3000.00 |
对于挂单停止位, 停止位预先放置在标准止损/止盈中, 不过是以挂单的形式。一旦挂单被触发, 智能交易系统将执行一个平仓操作, 依据触发的挂单交易量将主交易平仓。然而, 与标准止损/止盈不同, 智能交易系统在客户端执行此操作。除非交易平台是实时的, 且 EA 正在图表上运行, 否则不会执行。
# | 时间 | 类型 | 订单 | 手数 | 价格 | 止损 | 止盈 | 盈利 | 余额 |
1 | 2017.01.03 10:00 | sell | 1 | 0.30 | 1.04597 | 0.00000 | 0.00000 | ||
2 | 2017.01.03 10:00 | buy stop | 2 | 0.30 | 1.05097 | 0.00000 | 0.00000 | ||
3 | 2017.01.03 10:00 | buy limit | 3 | 0.30 | 1.04097 | 0.00000 | 0.00000 | ||
4 | 2017.01.03 11:34 | buy | 3 | 0.30 | 1.04097 | 0.00000 | 0.00000 | ||
5 | 2017.01.03 11:34 | close by | 1 | 0.30 | 1.04097 | 0.00000 | 0.00000 | 150.00 | 3150.00 |
6 | 2017.01.03 11:34 | close by | 3 | 0.00 | 1.04097 | 0.00000 | 0.00000 | 0.00 | 3150.00 |
7 | 2017.01.03 11:34 | delete | 2 | 0.30 | 1.05097 | 0.00000 | 0.00000 | ||
8 | 2017.01.05 11:00 | sell | 4 | 0.30 | 1.05149 | 0.00000 | 0.00000 | ||
9 | 2017.01.05 11:00 | buy stop | 5 | 0.30 | 1.05649 | 0.00000 | 0.00000 | ||
10 | 2017.01.05 11:00 | buy limit | 6 | 0.30 | 1.04649 | 0.00000 | 0.00000 | ||
11 | 2017.01.05 17:28 | buy | 5 | 0.30 | 1.05649 | 0.00000 | 0.00000 | ||
12 | 2017.01.05 17:28 | close by | 4 | 0.30 | 1.05649 | 0.00000 | 0.00000 | -150.00 | 3000.00 |
13 | 2017.01.05 17:28 | close by | 5 | 0.00 | 1.05649 | 0.00000 | 0.00000 | 0.00 | 3000.00 |
14 | 2017.01.05 17:28 | delete | 6 | 0.30 | 1.04649 | 0.00000 | 0.00000 |
虚拟停止位不会发送任何有关主要交易的停止位。在 EA 执行平仓订单的时刻, 经纪商才会被通知。下表显示了使用虚拟停止位的 EA 行为。在此, 一旦触发停止价位的目标价格, EA 就会向服务器发送交易请求, 将主要交易平仓。
# | 时间 | 类型 | 订单 | 手数 | 价格 | 止损 | 止盈 | 盈利 | 余额 |
1 | 2017.01.03 10:00 | sell | 1 | 0.30 | 1.04597 | 0.00000 | 0.00000 | ||
2 | 2017.01.03 11:34 | close | 1 | 0.30 | 1.04097 | 0.00000 | 0.00000 | 150.00 | 3150.00 |
3 | 2017.01.05 11:00 | sell | 2 | 0.30 | 1.05149 | 0.00000 | 0.00000 | ||
4 | 2017.01.05 17:28 | close | 2 | 0.30 | 1.05649 | 0.00000 | 0.00000 | -150.00 | 3000.00 |
订单 |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
开单时间 | 订单 | 品种 | 类型 | 交易量 | 价格 | 止损 | 止盈 | 时间 | 状态 | 注释 | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.30 / 0.30 | 1.04597 | 1.05097 | 1.04097 | 2017.01.03 10:00:00 | filled | |||
2017.01.03 11:34:38 | 3 | EURUSD | buy | 0.30 / 0.30 | 1.04097 | 2017.01.03 11:34:38 | filled | tp 1.04097 | ||||
2017.01.05 11:00:00 | 4 | EURUSD | sell | 0.30 / 0.30 | 1.05149 | 1.05649 | 1.04649 | 2017.01.05 11:00:00 | filled | |||
2017.01.05 17:28:37 | 5 | EURUSD | buy | 0.30 / 0.30 | 1.05649 | 2017.01.05 17:28:37 | filled | sl 1.05649 | ||||
成交 |
||||||||||||
时间 | 成交 | 品种 | 类型 | 方向 | 交易量 | 价格 | 订单 | 佣金 | 掉期利率 | 盈利 | 余额 | 注释 |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.30 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 3 | EURUSD | buy | out | 0.30 | 1.04097 | 3 | 0.00 | 0.00 | 150.00 | 3 150.00 | tp 1.04097 |
2017.01.05 11:00:00 | 4 | EURUSD | sell | in | 0.30 | 1.05149 | 4 | 0.00 | 0.00 | 0.00 | 3 150.00 | |
2017.01.05 17:28:37 | 5 | EURUSD | buy | out | 0.30 | 1.05649 | 5 | 0.00 | 0.00 | -150.00 | 3 000.00 | sl 1.05649 |
0.00 | 0.00 | 0.00 | 3 000.00 | |||||||||
在对冲模式下, 挂单的工作方式基本上与 MetaTrader 4 相同, 所以当挂单被触发时, EA 也会执行平仓操作。
订单 |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
开单时间 | 订单 | 品种 | 类型 | 交易量 | 价格 | 止损 | 止盈 | 时间 | 状态 | 注释 | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.30 / 0.30 | 1.04597 | 2017.01.03 10:00:00 | filled | |||||
2017.01.03 10:00:00 | 3 | EURUSD | buy stop | 0.30 / 0.00 | 1.05097 | 2017.01.03 11:34:38 | canceled | |||||
2017.01.03 10:00:00 | 4 | EURUSD | buy limit | 0.30 / 0.30 | 1.04097 | 2017.01.03 11:34:38 | filled | |||||
2017.01.03 11:34:38 | 5 | EURUSD | close by | 0.30 / 0.30 | 1.04097 | 2017.01.03 11:34:38 | filled | close #2 by #4 | ||||
2017.01.05 11:00:00 | 6 | EURUSD | sell | 0.30 / 0.30 | 1.05149 | 2017.01.05 11:00:00 | filled | |||||
2017.01.05 11:00:00 | 7 | EURUSD | buy stop | 0.30 / 0.30 | 1.05649 | 2017.01.05 17:28:37 | filled | |||||
2017.01.05 11:00:00 | 8 | EURUSD | buy limit | 0.30 / 0.00 | 1.04649 | 2017.01.05 17:28:37 | canceled | |||||
2017.01.05 17:28:37 | 9 | EURUSD | close by | 0.30 / 0.30 | 1.05649 | 2017.01.05 17:28:37 | filled | close #6 by #7 | ||||
成交 |
||||||||||||
时间 | 成交 | 品种 | 类型 | 方向 | 交易量 | 价格 | 订单 | 佣金 | 掉期利率 | 盈利 | 余额 | 注释 |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.30 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 3 | EURUSD | buy | in | 0.30 | 1.04097 | 4 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 4 | EURUSD | buy | out by | 0.30 | 1.04097 | 5 | 0.00 | 0.00 | 150.00 | 3 150.00 | close #2 by #4 |
2017.01.03 11:34:38 | 5 | EURUSD | sell | out by | 0.30 | 1.04597 | 5 | 0.00 | 0.00 | 0.00 | 3 150.00 | close #2 by #4 |
2017.01.05 11:00:00 | 6 | EURUSD | sell | in | 0.30 | 1.05149 | 6 | 0.00 | 0.00 | 0.00 | 3 150.00 | |
2017.01.05 17:28:37 | 7 | EURUSD | buy | in | 0.30 | 1.05649 | 7 | 0.00 | 0.00 | 0.00 | 3 150.00 | |
2017.01.05 17:28:37 | 9 | EURUSD | sell | out by | 0.30 | 1.05149 | 9 | 0.00 | 0.00 | 0.00 | 3 150.00 | close #6 by #7 |
2017.01.05 17:28:37 | 8 | EURUSD | buy | out by | 0.30 | 1.05649 | 9 | 0.00 | 0.00 | -150.00 | 3 000.00 | close #6 by #7 |
0.00 | 0.00 | 0.00 | 3 000.00 | |||||||||
使用虚拟停止位, 我们通常不会在 MetaTrader 4 中看到 "close" 标签。相反, 平仓操作使用与主要交易相反的类型, 但我们可以在成交历史中查看它们是否为买/卖、进/出。
订单 |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
开单时间 | 订单 | 品种 | 类型 | 交易量 | 价格 | 止损 | 止盈 | 时间 | 状态 | 注释 | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.30 / 0.30 | 1.04597 | 2017.01.03 10:00:00 | filled | |||||
2017.01.03 11:34:38 | 3 | EURUSD | buy | 0.30 / 0.30 | 1.04097 | 2017.01.03 11:34:38 | filled | |||||
2017.01.05 11:00:00 | 4 | EURUSD | sell | 0.30 / 0.30 | 1.05149 | 2017.01.05 11:00:00 | filled | |||||
2017.01.05 17:28:37 | 5 | EURUSD | buy | 0.30 / 0.30 | 1.05649 | 2017.01.05 17:28:37 | filled | |||||
成交 |
||||||||||||
时间 | 成交 | 品种 | 类型 | 方向 | 交易量 | 价格 | 订单 | 佣金 | 掉期利率 | 盈利 | 余额 | 注释 |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.30 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 3 | EURUSD | buy | out | 0.30 | 1.04097 | 3 | 0.00 | 0.00 | 150.00 | 3 150.00 | |
2017.01.05 11:00:00 | 4 | EURUSD | sell | in | 0.30 | 1.05149 | 4 | 0.00 | 0.00 | 0.00 | 3 150.00 | |
2017.01.05 17:28:37 | 5 | EURUSD | buy | out | 0.30 | 1.05649 | 5 | 0.00 | 0.00 | -150.00 | 3 000.00 | |
0.00 | 0.00 | 0.00 | 3 000.00 | |||||||||
订单 |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
开单时间 | 订单 | 品种 | 类型 | 交易量 | 价格 | 止损 | 止盈 | 时间 | 状态 | 注释 | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.30 / 0.30 | 1.04597 | 2017.01.03 10:00:00 | filled | |||||
2017.01.03 10:00:00 | 3 | EURUSD | buy stop | 0.30 / 0.00 | 1.05097 | 2017.01.03 11:34:38 | canceled | |||||
2017.01.03 10:00:00 | 4 | EURUSD | buy limit | 0.30 / 0.30 | 1.04097 | 2017.01.03 11:34:38 | filled | |||||
2017.01.05 11:00:00 | 5 | EURUSD | sell | 0.30 / 0.30 | 1.05149 | 2017.01.05 11:00:00 | filled | |||||
2017.01.05 11:00:00 | 6 | EURUSD | buy stop | 0.30 / 0.30 | 1.05649 | 2017.01.05 17:28:37 | filled | |||||
2017.01.05 11:00:00 | 7 | EURUSD | buy limit | 0.30 / 0.00 | 1.04649 | 2017.01.05 17:28:37 | canceled | |||||
成交 |
||||||||||||
时间 | 成交 | 品种 | 类型 | 方向 | 交易量 | 价格 | 订单 | 佣金 | 掉期利率 | 盈利 | 余额 | 注释 |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.30 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 3 | EURUSD | buy | out | 0.30 | 1.04097 | 4 | 0.00 | 0.00 | 150.00 | 3 150.00 | |
2017.01.05 11:00:00 | 4 | EURUSD | sell | in | 0.30 | 1.05149 | 5 | 0.00 | 0.00 | 0.00 | 3 150.00 | |
2017.01.05 17:28:37 | 5 | EURUSD | buy | out | 0.30 | 1.05649 | 6 | 0.00 | 0.00 | -150.00 | 3 000.00 | |
0.00 | 0.00 | 0.00 | 3 000.00 | |||||||||
订单 |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
开单时间 | 订单 | 品种 | 类型 | 交易量 | 价格 | 止损 | 止盈 | 时间 | 状态 | 注释 | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.30 / 0.30 | 1.04597 | 2017.01.03 10:00:00 | filled | |||||
2017.01.03 10:00:00 | 3 | EURUSD | buy stop | 0.30 / 0.00 | 1.05097 | 2017.01.03 11:34:38 | canceled | |||||
2017.01.03 10:00:00 | 4 | EURUSD | buy limit | 0.30 / 0.30 | 1.04097 | 2017.01.03 11:34:38 | filled | |||||
2017.01.05 11:00:00 | 5 | EURUSD | sell | 0.30 / 0.30 | 1.05149 | 2017.01.05 11:00:00 | filled | |||||
2017.01.05 11:00:00 | 6 | EURUSD | buy stop | 0.30 / 0.30 | 1.05649 | 2017.01.05 17:28:37 | filled | |||||
2017.01.05 11:00:00 | 7 | EURUSD | buy limit | 0.30 / 0.00 | 1.04649 | 2017.01.05 17:28:37 | canceled | |||||
成交 |
||||||||||||
时间 | 成交 | 品种 | 类型 | 方向 | 交易量 | 价格 | 订单 | 佣金 | 掉期利率 | 盈利 | 余额 | 注释 |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.30 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 3 | EURUSD | buy | out | 0.30 | 1.04097 | 4 | 0.00 | 0.00 | 150.00 | 3 150.00 | |
2017.01.05 11:00:00 | 4 | EURUSD | sell | in | 0.30 | 1.05149 | 5 | 0.00 | 0.00 | 0.00 | 3 150.00 | |
2017.01.05 17:28:37 | 5 | EURUSD | buy | out | 0.30 | 1.05649 | 6 | 0.00 | 0.00 | -150.00 | 3 000.00 | |
0.00 | 0.00 | 0.00 | 3 000.00 | |||||||||
下表显示在 MetaTrader 5 净持模式下使用虚拟停止位。净持模式中的虚拟停止位也许与对冲模式相似, 但内部运作方式不同。
订单 |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
开单时间 | 订单 | 品种 | 类型 | 交易量 | 价格 | 止损 | 止盈 | 时间 | 状态 | 注释 | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.30 / 0.30 | 1.04597 | 2017.01.03 10:00:00 | filled | |||||
2017.01.03 11:34:38 | 3 | EURUSD | buy | 0.30 / 0.30 | 1.04097 | 2017.01.03 11:34:38 | filled | |||||
2017.01.05 11:00:00 | 4 | EURUSD | sell | 0.30 / 0.30 | 1.05149 | 2017.01.05 11:00:00 | filled | |||||
2017.01.05 17:28:37 | 5 | EURUSD | buy | 0.30 / 0.30 | 1.05649 | 2017.01.05 17:28:37 | filled | |||||
成交 |
||||||||||||
时间 | 成交 | 品种 | 类型 | 方向 | 交易量 | 价格 | 订单 | 佣金 | 掉期利率 | 盈利 | 余额 | 注释 |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.30 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 3 | EURUSD | buy | out | 0.30 | 1.04097 | 3 | 0.00 | 0.00 | 150.00 | 3 150.00 | |
2017.01.05 11:00:00 | 4 | EURUSD | sell | in | 0.30 | 1.05149 | 4 | 0.00 | 0.00 | 0.00 | 3 150.00 | |
2017.01.05 17:28:37 | 5 | EURUSD | buy | out | 0.30 | 1.05649 | 5 | 0.00 | 0.00 | -150.00 | 3 000.00 | |
0.00 | 0.00 | 0.00 | 3 000.00 | |||||||||
示例 #2: 一款使用 Heiken Ashi 和 移动平均线的 EA, 有三个停止价位
更复杂的智能交易系统通常需要一个以上的止损和止盈。我们使用与上个示例相同的方法来添加额外的停止价位, 即名为 "stop1" 和 "stop2" 的停止价位:
int OnInit() { //--- 其它代码 CStops *stops=new CStops(); CStop *main=new CStop("main"); main.StopType(stop_type_main); main.VolumeType(VOLUME_TYPE_PERCENT_TOTAL); main.Main(true); main.StopLoss(stop_loss); main.TakeProfit(take_profit); stops.Add(GetPointer(main)); CStop *stop1=new CStop("stop1"); stop1.StopType(stop_type1); stop1.VolumeType(VOLUME_TYPE_PERCENT_TOTAL); stop1.Volume(0.35); stop1.StopLoss(stop_loss1); stop1.TakeProfit(take_profit1); stops.Add(GetPointer(stop1)); CStop *stop2=new CStop("stop2"); stop2.StopType(stop_type2); stop2.VolumeType(VOLUME_TYPE_PERCENT_TOTAL); stop2.Volume(0.35); stop2.StopLoss(stop_loss2); stop2.TakeProfit(take_profit2); stops.Add(GetPointer(stop2)); order_manager.AddStops(GetPointer(stops)); //--- 其它代码 }
下表显示了 MetaTrader 4 上的测试结果:
# | 时间 | 类型 | 订单 | 手数 | 价格 | 止损 | 止盈 | 盈利 | 余额 |
1 | 2017.01.03 10:00 | sell | 1 | 0.30 | 1.04597 | 1.05097 | 1.04097 | ||
2 | 2017.01.03 10:00 | buy stop | 2 | 0.11 | 1.04847 | 0.00000 | 0.00000 | ||
3 | 2017.01.03 10:00 | buy limit | 3 | 0.11 | 1.04347 | 0.00000 | 0.00000 | ||
4 | 2017.01.03 10:21 | buy | 3 | 0.11 | 1.04347 | 0.00000 | 0.00000 | ||
5 | 2017.01.03 10:21 | close by | 1 | 0.11 | 1.04347 | 1.05097 | 1.04097 | 27.50 | 3027.50 |
6 | 2017.01.03 10:21 | sell | 4 | 0.19 | 1.04597 | 1.05097 | 1.04097 | ||
7 | 2017.01.03 10:21 | close by | 3 | 0.00 | 1.04347 | 0.00000 | 0.00000 | 0.00 | 3027.50 |
8 | 2017.01.03 10:21 | delete | 2 | 0.11 | 1.04847 | 0.00000 | 0.00000 | ||
9 | 2017.01.03 10:34 | close | 4 | 0.11 | 1.04247 | 1.05097 | 1.04097 | 38.50 | 3066.00 |
10 | 2017.01.03 10:34 | sell | 5 | 0.08 | 1.04597 | 1.05097 | 1.04097 | ||
11 | 2017.01.03 11:34 | t/p | 5 | 0.08 | 1.04097 | 1.05097 | 1.04097 | 40.00 | 3106.00 |
12 | 2017.01.05 11:00 | sell | 6 | 0.30 | 1.05149 | 1.05649 | 1.04649 | ||
13 | 2017.01.05 11:00 | buy stop | 7 | 0.11 | 1.05399 | 0.00000 | 0.00000 | ||
14 | 2017.01.05 11:00 | buy limit | 8 | 0.11 | 1.04899 | 0.00000 | 0.00000 | ||
15 | 2017.01.05 12:58 | buy | 8 | 0.11 | 1.04899 | 0.00000 | 0.00000 | ||
16 | 2017.01.05 12:58 | close by | 6 | 0.11 | 1.04899 | 1.05649 | 1.04649 | 27.50 | 3133.50 |
17 | 2017.01.05 12:58 | sell | 9 | 0.19 | 1.05149 | 1.05649 | 1.04649 | ||
18 | 2017.01.05 12:58 | close by | 8 | 0.00 | 1.04899 | 0.00000 | 0.00000 | 0.00 | 3133.50 |
19 | 2017.01.05 12:58 | delete | 7 | 0.11 | 1.05399 | 0.00000 | 0.00000 | ||
20 | 2017.01.05 16:00 | close | 9 | 0.19 | 1.05314 | 1.05649 | 1.04649 | -31.35 | 3102.15 |
21 | 2017.01.05 16:00 | buy | 10 | 0.30 | 1.05314 | 1.04814 | 1.05814 | ||
22 | 2017.01.05 16:00 | sell stop | 11 | 0.11 | 1.05064 | 0.00000 | 0.00000 | ||
23 | 2017.01.05 16:00 | sell limit | 12 | 0.11 | 1.05564 | 0.00000 | 0.00000 | ||
24 | 2017.01.05 17:09 | sell | 12 | 0.11 | 1.05564 | 0.00000 | 0.00000 | ||
25 | 2017.01.05 17:09 | close by | 10 | 0.11 | 1.05564 | 1.04814 | 1.05814 | 27.50 | 3129.65 |
26 | 2017.01.05 17:09 | buy | 13 | 0.19 | 1.05314 | 1.04814 | 1.05814 | ||
27 | 2017.01.05 17:09 | close by | 12 | 0.00 | 1.05564 | 0.00000 | 0.00000 | 0.00 | 3129.65 |
28 | 2017.01.05 17:09 | delete | 11 | 0.11 | 1.05064 | 0.00000 | 0.00000 | ||
29 | 2017.01.05 17:28 | close | 13 | 0.11 | 1.05664 | 1.04814 | 1.05814 | 38.50 | 3168.15 |
30 | 2017.01.05 17:28 | buy | 14 | 0.08 | 1.05314 | 1.04814 | 1.05814 | ||
31 | 2017.01.05 17:40 | t/p | 14 | 0.08 | 1.05814 | 1.04814 | 1.05814 | 40.00 | 3208.15 |
如上表所示, 所有三个停止价位均被第一笔交易触发。对于虚拟停止位, EA 按预期在主要交易中执行部分平仓。对于使用挂单的停止位, 一旦挂单执行, EA 将执行平仓操作, 从主交易中扣除挂单交易量。最后, 对于主要停止位, 这是一个经纪商端停止位, 主要交易已离场, 剩余交易量为 0.08 手。
下表显示了 MetaTrader 5 对冲模式下的测试结果:
订单 |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
开单时间 | 订单 | 品种 | 类型 | 交易量 | 价格 | 止损 | 止盈 | 时间 | 状态 | 注释 | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.30 / 0.30 | 1.04597 | 1.05097 | 1.04097 | 2017.01.03 10:00:00 | filled | |||
2017.01.03 10:00:00 | 3 | EURUSD | buy stop | 0.11 / 0.00 | 1.04847 | 2017.01.03 10:21:32 | canceled | |||||
2017.01.03 10:00:00 | 4 | EURUSD | buy limit | 0.11 / 0.11 | 1.04347 | 2017.01.03 10:21:32 | filled | |||||
2017.01.03 10:21:32 | 5 | EURUSD | close by | 0.11 / 0.11 | 1.04347 | 2017.01.03 10:21:32 | filled | close #2 by #4 | ||||
2017.01.03 10:33:40 | 6 | EURUSD | buy | 0.11 / 0.11 | 1.04247 | 2017.01.03 10:33:40 | filled | |||||
2017.01.03 11:34:38 | 7 | EURUSD | buy | 0.08 / 0.08 | 1.04097 | 2017.01.03 11:34:38 | filled | tp 1.04097 | ||||
2017.01.05 11:00:00 | 8 | EURUSD | sell | 0.30 / 0.30 | 1.05149 | 1.05649 | 1.04649 | 2017.01.05 11:00:00 | filled | |||
2017.01.05 11:00:00 | 9 | EURUSD | buy stop | 0.11 / 0.00 | 1.05399 | 2017.01.05 12:58:27 | canceled | |||||
2017.01.05 11:00:00 | 10 | EURUSD | buy limit | 0.11 / 0.11 | 1.04899 | 2017.01.05 12:58:27 | filled | |||||
2017.01.05 12:58:27 | 11 | EURUSD | close by | 0.11 / 0.11 | 1.04896 | 2017.01.05 12:58:27 | filled | close #8 by #10 | ||||
2017.01.05 16:00:00 | 12 | EURUSD | buy | 0.19 / 0.19 | 1.05307 | 2017.01.05 16:00:00 | filled | |||||
2017.01.05 16:00:00 | 13 | EURUSD | buy | 0.30 / 0.30 | 1.05307 | 1.04807 | 1.05807 | 2017.01.05 16:00:00 | filled | |||
2017.01.05 16:00:00 | 14 | EURUSD | sell stop | 0.11 / 0.00 | 1.05057 | 2017.01.05 17:09:40 | canceled | |||||
2017.01.05 16:00:00 | 15 | EURUSD | sell limit | 0.11 / 0.11 | 1.05557 | 2017.01.05 17:09:40 | filled | |||||
2017.01.05 17:09:40 | 16 | EURUSD | close by | 0.11 / 0.11 | 1.05557 | 2017.01.05 17:09:40 | filled | close #13 by #15 | ||||
2017.01.05 17:28:47 | 17 | EURUSD | sell | 0.11 / 0.11 | 1.05660 | 2017.01.05 17:28:47 | filled | |||||
2017.01.05 17:29:15 | 18 | EURUSD | sell | 0.08 / 0.08 | 1.05807 | 2017.01.05 17:29:15 | filled | tp 1.05807 | ||||
成交 |
||||||||||||
时间 | 成交 | 品种 | 类型 | 方向 | 交易量 | 价格 | 订单 | 佣金 | 掉期利率 | 盈利 | 余额 | 注释 |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.30 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 10:21:32 | 3 | EURUSD | buy | in | 0.11 | 1.04347 | 4 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 10:21:32 | 4 | EURUSD | buy | out by | 0.11 | 1.04347 | 5 | 0.00 | 0.00 | 27.50 | 3 027.50 | close #2 by #4 |
2017.01.03 10:21:32 | 5 | EURUSD | sell | out by | 0.11 | 1.04597 | 5 | 0.00 | 0.00 | 0.00 | 3 027.50 | close #2 by #4 |
2017.01.03 10:33:40 | 6 | EURUSD | buy | out | 0.11 | 1.04247 | 6 | 0.00 | 0.00 | 38.50 | 3 066.00 | |
2017.01.03 11:34:38 | 7 | EURUSD | buy | out | 0.08 | 1.04097 | 7 | 0.00 | 0.00 | 40.00 | 3 106.00 | tp 1.04097 |
2017.01.05 11:00:00 | 8 | EURUSD | sell | in | 0.30 | 1.05149 | 8 | 0.00 | 0.00 | 0.00 | 3 106.00 | |
2017.01.05 12:58:27 | 9 | EURUSD | buy | in | 0.11 | 1.04896 | 10 | 0.00 | 0.00 | 0.00 | 3 106.00 | |
2017.01.05 12:58:27 | 10 | EURUSD | buy | out by | 0.11 | 1.04896 | 11 | 0.00 | 0.00 | 27.83 | 3 133.83 | close #8 by #10 |
2017.01.05 12:58:27 | 11 | EURUSD | sell | out by | 0.11 | 1.05149 | 11 | 0.00 | 0.00 | 0.00 | 3 133.83 | close #8 by #10 |
2017.01.05 16:00:00 | 12 | EURUSD | buy | out | 0.19 | 1.05307 | 12 | 0.00 | 0.00 | -30.02 | 3 103.81 | |
2017.01.05 16:00:00 | 13 | EURUSD | buy | in | 0.30 | 1.05307 | 13 | 0.00 | 0.00 | 0.00 | 3 103.81 | |
2017.01.05 17:09:40 | 14 | EURUSD | sell | in | 0.11 | 1.05557 | 15 | 0.00 | 0.00 | 0.00 | 3 103.81 | |
2017.01.05 17:09:40 | 16 | EURUSD | buy | out by | 0.11 | 1.05307 | 16 | 0.00 | 0.00 | 0.00 | 3 103.81 | close #13 by #15 |
2017.01.05 17:09:40 | 15 | EURUSD | sell | out by | 0.11 | 1.05557 | 16 | 0.00 | 0.00 | 27.50 | 3 131.31 | close #13 by #15 |
2017.01.05 17:28:47 | 17 | EURUSD | sell | out | 0.11 | 1.05660 | 17 | 0.00 | 0.00 | 38.83 | 3 170.14 | |
2017.01.05 17:29:15 | 18 | EURUSD | sell | out | 0.08 | 1.05807 | 18 | 0.00 | 0.00 | 40.00 | 3 210.14 | tp 1.05807 |
0.00 | 0.00 | 210.14 | 3 210.14 | |||||||||
如上表所示, EA 在 MetaTrader 5 对冲模式中的工作方式类似。对于三种类型的停止位, 其机制与 MetaTrader 4 中的相同。
下表显示了 MetaTrader 5 净持模式的测试结果:
订单 |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
开单时间 | 订单 | 品种 | 类型 | 交易量 | 价格 | 止损 | 止盈 | 时间 | 状态 | 注释 | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.30 / 0.30 | 1.04597 | 2017.01.03 10:00:00 | filled | |||||
2017.01.03 10:00:00 | 3 | EURUSD | buy stop | 0.30 / 0.00 | 1.05097 | 2017.01.03 11:34:38 | canceled | |||||
2017.01.03 10:00:00 | 4 | EURUSD | buy limit | 0.30 / 0.30 | 1.04097 | 2017.01.03 11:34:38 | filled | |||||
2017.01.03 10:00:00 | 5 | EURUSD | buy stop | 0.11 / 0.00 | 1.04847 | 2017.01.03 10:21:32 | canceled | |||||
2017.01.03 10:00:00 | 6 | EURUSD | buy limit | 0.11 / 0.11 | 1.04347 | 2017.01.03 10:21:32 | filled | |||||
2017.01.03 10:33:40 | 7 | EURUSD | buy | 0.11 / 0.11 | 1.04247 | 2017.01.03 10:33:40 | filled | |||||
2017.01.05 11:00:00 | 8 | EURUSD | sell | 0.30 / 0.30 | 1.05149 | 2017.01.05 11:00:00 | filled | |||||
2017.01.05 11:00:00 | 9 | EURUSD | buy stop | 0.30 / 0.00 | 1.05649 | 2017.01.05 16:00:00 | canceled | |||||
2017.01.05 11:00:00 | 10 | EURUSD | buy limit | 0.30 / 0.00 | 1.04649 | 2017.01.05 16:00:00 | canceled | |||||
2017.01.05 11:00:00 | 11 | EURUSD | buy stop | 0.11 / 0.00 | 1.05399 | 2017.01.05 12:58:27 | canceled | |||||
2017.01.05 11:00:00 | 12 | EURUSD | buy limit | 0.11 / 0.11 | 1.04899 | 2017.01.05 12:58:27 | filled | |||||
2017.01.05 16:00:00 | 13 | EURUSD | buy | 0.19 / 0.19 | 1.05307 | 2017.01.05 16:00:00 | filled | |||||
2017.01.05 16:00:00 | 14 | EURUSD | buy | 0.30 / 0.30 | 1.05307 | 2017.01.05 16:00:00 | filled | |||||
2017.01.05 16:00:00 | 15 | EURUSD | sell stop | 0.30 / 0.00 | 1.04807 | 2017.01.05 17:29:15 | canceled | |||||
2017.01.05 16:00:00 | 16 | EURUSD | sell limit | 0.30 / 0.30 | 1.05807 | 2017.01.05 17:29:15 | filled | |||||
2017.01.05 16:00:00 | 17 | EURUSD | sell stop | 0.11 / 0.00 | 1.05057 | 2017.01.05 17:09:40 | canceled | |||||
2017.01.05 16:00:00 | 18 | EURUSD | sell limit | 0.11 / 0.11 | 1.05557 | 2017.01.05 17:09:40 | filled | |||||
2017.01.05 17:28:47 | 19 | EURUSD | sell | 0.11 / 0.11 | 1.05660 | 2017.01.05 17:28:47 | filled | |||||
成交 |
||||||||||||
时间 | 成交 | 品种 | 类型 | 方向 | 交易量 | 价格 | 订单 | 佣金 | 掉期利率 | 盈利 | 余额 | 注释 |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.30 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 5 | EURUSD | buy | in/out | 0.30 | 1.04097 | 4 | 0.00 | 0.00 | 40.00 | 3 040.00 | |
2017.01.03 10:21:32 | 3 | EURUSD | buy | out | 0.11 | 1.04347 | 6 | 0.00 | 0.00 | 27.50 | 3 067.50 | |
2017.01.03 10:33:40 | 4 | EURUSD | buy | out | 0.11 | 1.04247 | 7 | 0.00 | 0.00 | 38.50 | 3 106.00 | |
2017.01.05 11:00:00 | 6 | EURUSD | sell | in/out | 0.30 | 1.05149 | 8 | 0.00 | -0.61 | 231.44 | 3 336.83 | |
2017.01.05 12:58:27 | 7 | EURUSD | buy | in/out | 0.11 | 1.04896 | 12 | 0.00 | 0.00 | 20.24 | 3 357.07 | |
2017.01.05 16:00:00 | 8 | EURUSD | buy | in | 0.19 | 1.05307 | 13 | 0.00 | 0.00 | 0.00 | 3 357.07 | |
2017.01.05 16:00:00 | 9 | EURUSD | buy | in | 0.30 | 1.05307 | 14 | 0.00 | 0.00 | 0.00 | 3 357.07 | |
2017.01.05 17:29:15 | 12 | EURUSD | sell | out | 0.30 | 1.05807 | 16 | 0.00 | 0.00 | 157.11 | 3 514.18 | |
2017.01.05 17:09:40 | 10 | EURUSD | sell | out | 0.11 | 1.05557 | 18 | 0.00 | 0.00 | 30.11 | 3 544.29 | |
2017.01.05 17:28:47 | 11 | EURUSD | sell | out | 0.11 | 1.05660 | 19 | 0.00 | 0.00 | 41.44 | 3 585.73 | |
0.00 | -0.61 | 586.34 | 3 585.73 | |||||||||
在此, 我们遇到了一个问题。如同前两次测试中观察到的那样, 在最后的停止价位平仓 0.30 手, 而非 0.08 手。
如早前讨论的那样, MetaTrader 5 净持模式中的标准止损和止盈与前两者不同。因此, EA 会将经纪商端停止位转换为挂单停止位。然而, 通过这种设置, EA 已经有两个基于挂单的停止价位, 其中一个是主要停止位。还是如前所述, 这将导致孤立交易。最终或主要停止价位总是等于主交易的初始交易量。而且由于还有其它的停止价位, 因此可能会导致主要停止价位在平仓时超过主要仓位的剩余交易量。
为了解决这个问题, 一种方法是将主停止位设置为虚拟来代替, 而不是经纪商端或基于挂单的方式。利用这个新设置, EA 现在有 2 个停止位, 一个是虚拟的, 而另一个停止位则基于挂单。使用此新设置的测试结果如下所示。
订单 |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
开单时间 | 订单 | 品种 | 类型 | 交易量 | 价格 | 止损 | 止盈 | 时间 | 状态 | 注释 | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.30 / 0.30 | 1.04597 | 2017.01.03 10:00:00 | filled | |||||
2017.01.03 10:00:00 | 3 | EURUSD | buy stop | 0.11 / 0.00 | 1.04847 | 2017.01.03 10:21:32 | canceled | |||||
2017.01.03 10:00:00 | 4 | EURUSD | buy limit | 0.11 / 0.11 | 1.04347 | 2017.01.03 10:21:32 | filled | |||||
2017.01.03 10:33:40 | 5 | EURUSD | buy | 0.11 / 0.11 | 1.04247 | 2017.01.03 10:33:40 | filled | |||||
2017.01.03 11:34:38 | 6 | EURUSD | buy | 0.08 / 0.08 | 1.04097 | 2017.01.03 11:34:38 | filled | |||||
2017.01.05 11:00:00 | 7 | EURUSD | sell | 0.30 / 0.30 | 1.05149 | 2017.01.05 11:00:00 | filled | |||||
2017.01.05 11:00:00 | 8 | EURUSD | buy stop | 0.11 / 0.00 | 1.05399 | 2017.01.05 12:58:27 | canceled | |||||
2017.01.05 11:00:00 | 9 | EURUSD | buy limit | 0.11 / 0.11 | 1.04899 | 2017.01.05 12:58:27 | filled | |||||
2017.01.05 16:00:00 | 10 | EURUSD | buy | 0.19 / 0.19 | 1.05307 | 2017.01.05 16:00:00 | filled | |||||
2017.01.05 16:00:00 | 11 | EURUSD | buy | 0.30 / 0.30 | 1.05307 | 2017.01.05 16:00:00 | filled | |||||
2017.01.05 16:00:00 | 12 | EURUSD | sell stop | 0.11 / 0.00 | 1.05057 | 2017.01.05 17:09:40 | canceled | |||||
2017.01.05 16:00:00 | 13 | EURUSD | sell limit | 0.11 / 0.11 | 1.05557 | 2017.01.05 17:09:40 | filled | |||||
2017.01.05 17:28:47 | 14 | EURUSD | sell | 0.11 / 0.11 | 1.05660 | 2017.01.05 17:28:47 | filled | |||||
2017.01.05 17:29:15 | 15 | EURUSD | sell | 0.08 / 0.08 | 1.05807 | 2017.01.05 17:29:15 | filled | |||||
成交 |
||||||||||||
时间 | 成交 | 品种 | 类型 | 方向 | 交易量 | 价格 | 订单 | 佣金 | 掉期利率 | 盈利 | 余额 | 注释 |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.30 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 10:21:32 | 3 | EURUSD | buy | out | 0.11 | 1.04347 | 4 | 0.00 | 0.00 | 27.50 | 3 027.50 | |
2017.01.03 10:33:40 | 4 | EURUSD | buy | out | 0.11 | 1.04247 | 5 | 0.00 | 0.00 | 38.50 | 3 066.00 | |
2017.01.03 11:34:38 | 5 | EURUSD | buy | out | 0.08 | 1.04097 | 6 | 0.00 | 0.00 | 40.00 | 3 106.00 | |
2017.01.05 11:00:00 | 6 | EURUSD | sell | in | 0.30 | 1.05149 | 7 | 0.00 | 0.00 | 0.00 | 3 106.00 | |
2017.01.05 12:58:27 | 7 | EURUSD | buy | out | 0.11 | 1.04896 | 9 | 0.00 | 0.00 | 27.83 | 3 133.83 | |
2017.01.05 16:00:00 | 8 | EURUSD | buy | out | 0.19 | 1.05307 | 10 | 0.00 | 0.00 | -30.02 | 3 103.81 | |
2017.01.05 16:00:00 | 9 | EURUSD | buy | in | 0.30 | 1.05307 | 11 | 0.00 | 0.00 | 0.00 | 3 103.81 | |
2017.01.05 17:09:40 | 10 | EURUSD | sell | out | 0.11 | 1.05557 | 13 | 0.00 | 0.00 | 27.50 | 3 131.31 | |
2017.01.05 17:28:47 | 11 | EURUSD | sell | out | 0.11 | 1.05660 | 14 | 0.00 | 0.00 | 38.83 | 3 170.14 | |
2017.01.05 17:29:15 | 12 | EURUSD | sell | out | 0.08 | 1.05807 | 15 | 0.00 | 0.00 | 40.00 | 3 210.14 | |
0.00 | 0.00 | 210.14 | 3 210.14 | |||||||||
取自停止价位的总交易量现在等于主要交易的初始交易量。
示例 #3: 停止位与资金管理
在之前的文章 (参见 跨平台智能交易系统: 资金管理) 中, 曾讨论过一些基于某个停止价位的资金管理方法 (止盈也是可能的, 但一般使用止损)。诸如固定分数, 固定风险, 以及每点数/点值的固定风险等等的资金管理方法, 往往需要有限的停止价位。不设置这个价位意味着非常大甚或无限的风险, 因此, 交易量计算也会非常大。为了展示使用本文中提到的类对象实现的带有资金管理能力的智能交易系统, 我们将修改第一个示例, 如此一来先前注释掉的代码行将包含在编译中。
首先, 我们删除在 OnInit 函数中的资金管理方法代码行上的注释标签, 如下面的代码所示:
int OnInit() { //--- 其它代码 order_manager=new COrderManager(); money_manager= new CMoneys(); CMoney *money_fixed=new CMoneyFixedLot(0.05); CMoney *money_ff=new CMoneyFixedFractional(5); CMoney *money_ratio=new CMoneyFixedRatio(0,0.1,1000); CMoney *money_riskperpoint=new CMoneyFixedRiskPerPoint(0.1); CMoney *money_risk=new CMoneyFixedRisk(100); money_manager.Add(money_fixed); money_manager.Add(money_ff); money_manager.Add(money_ratio); money_manager.Add(money_riskperpoint); money_manager.Add(money_risk); order_manager.AddMoneys(money_manager); //--- 其它代码 }
然后, 在源代码的顶部, 我们声明一个自定义枚举, 以便我们可以创建一个外部参数, 这将允许我们按照源代码中提供的顺序选择要使用的资金管理方法:
enum ENUM_MM_TYPE { MM_FIXED=0, MM_FIXED_FRACTIONAL, MM_FIXED_RATIO, MM_FIXED_RISK_PER_POINT, MM_FIXED_RISK };
之后, 我们为此枚举声明一个新的输入参数:
input ENUM_MM_TYPE mm_type=MM_FIXED_FRACTIONAL;
最后, 我们必须将该参数与 OnTick 函数中实际选择的资金管理方法挂钩:
void OnTick() { //--- manage_trades(); if(symbol_info.RefreshRates()) { signals.Check(); if(signals.CheckOpenLong()) { close_last(); if(time_filters.Evaluate(TimeCurrent())) { Print("Entering buy trade.."); money_manager.Selected((int)mm_type); //use mm_type, cast to 'int' type order_manager.TradeOpen(Symbol(),ORDER_TYPE_BUY,symbol_info.Ask()); } } else if(signals.CheckOpenShort()) { close_last(); if(time_filters.Evaluate(TimeCurrent())) { Print("Entering sell trade.."); money_manager.Selected((int)mm_type); //use mm_type, cast to 'int' type order_manager.TradeOpen(Symbol(),ORDER_TYPE_SELL,symbol_info.Bid()); } } } }
由于资金管理方法只进行纯粹的计算, 所以对于 MQL4 和 MQL5 之间的兼容性没有任何问题。前两个示例已经展示了停止价位在两个平台上的工作方式。下表显示了 MetaTrader 5 对冲模式下的测试结果。
下表显示了使用固定分数资金管理的测试结果。编码设置为帐户的 5% 风险。初始本金 3000 美元, 我们预计该数值将达到约 150 美元。由于止损和止盈具有相同的数值 (500 点), 那么我们预计交易如果触及止盈则可以赚取 150 美元。
订单 |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
开单时间 | 订单 | 品种 | 类型 | 交易量 | 价格 | 止损 | 止盈 | 时间 | 状态 | 注释 | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.30 / 0.30 | 1.04597 | 1.05097 | 1.04097 | 2017.01.03 10:00:00 | filled | |||
2017.01.03 11:34:38 | 3 | EURUSD | buy | 0.30 / 0.30 | 1.04097 | 2017.01.03 11:34:38 | filled | tp 1.04097 | ||||
2017.01.05 11:00:00 | 4 | EURUSD | sell | 0.32 / 0.32 | 1.05149 | 1.05649 | 1.04649 | 2017.01.05 11:00:00 | filled | |||
2017.01.05 16:00:00 | 5 | EURUSD | buy | 0.32 / 0.32 | 1.05307 | 2017.01.05 16:00:00 | filled | |||||
2017.01.05 16:00:00 | 6 | EURUSD | buy | 0.31 / 0.31 | 1.05307 | 1.04807 | 1.05807 | 2017.01.05 16:00:00 | filled | |||
2017.01.05 17:29:15 | 7 | EURUSD | sell | 0.31 / 0.31 | 1.05807 | 2017.01.05 17:29:15 | filled | tp 1.05807 | ||||
成交 |
||||||||||||
时间 | 成交 | 品种 | 类型 | 方向 | 交易量 | 价格 | 订单 | 佣金 | 掉期利率 | 盈利 | 余额 | 注释 |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.30 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 3 | EURUSD | buy | out | 0.30 | 1.04097 | 3 | 0.00 | 0.00 | 150.00 | 3 150.00 | tp 1.04097 |
2017.01.05 11:00:00 | 4 | EURUSD | sell | in | 0.32 | 1.05149 | 4 | 0.00 | 0.00 | 0.00 | 3 150.00 | |
2017.01.05 16:00:00 | 5 | EURUSD | buy | out | 0.32 | 1.05307 | 5 | 0.00 | 0.00 | -50.56 | 3 099.44 | |
2017.01.05 16:00:00 | 6 | EURUSD | buy | in | 0.31 | 1.05307 | 6 | 0.00 | 0.00 | 0.00 | 3 099.44 | |
2017.01.05 17:29:15 | 7 | EURUSD | sell | out | 0.31 | 1.05807 | 7 | 0.00 | 0.00 | 155.00 | 3 254.44 | tp 1.05807 |
0.00 | 0.00 | 254.44 | 3 254.44 | |||||||||
请注意, 计算的交易量数值还将取决于经纪商规定的手数精度, 由最小手数和最小手数步长参数确定。我们不能指望智能交易系统总是做出精确的计算。有了这些限制, 智能交易系统也许会发现在某些点必须舍进该数值。资金管理的其它方法同样如此。
对于每点数固定风险的资金管理, 编码设置每个止损点数为 0.1 美元。止陨和止盈均设置为 500 点, 我们预计这样的盈利/亏损将达到 50 美元。
订单 |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
开单时间 | 订单 | 品种 | 类型 | 交易量 | 价格 | 止损 | 止盈 | 时间 | 状态 | 注释 | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.10 / 0.10 | 1.04597 | 1.05097 | 1.04097 | 2017.01.03 10:00:00 | filled | |||
2017.01.03 11:34:38 | 3 | EURUSD | buy | 0.10 / 0.10 | 1.04097 | 2017.01.03 11:34:38 | filled | tp 1.04097 | ||||
2017.01.05 11:00:00 | 4 | EURUSD | sell | 0.10 / 0.10 | 1.05149 | 1.05649 | 1.04649 | 2017.01.05 11:00:00 | filled | |||
2017.01.05 16:00:00 | 5 | EURUSD | buy | 0.10 / 0.10 | 1.05307 | 2017.01.05 16:00:00 | filled | |||||
2017.01.05 16:00:00 | 6 | EURUSD | buy | 0.10 / 0.10 | 1.05307 | 1.04807 | 1.05807 | 2017.01.05 16:00:00 | filled | |||
2017.01.05 17:29:15 | 7 | EURUSD | sell | 0.10 / 0.10 | 1.05807 | 2017.01.05 17:29:15 | filled | tp 1.05807 | ||||
成交 |
||||||||||||
时间 | 成交 | 品种 | 类型 | 方向 | 交易量 | 价格 | 订单 | 佣金 | 掉期利率 | 盈利 | 余额 | 注释 |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.10 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 3 | EURUSD | buy | out | 0.10 | 1.04097 | 3 | 0.00 | 0.00 | 50.00 | 3 050.00 | tp 1.04097 |
2017.01.05 11:00:00 | 4 | EURUSD | sell | in | 0.10 | 1.05149 | 4 | 0.00 | 0.00 | 0.00 | 3 050.00 | |
2017.01.05 16:00:00 | 5 | EURUSD | buy | out | 0.10 | 1.05307 | 5 | 0.00 | 0.00 | -15.80 | 3 034.20 | |
2017.01.05 16:00:00 | 6 | EURUSD | buy | in | 0.10 | 1.05307 | 6 | 0.00 | 0.00 | 0.00 | 3 034.20 | |
2017.01.05 17:29:15 | 7 | EURUSD | sell | out | 0.10 | 1.05807 | 7 | 0.00 | 0.00 | 50.00 | 3 084.20 | tp 1.05807 |
0.00 | 0.00 | 84.20 | 3 084.20 | |||||||||
对于固定风险资金管理, 编码设置为 100 美元风险。然后, EA 必须计算适合这种风险的交易量。结果如下所示.
订单 |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
开单时间 | 订单 | 品种 | 类型 | 交易量 | 价格 | 止损 | 止盈 | 时间 | 状态 | 注释 | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.20 / 0.20 | 1.04597 | 1.05097 | 1.04097 | 2017.01.03 10:00:00 | filled | |||
2017.01.03 11:34:38 | 3 | EURUSD | buy | 0.20 / 0.20 | 1.04097 | 2017.01.03 11:34:38 | filled | tp 1.04097 | ||||
2017.01.05 11:00:00 | 4 | EURUSD | sell | 0.20 / 0.20 | 1.05149 | 1.05649 | 1.04649 | 2017.01.05 11:00:00 | filled | |||
2017.01.05 16:00:00 | 5 | EURUSD | buy | 0.20 / 0.20 | 1.05307 | 2017.01.05 16:00:00 | filled | |||||
2017.01.05 16:00:00 | 6 | EURUSD | buy | 0.20 / 0.20 | 1.05307 | 1.04807 | 1.05807 | 2017.01.05 16:00:00 | filled | |||
2017.01.05 17:29:15 | 7 | EURUSD | sell | 0.20 / 0.20 | 1.05807 | 2017.01.05 17:29:15 | filled | tp 1.05807 | ||||
成交 |
||||||||||||
时间 | 成交 | 品种 | 类型 | 方向 | 交易量 | 价格 | 订单 | 佣金 | 掉期利率 | 盈利 | 余额 | 注释 |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.20 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 3 | EURUSD | buy | out | 0.20 | 1.04097 | 3 | 0.00 | 0.00 | 100.00 | 3 100.00 | tp 1.04097 |
2017.01.05 11:00:00 | 4 | EURUSD | sell | in | 0.20 | 1.05149 | 4 | 0.00 | 0.00 | 0.00 | 3 100.00 | |
2017.01.05 16:00:00 | 5 | EURUSD | buy | out | 0.20 | 1.05307 | 5 | 0.00 | 0.00 | -31.60 | 3 068.40 | |
2017.01.05 16:00:00 | 6 | EURUSD | buy | in | 0.20 | 1.05307 | 6 | 0.00 | 0.00 | 0.00 | 3 068.40 | |
2017.01.05 17:29:15 | 7 | EURUSD | sell | out | 0.20 | 1.05807 | 7 | 0.00 | 0.00 | 100.00 | 3 168.40 | tp 1.05807 |
0.00 | 0.00 | 168.40 | 3 168.40 | |||||||||
结束语
在本文中, 我们讨论了在跨平台智能交易系统中添加停止价位。这两个交易平台虽然拥有许多平行功能, 但在停止价位的实现方式上却有很大差异。本文提供了一种方法, 可以调和这些差异, 令智能交易系统可以兼容这两个平台。
文章中使用的程序
# |
名称 |
类型 |
描述 |
---|---|---|---|
1. |
stops_ha_ma1.mqh |
头文件 |
在第一个示例中用于智能交易系统的主要头文件 |
2. |
stops_ha_ma1.mq4 | 智能交易系统 |
在第一个示例中用于 MQL4 智能交易系统的主要源文件 |
3. |
stops_ha_ma1.mq5 | 智能交易系统 | 在第一个示例中用于 MQL5 智能交易系统的主要源文件 |
4. | stops_ha_ma2.mqh | 头文件 | 在第二个示例中用于智能交易系统的主要头文件 |
5. | stops_ha_ma2.mq4 | 智能交易系统 |
在第二个示例中用于 MQL4 智能交易系统的主要源文件 |
6. | stops_ha_ma2.mq5 | 智能交易系统 |
在第二个示例中用于 MQL5 智能交易系统的主要源文件 |
7. | stops_ha_ma3.mqh | 头文件 | 在第三个示例中用于智能交易系统的主要头文件 |
8. | stops_ha_ma3.mq4 | 智能交易系统 |
在第三个示例中用于 MQL4 智能交易系统的主要源文件 |
9. | stops_ha_ma3.mq5 | 智能交易系统 |
在第三个示例中用于 MQL5 智能交易系统的主要源文件 |
文章中的类文件
# |
名称 |
类型 |
描述 |
---|---|---|---|
1. |
MQLx\Base\Stop\StopBase.mqh |
头文件 |
CStop (基类) |
2. |
MQLx\MQL4\Stop\Stop.mqh | 头文件 | CStop (MQL4 版本) |
3. |
MQLx\MQL5\Stop\Stop.mqh | 头文件 | CStop (MQL5 版本) |
4. | MQLx\Base\Stop\StopsBase.mqh | 头文件 | CStops (CStop 容器, 基类) |
5. | MQLx\MQL4\Stop\Stops.mqh | 头文件 | CStops (MQL4 版本) |
6. | MQLx\MQL5\Stop\Stops.mqh | 头文件 | CStops (MQL5 版本) |
7. | MQLx\Base\Stop\StopLineBase.mqh | 头文件 | CStopLine (图形表述, 基类) |
8. | MQLx\MQL4\Stop\StopLine.mqh | 头文件 | CStopLine (MQL4 版本) |
9. | MQLx\MQL5\Stop\StopLine.mqh | 头文件 | CStopLine (MQL5 版本) |
10. | MQLx\Base\Order\OrderStopBase.mqh | 头文件 | COrderStop (基类) |
11. | MQLx\MQL4\Order\OrderStop.mqh | 头文件 | COrderStop (MQL4 版本) |
12. | MQLx\MQL5\Order\OrderStop.mqh | 头文件 | COrderStop (MQL5 版本) |
13. |
MQLx\Base\Order\OrderStopVirtualBase.mqh | 头文件 |
COrderStopVirtual (虚拟停止价位, 基类) |
14. | MQLx\Base\Order\OrderStopVirtual.mqh | 头文件 |
COrderStopVirtual (MQL4 版本) |
15. |
MQLx\Base\Order\OrderStopVirtual.mqh | 头文件 |
COrderStopVirtual (MQL5 版本) |
16. | MQLx\Base\Order\OrderStopPendingBase.mqh | 头文件 |
COrderStopPending (挂单停止价位, 基类) |
17. | MQLx\Base\Order\OrderStopPending.mqh | 头文件 |
COrderStopPending (MQL4 版本) |
18. |
MQLx\Base\Order\OrderStopPending.mqh | 头文件 |
COrderStopPending (MQL5 版本) |
19. |
MQLx\Base\Order\OrderStopBroker.mqh | 头文件 |
COrderStopBroker (经纪商端停止价位, 基类) |
20. | MQLx\Base\Order\OrderStopBroker.mqh | 头文件 |
COrderStopBroker (MQL4 版本) |
21. | MQLx\Base\Order\OrderStopBroker.mqh | 头文件 |
COrderStopBroker (MQL5 版本) |
22. | MQLx\Base\Order\OrderStopsBase.mqh | 头文件 |
COrderStops (COrderStop 容器, 基类) |
23. | MQLx\Base\Order\OrderStops.mqh | 头文件 |
COrderStops (MQL4 版本) |
24. | MQLx\Base\Order\OrderStops.mqh | 头文件 |
COrderStops (MQL5 版本) |