当前位置:   article > 正文

用 Python 实现马丁格尔交易策略(附代码)

马丁公式代码

所谓马丁格尔(Martingale)策略是在某个赌盘里,当每次「输钱」时就以2 的倍数再增加赌金,直到赢钱为止。假设在一个公平赌大小的赌盘,开大与开小都是50% 的概率,所以在任何一个时间点上,我们赢一次的概率是50%,连赢两次的概率是25%,连赢三次的概率12.5%,连赢四次的概率6.25%,以此类推。同样,连输的概率也是这样的。于是,交易上,很多人尝试马丁格尔式的金字塔加仓法来进行交易。那么马丁格尔策略是否可以增加交易者的收益?

在这篇博客中,我们将通过以下主题来关注马丁格尔及其在交易策略中的应用。扫描本文最下方二维码获取全部完整源码、CSV数据文件和Jupyter Notebook 文件打包下载。

  • 什么是马丁格尔?

  • 马丁格尔是如何工作的?

  • 马丁格尔的条件期望值

  • 马丁格尔交易策略

  • 什么是反马丁格尔?

  • Python中的马丁格尔与反马丁格尔交易策略

「什么是马丁格尔?」

随机变量是一个未知的值或一个函数,它在每个可能的试验中都取一个特定的值。它可以是离散的,也可以是连续的。下面我们考虑离散随机变量来解释马丁格尔。

马丁格尔是一个随机变量M1, M2, M3...Mn的序列,其中

E[Mn+1|Mn] = Mn, n -> 0, 1, ..., n+1  (1)

而E [|Mn+1|] < ∞,

读作Mn+1的期望值,因为Mn的值等于Mn,即期望值保持不变。

对于一个随机变量,不同的值x1、x2、x3,各自的概率为p1、p2和p3,其期望值的计算方法为:

E[M] = x1 * p1 + x2 * p2 + x3 * p3,更简单地说,期望值与算术平均值相同。

注意:马丁格尔总是针对一些信息集和一些概率测量来定义。如果信息集或与过程相关的概率发生变化,该过程可能不再是马丁格尔了。

「马丁格尔是如何工作的?」

考虑一个简单的游戏,你抛出一枚公平的硬币,如果结果是正面,你就赢得一美元,如果是反面,你就失去一美元。

在这个游戏中,正面或背面的概率总是一半。所以,赢的平均值等于1/2(1)+1/2(-1)=0,这意味着你不能通过玩若干轮游戏来系统地赚取任何额外的钱(尽管随机收益或损失仍然是可能的)。

因此,上述情况满足马丁格尔属性,即在任何特定回合中,无论前几回合的结果如何,你的总收入预期都会保持不变。

「马丁格尔中的条件期望值」

马丁格尔定义中方程(1)左侧的表达式被称为 "条件期望"。条件期望值(也称为条件平均数)是在一组先决条件发生后计算的平均数。

随机变量X相对于变量Z的条件期望被定义为一个(新)随机变量Y=E(X|Z)

「马丁格尔交易策略」

马丁格尔交易策略是在亏损的交易中加倍你的风险或投资规模。由于你的预期长期回报仍然是相同的(价格下跌时亏损,价格上涨时收益),这种策略可以通过在价格下跌时买入点位,降低你的平均进场价格来实现。因此,即使在一系列亏损的交易之后,如果发生了盈利的交易,它就会挽回所有的损失,包括最初的交易金额,因为它的利润是2^p=∑ 2^p-1+1。

马丁格尔法的优点和缺点。优点之一是,由于交易者在每笔亏损的交易后将投资规模加倍,该策略有助于挽回损失并产生利润,提高净收益。而主要的缺点是,你在增加投资规模时没有止损限制。

注意:如果破产,你可能会损失你的全部资本,或者导致资本缩减,需要额外的资本,如果赔率在长期内没有改善,你会不断地输。

「什么是反马丁格尔?」

在反马丁格尔策略中,当价格向有利可图的方向移动时,投资规模增加一倍,当出现损失时,投资规模减少一半。这样做的目的是希望股票在趋势中继续上涨,这在势头驱动的市场中是可行的。

反马丁格尔策略的优点和缺点。反马丁格尔策略的主要优点是在不利条件下风险最小,因为交易量在损失时不会增加。尽管有优势,但如果出现长时间的亏损交易,反马丁格尔也不会带来利润。因此,进场信号应准确计算,以避免损失覆盖所获利润。

在下一节,我们将在Python中建立马丁格尔和反马丁格尔策略。

「用 Python 实现马丁格尔与反马丁格尔交易策略」

我们使用了超过6个月的苹果公司股票(AAPL)调整后的收盘价数据。这个数据是从雅虎金融网站上提取的,并存储在一个csv文件中。

「读取股票数据」

