当前位置: 首页 > news >正文

量化交易backtrader实践(三)_指标与策略篇(1)_指标简介与手工双均线策略

01_指标

指标是一个汉语词语,读音是zhǐ biāo,意思是衡量目标的参数;预期中打算达到的指数规格标准,一般用数据表示。

统计学术语

指标是说明总体数量特征的概念及其数值的综合,故又称为综合指标。在实际的统计工作和统计理论研究中,往往直接将说明总体数量特征的概念称为指标。

简单理解,概念+数值 = 指标。

在工作上,可以有验收指标,评价指标,销售指标等。因此股票研究中,会产生各种不同的指标,比如MA(移动平均值),比如30天最高,也可以出现许多的组合或者复杂指标,比如KDJ, MACD。更可以叠加成各种不同的战法指标。注意指标的概念,指标可以是有效的,也可以的错误的。

001_均线类指标

A_平均值与中位数

首先,平均值与中位数是两个概念,需要把它们的差别理解清楚。

平均值(Mean)和中位数(Median)都是描述数据集中趋势的统计量,但它们的定义和计算方式不同,适用于不同类型的数据分布。

  1. 平均值(Mean)

    • 定义:所有数值加起来的总和除以数值的数量。
    • 计算公式:平均值=\frac{\sum_{1}^{n}X_{i}}{n}
    • 其中Xi 表示数据集中的每一个数值,n是数值的总数。
    • 特点:容易受到极端值(非常高或非常低的数值)的影响。
  2. 中位数(Median)

    • 定义:将数据集从小到大排序后位于中间位置的数值。如果数据集中的数值个数是奇数,中位数就是中间的那个数;如果是偶数,则是中间两个数的平均值。
    • 计算方法:首先将数据集排序,然后找到中间的数值。
    • 特点:不受极端值的影响,更能反映数据的中心位置。
  • 敏感性:平均值对极端值敏感,中位数则不敏感。
  • 计算方式:平均值是所有数值的总和除以数值的数量,中位数是排序后位于中间位置的数值。
  • 数据分布:如果数据分布是对称的,平均值和中位数通常很接近;如果数据分布是偏斜的,两者可能会相差很大。
  • 应用场景:在数据分布不均或包含极端值的情况下,中位数通常是一个更稳健的中心趋势度量。

 我们用一个简单的例子来说明它们之间的差别,通过python代码随机产生31(中位数是排序后第16个)个介于50~100之间数(某个班的考试成绩),然后计算它们的平均值和中位数,然后在图中绘制散点图作为1号情况;接着我们更改这31个数里的索引为0和1的数值为10和15,打个比方有两个学生生病了,只做了几道题就交卷了,这样的情况下,计算平均值和中位数作为2号情况。

import matplotlib.pyplot as plt
import numpy as np# 生成31个随机数据(奇数的中位数)
np.random.seed(0)  # 设置随机种子以确保结果可复现
data = np.random.normal(70, 6, 31)  # 生成31个数据data2 = np.copy(data)   # 第二组数据改动2个值
data2[0] = 10
data2[1] = 20# 计算平均值和中位数
mean_value = np.mean(data)
median_value = np.median(data)
print('平均值=%.2f,中位数=%.2f'%(mean_value,median_value))# 对数据进行排序
sorted_data = np.sort(data)
print(sorted_data)# 绘制散点图
plt.scatter(range(len(data)), data, color='blue', label='Data Points')# 绘制平均值和中位数的线
plt.axhline(y=mean_value, color='red', linestyle='--', label=f'Mean: {mean_value:.2f}')
plt.axhline(y=median_value, color='green', linestyle='-', label=f'Median: {median_value:.2f}')# 标记平均值和中位数
plt.scatter(len(data)*1.05, mean_value, color='red', label='Mean')
plt.scatter(len(data)*1.05, median_value, color='green', label='Median')
plt.ylim(50,90)

 所以,要提高平均分的方法很简单,那两个生病的不计入,可见极值对平均值的影响有多大,这个在K线上其实也有同样的问题,某些日子的K线它就不是一个正常值,计算到平均值里就会产生一定的误导,如果我们使用中位数则极值的影响就非常小,它只看排在中间的那个的数值就行了。

B_平均值与正态分布

正态分布(Normal Distribution),也称为高斯分布,是连续概率分布的一种,其概率密度函数的形状是对称的钟形曲线,这种分布广泛存在于自然科学和社会科学中。

