开发自适应算法(第一部分):寻找基本模式

Maxim Romanov | 5 三月, 2021

介绍

任何交易算法通常都是一种工具,它可以给有经验的交易者带来利润,也可以瞬间使没有经验的交易者爆仓。创造一个可以获利和可靠的算法的问题是,我们无法理解为了赚钱需要做什么,以及“成功的交易者”使用什么方法。虽然高频交易、套利、期权策略和基于日历价差的系统拥有坚实的理论基础,清楚地说明了盈利需要做些什么,但基于价格分析和基本面数据的算法则更加模糊。这一领域没有完整的理论基础来描述定价,因此很难创建一个稳定的交易算法。在这里,交易变成了艺术,而科学有助于将一切系统化。

但是,是否有可能创建一个完全自动化的交易算法,只基于对任何交易工具的价格变化进行分析,而不进行优化,也不需要分别手动调整每个交易工具的参数?有没有一种算法,你可以简单地应用到一个必要的交易工具图表,以便它立即定义盈利的参数呢? 

有可能不管市场如何变化,算法一直不会亏损吗?我相信,这是可能的,尽管很难实现。解决这个问题有两种方法:

  1. 将神经网络与机器学习结合起来,得到一个“黑匣子”,按照自己的标准分析市场和盈利。尽管这种方法显而易见,也很有吸引力,但它有其自身的复杂性。如果这么容易做到的话,那么像谷歌和 Yandex 这样在使用机器学习和大量预算方面有着丰富经验的公司早就解决了这个问题,或者至少他们在市场数据分析和预测质量方面处于领先地位。我相信,有可能创建这样一个算法。它应该随着技术的发展而不断完善,以保持竞争力。毕竟,你将不得不与科技巨头竞争。
  2. 研究价格模式,建立价格形成的理论模型,并创建一个算法,创建尽可能多的影响定价的因素。在我看来,这种方法甚至比机器学习更复杂,但我认为它也是真实的。这种算法将随着理论背景的发展和开发人员知识的积累而不断完善,它还需要不断的更新。

我决定使用第二种方法,即创建一个完整的理论,并在此基础上开发一个算法。我将在一系列文章中开发这个算法,从一个小模式发展到一个大项目。此外,我将展示如何发现和研究模式,同时提高工作效率。

第一种算法将仅针对外汇交易和MetaTrader 4终端开发。在这一过程中,它将演变成一个通用的MetaTrader 5算法,在外汇和交易所都能工作。

基本模式

让我们从搜索构成算法基础的基本模式开始。这种模式应该是基本的,并且在大多数市场中都是固有的,以便在未来的任何市场中都能轻松地扩展。任何市场的可扩展性都表明该算法是真正的自适应算法。

首先,让我们来解释一下为什么在市场上很难持续盈利。这完全是关于直接竞争。有些交易者的任务是与其他交易者达成一笔有利可图的交易,但问题是,每一方都想达成一笔有利可图的交易,而有人肯定会蒙受损失。因此,市场不应该有每个人都能注意到的稳定的简单模式。

在我的第一篇文章《价格序列离散化、随机成分和“噪声”》中,我提到了市场中的随机成分,价格序列的增量分布与随机游走的增量分布非常相似。乍一看,价格序列似乎没有规律,一切都是随机发生的,不可能靠这个赚稳定的钱。

因此,作为一个基本原则,我认为任何资产的上涨烛形和下跌烛形的数量是完全相同的。这是一个非常简单的模式,任何对它的偏离都会为每个注意到它的人带来稳定的收益。我想,很多人会注意到它,因为它是如此简单。但是我们知道,不可能每个人都赚钱,所以从长远来看,烛形下跌的数量与上涨的数量不会有明显的变化。这一点在所提到的文章中作了含蓄的说明。从理论上讲,这个规则可能有偏差,因为我没有检查所有的工具,而只是大约一百个。然而,在现阶段这一点并不重要。 

例如,我们取任意时期的 100,000 个 GBPUSD H1 烛形,计算其中有多少在上升,有多少在下降。从2020年10月27日到过去,我取了10万个烛形,这期间包含了 50,007 个上涨烛形 48,633 个下跌烛形。剩下的烛形,开盘价等于收盘价。换言之,GBPUSD 包含了 50.7%的上涨和49.3%的下跌烛形,其余蜡烛为开盘价=收盘价,数值大致相等。如果我们采取更大的样本,结果将趋于50%。