已下载AAPL的2019年半年度(7月至12月)调整后的收盘价数据如下:

  1. # Import the libraries , !pip install "library" for first time installing
  2. import numpy as np, pandas as pd
  3. !pip install pyfolio
  4. import pyfolio as pf
  5. import matplotlib.pyplot as plt
  6. %matplotlib inline
  7. plt.style.use('seaborn-darkgrid')
  8. plt.rcParams['figure.figsize'] = (10,7)
  9. import warnings
  10. warnings.filterwarnings("ignore")
  1. # Load AAPL stock csv data and store to a dataframe
  2. df = pd.read_csv("AAPL.csv")
  3. df = df.rename(columns={'Adj_Close': 'price'})
  4. # Convert Date into Datetime format
  5. df['Date'] = pd.to_datetime(df['Date'])
  6. df.fillna(method='ffill', inplace=True)
  7. # Set date as the index of the dataframe
  8. df.set_index('Date',inplace=True)
  9. df.head()

5b8c76951aadb11d6f106fa55fbcfcd4.png

  1. # Create a copy of two dataframes for the trading strategies
  2. df_mg = df.copy()
  3. df_anti_mg = df.copy()

「简单的马丁格尔策略」

马丁格尔交易策略是在亏损的交易中加倍你的交易量。

我们从AAPL的一只股票开始,在亏损的交易中把交易量或数量翻倍。构建策略时,将获胜的交易视为比前一收盘价增加2%,将失败的交易视为比前一收盘价减少2%。

  1. # Create column for previous price
  2. df_mg['prev_price'] = df_mg['price'].shift(1)
  3. # Generate buy and sell signal for price increase and decrease respectively. And create consolidated 'signal' column by addition of both buy and sell signals
  4. df_mg['long_signal'] = np.where(df_mg['price'] > 1.02*df_mg['prev_price'], 1, 0)
  5. df_mg['short_signal'] = np.where(df_mg['price'] < .98*df_mg['prev_price'], -1, 0)
  6. df_mg['signal'] = df_mg['short_signal'] + df_mg['long_signal']
  7. df_mg.head()

b23a5d92201f4f1c0abbf16d9a867675.png

  1. # Initialise 'quantity' column
  2. df_mg['quantity'] = 0
  3. # Start with 1 stock, long position
  4. df_mg['signal'].iloc[0] = 1
  5. # Strategy to double the trade volume or quantity on losing trades
  6. for i in range(df_mg.shape[0]):
  7. if i == 0:
  8. df_mg['quantity'].iloc[0] = 1
  9. else:
  10. if df_mg['signal'].iloc[i] == 1:
  11. df_mg['quantity'].iloc[i] = df_mg['quantity'].iloc[i-1]
  12. if df_mg['signal'].iloc[i] == -1:
  13. df_mg['quantity'].iloc[i] = df_mg['quantity'].iloc[i-1]*2
  14. if df_mg['signal'].iloc[i] == 0:
  15. df_mg['quantity'].iloc[i] = df_mg['quantity'].iloc[i-1]
  16. df_mg.head()

20e57451685a9d9e1a06bbe9da0a18af.png

  1. # Calculate returns
  2. df_mg['returns'] = ((df_mg['price'] - df_mg['prev_price'])/ df_mg['price'])*df_mg['quantity']
  1. # Cumulative strategy returns
  2. df_mg['cumulative_returns'] = (df_mg.returns+1).cumprod()
  3. # Plot cumulative returns
  4. plt.figure(figsize=(10,5))
  5. plt.plot(df_mg.cumulative_returns)
  6. plt.grid()
  7. # Define the label for the title of the figure
  8. plt.title('Cumulative Returns for Martingale strategy', fontsize=16)
  9. # Define the labels for x-axis and y-axis
  10. plt.xlabel('Date', fontsize=14)
  11. plt.ylabel('Cumulative Returns', fontsize=14)
  12. # Define the tick size for x-axis and y-axis
  13. plt.xticks(fontsize=12)
  14. plt.yticks(fontsize=12)
  15. plt.show()

5028162d4de10fecc78812d57fc38900.png

  1. # Plot position
  2. plt.figure(figsize=(10,5))
  3. plt.plot(df_mg.quantity)
  4. plt.grid()
  5. # Define the label for the title of the figure
  6. plt.title('Position sizing', fontsize=16)
  7. # Define the labels for x-axis and y-axis
  8. plt.xlabel('Price', fontsize=14)
  9. plt.ylabel('Quantity', fontsize=14)
  10. # Define the tick size for x-axis and y-axis
  11. plt.xticks(fontsize=12)
  12. plt.yticks(fontsize=12)
  13. plt.show()

67f91a1e699cdcc0bdeca95f1ed72c5e.png

注意:我们可以从上图中注意到,交易量或数量以指数形式增加,累计收益也随之增加。但在这种情况下,我们可能会耗尽资本来加倍仓位,从而导致破产。

「简单的反马丁格尔策略」

反马丁格尔策略是在获胜的交易中把交易量翻倍,在失败的交易中把交易量减半。