在正态分布中,平均值是分布的中心,也是分布的峰值所在的位置。正态分布的曲线是关于平均值对称的,这意味着平均值将数据集分为两个相等的部分。

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import normmean_value = np.mean(data)
std_value = np.std(data)
print(mean_value,std_value)mean_value2 = np.mean(data2)
std_value2 = np.std(data2)
print(mean_value2,std_value2)# 绘制正态分布曲线
x = np.linspace(0, 120, 120)
y = norm.pdf(x,mean_value,std_value)
plt.plot(x, y, 'k', linewidth=2)# 绘制正态分布曲线y2 = norm.pdf(x,mean_value2,std_value2)
plt.plot(x, y2, 'r', linewidth=3)# 设置图例
plt.legend()# 设置图表标题和坐标轴标签
plt.title('Normal Distribution')
plt.xlabel('Value')
plt.ylabel('Probability Density')# 显示图表
plt.show()

我们把上面的2组数据分别计算后绘制正态分布图在一起,就可以发现,原数据平均值72.6,标准差为6.39,而添加了离谱的10,15的数据后,平均值变到了68.63,标准差增大到了15.45,图形上可以看到原数据(黑线)分布范围小,也就是大家的成绩都差不多,而更改了分布(红线)范围就非常大,也就表示有某些人的成绩跟大家差得太远。

A股市场有5000多支股票,也会遵循着正态分布的规律,所以我们的策略本身应用于这些股票的时候,就会出现偏差,有的股票上表现特别的好,大多数表现一般,某些股票上表现的极差。

在正态分布中,大约68%的数据位于均值(μ)的一个标准差(σ)范围内,大约95%的数据位于两个标准差范围内,大约99.7%的数据位于三个标准差范围内。这些百分比是正态分布的属性,也称为68-95-99.7规则或经验法则。

具体来说:

  • 约68%的数据值落在 μ−σ 到 μ+σ之间。
  • 约95%的数据值落在 μ−2σ 到 μ+2σ 之间。
  • 约99.7%的数据值落在 μ−3σ到 μ+3σ 之间。

对于股票来说,大多数的情况下都在2个标准差之内运行,只有少数情况下会跳到2个标准差之外,但是另外一个帕累托原则(Pareto Principle),简称2-8规律却告诉我们在任何一组事物中,最重要的只占一小部分,约20%,而其余80%尽管是多数,却往往是次要的。联想一下,看看是不是大多数情况下行情都是小涨小跌,只有极少数的情况下会有大行情?再想一下,是不是在大行情里才能赚取超额利润?

布林线指标就是根据正态分布进行计算的指标,对它的理解也可以这样认为,大多数情况下股价会在2个标准差之间波动,极少数情况穿出2个标准差可能就是极致行情。

C_移动平均线

关于移动平均线的定义,可以直接问AI得到:

移动平均线(Moving Average,简称MA)是技术分析中的一种常用工具,它有助于平滑价格数据,展现价格趋势的方向和强度。“移动”这个词在这里有两层含义:

  1. 数据的滚动性:移动平均线不是固定不变的,它随着时间的推移而“移动”。在计算移动平均值时,你会选择一个特定的时间周期(如5天、10天、30天等),然后计算这个周期内的平均价格。随着新的数据点加入和旧的数据点退出,移动平均线会相应地更新,从而“移动”。

  2. 平均的计算方式:移动平均线是对过去某个特定时间周期内的价格数据进行平均。随着新的交易日的结束,最旧的数据点会被新的数据点替换,然后重新计算平均值。这个过程就像是计算平均的过程在时间序列上“移动”。

移动平均线可以帮助交易者识别市场趋势,因为它们可以过滤掉短期的价格波动,使主要趋势更加明显。当价格在移动平均线之上时,通常被视为上升趋势;当价格在移动平均线之下时,通常被视为下降趋势。

移动平均线有几种不同的类型,包括简单移动平均线(SMA)、指数移动平均线(EMA)和加权移动平均线(WMA)。每种类型都有其特定的计算方法,但它们的核心目的都是提供对市场趋势的洞察。

