社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

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

Python中文社区 • 1 年前 • 329 次点击  

所谓马丁格尔(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月)调整后的收盘价数据如下:

# Import the libraries , !pip install "library" for first time installing
import numpy as np, pandas as pd
!pip install pyfolio
import pyfolio as pf

import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('seaborn-darkgrid')
plt.rcParams['figure.figsize'] = (10,7)

import warnings
warnings.filterwarnings("ignore")
# Load AAPL stock csv data and store to a dataframe
df = pd.read_csv("AAPL.csv")
df = df.rename(columns={'Adj_Close': 'price'})

# Convert Date into Datetime format
df['Date'] = pd.to_datetime(df['Date'])
df.fillna(method='ffill', inplace=True)

# Set date as the index of the dataframe
df.set_index('Date',inplace=True)
df.head()

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

「简单的马丁格尔策略」

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

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

# Create column for previous price
df_mg['prev_price'] = df_mg['price'].shift(1)

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

# Initialise 'quantity' column 
df_mg['quantity'] = 0

# Start with 1 stock, long position
df_mg['signal'].iloc[0] = 1

# Strategy to double the trade volume or quantity on losing trades
for i in range(df_mg.shape[0]):
if i == 0:
df_mg['quantity'].iloc[0] = 1
else:
if df_mg['signal'].iloc[i] == 1:
df_mg['quantity'].iloc[i] = df_mg['quantity'].iloc[i-1]
if df_mg['signal'].iloc[i] == -1:
df_mg['quantity'].iloc[i] = df_mg['quantity'].iloc[i-1]*2
if df_mg['signal'].iloc[i] == 0:
df_mg['quantity'].iloc[i] = df_mg['quantity'].iloc[i-1]

df_mg.head()

# Calculate returns
df_mg['returns'] = ((df_mg['price'] - df_mg['prev_price'])/ df_mg['price'])*df_mg['quantity']
# Cumulative strategy returns
df_mg['cumulative_returns'] = (df_mg.returns+1).cumprod()

# Plot cumulative returns
plt.figure(figsize=(10,5))
plt.plot(df_mg.cumulative_returns)
plt.grid()

# Define the label for the title of the figure
plt.title('Cumulative Returns for Martingale strategy', fontsize=16)

# Define the labels for x-axis and y-axis
plt.xlabel('Date', fontsize=14)
plt.ylabel('Cumulative Returns', fontsize=14)

# Define the tick size for x-axis and y-axis
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)

plt.show()

# Plot position
plt.figure(figsize=(10,5))
plt.plot(df_mg.quantity)
plt.grid()

# Define the label for the title of the figure
plt.title('Position sizing', fontsize=16)

# Define the labels for x-axis and y-axis
plt.xlabel('Price', fontsize=14)
plt.ylabel('Quantity', fontsize=14)

# Define the tick size for x-axis and y-axis
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)

plt.show()

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

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

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

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

# This step before deciding trade size is same as the above martingale strategy
# Create column for previous price
df_anti_mg['prev_price'] = df_anti_mg['price'].shift(1)

# Generate buy and sell signal for price increase and decrease respectively. And create consolidated 'signal' column by addition of both buy and sell signals
df_anti_mg['long_signal'] = np.where(df_anti_mg['price'] > 1.02*df_anti_mg['prev_price'], 1, 0)
df_anti_mg['short_signal'] = np.where(df_anti_mg['price'] < .98*df_anti_mg['prev_price'], -1, 0)
df_anti_mg['signal'] = df_anti_mg['short_signal'] + df_anti_mg['long_signal']
df_anti_mg.head()

# Intialise 'quantity' column 
df_anti_mg['quantity'] = 0

# Start with $10,000 cash long position
cash = 10000
df_anti_mg['signal'].iloc[0] = 1

# Strategy to double the trade volume or quantity on losing trades
for i in range(df_anti_mg.shape[0]):
if i == 0:
df_anti_mg['quantity'].iloc[0] = 1
else:
if df_anti_mg['signal'].iloc[i] == 1:
df_anti_mg['quantity'].iloc[i] = df_anti_mg['quantity'].iloc[i-1]*2
if df_anti_mg['signal'].iloc[i] == -1:
df_anti_mg['quantity'].iloc[i] = df_anti_mg['quantity'].iloc[i-1]/2
if df_anti_mg['signal'].iloc[i] == 0:
df_anti_mg['quantity'].iloc[i] = df_anti_mg['quantity'].iloc[i-1]

df_anti_mg.head()

# Calculate returns
df_anti_mg['returns'] = ((df_anti_mg['price'] - df_anti_mg['prev_price'])/ df_anti_mg['prev_price'])*df_anti_mg['quantity']
# Cumulative strategy returns
df_anti_mg['cumulative_returns'] = (df_anti_mg.returns+1).cumprod()

# Plot cumulative returns
plt.figure(figsize=(10,5))
plt.plot(df_anti_mg.cumulative_returns)
plt.grid()

# Define the label for the title of the figure
plt.title('Cumulative Returns for Anti-Martingale strategy', fontsize=16)

# Define the labels for x-axis and y-axis
plt.xlabel('Date', fontsize=14)
plt.ylabel('Cumulative Returns', fontsize=14)

# Define the tick size for x-axis and y-axis
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)

plt.show()

# Plot position
plt.figure(figsize=(10,5))
plt.plot(df_anti_mg.quantity)
plt.grid()

# Define the label for the title of the figure
plt.title('Position sizing', fontsize=16)

# Define the labels for x-axis and y-axis
plt.xlabel('Date', fontsize=14)
plt.ylabel('Quantity', fontsize=14)

# Define the tick size for x-axis and y-axis
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)

plt.show()

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

「总结」

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

E N D


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


长按扫码获取完整源码


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/137101
 
329 次点击