我不会在这篇文章中测算每个资产工具,我观察了数百种工具,结果到处都是相似的。但为了让人信服,让我们从一个完全不同的市场 GAZP(Gazprom)M15上取一个资产工具,测量 99914 根烛形中上涨和下跌的烛形数量。结果是48237个上涨和48831个下跌烛形,剩下的属于中性。如你所见,看跌蜡烛和看涨烛形的数量大致相等。

这种模式不仅存在于大量的资产工具中,而且在任何时间框架内都存在。为了确保这一点,让我们分析 GBPUSD M1,并采取稳步增长的 AAPL股票 M15。我把所有的数据组合成一张表。

交易品种 时间框架 烛形总数 上涨烛形总数 下跌烛形总数
GBPUSD M1 100,000 50.25% 49.74%
GBPUSD H1 100,125 50.69% 49.30%
GAZP M15 99,914 49.69% 50.30%
 AAPL  M15  57,645 50.60% 49.40%

根据该表,在所考虑的工具中,烛形上升和下降的比率趋向于50%,并且在所有考虑的时间框架内都是有效的。XLSX 文件包含我的测量中使用的数据以及结果,附在下面。

表中所示的结果证实了以下结论:大量样本的价格序列的统计参数与随机游走参数非常相似。此外,在少量样本上,会出现偏离参考分布的情况。该算法将基于这样的假设,即价格序列的增量分布只是表面上类似于正态分布。

在少量样本中,其分布形状与参考样本不同,而随着样本数量的增加,其分布形状趋于参考样本。最重要的是,分布趋向于参考分布的速度对于每个工具来说都是独立的,并且相当稳定。 

分布

图 1

图1显示了上面描述的所有内容。增量的参考分布以红色显示,而具有大量样本的价格序列的增量分布以黑色显示。少量样本的价格序列增量分布以紫色、绿色和蓝色显示。

人们发现了大量交易工具固有的基本规律,并作出了在何处寻找利润的假设。看跌蜡烛的数量=看涨烛形的数量,当偏离均衡时,每种工具的均衡回报率是独立的、稳定的,并在一定范围内波动。我会用这种模式来赚钱。

开发测试算法

现在我们需要利用这种模式开发最简单的算法,并对其进行测试,以了解该理论是否值得进一步开发。看涨和看跌烛形数量与50%的局部偏差将用于交易。平均而言,看跌烛形和看涨烛形的数量大致相同,然而,一种烛形比另一种烛形的优势可以从50%大不相同,然后趋于平衡。算法的工作原理如下:

通用简化算法

  • 扫描一个由 N 根烛形组成的窗口; 
  • 检查哪些烛形占优势-看跌或看涨;
  • 如果出现频率超过阈值,则启动一系列建立仓位的信号;
  • 看跌烛形普遍 = 买入信号,看涨烛形普遍 = 卖出;
  • 计算手数;
  • 在随后的每个烛形上打开一个新仓位,直到触发序列关闭条件; 
  • 触发序列关闭条件;
  • 平掉所有仓位;
  • 搜索新的信号。

为了简单起见,该算法使用了市场订单。该算法只使用收盘价,所有操作都是在新烛形生成后执行的,不需要分析烛形内部的任何东西。我们只需要控制当前的利润和资金,任何其他计算都是不必要的。

开启仓位信号

  1. 分析窗口. 设置蜡烛数(分析窗口)以检查当前看跌和看涨烛形的百分比。分析固定数量的烛形不是一个好主意,因为可能有较长或较短的部分与50%或以上的偏差。将分析窗口从最小烛形数设置为最大烛形数,优先级为较大烛形数,因为小区域可以是大区域的一部分,但需要搜索整个范围。分析窗口由MinBars和MaxBars参数设置。该算法在 MinBars 到 MaxBars 的范围内搜索下跌或上涨烛形的优势分布,一旦找到,该算法就选择超过阈值的下跌或上涨烛形的最大数量。
  2. 开启仓位的超额百分比阈值. 我们需要定义看跌或看涨的超额百分比可以被视为信号产生的阈值,该参数可通过优化选择。设置中含有 OpenPerc 参数,它以百分比设置,是开启仓位的百分比值。如果样本中看跌烛形的百分比大于或等于开仓百分比,则开仓买入。如果样本中看涨烛形的百分比大于或等于开仓百分比,则开仓卖出。 
  3. Range 枚举. 我们需要用一些步骤来分析这个范围内的烛形。奇数步长是不合适的,因为它不可避免地具有50%的偏差,从而提供错误的入场信号,因此检查范围的步骤可以在设置中找到(Step 参数)。range 枚举从最小值移到最大值。