其中我们使用最多的SMA和EMA,关于它们的区别也可以直接问AI

  1. 计算方法:

    • SMA(简单移动平均线): SMA是通过计算特定时间周期内的数值的平均值来得到的。例如,如果你计算10天的SMA,你会将过去10天的收盘价相加然后除以10。随着时间的推移,你会移动这个窗口一天,再次计算平均值,这样你就得到了一个SMA的数据点。SMA给予所有数据点相同的权重。

    • EMA(指数移动平均线): EMA也计算平均值,但它使用指数衰减的方式,给予最近的数据点更大的权重。EMA的计算稍微复杂一些,它使用一个平滑因子(通常是周期的倒数加一的一半,例如对于10天EMA,平滑因子是2/(10+1))来确定最近数据点的权重。EMA的计算需要一个初始值,通常取为第一天的值或周期内的平均值。

  2. 对价格变化的响应:

    • SMA对价格变化的响应比较慢,因为它给予所有数据点相同的权重,所以它对最近的价格变动不太敏感。
    • EMA对价格变化的响应更快,因为它给予最近的价格更大的权重,所以它能够更快地适应价格的变化。
  3. 趋势跟踪:

    • 由于SMA的滞后性,它更适用于识别已经确立的趋势。
    • EMA由于其敏感性,更适用于捕捉趋势的早期变化。

可以用excel的公式来了解: MA5相当于C2:C6的累加再除以5,EMA5相当于C6*2/(5+1) + F5*(1-2/(5+1)) ,这里2/(N+1)就是平滑因子,1-2/(N+1) = 1- 2/6 = 4/6

002_双均线策略的简单实现

在基本了解了移动平均线这类指标后,我们在不使用backtrader的前提下,自己动手实现一个双均线策略,也通过这个实践过程,去对应感受backtrader的功能。

A_数据获取

一支股票的数据获取在第一篇里有详细的过程,这里直接用第二篇里准备好的代码

# Notebook 数据准备
import akshare as ak
import pandas as pddef get_df_from_stock(code1):stock_df = ak.stock_zh_a_hist(symbol=code1, period="daily", start_date="20220901", adjust="qfq")stock_df.rename(columns={'日期':'date', '开盘':'open', '收盘':'close','最高':'high', '最低':'low',  '成交量':'volume',},inplace=True)stock_df.index = pd.to_datetime(stock_df.date)stock_df['openinterest'] = 0stock_df = stock_df[['open','high','low','close','volume','openinterest']]return stock_dfmyStockList = ['001287','002179','600860','300233','002774']df_stock_list = []for x in myStockList:df_tmp = get_df_from_stock(x)df_stock_list.append(df_tmp)df = df_stock_list[1]
df-----------------------open	high	low	    close	volume	openinterest
date						
2022-09-01	45.90	47.12	45.64	46.75	96128	0
2022-09-02	46.90	47.90	46.55	47.18	59848	0
2022-09-05	47.15	47.86	46.75	46.98	42456	0
2022-09-06	46.98	48.40	46.82	48.19	71577	0
2022-09-07	48.18	48.58	47.88	48.37	56144	0
...	...	...	...	...	...	...
2024-09-19	37.31	37.42	36.30	36.92	47857	0
2024-09-20	36.99	37.19	36.30	36.82	52096	0
2024-09-23	36.60	37.69	36.58	36.87	68754	0
2024-09-24	36.87	38.31	36.65	38.16	93653	0
2024-09-25	38.16	39.05	37.39	37.79	160848	0
501 rows × 6 columns

B_简单数据处理_in_pandas

1) SMA数据

SMA的数据由rolling(滚动)和mean(平均)两个部分组成,pandas里也的确是这么用的

