请 [注册] 或 [登录]  | 返回主站

量化交易吧 /  量化策略 帖子:3364712 新帖:33

基于价格运动方向和速度的交易策略

我是一个土豆发表于:4 月 17 日 19:16回复(1)

简介

我们都知道当流动性充分的市场价格运动时,总是呈现出周期性的本质,先上涨然后下跌。在长周期时间框架下能够很清晰的看到这个现象。价格运动具有某种持续性正是正弦性本质的反应。否则将看上去像zigzag:价格在短时间内突然的上升和下降运动。让我们试图找出产生这种现象的原因并且将其运用到交易中。


价格运动的开始和持续

世界上的任何运动都可以被运动的方向,加速度和速度所表征。在金融市场中同样适用。这预示着一条重要的法则,那就是强烈的运动不会立即停止。就好比一列火车:当列车以全速运行时踩下刹车,那么此时的刹车距离可能长达1公里。

那么趋势何时开始呢?当绝大多数市场参与者由于某些原因转变他们的观点时,无论是涉及全球经济趋势的改变还是其他一些能影响市场走向的重要因素。群体性意见形成后那么趋势就开始了。市场参与者越来越相信价格运动会变得越来越强烈,而且会继续下去。进入市场的大玩家交易量巨大,因此价格运动会有方向,加速度和特定速度。那些在趋势开始时进入的交易者会给市场带来一个冲击和速度,并开始盈利。其他后进入市场的交易者的价格优势就没有那么明显了。和最先进入市场的交易者不同,他们试图利用价格运动的方向。

当变化到来时趋势结束。但为何价格仍然以其本来方式运行?为何不是突然变化?原因就是那些推动价格往其希望方向运动的人开始平仓了,因此抑制了趋势。而那些刚刚“驾驭波浪”的交易者仍旧坚信一切都没变化,甚至是图继续使价格朝原本方向运动。这列“列车”不会立即停止。直到它开始向反方向运动,此时趋势结束。


如何才能不被这列“列车”碾压的交易策略

利用价格运动获利的交易思想基于分析当前的趋势深度,例如趋势的幅度和持续时间。

为了给出一个形象的例子,我们使用经典指标RSI (相对强弱指标)和AC(加速/减速指标)。

1. 进入市场的条件

我们使用第一个指标来表征当前价格运动的幅度和速度。

我们通过分级来确定距离和幅度:

图1 RSI 震荡器的水平

图 1. RSI 震荡器的水平

价格运动幅度的评价标准

  • 40 - 60 区间被认为是平稳区域(震荡区域)。当价格在此区间时没有任何趋势。0代表无显著趋势。

买入区间:

  • 60-70 区间 — 这是可能一个上升趋势的开始。用1代表。
  • 70-80 区间 — 上升趋势更为显著。运动开始加速。用2代表。
  • 80-90 区间 - 运动保持原来方向。全速运行。用3代表。
  • 90-100 区间。根据指标规则,这是一个单边运动,没有任何回退。非常的少见。用4代表这种情况。

用类似的方式来表示卖出的情况:

  • 30-40 区间。开始下跌。用 -1 表示。
  • Zone 20-30. 运动开始加速。用 -2 表示。
  • 10-20 区间。稳定的下降趋势。用 -3 表示。
  • 0-10 区间。强烈的单边运动区间。用 -4 表示。

我们可以用如下的MQL4语言来描述上述场景:

//--- 买
   double rsi=iRSI(Symbol(),tf,period,PRICE_CLOSE,0);
   index_rsi = 0;
   if(rsi>90.0) index_rsi=4;
   else if( rsi > 80.0 ) 
   index_rsi = 3;
   else if( rsi > 70.0 ) 
   index_rsi = 2;
   else if( rsi > 60.0 ) 
   index_rsi = 1;
   else if( rsi < 10.0 ) 
   index_rsi = -4;
   else if( rsi < 20.0 ) 
   index_rsi = -3;
   else if( rsi < 30.0 ) 
   index_rsi = -2;
   else if( rsi < 40.0 ) 
   index_rsi = -1;

