期货量化交易软件:利用 MQL5 实现 Janus 因子
概述
每位交易者都知道市场价格遵循两种广义的形态之一。 价格要么形成趋势,要么横盘移动。 这样的结果就是,市场参与者的策略在很大程度上可以简化为顺势、或在某种程度上逆势。 Janus 因子是一种捕捉这种二元市场行为的理论。 在本文中,赫兹量化软件将解密其基础,并演示促进这种分析方法的指标实现。

反馈
根据 Janus 理论,市场是由价格之间的相互作用,以及交易者对价格的反应驱动的。 安德森(Anderson)将这种相互作用比作反馈系统。 读者可以在维基百科上了解有关反馈系统的更多信息。 当市场处于趋势时,市场参与者会因利润奔跑而展现出信心。 在上升趋势中,较高的价格证实了参与者对趋势的预期,而这反过来又会吸引更多人买入。 这样做具有推高价格的效果。

图例.1 描绘上升趋势中的正反馈。
在下降趋势中,价格下跌会给交易者灌输恐惧,导致他们抛售从而尽量减少损失。 更多的抛售给价格带来压力,推动它们走低。 因此,市场趋势是反馈最积极的一个例子。 价格将继续加速,直到交易者对价格变化做出反应。

图例.2 描绘下跌趋势中的正反馈。
当交易者对市场缺乏信心时,就会看到负面反馈,因此他们选择在价格走势后提前锁定盈利。 过早获利回吐会扼杀限制价格走势幅度的动量。 再加上多头和空头之间的不断争斗,效果是价格暂时趋于稳定。

图例.3 市场的负反馈
资金流
这种反馈概念的一个重要因素是,当不同条件盛行时交易者偏好的品种类型。 安德森对股票的分析表明,在上升趋势中,交易者青睐绩效相对更好的股票,同时从表现不佳的股票撤资。 在下跌趋势中,表现不佳的股票损失最大,因为交易员看中它们只是为了短线盈利。
在缺乏趋势的情况下,无法区分出很多强势和弱势股票,因为交易者会选择特定的价格水平来入场和离场。 考虑到这一点,他假设,通过分析一组股票的相对绩效,可以检测到负反馈和正反馈的时期。
计算 Janus 因子
为了确定绩效,计算定期回报。 将所研究的一组股票的回报结合起来,产生一个平均值,当作衡量基准线。 称其为基准回报。 被评估股票的集合则作为参照指数。
在 Janus Factor - Trend Follower's Guide to Market Dialectics 一书中,安德森阐述了根据回报率计算的各种股票指标,他用它来洞察市场行为。
Janus 函数库 - janus.mqh
所有计算 Janus 相关的通用数据和例程都包含在 janus.mqh 之中。 包含文件声明了三种自定义类型:
CSymboldata 类处理品种数据和相关操作。
//+------------------------------------------------------------------+ //|Class which manage the single Symbol | //+------------------------------------------------------------------+ class CSymbolData { private: string m_name; // name of the symbol ENUM_TIMEFRAMES m_timeframe;// timeframe int m_length; // length for copy rates MqlRates m_rates[]; // store rates datetime m_first; // first date on server or local history datetime SetFirstDate(void) { datetime first_date=-1; if((datetime)SymbolInfoInteger(m_name,SYMBOL_TIME)>0) first_date=(datetime)SeriesInfoInteger(m_name,m_timeframe,SERIES_FIRSTDATE); //--- if(first_date==WRONG_VALUE || first_date==0) { if(TerminalInfoInteger(TERMINAL_CONNECTED)) { while(!SeriesInfoInteger(m_name,m_timeframe,SERIES_SERVER_FIRSTDATE,first_date) && !IsStopped()) Sleep(10); } } //--- #ifdef DEBUG Print(m_name," FirstDate ",first_date); #endif return first_date; } public: CSymbolData(string name,ENUM_TIMEFRAMES tf=PERIOD_CURRENT) { m_name = name; m_length = 0; m_timeframe = tf; SymbolSelect(m_name,true); } ~CSymbolData(void) { ArrayFree(m_rates); } datetime GetFirstDate(void) { m_first = SetFirstDate(); return m_first; } string GetName(void) { return m_name; } int GetLength(void) { return m_length; } void SetLength(const int set_length) { if(set_length>0) { m_length=set_length; ArrayResize(m_rates,m_length,m_length); ArraySetAsSeries(m_rates,true); } } bool Update(void) { int copied = CopyRates(m_name,m_timeframe,0,m_length,m_rates); #ifdef DEBUG Print("copied ", copied, " requested ", m_length); #endif //-- return copied == m_length; }; MqlRates GetRateAtPos(const int i) { if(i<0 || i>=m_length) { #ifdef DEBUG Print("Array out of range ",i,".Size of array is ",m_length); #endif return (i<0)?m_rates[0]:m_rates[m_length-1]; } return m_rates[i]; } };
CSymbolCollection是 CSymboldata 对象的容器,它表示正在分析的品种集合。 这两个类的代码都改编自 Mql5 代码库中的清单。 对基础缓冲区的索引方向进行了修改。 应当注意的是,所有类都实现了从右到左的索引格式,零索引指向最新的柱线。
为了演示 Janus 因子技术,赫兹量化软件将将其应用于金融对的分析。 安德森最初设计的方法是为了分析股票,但大多数经纪商的股票代码数据可用性并不一致。