当前位置:   article > 正文

金融量化分析——双均线策略_双均线策略代码

双均线策略代码

目录

一、数据采集

二、提取有效数据

三、金叉、死叉分析

四、模拟实操

五、完整代码

六、未来展望


一、数据采集

1、首先安装Tushare:

pip install Tushare

2、使用Tushare接口,并导入所需的包:

  1. import tushare as ts
  2. import pandas as pd
  3. import matplotlib as plt
  4. import numpy as np
  5. import mplfinance as mpf//绘制K线的包,本节没有用到

3、试着获取从2023-10-1到2023-11-1期间的茅台股票数据,:

df = pro.daily(ts_code='600519.SH', start_date='20231001', end_date='20231101')

4、将数据保存至CSV文件:

df.to_csv('600519data.csv',index=False)

二、提取有效数据

1、读取刚才保存的CSV文件,并选取所需数据:

df = pd.read_csv("600519data.csv",index_col='trade_date',parse_dates=['trade_date'])[['open','close','low','high']]

2、 由于所获得数据是时间倒序,所以需要按照时间标签正序排序

df = df.sort_index()

3、创建两列,并分别命名“ma5”和“ma30”,分别代表5日、30日均线的值:

  1. df['ma5'] = np.nan
  2. df['ma30'] = np.nan
  3. for i in range(4,len(df)):
  4. df.loc[df.index[i],'ma5'] = df['close'][i-4:i+1].mean()
  5. for i in range(29,len(df)):
  6. df.loc[df.index[i],'ma30'] = df['close'][i-29:i+1].mean()

也可使用另一种方法:

  1. df['ma5'] = df['close'].rolling(5).mean
  2. df['ma30'] = df['close'].rolling(30).mean

4、查看均线图:

df[['close','ma5','ma30']].plot()

三、金叉、死叉分析

1、创建两列数组,作为金叉和死叉:

若当日5日均线值大于等于30日均线值,并且前一日5日均线值小于30日均线值,则称交点为金叉.

若当日5日均线值小于等于30日均线值,并且前一日5日均线值大于30日均线值,则称交点为死叉.

  1. golden_cross = []
  2. death_cross = []
  3. for i in range(1,len(df)):
  4. if df['ma5'][i]>=df['ma30'][i] and df['ma5'][i-1]<df['ma30'][i-1]:
  5. golden_cross.append(df.index[i])
  6. if df['ma5'][i]<=df['ma30'][i] and df['ma5'][i-1]>df['ma30'][i-1]:
  7. death_cross.append(df.index[i])

判定金叉、死叉另一种方法:

  1. sr1 = df['ma5'] < df['ma30']
  2. sr2 = df['ma5'] > df['ma30']
  3. death_cross1 = df[sr1 & sr2.shift(1)].index
  4. golden_cross1 = df[-(sr1 | sr2.shift(1))].index

左图为金叉,右图为死叉: 

四、模拟实操

        本文采取的双均线策略是选择5日和30日这两条移动平均线,当第一个金叉出现的时候买入,紧接着出现死叉的时候再卖出。