我们使用比尔威廉姆斯的AC指标,来衡量当前价格运动的速度和加速度。

图 2. AC指标

图 2. AC指标

衡量速度的标准

增长率。

  • 首先是比较当前和前一个K线。如果当前K线超过了前一个,很可能价格要加速上涨。用1表示。
  • 其次是比较相邻的3个柱形(从当前到第二个K线)。如果后面每一根K线都超过它前面的K线,我们可以认为价格在不断的加速上涨。用2表示。
  • 类似的可以比较连续的4根K线,每一个前面的K线增幅都小于后来的K线。用3表示。
  • 比较最近的连续5根K线,如果都是同一个方向。用4表示。

下跌。

  • 类似的。比较当前K线和前一跟K线。如果当前K线比前一个小,用-1代表。
  • 比较3根K线,当前的都小于前一个。用 -2 表示。
  • 比较4根K线。用 -3 代表。
  • 比较5根K线。用 -4 代表。

MQL4中实现如下:

double ac[];
   ArrayResize(ac,5);
   for(int i=0; i<5; i++)
      ac[i]=iAC(Symbol(),tf,i);

   index_ac=0;
//--- 买入信号
   if(ac[0]>ac[1])
      index_ac=1;
   else if(ac[0]>ac[1] && ac[1]>ac[2])
      index_ac=2;
   else if(ac[0]>ac[1] && ac[1]>ac[2] && ac[2]>ac[3])
      index_ac=3;
   else if(ac[0]>ac[1] && ac[1]>ac[2] && ac[2]>ac[3] && ac[3]>ac[4])
      index_ac=4;
//--- 卖出信号
   else if(ac[0]<ac[1])
      index_ac=-1;
   else if(ac[0]<ac[1] && ac[1]<ac[2])
      index_ac=-2;
   else if(ac[0]<ac[1] && ac[1]<ac[2] && ac[2]<ac[3])
      index_ac=-3;
   else if(ac[0]<ac[1] && ac[1]<ac[2] && ac[2]<ac[3] && ac[3]<ac[4])
      index_ac=-4;

如果我们得到了运动幅度表示值并且知道运动速度,就能够对入场条件进行设定了。

入场条件有:

//--- 买入信号
if(index_rsi==1 && index_ac>=1) //潜在的多头运动
if(index_rsi==2 && index_ac>=1) //弱的多头运动
if(index_rsi==3 && index_ac==1) //弱的多头运动
if(index_rsi==3 && index_ac>=2) //适度的多头运动
if(index_rsi==4 && index_ac>=1) //强烈的多头运动

//--- 卖出信号  
if(index_rsi==-1 && index_ac<=-1) //潜在的空头运动
if(index_rsi==-2 && index_ac<=-1) //弱的空头运动
if(index_rsi==-3 && index_ac==-1) //弱的空头运动
if(index_rsi==-3 && index_ac<=-2) //适度的空头运动
if(index_rsi==-4 && index_ac<=-1) //强烈的空头运动

//--- flat 
if(index_rsi==0) 



2. 出场条件

我们已经定义并对入场参数进行了分类。接下来将通过如下分析来解释出场条件是如何形成的。

打个比方,想象成像孩子的玩具橡胶球。现在让我们想象一下如果从很高的地方将这个球扔进水里会发生什么。首先它会下降并且由于重力加速度的原因加速下降。然后它撞向水面。但是它有足够的速度沉入水底一定深度,直到出现反向速度。受到 阿基米德定律影响,它会浮出水面。

现在我们仔细分析下这个例子:

  • 你已经直到这个球就是价格。
  • 扔球的人代表启动趋势的市场参与者。
  • 引起加速度的重力代表了当趋势出现时参与进来的交易者。
  • 水代表影响改变价格运动方向的重要因素。
  • 阿基米得定律代表那些启动趋势者的平仓操作。