与上述马丁格尔策略类似,我们从AAPL的一只股票开始,在获胜的交易中把交易量或数量增加一倍,在失败的交易中把交易量或数量减少一半。该策略的建立是考虑到盈利的交易是2%的增长,而失败的交易是在前一个收盘价的基础上减少2%。

  1. # This step before deciding trade size is same as the above martingale strategy
  2. # Create column for previous price
  3. df_anti_mg['prev_price'] = df_anti_mg['price'].shift(1)
  4. # Generate buy and sell signal for price increase and decrease respectively. And create consolidated 'signal' column by addition of both buy and sell signals
  5. df_anti_mg['long_signal'] = np.where(df_anti_mg['price'] > 1.02*df_anti_mg['prev_price'], 1, 0)
  6. df_anti_mg['short_signal'] = np.where(df_anti_mg['price'] < .98*df_anti_mg['prev_price'], -1, 0)
  7. df_anti_mg['signal'] = df_anti_mg['short_signal'] + df_anti_mg['long_signal']
  8. df_anti_mg.head()

760ca371610c7180585369890e347b50.png

  1. # Intialise 'quantity' column
  2. df_anti_mg['quantity'] = 0
  3. # Start with $10,000 cash long position
  4. cash = 10000
  5. df_anti_mg['signal'].iloc[0] = 1
  6. # Strategy to double the trade volume or quantity on losing trades
  7. for i in range(df_anti_mg.shape[0]):
  8. if i == 0:
  9. df_anti_mg['quantity'].iloc[0] = 1
  10. else:
  11. if df_anti_mg['signal'].iloc[i] == 1:
  12. df_anti_mg['quantity'].iloc[i] = df_anti_mg['quantity'].iloc[i-1]*2
  13. if df_anti_mg['signal'].iloc[i] == -1:
  14. df_anti_mg['quantity'].iloc[i] = df_anti_mg['quantity'].iloc[i-1]/2
  15. if df_anti_mg['signal'].iloc[i] == 0:
  16. df_anti_mg['quantity'].iloc[i] = df_anti_mg['quantity'].iloc[i-1]
  17. df_anti_mg.head()

28d13bf0af7dc7014af27588e57a33c4.png

  1. # Calculate returns
  2. df_anti_mg['returns'] = ((df_anti_mg['price'] - df_anti_mg['prev_price'])/ df_anti_mg['prev_price'])*df_anti_mg['quantity']
  1. # Cumulative strategy returns
  2. df_anti_mg['cumulative_returns'] = (df_anti_mg.returns+1).cumprod()
  3. # Plot cumulative returns
  4. plt.figure(figsize=(10,5))
  5. plt.plot(df_anti_mg.cumulative_returns)
  6. plt.grid()
  7. # Define the label for the title of the figure
  8. plt.title('Cumulative Returns for Anti-Martingale strategy', fontsize=16)
  9. # Define the labels for x-axis and y-axis
  10. plt.xlabel('Date', fontsize=14)
  11. plt.ylabel('Cumulative Returns', fontsize=14)
  12. # Define the tick size for x-axis and y-axis
  13. plt.xticks(fontsize=12)
  14. plt.yticks(fontsize=12)
  15. plt.show()

aa9ceb5b7cc481782b81daf6ec9c1794.png

  1. # Plot position
  2. plt.figure(figsize=(10,5))
  3. plt.plot(df_anti_mg.quantity)
  4. plt.grid()
  5. # Define the label for the title of the figure
  6. plt.title('Position sizing', fontsize=16)
  7. # Define the labels for x-axis and y-axis
  8. plt.xlabel('Date', fontsize=14)
  9. plt.ylabel('Quantity', fontsize=14)
  10. # Define the tick size for x-axis and y-axis
  11. plt.xticks(fontsize=12)
  12. plt.yticks(fontsize=12)
  13. plt.show()

dbd20d22a0dba2bb1bd9aae233743a4c.png

标准马丁格尔在长期内会导致高度可变的结果,因为它可能会遇到指数级增长的损失。而反马丁格尔的回报分布明显更平坦,方差更小,因为它减少了损失的风险,而增加了利润的风险。考虑到这一点,我们看到大多数成功的交易者倾向于遵循反马丁格尔策略,因为与马丁格尔策略相比,他们被认为在连胜期间增加投资规模的风险较小。

「总结」

在这篇文章中,我们首先通过条件期望值的概念了解了马丁格尔的直观含义。接下来,我们学习了马丁格尔策略的类型。在马丁格尔交易策略下,交易规模或数量在亏损的交易中翻倍,通过后面的盈利交易来弥补亏损并产生利润。在反马丁格尔交易策略中,交易规模或数量在亏损的交易中减半,在盈利的交易中翻倍。我们还了解了可能适合这两种策略的市场条件。最后,我们用Python实现了马丁格尔和反马丁格尔交易策略。

f92bb9378a2259a5b5f484b248cfb0ad.png

E N D

4ddcf58d6ab80f62ba4798ba07aeb69c.png

扫描本文最下方二维码获取源码和数据文件打包下载。

bb97101019cae648bdc1768406fb101a.jpeg

长按扫码获取完整源码

f9312a9ffd238fe69589b1a271ed71fc.jpeg

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号