跳转到根目录:知行合一:投资篇
已完成:
1、投资&技术
??1.1.1 投资-编程基础-numpy
??1.1.2 投资-编程基础-pandas
??1.2 金融数据处理
??1.3 金融数据可视化
2、投资方法论
??2.1.1 预期年化收益率
3、投资实证
??[3.1 2023这一年] 被鸽
这个比较简单 ,在之前的文章中已经有更加详细的描述(1.2 金融数据处理),这里就是简单的叙说一下:
import qstock as qs
# 如果没有安装qstock,执行:
# pip install qstock
# pip install pywencai
df=qs.get_data('510300') # 获取的是510300的所有日线历史行情数据,自己保存,不用每次都去拉,做一些简单算法、回测是够用了。
df.to_csv('510300.csv')
print(df)
name code open high low close volume \
date
2012-05-28 沪深300ETF 510300 1.951 2.007 1.944 2.004 12775188
2012-05-29 沪深300ETF 510300 2.002 2.061 2.002 2.044 7149490
2012-05-30 沪深300ETF 510300 2.042 2.047 2.033 2.036 2658872
2012-05-31 沪深300ETF 510300 2.021 2.045 2.013 2.030 1781560
2012-06-01 沪深300ETF 510300 2.029 2.060 2.020 2.030 1793500
... ... ... ... ... ... ... ...
2023-12-29 沪深300ETF 510300 3.488 3.505 3.482 3.499 25188735
2024-01-02 沪深300ETF 510300 3.502 3.502 3.451 3.453 9429306
2024-01-03 沪深300ETF 510300 3.446 3.460 3.428 3.443 10617503
2024-01-04 沪深300ETF 510300 3.442 3.442 3.387 3.413 16661525
2024-01-05 沪深300ETF 510300 3.404 3.439 3.377 3.396 16996697
turnover turnover_rate
date
2012-05-28 3.285755e+09 3.49
2012-05-29 1.875593e+09 1.96
2012-05-30 7.017258e+08 0.73
2012-05-31 4.681931e+08 0.49
2012-06-01 4.734772e+08 0.49
... ... ...
2023-12-29 8.806299e+09 6.89
2024-01-02 3.269677e+09 2.58
2024-01-03 3.654758e+09 2.90
2024-01-04 5.674870e+09 4.56
2024-01-05 5.796964e+09 4.65
[2826 rows x 9 columns]
什么叫年化4%?这么理解,今年1月1日是1块钱,到年底的时候,是多少钱?1*(1+0.04) = 1.04元。
假设今年一共是250个交易日(所以250日线很重要),所以照理来说,每个交易日上涨大约就是 1.04/250 = 0.00416元。
我们要画的折线图,其实是沪深300的收盘价走势图。这个也比较容易,在之前 1.3 金融数据可视化中第1.2.2小节已经画过了,很简单。这里也为了不跳出,把代码贴出来。
#导入数据分析和量化常用库
import pandas as pd
import numpy as np
#导入pyecharts
from pyecharts.charts import *
df=qs.get_data('510300')
g=(Line()
.add_xaxis(df.index.strftime('%Y-%m-%d').tolist())
.add_yaxis('',df.close))
g.render_notebook()
就这么点代码,感谢cctv,错了,感谢python、pandas、pyecharts。
后面的完整案例,就是在此基础上,进一步优化了图形上的一些配置,可以在鼠标移动到上面hover的时候,能显示出来对应的点位信息,而已。
pyecharts画直线,其实也是很简单的。
from pyecharts import options as opts
from pyecharts.charts import Line
import random
# 创建数据集合
x_data = [i for i in range(10)]
# y_data = [random.randint(-50, 50) for _ in x_data]
y_data = 2 * x_data
# 初始化 Line 对象
line = (Line()
.add_xaxis(x_data)
.add_yaxis("", y_data))
# 设置全局配置项
line.set_global_opts(title_opts=opts.TitleOpts(title="直线图"),
toolbox_opts=opts.ToolboxOpts())
line.render_notebook()
代码主要的流程:
定义要获取的标的,比如沪深300,代码510300。使用qstock获取日线历史行情数据。
直线画线的其实时间,比如可以定在 2016-02-25。(定在哪里,这个就见仁见智了,老股民画线有自己的心得。)
当然,我们可以自己定起始时间。
根据我们想要的年华,比如4%,6%,8%,分别计算在此复合年化下的直线数值,以便在pyecharts画线的时候用到。
画图,收盘价折线图 + 4%直线 + 6%直线 + 8%直线。
from pyecharts.charts import Line
import pandas as pd
import pyecharts.options as opts
import qstock as qs
# 在线选色 http://tools.jb51.net/static/colorpicker/
security = '510300' # 510300 510500
start_date_str = '2016-02-25' # 2016-02-25 2014-05-23
lines = [
{'start_date_str': start_date_str, 'number_of_percent': 0.04, 'name_of_line': '预测值4%', 'color': '#cc0099'},
{'start_date_str': start_date_str, 'number_of_percent': 0.06, 'name_of_line': '预测值6%', 'color': '#16c79a'},
{'start_date_str': start_date_str, 'number_of_percent': 0.08, 'name_of_line': '预测值8%', 'color': '#00d7ff'}
]
def calculate_new_col(df, number_of_percent, name_of_line, start_date_str):
end = begin = df.loc[start_date_str, 'close'] # 2.6142 获取起始日的收盘价
rate = number_of_percent # 0.06 获取收益率预期值
year = len(df.loc[start_date_str:].index) / 250 # 计算有多少年,以便计算收益率下的终值
end *= ((1 + rate) ** year) # 终值,**是次方运算
slot = len(df.loc[start_date_str:].index) - 1 # 有多少个时间区间,将总收益平分(直线,是等差数列,平分总收益)
per_step = (end - begin) / slot # 将总收益平分(直线,是等差数列,平分总收益),每个slot递增 per_step
# 计算新列(比如年化4%)的值
row_keys = df.loc[start_date_str:].index
this_day_value = begin
for row_key in row_keys:
df.loc[row_key, name_of_line] = this_day_value
this_day_value = this_day_value + per_step
df[name_of_line] = df[name_of_line].round(3)
# 加载数据
df = qs.get_data(security)
# 计算线条所需的数据
for item in lines:
calculate_new_col(df=df, number_of_percent=item['number_of_percent'], name_of_line=item['name_of_line'], start_date_str=item['start_date_str'])
x_data = df.index.date.tolist() # x轴所需的数据
close_data = df['close'].values.tolist() # 收盘价数据
line = (
Line(init_opts=opts.InitOpts(width="1400px", height="700px")) # 设置图表大小
.add_xaxis(x_data) # 设置x轴, 需要加tolist
.add_yaxis("收盘价",
close_data,
is_connect_nones=True,# 缺失值的处理
symbol_size=10, # 标识的大小
is_smooth=True,# 线条样式 , 是否设置成圆滑曲线
linestyle_opts=opts.LineStyleOpts(width=1,color ='#000000',type_="solid"), # 线条颜色和宽度
label_opts=opts.LabelOpts(is_show=True,position='top',color ='#000000'),# 文字标签的位置和颜色
itemstyle_opts=opts.ItemStyleOpts(border_width=3, border_color="#000000", color="#000000"),# 标识的颜色和宽度
)
.set_global_opts(title_opts=opts.TitleOpts(title="%s趋势分析" % security,subtitle="", # 主标题
title_textstyle_opts=opts.TextStyleOpts(font_size=30), #主标题字体大小
pos_left='6%'), # 主标题位置
legend_opts=opts.LegendOpts(is_show=True,# 是否显示图例
pos_top="3%",# 图例位置
item_width=15,# 宽度
item_height=15,#高度
item_gap=10,# 图例间隔
textstyle_opts=opts.TextStyleOpts(font_size=15)), # 图例文字大小
tooltip_opts=opts.TooltipOpts(trigger="axis"),# 提示框触发, 按坐标轴
yaxis_opts=opts.AxisOpts(type_="value",
axistick_opts=opts.AxisTickOpts(is_show=False), # 刻度线不显示
axisline_opts=opts.AxisLineOpts(is_show=False), # y轴线不显示
splitline_opts=opts.SplitLineOpts(is_show=True), # y轴网格线显示
axislabel_opts=opts.LabelOpts(formatter="{value} 元")),# y轴刻度文字
xaxis_opts=opts.AxisOpts(axistick_opts=opts.AxisTickOpts(is_align_with_label=True),
is_scale=False,
boundary_gap=False))
)
for item in lines:
line_data = df[item['name_of_line']].values.tolist()
line.add_yaxis(item['name_of_line'],
line_data,
is_connect_nones=True,
#symbol="triangle" 标识的样式 三角形
symbol_size=10, # 标识的大小
is_smooth=True, # 线条样式 , 是否设置成圆滑曲线
linestyle_opts=opts.LineStyleOpts(width=3,color=item['color']), # 线条颜色和宽度
label_opts=opts.LabelOpts(is_show=True,position='top',color=item['color']),# 文字标签的位置和颜色
itemstyle_opts=opts.ItemStyleOpts(border_width=3, border_color=item['color'], color=item['color']), # 标识的颜色和宽度
)
# 在pycharm中,保存html
# line.render("%s趋势分析.html" % security)
# 在notebook中,直接显示出来
line.render_notebook()
上述代码,可得绘图如下:
这个图,真是好看啊,4%是妥妥的~即使是在如此行情的2024年,也是没有跌破啊。
下面就是分别调整2个参数:
security = ‘510300’
start_date_str = ‘2016-02-25’
其实还有下面的参数可以配:number_of_percent,这里只是3条线,4%,6%,8%,也可以再加10%的等等。
lines = [
{'start_date_str': start_date_str, 'number_of_percent': 0.04, 'name_of_line': '预测值4%', 'color': '#cc0099'},
{'start_date_str': start_date_str, 'number_of_percent': 0.06, 'name_of_line': '预测值6%', 'color': '#16c79a'},
{'start_date_str': start_date_str, 'number_of_percent': 0.08, 'name_of_line': '预测值8%', 'color': '#00d7ff'}
]
下面主要就是按照不同的标的,调整起始时间看看画出来的图的效果。也好对这个标的心中有数。
标注:沪深300 510300
直线起始时间:2016-02-25
上图,是需要把完整代码前面2行改一下就行:
security = '510300'
start_date_str = '2016-02-25'
标注:沪深300 510300
直线起始时间:2014-05-23
上图,是需要把完整代码前面2行改一下就行:
security = '510300'
start_date_str = '2014-05-23'
标注:中证500 510500
直线起始时间:2016-02-25
上图,是需要把完整代码前面2行改一下就行:
security = '510500'
start_date_str = '2016-02-25'
标注:中证500 510500
直线起始时间:2014-05-23
上图,是需要把完整代码前面2行改一下就行:
security = '510500'
start_date_str = '2014-05-23'
由于创业板波动太大,那我们从远一点2012年开始画图,而且,8%貌似都不能很好的拟合19年和23年的低点,我们加了一条10%的红线!
security = '159915'
start_date_str = '2012-12-11'
lines = [
{'start_date_str': start_date_str, 'number_of_percent': 0.04, 'name_of_line': '预测值4%', 'color': '#cc0099'},
{'start_date_str': start_date_str, 'number_of_percent': 0.06, 'name_of_line': '预测值6%', 'color': '#16c79a'},
{'start_date_str': start_date_str, 'number_of_percent': 0.08, 'name_of_line': '预测值8%', 'color': '#00d7ff'},
{'start_date_str': start_date_str, 'number_of_percent': 0.1, 'name_of_line': '预测值10%', 'color': '#ff0000'}
]
这意味着:如果是从12年12月开始,即使是拿着不动,到现在也能拿到10%的复合年化收益率,还是非常非常可观的。
横评各个标的,如果拉长时间来看,4% ~ 10% 都是有可能的,关键还是在画线的开始时点在哪里。
留一个坑:有没有办法能简单的评价出此标的的内在收益率?其实是有的,只需要将日线行情数据,利用最佳拟合直线来绘制,再分别计算得出其斜率值,这就能大概知道此标的的内在收益率了。这个就留待后面再揭晓实现方案~
但是不管怎么说,这条线,都是向上的,要保持耐心和信心,一定能有所获得!