量化投资01----股票_贵州茅台600519_双均线策略回测

贵州茅台 SH600519
双均线策略回测(5日均线、30日均线,金叉买入,死叉卖出)
交易从 2010年开始,2019年底结束。
10万初始资金
尽量买入(按手),尽量卖出,均以开盘价
未计算手续费
最终盈亏(见底部)

import akshare as ak
import pandas as pd
#获取某只股票的历史行情代码
df = ak.stock_zh_index_daily(symbol="sh600519")
#将结果写入到CSV文件中
df.to_csv('./sh600519.csv')
#将本地存储的数据读到DataFrame中
df = pd.read_csv('./sh600519.csv')
df.head()
Unnamed: 0dateopenhighlowclosevolume
002001-08-2734.5137.7832.8535.5540631800
112001-08-2834.9937.0034.6136.8612964779
222001-08-2936.9837.0036.1036.385325275
332001-08-3036.2837.5136.0037.104801306
442001-08-3137.1537.6236.8037.012323148
#删除df中指定的列
#axis=1 表示轴心为行,删除的是列
df.drop(labels='Unnamed: 0',axis=1,inplace=True)
df.head()
dateopenhighlowclosevolume
02001-08-2734.5137.7832.8535.5540631800
12001-08-2834.9937.0034.6136.8612964779
22001-08-2936.9837.0036.1036.385325275
32001-08-3036.2837.5136.0037.104801306
42001-08-3137.1537.6236.8037.012323148
#查看每一列对应的数据类型
df['date'].dtype
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5047 entries, 0 to 5046
Data columns (total 6 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   date    5047 non-null   object 
 1   open    5047 non-null   float64
 2   high    5047 non-null   float64
 3   low     5047 non-null   float64
 4   close   5047 non-null   float64
 5   volume  5047 non-null   int64  
dtypes: float64(4), int64(1), object(1)
memory usage: 236.7+ KB
#将Data这一列转换为时间类型
df['date'] = pd.to_datetime(df['date'])
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5047 entries, 0 to 5046
Data columns (total 6 columns):
 #   Column  Non-Null Count  Dtype         
---  ------  --------------  -----         
 0   date    5047 non-null   datetime64[ns]
 1   open    5047 non-null   float64       
 2   high    5047 non-null   float64       
 3   low     5047 non-null   float64       
 4   close   5047 non-null   float64       
 5   volume  5047 non-null   int64         
dtypes: datetime64[ns](1), float64(4), int64(1)
memory usage: 236.7 KB
#将 date这一列作为源数据的行索引
df.set_index('date',inplace=True)
df.head()
openhighlowclosevolume
date
2001-08-2734.5137.7832.8535.5540631800
2001-08-2834.9937.0034.6136.8612964779
2001-08-2936.9837.0036.1036.385325275
2001-08-3036.2837.5136.0037.104801306
2001-08-3137.1537.6236.8037.012323148
#所有收盘价比开盘价上涨3%以上的日期
(df['open']-df['close'])/df['open'] > 0.03
#如果布尔值Series作为行索引,则可以去出true对应行数据,忽略false对应的行数据
df.loc[(df['open']-df['close'])/df['open'] > 0.03]

#取得日期
df.loc[(df['open']-df['close'])/df['open'] > 0.03].index
DatetimeIndex(['2001-10-10', '2001-11-07', '2001-11-16', '2001-12-20',
               '2002-01-04', '2002-01-17', '2002-01-28', '2002-04-17',
               '2002-11-08', '2003-01-02',
               ...
               '2021-07-26', '2021-07-27', '2021-07-29', '2021-08-17',
               '2021-08-26', '2021-10-18', '2021-12-29', '2022-01-13',
               '2022-01-28', '2022-03-07'],
              dtype='datetime64[ns]', name='date', length=189, freq=None)
#所有开盘比钱日收盘跌幅超过2%的日期
#将收盘价整体下移一行,用来取得前收盘
df['close'].shift(1)

df.loc[(df['open']-df['close'].shift(1))/df['close'].shift(1) < -0.02].index
DatetimeIndex(['2001-09-12', '2002-06-26', '2002-07-25', '2002-12-13',
               '2003-07-14', '2004-07-01', '2004-10-29', '2005-08-05',
               '2006-05-25', '2006-08-21',
               ...
               '2020-03-23', '2020-10-26', '2021-02-26', '2021-03-04',
               '2021-04-28', '2021-08-20', '2021-11-01', '2022-03-14',
               '2022-03-15', '2022-03-28'],
              dtype='datetime64[ns]', name='date', length=101, freq=None)
#假如从2010年1月1日开始,
#每个月第一个交易日买入1手股票
#每年最后一个交易日卖出所有的股票
#到今天为止,我的收益如何?
#买卖股票用开盘价

# 取10年的集合
#df['2010-01-01':'2019-12-31']

#resample数据的重新取样
#根据月份从原始数据中指定的数据
#每月第一个行数据,则买入股票所花费的金额为
#注意,这里数据没问题,但是索引是有问题的
#df['2010-01-01':'2019-12-31'].resample('M').first()['open']

pay = df['2010-01-01':'2019-12-31'].resample('M').first()['open'].sum()*100
pay
4162439.0
#取每年的最后一个交易日
earn = df['2010-01-01':'2019-12-31'].resample('A').last()['open'].sum()*100
#如果要删掉一个数据则用df['2010-01-01':'2019-12-31'].resample('A').first()[:-1]
earn
390654.0
#计算总收益
earn-pay
-3771785.0
#均线计算 MA=(C1+C2+CN)/N,其中C是收盘价,N是移动平均天数
# 5,10,30,60,120,240 常见的N日均线
ma5 = df['close'].rolling(5).mean()
ma30 = df['close'].rolling(30).mean()
#均线画图
import matplotlib.pyplot as plt
plt.plot(ma5[50:180])
plt.plot(ma30[50:180])
[<matplotlib.lines.Line2D at 0x1e47b57d360>]

130的走势,非全部

ma5 = ma5[30:]
ma30 = ma30[30:]

s1 = ma5 < ma30
s2 = ma5 > ma30

df = df[30:]

death_ex = s1 & s2.shift(1) #判断死叉的条件,一组BOOL值
death_date = df.loc[death_ex].index

golden_ex = -(s1 | s2.shift(1)) #判断金叉的条件,一组BOOL值
golden_date = df.loc[golden_ex].index

#交易从 2010年开始,10万初始资金,尽量买入(按手),尽量卖出,均以开盘价
s1 = pd.Series(data=1,index=golden_date)
s2 = pd.Series(data=0,index=death_date)
#s = s1.append(s2)
s= pd.concat([s1,s2],axis=0)
s = s.sort_index()
s = s['2010':'2020']

capital = 100000 # 初始资金10万
money = capital #当前有多少活动资金
hold = 0 #持有的股票数
for i in range(0,len(s)):
    p = df.loc[s.index[i]]['open']
    if s[i] == 1: #金叉,需要买进        
        #print(p)
        hand_count = money // (p*100)
        hold = hand_count * 100
        money -= hold*p
    else:
        #将 hold的股票卖出去
        money += hold*p
        hold = 0
print(money-capital)        
        
6193.0
(没算手续费,没算利息,没亏,十年啊,太尴尬了,金叉,死叉不可信啊!)

jupyter的源文件,如果想要得话就给我留言吧,我发出来。

## 讲师介绍: 近 5 年个人投资理财年化收益平均超 25%。如果你也想提升自己的睡后收入,轻松赚钱,那么这门课就是为你量身打造。课程基于一个完整真实的量化交易业务来讲授,并融入老师的理财经验以及使用编程技术辅助投资的技巧,让你面对各种复杂投资情况也能做到游刃有余。 ## 学习目标: 从不懂“理财”开始到实现自动交易,成为一个“技术流”理财高手 编程技术 + 核心量化策略 + 交易系统开发 + 讲师经验分享,学会用技术辅助理财 本课程从最基础的什么是量化开始讲起,即使对投资理财不了解同样可以学习,轻松入门无压力。 从如何获取数据开始,到实现实盘交易,课程对量化交易的每一步都进行细致讲解,为你铺开量化交易的每一个细节。 不仅仅只是教你学会使用某种工具,更会教给你量化交易的投资思想,让你面对各种情况都游刃有余。 ## 课程亮点: 设计适合自己并能适应市场的交易策略,才是量化交易的灵魂 课程亲手带你设计并实现两种交易策略,快速培养你的策略思维能力 1. 择时策略:通过这个策略学会如何利用均线,创建择时策略,优化股票买入卖出的时间点。2. 选股策略:掌握选股策略的核心逻辑,并基于收益率创建动量选股策略,并验证其有效性。 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统 第三方平台大而全,不易扩展,效率还差,信息安全也是大问题,打造自己的交易平台才是更优解
股票回测量化交易中非常重要的一环,它可以通过历史数据对交易策略进行模拟和评估,从而评估策略的可行性和优劣性。在Python中,有很多开源的量化交易框架可以用来进行股票回测,如zipline、backtrader等。 下面是一个使用zipline框架进行简单交易策略回测的例子: 1. 安装zipline ```python pip install zipline ``` 2. 编写交易策略代码 ```python from zipline.api import order_target_percent, record, symbol def initialize(context): context.asset = symbol('AAPL') def handle_data(context, data): # 获取过去10天的收盘价 prices = data.history(context.asset, 'price', 10, '1d') # 计算平均价 mean_price = prices.mean() # 如果当前价格低于平均价,则买入 if data.current(context.asset, 'price') < mean_price: # 调整持仓比例至100% order_target_percent(context.asset, 1.0) # 否则卖出 else: # 调整持仓比例至0% order_target_percent(context.asset, 0.0) # 记录当前持仓比例 record(position=context.portfolio.positions[context.asset].amount) ``` 3. 运行回测 ```python from zipline import run_algorithm from zipline.api import symbol from datetime import datetime start = datetime(2016, 1, 1) end = datetime(2017, 1, 1) result = run_algorithm( start=start, end=end, initialize=initialize, capital_base=10000, handle_data=handle_data, bundle='quandl' ) ``` 在上述代码中,我们定义了一个简单的交易策略,即如果当前价格低于过去10天的平均价,则买入,否则卖出。然后我们使用zipline框架进行回测,设定回测开始和结束时间、初始资本、数据来源等参数,最终得到回测结果。 需要注意的是,这只是一个简单的例子,实际的交易策略可能会更加复杂,需要考虑更多的因素。另外,在进行股票回测时,也需要注意避免过度拟合或过度优化,以免出现回测虚高的情况。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值