import pandas as pd
import numpy as npdf['Short_MA'] = df['close'].rolling(window=5).mean()  # 例如5天移动平均线
df['Long_MA'] = df['close'].rolling(window=10).mean()   # 例如10天移动平均线df.head(20)-------------------------open	high	low	    close	volume	op	Short_MA Long_MA
date								
2022-09-01	45.90	47.12	45.64	46.75	96128	0	NaN	    NaN
2022-09-02	46.90	47.90	46.55	47.18	59848	0	NaN	    NaN
2022-09-05	47.15	47.86	46.75	46.98	42456	0	NaN	    NaN
2022-09-06	46.98	48.40	46.82	48.19	71577	0	NaN	    NaN
2022-09-07	48.18	48.58	47.88	48.37	56144	0	47.494	NaN
2022-09-08	48.08	49.04	48.08	48.80	61370	0	47.904	NaN
2022-09-09	48.98	49.05	47.53	48.37	56915	0	48.142	NaN
2022-09-13	48.21	49.07	47.90	48.78	50211	0	48.502	NaN
2022-09-14	48.59	50.98	48.22	50.45	113593	0	48.954	NaN
2022-09-15	50.28	50.67	48.38	48.99	68075	0	49.078	48.286
2022-09-16	48.98	50.90	48.75	49.15	85685	0	49.148	48.526
2022-09-19	49.16	50.13	48.35	48.88	58896	0	49.250	48.696
2022-09-20	49.36	49.96	48.73	49.38	55072	0	49.370	48.936
2022-09-21	49.06	49.46	47.88	47.94	50475	0	48.868	48.911
2022-09-22	47.90	49.26	47.65	48.73	67467	0	48.816	48.947
2022-09-23	49.36	50.93	48.49	49.11	136230	0	48.808	48.978
2022-09-26	48.73	48.82	47.29	47.63	74714	0	48.558	48.904
2022-09-27	47.67	47.82	46.94	47.23	61429	0	48.128	48.749
2022-09-28	47.23	47.86	45.13	45.32	109959	0	47.604	48.236
2022-09-29	45.32	46.36	44.83	45.02	76422	0	46.862	47.839

我们看到,SMA的特点就在于N-1日是没有计算数据的,比如5日均线前4天为NaN,10日均线则前9天为NaN。有些时候我们会把NaN用close的值替代掉或者去掉N-1天的数据,这也是上一节看到在股票软件评测系统中有增加100天数据用于计算的选项。增加100天就可以避免做这些操作。

df["Long_MA"][:9] = df['close'][:9]# 或者df = df.loc[9:,:]
2)同列当天与前一天比较

这个最典型的就是日收益的计算,拿今天收盘价减去昨天收盘价,在pandas里用shift(x)来实现,

df['c_prev'] = df.close.shift(1)
df['c_next'] = df.close.shift(-1)
df['day_change'] = df.close - df.close.shift(1)  # 当天收盘价 - 昨日收盘价df = df.tail(120)
df.head(10)---------------------open	high	low	    close	volume	o	Short_MA	Long_MA	c_prev	c_next	day_change
date											
2024-04-01	33.88	34.35	33.78	34.08	151838	0	33.912	34.982	33.81	33.40	0.27
2024-04-02	34.09	34.10	33.23	33.40	125136	0	33.632	34.651	34.08	32.82	-0.68
2024-04-03	33.21	33.30	32.61	32.82	141144	0	33.552	34.300	33.40	32.83	-0.58
2024-04-08	32.68	32.96	32.25	32.83	118979	0	33.388	34.033	32.82	32.65	0.01
2024-04-09	32.83	33.05	32.48	32.65	92947	0	33.156	33.668	32.83	32.35	-0.18
2024-04-10	32.50	32.58	31.84	32.35	98752	0	32.810	33.361	32.65	31.70	-0.30
2024-04-11	32.00	32.33	31.61	31.70	137972	0	32.470	33.051	32.35	30.79	-0.65
2024-04-12	31.61	31.86	30.61	30.79	224733	0	32.064	32.808	31.70	32.27	-0.91
2024-04-15	30.70	32.33	30.58	32.27	251100	0	31.952	32.670	30.79	32.07	1.48
2024-04-16	32.29	32.80	32.01	32.07	206348	0	31.836	32.496	32.27	32.51	-0.20
3) Cross判断

有了移动平均线,又有了上一个,下一个数据的比较,我们就可以制作cross判断了。

从之前的基础中我们知道,cross交叉是由2组条件相与得到的,无论是股票软件的cross(line1,line2)还是backtrader中的crossover(line1,line2)都需要2条线的数据,这里以5日和10日平均线为例,MA5上穿MA10就是意味着当天的MA5>MA10,而且昨天的MA5.shift(1)<MA10.shift(1) ,所以我们可以得到上穿(金叉)买点和下穿(死叉)卖点。


df['crs_up'] = (df['Short_MA'] > df['Long_MA']) & (df['Short_MA'].shift(1) < df['Long_MA'].shift(1))
df['crs_dn'] = (df['Short_MA'] < df['Long_MA']) & (df['Short_MA'].shift(1) > df['Long_MA'].shift(1))