决定获利的两个主要因素如下:

  1. 确定球被扔出即买卖的时间。
  2. 当球落入水里并减速时平仓。

要测定球的下落距离是很难的,因为在金融市场中我们看不到抛球的人以及水。我们仅能看到球的速度和方向。

我们已经讨论了测量价格运动幅度和速度的准则。

现在我们要将其量化:

//--- 下跌反转的可能
if(index_rsi>2 && index_ac<0) 

当价格向上运动了很长一段时间,加速度开始减小时(开始反向)。这时趋势改变就十分可能到来。

//--- 上涨反转的可能
if(index_rsi<-2 && index_ac>0) 

同给出的例子相似:球已经下跌相当长一段时间,但跌入水中并且水的浮力将其推向另一个方向。这预示着是平仓的时候了。


3. 增强入场和出场的效率

众所周知,某些交易指标如果使用大周期会更好的反应对价格运动速度的变化。但也会出现更多的虚假信号。

另一种办法就是不将其计算周期变小,而是追踪其在不同的时间框架下的表现。

图 3. 基于RSI 和 AC 信号的不同时间周期下的趋势。

图 3. 基于RSI 和 AC 信号的不同时间周期下的趋势。

基于我们的标准及RSI和AC指标,图中清晰的展现了价格的运动趋势。我们来仔细观察下。

M1图上的运动和速度:强烈的运动, AC值为4,RSI指数为2。M5图上的运动幅度一样但是速度为1。15分钟图表上的运动类似,但是没有短时间框架下的那么明显。至于30分钟和1小时图表,我们看到30分钟图上已经出现了一个信号,并且1小时图上已经减速甚至可能出现反转信号。

这个例子给了我们一个综合结果:

如果仅仅考虑H1,我们会下一个卖单等待价格反转。但是在更短的时间框架上来分析的话,这将是一个假信号。


4. 用EA实现交易策略

EA代码:

//+------------------------------------------------------------------+
//|                                                       tester.mq4 |
//|                                                Alexander Fedosov |
//+------------------------------------------------------------------+
#property copyright "Alexander Fedosov"
#property strict
#include <trading.mqh>      //交易函数库
//+------------------------------------------------------------------+
//| Parameters                                                       |
//+------------------------------------------------------------------+
input int             SL = 40;               // 止损
input int             TP = 70;               // 止赢
input bool            Lot_perm=true;         // 根据帐户余额确定交易量
input double          lt=0.01;               // 交易量
input double          risk = 2;              // 风险,%
input int             slippage= 5;           // 滑点
input int             magic=2356;            // Magic数字
input int             period=8;              // RSI 指标周期
input ENUM_TIMEFRAMES tf=PERIOD_CURRENT;     // EA运行周期
int dg,index_rsi,index_ac;
trading tr;
//+------------------------------------------------------------------+
//| EA初始化函数                                                      |
//+------------------------------------------------------------------+
int OnInit()
  {
//---为交易函数辅助类确定变量
//--- 报错显示,默认俄语
   tr.ruErr=true;
   tr.Magic=magic;
   tr.slipag=slippage;
   tr.Lot_const=Lot_perm;
   tr.Lot=lt;
   tr.Risk=risk;
//--- 尝试次数
   tr.NumTry=5;
//--- 确定当前图表的报价位数
   dg=tr.Dig();
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 主函数                                                            |
//+------------------------------------------------------------------+
void OnTick()
  {
   depth_trend();
   speed_ac();
//--- 侦测未平仓订单
   if(OrdersTotal()<1)
     {
      //--- 侦测买入条件
      if(Buy())
         tr.OpnOrd(OP_BUY,tr.Lots(),Ask,SL*dg,TP*dg);
      //---侦测卖出条件
      if(Sell())
         tr.OpnOrd(OP_SELL,tr.Lots(),Bid,SL*dg,TP*dg);
     }
//--- 有未平仓订单吗?
   if(OrdersTotal()>0)
     {
      //---侦测到如果满足平仓条件则平仓卖单。
      if(Sell_close())
         tr.ClosePosAll(OP_SELL);
      //---侦测到如果满足平仓条件则平仓买单。
      if(Buy_close())
         tr.ClosePosAll(OP_BUY);
     }

  }
//+------------------------------------------------------------------+
//| 确定趋势幅度的函数                                                  |
//+------------------------------------------------------------------+
void depth_trend()
  {
//--- 买
   double rsi=iRSI(Symbol(),tf,period,PRICE_CLOSE,0);
   index_rsi = 0;
   if(rsi>90.0) index_rsi=4;
   else if(rsi>80.0)
      index_rsi=3;
   else if(rsi>70.0)
      index_rsi=2;
   else if(rsi>60.0)
      index_rsi=1;
   else if(rsi<10.0)
      index_rsi=-4;
   else if(rsi<20.0)
      index_rsi=-3;
   else if(rsi<30.0)
      index_rsi=-2;
   else if(rsi<40.0)
      index_rsi=-1;
  }
//+------------------------------------------------------------------+
//| 确定趋势速度的函数                                                  |
//+------------------------------------------------------------------+
void speed_ac()
  {
   double ac[];
   ArrayResize(ac,5);
   for(int i=0; i<5; i++)
      ac[i]=iAC(Symbol(),tf,i);

   index_ac=0;
//--- 买入信号
   if(ac[0]>ac[1])
      index_ac=1;
   else if(ac[0]>ac[1] && ac[1]>ac[2])
      index_ac=2;
   else if(ac[0]>ac[1] && ac[1]>ac[2] && ac[2]>ac[3])
      index_ac=3;
   else if(ac[0]>ac[1] && ac[1]>ac[2] && ac[2]>ac[3] && ac[3]>ac[4])
      index_ac=4;
//--- 卖出信号
   else if(ac[0]<ac[1])
      index_ac=-1;
   else if(ac[0]<ac[1] && ac[1]<ac[2])
      index_ac=-2;
   else if(ac[0]<ac[1] && ac[1]<ac[2] && ac[2]<ac[3])
      index_ac=-3;
   else if(ac[0]<ac[1] && ac[1]<ac[2] && ac[2]<ac[3] && ac[3]<ac[4])
      index_ac=-4;
  }
//+------------------------------------------------------------------+
//| 侦测买入条件的函数                                                  |
//+------------------------------------------------------------------+
bool Buy()
  {
   bool res=false;
   if((index_rsi==2 && index_ac>=1) || (index_rsi==3 && index_ac==1))
      res=true;
   return (res);
  }
//+------------------------------------------------------------------+
//| 侦测卖出条件的函数                                                  |
//+------------------------------------------------------------------+
bool Sell()
  {
   bool res=false;
   if((index_rsi==-2 && index_ac<=-1) || (index_rsi==-3 && index_ac==-1))
      res=true;
   return (res);
  }
//+------------------------------------------------------------------+
//| 侦测买单平仓条件的函数                                              |
//+------------------------------------------------------------------+
bool Buy_close()
  {
   bool res=false;
   if(index_rsi>2 && index_ac<0)
      res=true;
   return (res);
  }
//+------------------------------------------------------------------+
//| 侦测卖单平仓条件的函数                                              |
//+------------------------------------------------------------------+
bool Sell_close()
  {
   bool res=false;
   if(index_rsi<-2 && index_ac>0)
      res=true;
   return (res);
  }


我们仅使用两个参数对策略进行略微优化:tf (时间周期)和period (RSI指标周期)。

在M15上得到如下结果:


图 4. EA历史数据回测结果

注意!这仅仅是测试版。我们不建议将它用于测试和实盘交易。

总结

由于不可能预测市场行为,确定趋势的开始和结束对于全球交易者来说都是一件复杂的事情。

但是确定当前趋势的入场和出场时间来赚取可观的利润却是完全可能做到的。在这种情况下确定和动态追踪价格运动的速度我们的方法是适用的。

祝你交易成功。


全部回复

0/140

量化课程

    移动端课程