序列中的最大仓位数

在交易过程中,一个仓位是由一系列的订单填充的,因此我们需要限制仓位的最大数量。要做到这一点,我们需要计算烛形的数量,在这个数量上多余的烛形可以被拉直到50%。我们使用触发序列开始的样本(由 N 根烛形组成),计算主要烛形的数量,从中减去剩余的烛形,将其与初始样本中的烛形数量相加,然后乘以K调整因子。K比值与工具的统计特性间接相关。

这就是我们如何获得预期的烛形数量,在这个数量上,50%的偏差应该消失。

R=(N+NB-NM)*K
N - 样本中超过阈值的烛形数
NB - 主烛形数
NM - 剩余的烛形数
K - 设置中定义的调整因子

接下来,我们需要计算机器人开启的最大仓位数。为了实现这一点,我们需要从蜡烛总数 R 中减去初始 N 个样本中的蜡烛数。结果是机器人在序列中不应超过的最大仓位数 E。

E = R-N
E - 序列中最大仓位数
R - 烛形总数,按计划返回 50%

该算法还不是自适应的,而是先进行第一步,然后根据初始样本中蜡烛的个数调整仓位的个数。

手数选择

已经创建了检查模式的算法,因此,我们需要添加几个设置来确定手数。假设手数大小取决于序列中的预期仓位数,序列中的仓位越多,手数就越小。为此,请添加两个设置: Depo 和 RiskPerc. 为了简单起见,我们假设 $1000 = 1手($500 = 0.5手)。从 Depo 设置中获取值并将其乘以RiskPerc。将得到的值除以最大仓位数 E,并四舍五入到最接近的正确值。这就是我们如何得到一个仓位的手数大小。

如果存款增加,我们需要增加手数自动增加功能。在这种情况下,如果Depo=0,则当前存款价值乘以RiskPerc,并使用获得的值找到开盘头寸的手数。

平仓

在这样集中情况下会发生平仓:

1) 未平仓的总利润达到 CloseProfit 中设置的值。由于EA开设的头寸数量不是恒定的,手数大小可能会发生变化,因此以美元数设定固定利润是不正确的。我们需要美元的利润取决于当前未平仓的仓位数和市场上的总手数。为此我们需要 "profit per lot(每手利润)" 的概念.

CloseProfit 设置为总仓位为1手的利润,机器人根据建仓的手数重新计算利润。如果我们有10个未平仓位,每个仓位0.01手,则总手数为0.1。因此,为了得到平仓的利润值,Profit = CloseProfit * 0.1。每次头寸数量发生变化时,调整利润以平仓。因此,当总利润大于或等于计算的利润值时,EA 关闭头寸。

2)在当前超出百分比小于或等于 ClosePerc 时。ClosePerc 设置当前烛形的多余百分比,以生成关闭一系列仓位的信号。打开第一个仓位时,发现多出的烛形出自 N 根烛形。现在,随着每一个新烛形,烛形的数量增加成为 N+1;N+2;N+3 等等。。。对于每一个新的烛形,我们需要检查烛形数量增加1时,样本上主要块的当前过剩百分比。满足条件后就关闭序列。

3)根据达到 MinEquity. 如果当前资金已跌破设定值,则需要关闭未平仓位序列,并在资金增加之前避免开启新的仓位。这是保护存款不受损失的止损功能。

测试