从输出的数据可以看到,当前一天的MA5<MA10,而当天的MA5>MA10时,crs_up就会置True,表示这里发生了金叉,我们的买卖策略在这里做买入,买入价格使用当天的收盘价。

之后,当前一天的MA5>MA10,而当天的MA5<MA10,crs_dn就会置True,这里就是卖出。

4) EMA的计算及使用上一个值

EMA的计算在上面已经学习过了,它要使用到前一天的EMA和当天的close并根据平滑因子计算,因此EMA不管是多少(5或者10),都只需要计算当天的close和前一天的ema,不像MA5那样前4个都是NaN。

在pandas中可以直接使用ewm和mean()来计算得到:

df['EMA_5'] = df['close'].ewm(span=5, adjust=False).mean()
df[['close','volume','EMA_5']]  -----------------close	volume	EMA_5
date			
2022-09-01	46.75	96128	46.750000
2022-09-02	47.18	59848	46.893333
2022-09-05	46.98	42456	46.922222
2022-09-06	48.19	71577	47.344815
2022-09-07	48.37	56144	47.686543
...	...	...	...
2024-09-20	36.82	52096	37.085958
2024-09-23	36.87	68754	37.013972
2024-09-24	38.16	93653	37.395981
2024-09-25	37.79	160848	37.527321
2024-09-26	37.69	72755	37.581547

如果没有这么一个函数,我们可以尝试自己来制作。由于是当天的值需要使用到前一天的值,这个比较适合用循环来做,类似于backtrader里的next()中来完成,而不太合适直接用DataFrame的列计算的直接方式。

calc_days = 5
smooth_factor = 2.0/(calc_days + 1)print('smooth_factor',smooth_factor)df['calc_ema5'] = 0# 计算累积值
for i in range(len(df)):if i == 0:# 第一个元素就是当天的Close值df.at[df.index[i], 'calc_ema5'] = df.at[df.index[i], 'close']else:# 从第二个元素开始,累加当天的Close值和前一天的累加值df.at[df.index[i], 'calc_ema5'] = df.at[df.index[i], 'close'] * smooth_factor + df.at[df.index[i - 1], 'calc_ema5'] * (1-smooth_factor)df[['close','volume','EMA_5','calc_ema5']]---------------------------close	volume	EMA_5	    calc_ema5
date				
2022-09-01	46.75	96128	46.750000	46.750000
2022-09-02	47.18	59848	46.893333	46.893333
2022-09-05	46.98	42456	46.922222	46.922222
2022-09-06	48.19	71577	47.344815	47.344815
2022-09-07	48.37	56144	47.686543	47.686543
...	...	...	...	...
2024-09-20	36.82	52096	37.085958	37.085958
2024-09-23	36.87	68754	37.013972	37.013972
2024-09-24	38.16	93653	37.395981	37.395981
2024-09-25	37.79	160848	37.527321	37.527321
2024-09-26	37.69	72755	37.581547	37.581547

从输出结果上看,我们自己做的calc_ema5与使用ewm和mean()得到的EMA5的值是一模一样的。

C_绘图与收益计算

对于一个双均线的策略,前面已经计算得到了短均线 SMA5和长均线SMA10,然后根据金叉买入死叉卖出(Cross的计算)得到的买点和卖点,在这样的基础上已经可以计算策略的收益了,也可以使用绘图的模块来绘制K线和买卖位置。

参考文档:

  • Python的mpl_finance模块从2020年已经提醒弃用,新mplfinance模块详解(一)-CSDN博客
1)Mpl_finance模块简单绘图

在backtrader里我们都不需要去考虑绘图的问题。这里简单过一下怎么使用mpl_finance模板进行快速绘图。

使用mpl_finance进行K线图绘制非常的简单,只要把dataframe的数据传进去就行了。

import mplfinance as mpf
mpf.plot(df, type='candle',style='charles',volume=True)

 

需要注意,mpf绘图的df是有格式要求的,但它又恰好与我们制作的准备给backtrader的数据格式相同,即 open,high,low,close,volume五个数据必须按顺序来

	        open	high	low	    close	volume
date					
2022-09-01	45.90	47.12	45.64	46.75	96128
2022-09-02	46.90	47.90	46.55	47.18	59848
2022-09-05	47.15	47.86	46.75	46.98	42456
2022-09-06	46.98	48.40	46.82	48.19	71577
2022-09-07	48.18	48.58	47.88	48.37	56144
...	...	...	...	...	...
2)添加均线

