股票量化软件:在赫兹量化中如何创建自己的追踪止损

1. 创建追踪止损的基类

如前文所述,存在大量的追踪止损,但它们都具有共同的功能面:

  • 确定持仓类型(方向)

  • 确定持仓的当前止损水平

  • 计算新的止损水平

  • 检查是否需要更改当前的止损水平

  • 修改持仓的止损水平

追踪止损的类型仅决定计算的止损水平的值。因此,追踪止损的基本功能性将包含基类中。对于依赖于追踪止损类型的功能性,我们将创建子类。应用至这些子类的方法将通过基类的虚拟方法实现。

由于我们计划使用技术指标,要确保它们的稳定操作,需要向它们提供周期性装置。为此,我们将使用计时器。我们还计划开启/关闭追踪止损(在将类用作手工操作的交易系统的一部分时),并使用图形对象 - 按钮来实现此操作(在将类用作辅助“EA 交易”的一部分时)。根据这些功能要求,基类将具有以下方法集:

 
 

class CTrailingStop { protected: public: void CTrailingStop(){}; void ~CTrailingStop(){}; void Init(){}; // 初始化类 bool StartTimer(){}; // 启动计时器 void StopTimer(){}; // 停止计时器 void On(){}; // 开启追踪止损 void Off(){}; // 关闭追踪止损 bool DoStoploss(){}; // 控制持仓止损水平的主函数 void EventHandle(){}; // 处理图标时间的方法(按下按钮开启追踪止损) void Deinit(){}; // 去初始化 virtual bool Refresh(){}; // 刷新指标 virtual void Setparameters(){}; // 设置参数和加载指标 virtual int Trend(){}; // 由指标显示的趋势 virtual double BuyStoploss(){}; // 买入持仓的止损值 virtual double SellStoploss(){}; // 卖出持仓的止损值 };

在调用 Init() 方法时,它将接收不依赖于所使用追踪止损的类型的通用参数。该方法将设置追踪止损模式,并使用一些市场参数来准备变量。

  • StartTimer() - 将用于启动周期性寻址指标以及将其强制性存储在终端缓存中所需的计时器。

  • Stoptimer() - 将用于在结束“EA 交易”的工作时停止计时器。

  • On() - 启用追踪止损并设置按钮为按下模式(如果使用按钮)。

  • Off() - 禁用追踪止损并设置按钮为未按下模式(如果使用按钮)。

  • DoStoploss() - 控制持仓的止损水平的主方法。

  • EventHandle() - 用于处理图表事件,特别是响应按下按钮和基于按钮位置开启/关闭追踪止损。

  • Deinit() - 在“EA 交易”结束其工作时运行,确保释放指标句柄。

  • Refresh() - 刷新指标值。需要该方法以在计算止损值前确定指标的当前值。同样地,该方法是独立使用的 - 它由计时器定期调用,以保持指标处于工作状态。

  • SetParameters() - 在您调用此方法时,它将接收指标参数,指标和指定的参数一起加载。

  • Trend() - 确定通过指标显示的趋势的方法。如果指标显示上行方向,该方法返回值 1;如果显示下行方向,返回值 -1。