算法还非常初级,它无法适应不断变化的市场条件,只能用来检验创意的可行性。因此,我将使用优化来选择设置。通过枚举所有选项来执行优化,而不使用遗传算法。EA 早在2014年就开发出来了,是为 MetaTrader 4 设计的。我首先将在 GBPUSD H1 上进行测试。我将人为设置40的高点差,以便在非完美条件下执行优化,以确保未来有一定的稳定度。需要增加点差,因为EA控制未平仓头寸的当前利润,并受点差的影响。

我只会优化三个条件:最小蜡烛数 MinBars,未平仓位百分比 OpenPerc 和每手利润 CloseProfit。据推测,用于分析的最小蜡烛数越大,开仓百分比越高,信号越可靠,但频率越低。CloseProfit 间接依赖于波动性。因此,在进行优化之前,需要先观察工具的波动性,并设定适当的区间。优化是在从 2019.11.25 到 2020.11.25 的 H1 上进行的。

优化 GBPUSD

图 2. 优化结果

暴力优化是必要的,以了解参数如何影响结果,以及结果如何收敛的假设,算法应如何工作在理论上。图2显示了一些结果,我们需要启用按最大利润排序,并选择具有最充分的回撤和盈利指标的设置。突出显示的设置似乎很好。

对优化结果的进一步分析表明,MinBars 和 OpenPercent 的增加会降低盈利能力和回撤。接下来,我选取突出显示的参数,在一年内对它们进行测试,得到结果,并定义了当MinBars 和 OpenPercent 增加/减少时的变化。我的结论是,随着 MinBars 和 OpenPercent 的增加,交易数量减少,信号可靠性增加。这意味着,我们需要在盈利能力和回撤之间找到平衡。

对于交易,我故意采用了更为保守的参数,以确保在不断变化的市场条件下的安全边际。下面的图3显示了EA如何开启仓位。

交易

图 3. 开启仓位

图3显示了,如果需要的话一个头寸是由几个交易组成的。入场信号随时间延长。该算法的第一个版本的特点是粗糙的信号在某些时间点相当长。它看起来更像是一个模糊输入,而不是一个标准的平均值。这是一个界限模糊的区域,在这个区域中,看跌的蜡烛比看涨的蜡烛更有可能出现。从这种概率中获利是可能的。

算法在MinBars=70 时仍然可靠,但我将其设置为80,以便在交易工具特征中有波动的余地。选择CloseProfit 参数时,逻辑类似。在本例中,它等于150。在更小值的情况下,算法变得更稳定,但利润降低。如果增加到168,算法就不再可靠了,所以我就坚持150。因此,我们得到了一年的盈利能力图,如图4所示。CloseProfit 只不过是转换成美元的平均波动率。

GBPUSD 2019 图表

GBPUSD 2019 报告

图 4. GBPUSD H1, 2019.11.25 - 2020.11.25

用于优化的存款数设为 $10,000. 在完成研究之后,我们可以将总的设置调回最优值。测试和优化是在参考点模式下进行的,因为该算法适用于接近价格,因此烛形内的事件对其不重要。图5显示了在“Every Tick”模式下对同一时期的测试。

GBPUSD tick 2019 图表

GBPUSD tick 2019 报告

图 5. GBPUSD H1, 2019.11.25 - 2020.11.25 "Every tick" 模式

根据图5,在“Every Tick”模式下,利润甚至略有增加,因为测试变得更加精确。盈利能力图表几乎完全相同。这两项测试都产生了略高于5的优异利润系数。

基于一个优化年的测试得出关于模式可靠性的结论是错误的,那么让我们看看该算法在过去使用这些参数能够持续多少年。图6显示了优化时期之外的测试结果。

GBPUSD 2001 图表

GBPUSD 2001 报告

图 6. GBPUSD H1, 2001.01.01 - 2020.11.25

图6显示了自2001年以来的回溯测试,参数与从2019.11.25到2020.11.25的一年优化期间获得的参数相同。测试表明,在这样一个大的时间间隔内,回撤只增加了几美元,而利润却显著增加,利润系数上升到7.5。为了了解这种模式在长时间内的表现,我们对3000美元的存款进行了测试,没有再融资。 

该算法在一年内进行了优化,并取得了20年的稳定结果,说明该模式是相当稳定的,参数不随历史变化而调整。出于某种原因,英镑兑美元对与其固有的统计特征没有太大的偏离。 