这里添加上SMA5和SMA10的均线,添加线或点都用addplot,这里数据有点多,添加的图线会看不清,于是数据量截取只保留80天的K线来显示。addplot可以是一个数据,也可以是个list(list里也可以只有一个数据)

import mplfinance as mpfadd_plot= [mpf.make_addplot(df.Long_MA,color='r'),mpf.make_addplot(df.Short_MA,color='g'),]mpf.plot(df,addplot=add_plot, type='candle',style='charles',volume=True)

 这样就把K线和SMA5/SMA10的线都画出来了。

3)添加买卖点图标

在买点和卖点位置画图标,则需要买点的最低价和卖点的最高价进行图标绘制,数据可以是list,也可以直接是np.ndarray类型。

基于前面已经有了crs_up和crs_dn的列,先通过np.where的使用得到买点和卖点的数据,以买点buy_list为例,当df['crs_up']为True的时候,取df['low']的值,否则就是空。

# 画图标需要有价格,买画在low下,卖画在high上buy_list = list(np.where(df['crs_up'], df['low'], np.nan))  # list
sell_list = np.where(df['crs_dn'], df['high'], np.nan)   # np.ndarrayprint(type(buy_list))
print(type(sell_list))----------------------------
<class 'list'>
<class 'numpy.ndarray'>

然后,把买卖点图标加入到addplot中,就能绘制出带买点卖点的图了。

import mplfinance as mpfadd_plot= [mpf.make_addplot(df.Long_MA,color='r'),mpf.make_addplot(df.Short_MA,color='g'),mpf.make_addplot(buy_list,scatter=True,marker='^',markersize=80,color='r'),mpf.make_addplot(sell_list,scatter=True,marker='v',markersize=80)]mpf.plot(df,addplot=add_plot, type='candle',style='charles',volume=True)

4)计算收益和成功率

收益计算采用在买点的位置记录close价格,在卖点的位置的close减去买点的价格,最后再乘上一个股票数量(假设为1200股,接近5W);而成功次数用一次买卖计数加1,如果收益为正则成功次数加1的方式计算。

def calcu_profit(df):df.loc[:,'profit'] = 0.0total_times = 0win_times = 0buyPrice = 0for index, row in df.iterrows():if row.crs_up == True:buyPrice = row.closeif row.crs_dn == True and buyPrice!=0:total_times += 1df.loc[index,'profit'] = round(row.close - buyPrice,2)if row.close -buyPrice >0:win_times +=1pct = (win_times/total_times)*100profit = round(df['profit'].sum(),2)print('总交易次数', total_times)print('成功次数', win_times)print('胜率 %.2f%%'%pct)print('收益',profit*1200)calcu_profit(df)------------------
总交易次数 4
成功次数 2
胜率 50.00%
收益 -3108.0

 D_使用ta-lib的指标

双均线比较简单,用pandas直接可以实现,但有些指标像KDJ,MACD,BOLL,RSI等就不是那么容易的实现,我们也不需要重复造轮子,可以直接用ta-lib中的指标。

ta-lib直接pip install安装容易出问题,可以在网站上搜索ta-lib找到通用的离线安装包下载安装

  • 【免费】TA-Lib-0.4.26-cp*-cp*m-win*.whlTA-Lib库离线安装文件打包资源-CSDN文库

使用起来也非常方便,以布林线指标为例,直接调用talib.BBANDS即可

import talibdf['Upper'], df['Middle'], df['Lower'] = talib.BBANDS(df['close'], timeperiod=20, nbdevup=2, nbdevdn=2, matype=0)

003_手工实现与backtrader的对比

A_数据获取

数据获取方面,都是需要借助第三方库或者爬虫等,步骤上没什么差别。

手工实现上,直接使用pandasData就可以了,而在backtrader中,还需要通过feeds把pandasData处理成backtrader自己的结构,我们在第二篇里详细介绍了关于Datas,Data,lines等内容,这些是手工简单实现所没有的,也是比较复杂的部分。

B_交易系统设置

手工实现最关键的是没有backtrader的交易系统设置的部分。

持仓position判断,交易规模sizer,手工的代码里没有。

交易手续费与滑点计算,手工的代码里也没有。

交易时机管理,backtrader以第二日开盘价成交,如果要以当日收盘价则为cheat-on_close。