  • BuyStoploss() 和 SellStoploss() 方法将返回指标计算的买入和卖出持仓止损的新值。

1.1. Init() 方法

Init() 方法是创建类的实例后调用的首个方法。它接收独立于追踪止损类型的通用参数:交易品种、时间表、追踪止损模式(按订单号或按柱)、附加或不附加指标至图表、创建或不创建按钮。接下来,它将接收按钮属性:按钮的 X 坐标、按钮的 Y 坐标、按钮颜色、按钮标题颜色。

后续工作所需的参数存储在类变量中。此外,在 Init() 方法工作时,它将确定止损所需的主要未变更市场参数:逗号后面的位数和点的值。最后,取决于追踪止损的类型,按钮名称及其标题形成。如果设置为使用按钮,将创建按钮。

我们在“保护”部分声明所有需要的变量:

 
 

protected: string m_symbol; // 交易品种 ENUM_TIMEFRAMES m_timeframe; // 时间框架 bool m_eachtick; // 在每个tick上运行 bool m_indicator; // 在图表上显示指标 bool m_button; // 显示“开/关”按钮 int m_button_x; // 按钮的x坐标 int m_button_y; // 按钮的y坐标 color m_bgcolor; // 按钮颜色 color m_txtcolor; // 按钮标题颜色 int m_shift; // 柱形偏移量 bool m_onoff; // 开关 int m_handle; // 指标句柄 datetime m_lasttime; // 最近一次执行追踪止损的时间 MqlTradeRequest m_request; // 交易请求结构体 MqlTradeResult m_result; // 交易请求结果结构体 int m_digits; // 价格的小数点后的位数 double m_point; // 点值 string m_objname; // 按钮名称 string m_typename; // 追踪止损类型名称 string m_caption; // 按钮标题

现在我们来编写 Init() 方法本身:

 
 

//--- 追踪止损初始化方法 void Init(string symbol, ENUM_TIMEFRAMES timeframe, bool eachtick = true, bool indicator = false, bool button = false, int button_x = 5, int button_y = 15, color bgcolor = Silver, color txtcolor = Blue) { //--- 设置参数 m_symbol = symbol; // 交易品种 m_timeframe = timeframe; // 时间框架 m_eachtick = eachtick; // true - 每个tick上运行,false - 每个bar上运行一次 //--- 设置指标值应用的柱形 if(eachtick) { m_shift=0; // 在每个tick模式下创建柱形 } else { m_shift=1; // 在每个bar模式下创建柱形 } m_indicator = indicator; // true - 将指标附着到图表上 m_button = button; // true - 创建按钮来开/关追踪止损 m_button_x = button_x; // 按钮的x坐标 m_button_y = button_y; // 按钮的y坐标 m_bgcolor = bgcolor; // 按钮颜色 m_txtcolor = txtcolor; // 按钮标题颜色 //--- 获取不变的市场历史 m_digits=(int)SymbolInfoInteger(m_symbol,SYMBOL_DIGITS); // 价格的小数点后的位数 m_point=SymbolInfoDouble(m_symbol,SYMBOL_POINT); // 点值 //--- 创建按钮名称和标题 m_objname="CTrailingStop_"+m_typename+"_"+symbol; //按钮名称 m_caption=symbol+" "+m_typename+" Trailing"; // 按钮标题 //--- 填充交易请求结构体 m_request.symbol=m_symbol; //准备交易请求结构体,设置交易品种 m_request.action=TRADE_ACTION_SLTP; //准备交易请求结构体,设置交易操作类型 //--- 创建按钮 if(m_button) { ObjectCreate(0,m_objname,OBJ_BUTTON,0,0,0); // 创建 ObjectSetInteger(0,m_objname,OBJPROP_XDISTANCE,m_button_x); // 设置x轴坐标 ObjectSetInteger(0,m_objname,OBJPROP_YDISTANCE,m_button_y); // 设置y轴坐标 ObjectSetInteger(0,m_objname,OBJPROP_BGCOLOR,m_bgcolor); // 设置背景颜色 ObjectSetInteger(0,m_objname,OBJPROP_COLOR,m_txtcolor); // 设置标题颜色 ObjectSetInteger(0,m_objname,OBJPROP_XSIZE,120); // 设置宽度 ObjectSetInteger(0,m_objname,OBJPROP_YSIZE,15); // 设置高度 ObjectSetInteger(0,m_objname,OBJPROP_FONTSIZE,7); // 设置字体大小 ObjectSetString(0,m_objname,OBJPROP_TEXT,m_caption); // 设置按钮标题 ObjectSetInteger(0,m_objname,OBJPROP_STATE,false); // 设置按钮状态,默认关闭 ObjectSetInteger(0,m_objname,OBJPROP_SELECTABLE,false); // 用户不能选择和移动按钮,仅能点击它 ChartRedraw(); // 图标重绘 } //--- 设置追踪止损的状态 m_onoff=false; // 追踪止损的状态 - 开/关,默认关 };

您可以看到,在创建按钮名称和标题时使用了 m_typename 变量,该变量未使用任何值进行初始化。子类构造函数将分配一个值给该变量。因此,使用不同追踪止损方法,它将具有对应于所用追踪止损类型的不同的值。

1.2. StartTimer() 方法

StartTimer() 方法用于启动“EA 交易”的通用计时器。

 
 

//--- 开启计时器 bool StartTimer() { return(EventSetTimer(1)); };

使用计时器时,您必须将 Refresh() 方法的调用添加至 OnTimer() 函数,以周期性请求指标。

1.3. StopTimer() 方法

StopTimer() 方法用于停止“EA 交易”的计时器。

 
 

//--- 停止计时器 void StopTimer() { EventKillTimer(); };

使用该方法,当“EA 交易”结束工作时,该方法将停止计时器。在运行类的 Deinit() 方法时,该方法将被调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值