基于单一货币对和时间框架的测试而得出结论是错误的。因此,让我们考虑 EURUSD 上的测试。与前一个案例一样,优化在一年内进行,从 2019.11.25 到 2020.11.25,H1 时段上。我用与前一个例子相同的方法来选择参数。结果如图7所示。

EURUSD 2019 图表

EURUSD 2019 报告

图 7. EURUSD H1, 2019.11.25 - 2020.11.25

如图7所示,EURUSD 的盈利能力低于 GBPUSD 的盈利能力,而回撤幅度略大。盈利能力图表显示,有一段有多个未平仓头寸。在稍微减小MinBars 和 OpenPercent 参数后,我们能够减少仓位的数量,从而减少回撤。让我们继续进行长期测试。图8显示了在 EURUSD 上从 2007.01.01 到 2020.11.25 的测试。

EURUSD 2007 图表

EURUSD 2007 报告

图 8. EURUSD H1, 2007.01.01 - 2020.11.25

与 GBPUSD 相比,在 EURUSD 上的交易没有那么稳定,使用时间更久远的数据进行稳定工作的时间已经少了六年,结果还是不错的。在一年内进行了参数优化,稳定工作持续了近14年。这一事实再次表明,这些参数并不是简单地根据历史进行调整,交易工具具有相当稳定的模式。

接下来,您需要检查算法在其他时间段上的行为。从理论上讲,随着时间范围的减少,稳定性应该降低,因为较低时间范围内烛形的大小相对于点差会显著减小。因此,利润会减少,交易成本会增加。此外,在较小的时间范围内,进入点的时间可能会变得更加紧张,从而导致更多的空头头寸,相应地,更大的回撤。

让我们在 GBPUSD M15 做个测试. 和之前的例子中类似,优化进行于 2019.11.25 到 2020.11.25. 但我不会显示一年内的优化图。相反,我将显示算法能够顺利通过的最大可能间隔。

GBPUSD M15 图表

图 9. GBPUSD m15 2000.01.01-2020.11.25

图9显示了从2000年开始进行的 GBPUSD M15 上的测试。但入场信号和仓位的数量很少。正如我在上面所写的,较低的时间段显示的稳定性较差,而且设置结果非常保守。很少产生入场信号,盈利能力不高,但相对于回撤而言是足够的。

接下来,让我们在更高的时间框架 GBPUSD H4 上进行测试。H4 上用于优化的烛形数量更少,所以,我将会在两年内进行优化,即从 2018.11.25 到 2020.11.25. 结果将显示在最大间隔上。

GBPUSD H4

GBPUSD H4 报告

图 10. GBPUSD H4 2000.01.01-2020.11.25

H4 上显示出从 2000.01.01 到 2020.11.25 的几乎20年中具有稳定的结果。与前面的案例一样,整个优化归结为在利润和可靠性之间找到平衡点。M15的保守设置在H1和H4上都能可靠工作。但由于信号非常罕见,交易数量很少,因此没有意义。

你也可以测试任何其他交易工具。根据交易品种的不同,算法的效果可能或好或坏,但这一趋势仍在继续——一年的优化可以让几年的工作稳定下来。下面是 GBPJPY H1 上的结果. 优化进行了一年,结果如图11所示。

GBPJPY 图表

GBPGPY 报告

图 11. GBPJPY 2009.01.01 - 2020.11.25

GBPJPY 在从 2009 开始的回溯测试中显示出稳定的结果。结果并不像 GBPUSD 那样令人印象深刻,但确实有效。 

EA 的特点是能够将赚来的资金再投资,您需要应用这一点。到目前为止,我展示了保守设置下的测试。但是,如果我们设置非常激进的设置,并启用大的手数呢?我不喜欢高风险,但让我们看看算法的能力。我将在2006年1月1日至2020年11月25日期间,在“Every Tick”模式下对 GBPUSD 进行测试。当然,也可以测试另一个交易品种。点差减小到 20,这比平均数略高一些。图12显示了近15年的回溯测试结果。


GBPUSD 最大风险

图 12. GBPUSD 从 2006.01.01 到 2020.11.25, 激进设置