将两个存有金叉死叉数据的序列合并到一个序列sr里,

  1. first_money = 100000
  2. money = first_money
  3. hold = 0 #持有多少股
  4. sr1= pd.Series(1,index = golden_cross)
  5. sr2 = pd.Series(0,index = death_cross)
  6. sr = sr1._append(sr_death).sort_index()
  7. for i in range(0,len(sr)):
  8. p =df['open'][sr.index[i]]
  9. if sr.iloc[i] == 1:
  10. #金叉
  11. buy = (money // (100 * p))
  12. hold += buy*100
  13. money -= buy*100*p
  14. else:
  15. money += hold *p
  16. hold = 0
  17. p = df['open'][-1]
  18. now_moeny = hold * p + money
  19. print(now_moeny - first_money)

        结果显示,从2013年1月1日开始到2023年11月1日结束,在本金10w的情况下采取双均线策略,可以盈利1324734.0元,也就是132w+元。

五、完整代码

  1. import tushare as ts
  2. import pandas as pd
  3. import matplotlib as plt
  4. import numpy as np
  5. import mplfinance as mpf
  6. #读取数据
  7. df = pd.read_csv("600519data.csv",index_col='trade_date',parse_dates=['trade_date'])[['open','close','low','high']]
  8. #数据排序
  9. df = df.sort_index()
  10. #创建当日的5日和30日的均线值
  11. df['ma5'] = np.nan
  12. df['ma30'] = np.nan
  13. for i in range(4,len(df)):
  14. df.loc[df.index[i],'ma5'] = df['close'][i-4:i+1].mean()
  15. for i in range(29,len(df)):
  16. df.loc[df.index[i],'ma30'] = df['close'][i-29:i+1].mean()
  17. #丢掉缺失数据
  18. df = df.dropna()
  19. #判断金叉、死叉
  20. golden_cross = []
  21. death_cross = []
  22. for i in range(1,len(df)):
  23. if df['ma5'][i]>=df['ma30'][i] and df['ma5'][i-1]<df['ma30'][i-1]:
  24. golden_cross.append(df.index[i])
  25. if df['ma5'][i]<=df['ma30'][i] and df['ma5'][i-1]>df['ma30'][i-1]:
  26. death_cross.append(df.index[i])
  27. #模拟实操
  28. first_money = 100000
  29. money = first_money
  30. hold = 0 #持有多少股
  31. sr1= pd.Series(1,index = golden_cross)
  32. sr2 = pd.Series(0,index = death_cross)
  33. sr = sr1._append(sr_death).sort_index()
  34. for i in range(0,len(sr)):
  35. p =df['open'][sr.index[i]]
  36. if sr.iloc[i] == 1:
  37. #金叉
  38. buy = (money // (100 * p))
  39. hold += buy*100
  40. money -= buy*100*p
  41. else:
  42. money += hold *p
  43. hold = 0
  44. p = df['open'][-1]
  45. now_moeny = hold * p + money
  46. print(now_moeny - first_money)

六、未来展望

        由于第二天才能知道昨天的收盘价,即使当天知道收盘价后也无法买入了,也就是说第二天才知道昨天是否有金叉死叉,所以实际操作中应该是后一天买入或者卖出。

        因此,在未来改进过程中可以将上述代码的p变量赋值第二天的开盘价格,以此来增加模拟策略的准确度。

七、拓展:利用聚宽金融量化交易平台

1、创建初始化函数

依旧选择贵州茅台股票,600519

  1. # 初始化函数,设定基准等等
  2. def initialize(context):
  3. # 开启动态复权模式(真实价格)
  4. set_option('use_real_price', True)
  5. # 股票类每笔交易时的手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱
  6. set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
  7. # 选取贵州茅台股票
  8. g.security = ['600519.XSHG']
  9. # 5日、60日
  10. g.p1 = 5
  11. g.p2 = 60

2、交易函数

(1)聚宽的attribute_history的函数:

一般只用前两个参数,第二个count参数为期望的最终数量。

  • count: 大于0的整数,表示获取bar的个数。如果行情数据的bar不足count个,返回的长度则小于count个数。

(2)账户信息函数

context.portfolio.positions,账户是否持仓。

context.portfolio.available_cash,账户鱼儿

(3)order_target函数,常用的依旧是前两个参数。

第二个参数可以填写账户金额,系数自动计算这些钱能买最大股票数。

  1. def handle_data(context, data):
  2. for stock in g.security:
  3. # 金叉:如果5五日均线大于10日均线,并且不持仓
  4. # 死叉:如果5五日均线小于10日均线,并且持仓股票
  5. df = attribute_history(stock, g.p2)
  6. ma10 = df['close'].mean()
  7. ma5 = df['close'][-5:].mean()
  8. if ma10 > ma5 and stock in context.portfolio.positions:
  9. # 死叉
  10. order_target(stock,0)
  11. if ma10 < ma5 and stock not in context.portfolio.positions:
  12. # 金叉
  13. order_target(stock,context.portfolio.available_cash * 0.8)

3、完整代码

  1. # 导入函数库
  2. from jqdata import *
  3. # 初始化函数,设定基准等等
  4. def initialize(context):
  5. # 开启动态复权模式(真实价格)
  6. set_option('use_real_price', True)
  7. # 股票类每笔交易时的手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱
  8. set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
  9. # 选取贵州茅台股票
  10. g.security = ['600519.XSHG']
  11. # 5日、60日
  12. g.p1 = 5
  13. g.p2 = 60
  14. ## 开盘前运行函数
  15. def handle_data(context, data):
  16. for stock in g.security:
  17. # 金叉:如果5五日均线大于10日均线,并且不持仓
  18. # 死叉:如果5五日均线小于10日均线,并且持仓股票
  19. df = attribute_history(stock, g.p2)
  20. ma10 = df['close'].mean()
  21. ma5 = df['close'][-5:].mean()
  22. if ma10 > ma5 and stock in context.portfolio.positions:
  23. # 死叉
  24. order_target(stock,0)
  25. if ma10 < ma5 and stock not in context.portfolio.positions:
  26. # 金叉
  27. order_target(stock,context.portfolio.available_cash * 0.8)

4、运行结果

时间选择的是2022-10-1至2023-10-1,可以看到一年时间收益4.46%。

至于双均线策略是否有用,小伙伴们还可多换些股票和时间区间来验证。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/831766
推荐阅读
相关标签
  

闽ICP备14008679号