BW MFI 定义
在本主题中,赫兹量化国联期货急速版将详细学习市场促进指数(MFI)指标。 它是由著名交易员和作家比尔·威廉姆斯开发的技术指标之一。 该指标旨在通过研究和分析价格和交易量来衡量市场方向。 这将有助于作为交易者的我们,因为它有助于检测行情的未来走势,并将提供有关当前价格走势强度的见解:是延续还是可能逆转。 这对我们非常有用,因为它有助于与市场上最强大的一方进行交易,并做出正确的决策。
为了能够了解状况,我们可以分析 MFI 和交易量。 情况可能如下:
-
如果 BW MFI 和交易量增加,则表明市场参与者对该金融产品感兴趣。
-
如果 BW MFI 和交易量减少,则表明市场参与者对该金融产品不感兴趣。
-
如果 BW MFI 增加但交易量减小,则表示交易量不支持当前走势。
-
如果 BW MFI 减少而交易量增加,则表明买卖双方之间在市场上处于平衡。
现在赫兹量化国联期货急速版来看看如何手动计算 BW MFI。 这将有助于理解其背后的主要思想或概念,其实我们现在不需要这样做,因为我们可以简单地使用内置在 MetaTrader 5 中的该指标。 为了计算 BW MFI,我们需要取最高价减去最低价后,再将结果除以交易量。
BW MFI = (High - Low) / Volume 其中: High => 最高价 Low => 最低价 Volume => 当期交易量
添加图片注释,不超过 140 字(可选)
算法
为了便于理解猴子算法,从伪代码开始是合理的。
MA 算法的伪代码:
1. 将猴子随机分布在搜索空间当中。 2. 测量猴子位置的高度。 3. 执行固定次数的局部跳转。 4. 如果在步骤 3 中得到的新顶点更高,则y以后应从该位置进行局部跳转。 5. 如果局部跳转次数限制已用尽,且未找到新顶点,则进行全局跳转。 6. 在步骤 5 之后,重复步骤 3 7. 从步骤 2 开始重复,直到满足停止准则。
赫兹量化国联期货急速版们来更详细地分析伪代码的每个关键点。
1. 在优化伊始,猴子对于搜索空间是未知的。 动物被随机定位在未知的地形中,因为食物出现的位置在任何地方都有同样可能。
2. 测量猴子所在高度的过程是由适应度函数履行任务。
3. 进行局部跳转时,算法参数中指定的数字有限制。 这意味着猴子正试图通过在觅食区域进行小范围局部跳跃来改善其当前位置。 如果新找到的食物来源更好,则转到步骤 4。
4. 找到新的食物来源,重置局部跳跃计数。 现在,将从该位置寻找新的食物来源。
5. 如果局部跳跃不能导致发现更好的食物来源,猴子得出结论,当前区域已充分探索,是时候寻找更远的新地方了。 在此刻,出现进一步跳跃的方向问题? 该算法的思路是取所有猴子的坐标中心,从而提供一些交流 — 猴群中每只猴子之间的交流:猴子可以大声尖叫,并且具有良好的空间听力,能够判定彼此间的确切位置。 同时,知道彼此的位置(伙伴们不会在没有食物的地方呼唤),故可大致计算出食物的最佳新位置,因此,有必要朝这个方向跳跃。
在原始算法中,猴子沿着一条穿过所有猴子坐标中心和动物当前位置的线进行全局跳跃。 跳转的方向可以是朝向坐标中心,也可以是与中心相反的方向。 从中心朝反方向的跳跃,与为所有猴子寻找具有近似坐标的食物的逻辑相矛盾,这已被我使用该算法的实验所证实 — 事实上,它有 50% 的概率,这是与全局最优值的距离。
实践表明,跳出坐标中心之外,比不跳或朝反方向跳跃更有利可图。 不会发生所有猴子集中在某一点的情况,尽管乍一看这种逻辑不可避免。 事实上,猴子已经用尽了局部跳跃的极限,跳得比中心更远,从而扭转了种群中所有猴子的位置。 如果我们在脑海中想象高等类人猿服从这个算法,我们会看到动物团伙不时跳过群体的几何中心,而团伙本身则朝着食物更丰富的来源移动。 这种“团伙移动”的效果在算法的动画上可以清晰地看到(原来的算法没有这个效果,且结果更差)。
6. 进行全局跳跃后,猴子开始把食物来源的位置指定到新的地方。 该过程一直持续到满足停止准则。
该算法的整个思路可以很容易地适应单个示意图。 猴子的运动用图例 1 中带有数字的圆圈表示。 每个数字都是猴子的新位置。 黄色小圆圈表示失败的局部跳转尝试。 数字 6 表示局部跳跃极限已用尽,且未找到新的最佳食物来源位置。 没有数字的圆圈代表其余团伙的位置。 团伙的几何中心由一个带有坐标(x,y)的小圆圈表示。
添加图片注释,不超过 140 字(可选)
图例 1. 猴子按团伙移动的示意图
我们来看一下 MA 的代码。
用 S_Monkey 结构描述猴子团伙很方便。 该结构包含具有当前坐标的 c [] 数组、具有最佳食物坐标的 cB [] 数组(正是从具有这些坐标的位置发生局部跳跃)、h 和 hB — 分别是当前位置的高度值,和最高点的值。 lCNT — 局部跳转计数器,用于限制尝试改善位置的次数。
//—————————————————————————————————————————————————————————————————————————————— struct S_Monkey { double c []; //coordinates double cB []; //best coordinates double h; //height of the mountain double hB; //best height of the mountain int lCNT; //local search counter }; //——————————————————————————————————————————————————————————————————————————————
C_AO_MA 猴子算法类与前面讨论的算法没有什么不同。 猴子团伙在类中表示为 m[] 结构数组。 类中声明的方法和成员代码量都很小。 这是由于算法简洁,因此与许多其它优化算法不同,此处无需排序。 我们将需要数组来设置优化参数的最大值、最小值和步长,以及常量变量以便能将算法的外部参数传递给它们。 我们继续讲述包含 MA 主逻辑的方法。
//—————————————————————————————————————————————————————————————————————————————— class C_AO_MA { //---------------------------------------------------------------------------- public: S_Monkey m []; //monkeys public: double rangeMax []; //maximum search range public: double rangeMin []; //minimum search range public: double rangeStep []; //step search public: double cB []; //best coordinates public: double hB; //best height of the mountain public: void Init (const int coordNumberP, //coordinates number const int monkeysNumberP, //monkeys number const double bCoefficientP, //local search coefficient const double vCoefficientP, //jump coefficient const int jumpsNumberP); //jumps number public: void Moving (); public: void Revision (); //---------------------------------------------------------------------------- private: int coordNumber; //coordinates number private: int monkeysNumber; //monkeys number private: double b []; //local search coefficient private: double v []; //jump coefficient private: double bCoefficient; //local search coefficient private: double vCoefficient; //jump coefficient private: double jumpsNumber; //jumps number private: double cc []; //coordinate center private: bool revision; private: double SeInDiSp (double In, double InMin, double InMax, double Step); private: double RNDfromCI (double min, double max); private: double Scale (double In, double InMIN, double InMAX, double OutMIN, double OutMAX, bool revers); }; //——————————————————————————————————————————————————————————————————————————————
公开 Init() 方法初始化算法。 在此,我们设置数组的大小。 我们用尽可能小的“双精度”值初始化猴子找到的最佳领土的品质,我们将对 MA 结构数组的相应变量执行相同的操作。
//—————————————————————————————————————————————————————————————————————————————— void C_AO_MA::Init (const int coordNumberP, //coordinates number const int monkeysNumberP, //monkeys number const double bCoefficientP, //local search coefficient const double vCoefficientP, //jump coefficient const int jumpsNumberP) //jumps number { MathSrand ((int)GetMicrosecondCount ()); // reset of the generator hB = -DBL_MAX; revision = false; coordNumber = coordNumberP; monkeysNumber = monkeysNumberP; bCoefficient = bCoefficientP; vCoefficient = vCoefficientP; jumpsNumber = jumpsNumberP; ArrayResize (rangeMax, coordNumber); ArrayResize (rangeMin, coordNumber); ArrayResize (rangeStep, coordNumber); ArrayResize (b, coordNumber); ArrayResize (v, coordNumber); ArrayResize (cc, coordNumber); ArrayResize (m, monkeysNumber); for (int i = 0; i < monkeysNumber; i++) { ArrayResize (m [i].c, coordNumber); ArrayResize (m [i].cB, coordNumber); m [i].h = -DBL_MAX; m [i].hB = -DBL_MAX; m [i].lCNT = 0; } ArrayResize (cB, coordNumber); } //——————————————————————————————————————————————————————————————————————————————
第一个公开方法 Moving(),需要在每次迭代时执行,实现猴子跳跃逻辑。 在第一次迭代中,若 “revision” 标志为 “false” 时,则有必要采用所研究空间坐标范围内的随机值初始化代理者,这相当于猴子在团伙栖息地内的随机位置。 为了减少重复的乘法运算,例如计算全局和局部跳转的系数,我们将相应坐标的值(每个坐标可以有自己的维度)存储在 v [] 和 b [] 数组当中。 我们将每只猴子的局部跳跃计数器重置为零。
//---------------------------------------------------------------------------- if (!revision) { hB = -DBL_MAX; for (int monk = 0; monk < monkeysNumber; monk++) { for (int c = 0; c < coordNumber; c++) { m [monk].c [c] = RNDfromCI (rangeMin [c], rangeMax [c]); m [monk].c [c] = SeInDiSp (m [monk].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); m [monk].h = -DBL_MAX; m [monk].hB = -DBL_MAX; m [monk].lCNT = 0; } } for (int c = 0; c < coordNumber; c++) { v [c] = (rangeMax [c] - rangeMin [c]) * vCoefficient; b [c] = (rangeMax [c] - rangeMin [c]) * bCoefficient; } revision = true; }
为了计算所有猴子的坐标中心,需用到 cc [] 数组,其维度对应于坐标数量。 此处的思路是将猴子的坐标相加,然后将结果总和除以团伙规模。 因此,坐标的中心既是坐标的算术平均值。
//calculate the coordinate center of the monkeys---------------------------- for (int c = 0; c < coordNumber; c++) { cc [c] = 0.0; for (int monk = 0; monk < monkeysNumber; monk++) { cc [c] += m [monk].cB [c]; } cc [c] /= monkeysNumber; }
根据伪代码,如果没有达到局部跳跃的极限,猴子就以相等的概率从它当前位置向各个方向跳跃。 局部跳跃圆圈的半径由局部跳跃系数调节,该系数根据 b[] 数组坐标的维数重新计算。
//local jump-------------------------------------------------------------- if (m [monk].lCNT < jumpsNumber) //local jump { for (int c = 0; c < coordNumber; c++) { m [monk].c [c] = RNDfromCI (m [monk].cB [c] - b [c], m [monk].cB [c] + b [c]); m [monk].c [c] = SeInDiSp (m [monk].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); } }
我们继续讨论 MA 算法逻辑中非常重要的部分 — 算法的性能在很大程度上取决于全局跳转的实现。 不同的作者从不同的角度应对这个问题,提供了各种各样的解。 根据研究,局部跳跃对算法的收敛性影响不大。 全局跳跃决定了算法从局部极值“跳跃”的能力。 我对全局跳跃的实验揭示出针对这种特定算法这是仅有的可行方法,能改善结果。
上面,我们讨论了朝坐标中心跳跃的可取性,如果终点在中心后面,而不是在中心和当前坐标之间,那就更好了。 这种方式应用了我们在关于杜鹃鸟优化算法(COA)一文中详述的 利维(Levy)飞行方程。
添加图片注释,不超过 140 字(可选)
图例 2. 利维(Levy)飞行函数的图形取决于方程度数
猴子坐标使用以下公式计算:
m [monk].c [c] = cc [c] + v [c] * pow (r2, -2.0);