您可能还记得,该算法使用收盘价。因此,这个结果不是“测试圣杯”。此外,设置了20的适当点差。该算法在真实市场上的交易结果通常与测试中得到的结果相吻合。我从来没有使用这样激进的设置进行交易。此外,不可能将MetaTrader 4的实际点差考虑在内,因此我不会认为它在实际交易中也会工作得这样好。

分析结果

EA方法简单,易于优化。短时间的优化和非优化参数的使用使其能够在几年甚至几十年内保持稳定。这表明,发现的模式不是偶然的,是真正存在于市场上。然而,该算法是相当“刚性”的,因为它有几个自由度和严格指定的参数操作。如果价格序列超出了算法的能力,那么它就会立即失去稳定性。 

最重要的是,它可以在任何时间框架内使用,从烛形的大小大大超过点差和佣金开始。随着时间框架的增加,稳定性会增长到每日的时间段。然而,由于烛形的尺寸变得很大,导致数量大量的减少,因此对存款的要求也增加了。

我们可以得出结论,价格序列只是表面上类似于我在第一篇文章价格序列离散化、随机成分和噪声中描述的随机游走。价格系列至少包含一个隐藏模式。

另一方面,我知道并完全理解允许盈利的模式,这意味着是时候进行一些严肃的更新了。

在交易中的用法

当前算法的最大缺点是相对于风险的回报率较低。我们需要对自己诚实,明白存在风险(就像其他任何地方一样)。但是,在改进的过程中,我们可以使用EA进行交易。要做到这一点,我们需要提高其盈利能力,并保持回撤水平。有必要利用算法的特点。它很少为交易工具生成信号,而且通常,对于不同的交易工具,它们的时间间隔很大。大多数时候,该工具没有交易,我们需要填补这些“停机时间”。 

一般来说,不同工具的信号之间没有稳定的相关性。我们应该利用这一特点增加利润,同时保持回撤水平。

为了增加盈利能力,我们需要同时分析几种工具。当其中一个工具出现信号时,打开它的仓位。如果一个工具的仓位打开,则忽略来自其他交易品种的系列启动信号。这允许尽可能有效地利用时间,增加信号的数量,并相应地按比例提高利润。最大回撤保持在一个工具的水平。

序列开始信号不仅在独立交易品种之间弱相关,而且在同一交易品种的不同时间段之间弱相关。因此,通过在交易中使用三个相同交易品种的时间段,可以更有效地利用时间,实现市场上几乎总是有未平仓头寸的情况。在利润大幅增长的同时,回撤水平保持在同一水平。

对真实账户进行了若干修改:

1)增加9个新的独立交易工具,每个工具都有自己的参数。这使得算法可以一次分析和交易10种交易工具。任何工具的参数都有可能在某种程度上得到优化,所以这个决定似乎是合乎逻辑的。

2)多个交易工具有限的同时开仓。为此增加了 MaxSeries 参数。如果设置为1,则只对一种工具进行交易。如果为2,则可以在两个工具上同时打开仓位,依此类推。这将使得EA能够利用其“空闲时间”更频繁地生成仓位打开信号。利润按比例增加,而最大回撤保持在一种工具的水平。

MetaTrader 4 测试器无法进行多币种测试,但如果交易不止一个符号,如果不同工具的信号之间不存在相关性,则回撤可能与同时交易工具数量的平方根成比例增加。如果我们预计回撤1000美元,那么,同时交易三种工具,我们可以预计回撤将增加到1000美元*根(3)=1732美元的水平。

3)增加了对“MinEquity”基金最低数量的限制。一旦达到这个值,交易停止并且仓位关闭。这样的计划风险和坚持是有必要的。

4)EA可以在多个时间框架同时使用,以提高盈利能力。根据我的测试,仓位打开信号通常在不同的时间段之间具有相关性,尽管它远不是100%。

我使用EA在25种货币对上进行交易,以及在H1和H4时间段上同时进行保守设置,可以保持每月10%的盈利能力。在另一个账户中,在稍微激进的设置下,我设法实现了每月15%的盈利能力,在那里有很多交易。

结论和进一步开发

下一篇文章将专门讨论我为提高算法可靠性和灵活性而开发的机制。

EA 规范和适当的要求规范附在下面。

思路和需求规范的作者是 Maxim Romanov,代码由 Vyacheslav Ivanov 书写。