赞
踩
双均线策略是比较经典的策略,股票的价格均线是投资参考的重要指标。均线有快线和慢线之分,当快线向上穿过慢线则是金叉,一般执行买入操作,当快线向下穿过慢线时则形成死叉,一般执行卖出操作。基于这个基本思路,出于兴趣爱好,便使用python复现了这个量化策略。代码封装如下。
在运行这个代码块时,请先运行以下代码:
pip install pandas
pip install numpy
pip install matplotlib
pip install tqdm
pip install qstock
在电脑上安装了这些库之后就可以运行下面的封装代码了,具体讲解在代码块下面。
- import pandas as pd
- import numpy as np
- import matplotlib.pyplot as plt
- from tqdm import tqdm
- import qstock as qs
-
- class Dual_moving_average_stra():
- '''
- code --> '000001' str
- start_time --> '20220101' str
- window0 --> 5 int
- window1 --> 10 int
- verbose --> bool default=True
- plot --> bool default=True
- init_money = 10000 一万块本金 看末期能有多少收益
- '''
- def __init__(self, code, start_time, window0, window1, verbose=True, plot=True):
- self.code = code
- self.start_time = start_time
- self.window0 = window0
- self.window1 = window1
- self.verbose = verbose
- self.plot = plot
-
- def get_data(self):
- #print(self.code, self.start_time)
- df = qs.get_data(self.code, start=self.start_time, end=None, freq=101, fqt=1)
- df['MA_' + str(self.window0)] = df.rolling(self.window0, min_periods=1).mean()['close']
- df['MA_' + str(self.window1)] = df.rolling(self.window1, min_periods=1).mean()['close']
- df['gold'] = np.nan
- df.gold = df['MA_' + str(self.window0)] > df['MA_' + str(self.window1)]
- signal = pd.DataFrame()
- signal = df.gold.apply(lambda x:1 if x==True else 0)
- df['gold_death_cha'] = signal - signal.shift(1).fillna(0)
- return df
-
- def strategy(self):
- init_money = 10000
- quant = 0
- df = self.get_data()
- signal = df.gold_death_cha
- price_list = df.open
- money_list = []
-
- for i in tqdm(range(df.shape[0])):
- if i+1 == df.shape[0]: # 因为是次日买卖 所以得提前一天结束代码
- break
-
- price = price_list.iloc[i+1]
-
- if signal.iloc[i] == 1:
- # 金叉全仓买入
- quant += int(init_money / (price * 100))
- init_money -= quant * price * 100
- if self.verbose == True:
- print('此次购买数量:', quant)
- print('证券价格:', price)
- print('本金还剩:',init_money)
- print('金叉买入执行完毕----------------------------------')
-
- if signal.iloc[i] == -1:
- init_money += quant * price * 100
- quant = 0 # 清仓
- money_list.append(init_money)
- if self.verbose == True:
- print('清仓:', quant)
- print('证券价格:', price)
- print('本金还剩:',init_money)
- print('死叉卖出执行完毕----------------------------------')
-
- if self.plot == True:
- plt.figure(figsize=(20,20))
- plt.subplot(2,1,1)
- plt.grid()
- plt.plot(df.index, df.close, label='close', linewidth=3)
- plt.plot(df.index, df['MA_' + str(self.window0)], c='red', label=('MA_' + str(self.window0)), linewidth=3)
- plt.plot(df.index, df['MA_' + str(self.window1)], c='grey', label=('MA_' + str(self.window1)), linewidth=3)
- plt.xticks(rotation=45)
- plt.legend(fontsize=20)
-
- plt.subplot(2,1,2)
- plt.grid()
- plt.plot(range(len(money_list)), money_list, linewidth=3, label='money')
- plt.xticks(rotation=45)
- plt.legend(fontsize=20)
- plt.show()
这是一个金叉死叉的策略,在股价出现死叉时则全仓卖出,在股价出现金叉时则全仓买入,然后给予10000元的本金,查看最后一期能剩余多少本金。
首先实例化我们的对象:
model = Dual_moving_average_stra('600460', '20200101', 5, 20)
第一个参数是股票代码,第二个参数是提取数据的开始时间,例子中是从2020年开始的。5表示计算股票的5日均线,20表示计算股票的20日均线。然后就完成了模型的实例化。
model.strategy()
然后再运行这个代码就可以查看策略的效果了。
- 此次购买数量: 6
- 证券价格: 16.52
- 本金还剩: 88.0
- 金叉买入执行完毕----------------------------------
- 清仓: 0
- 证券价格: 13.63
- 本金还剩: 8266.0
- 死叉卖出执行完毕----------------------------------
- 此次购买数量: 4
- 证券价格: 18.67
- 本金还剩: 797.9999999999991
- 金叉买入执行完毕----------------------------------
- 清仓: 0
- 证券价格: 17.74
- 本金还剩: 7893.999999999998
- 死叉卖出执行完毕----------------------------------
- 此次购买数量: 5
- 证券价格: 14.7
- 本金还剩: 543.9999999999982
- 金叉买入执行完毕----------------------------------
- 清仓: 0
- 证券价格: 14.26
- 本金还剩: 7673.999999999998
- 死叉卖出执行完毕----------------------------------
- 此次购买数量: 5
- 证券价格: 14.67
- 本金还剩: 338.9999999999991
- 金叉买入执行完毕----------------------------------
- 清仓: 0
- 证券价格: 17.23
- 本金还剩: 8954.0
- 死叉卖出执行完毕----------------------------------
- 此次购买数量: 5
- 证券价格: 16.63
- 本金还剩: 639.0
- 金叉买入执行完毕----------------------------------
- 清仓: 0
- 证券价格: 16.28
- 本金还剩: 8779.0
- 死叉卖出执行完毕----------------------------------
- 此次购买数量: 5
- 证券价格: 15.78
- 本金还剩: 889.0000000000009
- 金叉买入执行完毕----------------------------------
- 清仓: 0
- 证券价格: 25.62
- 本金还剩: 13699.0
- 死叉卖出执行完毕----------------------------------
- 此次购买数量: 5
- 证券价格: 27.09
- 本金还剩: 154.00000000000182
- 金叉买入执行完毕----------------------------------
- 清仓: 0
- 证券价格: 25.66
- 本金还剩: 12984.000000000004
- 死叉卖出执行完毕----------------------------------
- 此次购买数量: 4
- 证券价格: 26.12
- 本金还剩: 2536.0000000000036
- 金叉买入执行完毕----------------------------------
- 清仓: 0
- 证券价格: 24.28
- 本金还剩: 12248.000000000004
- 死叉卖出执行完毕----------------------------------
- 此次购买数量: 4
- 证券价格: 30.48
- 本金还剩: 56.00000000000364
- 金叉买入执行完毕----------------------------------
- 清仓: 0
- 证券价格: 57.4
- 本金还剩: 23016.000000000004
- 死叉卖出执行完毕----------------------------------
- 此次购买数量: 3
- 证券价格: 63.35
- 本金还剩: 4011.0000000000036
- 金叉买入执行完毕----------------------------------
- 清仓: 0
- 证券价格: 61.9
- 本金还剩: 22581.000000000004
- 死叉卖出执行完毕----------------------------------
- 此次购买数量: 3
- 证券价格: 57.57
- 本金还剩: 5310.000000000004
- 金叉买入执行完毕----------------------------------
- 清仓: 0
- 证券价格: 53.4
- 本金还剩: 21330.0
- 死叉卖出执行完毕----------------------------------
- 此次购买数量: 3
- 证券价格: 61.11
- 本金还剩: 2997.0
- 金叉买入执行完毕----------------------------------
- 清仓: 0
- 证券价格: 54.7
- 本金还剩: 19407.000000000004
- 死叉卖出执行完毕----------------------------------
- 此次购买数量: 3
- 证券价格: 63.39
- 本金还剩: 390.00000000000364
- 金叉买入执行完毕----------------------------------
- 清仓: 0
- 证券价格: 65.1
- 本金还剩: 19920.000000000004
- 死叉卖出执行完毕----------------------------------
- 此次购买数量: 3
- 证券价格: 61.64
- 本金还剩: 1428.0000000000036
- 金叉买入执行完毕----------------------------------
- 清仓: 0
- 证券价格: 59.26
- 本金还剩: 19206.000000000004
- 死叉卖出执行完毕----------------------------------
- 此次购买数量: 3
- 证券价格: 51.92
- 本金还剩: 3630.0000000000036
- 金叉买入执行完毕----------------------------------
- 清仓: 0
- 证券价格: 50.55
- 本金还剩: 18795.0
- 死叉卖出执行完毕----------------------------------
- 此次购买数量: 3
- 证券价格: 55.29
- 本金还剩: 2208.0
- 金叉买入执行完毕----------------------------------
- 清仓: 0
- 证券价格: 54.35
- 本金还剩: 18513.0
- 死叉卖出执行完毕----------------------------------
- 此次购买数量: 4
- 证券价格: 42.49
- 本金还剩: 1517.0
- 金叉买入执行完毕----------------------------------
- 清仓: 0
- 证券价格: 45.58
- 本金还剩: 19749.0
- 死叉卖出执行完毕----------------------------------
- 此次购买数量: 4
- 证券价格: 46.08
- 本金还剩: 1317.0
- 金叉买入执行完毕----------------------------------
- 清仓: 0
- 证券价格: 45.45
- 本金还剩: 19497.0
- 死叉卖出执行完毕----------------------------------
- 此次购买数量: 3
- 证券价格: 50.79
- 本金还剩: 4260.0
- 金叉买入执行完毕----------------------------------
- 清仓: 0
- 证券价格: 46.77
- 本金还剩: 18291.0
- 。。。
模型可以打印每次买入和卖出的日志,模型中的参数 verbose 和plot是默认打开的,可以看需求关闭。同时Plot参数提供了可视化, 上方的图表示股价图,下方图则是本金变化图形。
从图形可以看出600460的股价从20年的低点到21年的高年翻了将近6倍,而均线策略最高只取得了两倍的收益。
我们可以继续换一组参数,用5日线和10日线来操作。
- model = Dual_moving_average_stra('600460', '20200101', 5, 10)
- model.strategy()
可以看出来效果会比5日线和20日线的组合好一点。个人感觉这个策略比较依赖标的。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。