手工代码没有订单的概念,订单的类型,撤单等。

C_观测器与绘图

backtrader有观测器模块observers,可以统计回测信息并进行可视化展示,手工代码没有。

D_参数优化

手工代码没有参数优化功能。

E_评价

手工代码没有内置评价模块,虽然也可以自己计算日收益然后交给第三方库例如quantstats进行评价。

F_绘图增强

手工代码的绘图还处于比较初级的阶段,远远没有backtrader的图形那样实用,不过这些都不是大问题,毕竟股票软件有着更好的视觉体验,我们可以结合着股票软件来进行图形显示。

G_内置指标

backtrader有很多的内置指标,可以直接使用,指标这一块也没有太大的问题,因为手工代码也可以借助ta-lib的库来获取指标计算数据,并且backtrader也内置了ta-lib指标的调用。

小结

手工做一个双均线策略,或者再来一个布林线策略,能让我们对策略实现的流程有更深刻的理解,也细致的复习了关于pandas的典型应用。同时我们也看到了,我们所有想到的和没有想到的,backtrader基本上已经全部帮我们实现了,所以借助backtrader,我们就不需要把时间和精力放在重复造轮子这件事上,而是在弄清楚它的运行机制和原理后,好好利用它去得到适合的标的、适合的策略、适合的时机,赚取相对而言较好的收益。

相关文章:

  • C语言课程设计题目六:学生信息管理系统设计
  • OpenCV视频I/O(10)视频采集类VideoCapture之从视频流中检索一帧图像函数 retrieve()的使用
  • Java面试常见问题总结
  • L8打卡学习笔记
  • [数据集][目标检测]猪数据集VOC-2856张
  • 开放式蓝牙耳机哪个品牌更靠谱?5款高性价比开放式耳机推荐
  • RHCS认证-Linux(RHel9)-Ansible
  • 元宇宙的未来趋势:Web3的潜在影响
  • 集成MinIO实现文件存储管理:文件上传、文件下载、文件删除、获取文件访问地址、获取文件访问地址
  • ESP32 Bluedroid 篇(1)—— ibeacon 广播
  • Error和Exception
  • html TAB、table生成
  • 【MWORKS专业工具箱系列教程】控制系列工具箱第四期:时域分析
  • ARCGIS PRO SDK MapProjectItem 地图项目类
  • Flutter路由
  • Effective Java 笔记(一)
  • Linux后台研发超实用命令总结
  • oldjun 检测网站的经验
  • Python3爬取英雄联盟英雄皮肤大图
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • SQLServer之创建显式事务
  • Transformer-XL: Unleashing the Potential of Attention Models
  • Vue.js源码(2):初探List Rendering
  • 分布式任务队列Celery
  • 机器学习中为什么要做归一化normalization
  • 记一次和乔布斯合作最难忘的经历
  • 数据科学 第 3 章 11 字符串处理
  • 微信小程序:实现悬浮返回和分享按钮
  • 仓管云——企业云erp功能有哪些?
  • 国内唯一,阿里云入选全球区块链云服务报告,领先AWS、Google ...
  • # AI产品经理的自我修养:既懂用户,更懂技术!
  • # Java NIO(一)FileChannel
  • # SpringBoot 如何让指定的Bean先加载
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • (13)DroneCAN 适配器节点(一)
  • (2024)docker-compose实战 (8)部署LAMP项目(最终版)
  • (第61天)多租户架构(CDB/PDB)
  • (读书笔记)Javascript高级程序设计---ECMAScript基础
  • (附源码)计算机毕业设计SSM疫情居家隔离服务系统
  • (七)Appdesigner-初步入门及常用组件的使用方法说明
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (十五)、把自己的镜像推送到 DockerHub
  • (一)C语言之入门:使用Visual Studio Community 2022运行hello world
  • (转)Android学习笔记 --- android任务栈和启动模式
  • .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)...
  • .NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)
  • .net 中viewstate的原理和使用
  • .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(二)...
  • .netcore 6.0/7.0项目迁移至.netcore 8.0 注意事项
  • .net访问oracle数据库性能问题
  • .Net接口调试与案例
  • //usr/lib/libgdal.so.20:对‘sqlite3_column_table_name’未定义的引用
  • @RestControllerAdvice异常统一处理类失效原因
  • @SpringBootApplication 包含的三个注解及其含义