量化交易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,我们就不需要把时间和精力放在重复造轮子这件事上,而是在弄清楚它的运行机制和原理后,好好利用它去得到适合的标的、适合的策略、适合的时机,赚取相对而言较好的收益。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/433450.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv7改进之MAE主干: 超强ConvNeXtV2 升级版结构,当MAE+YOLO卷积高效涨点

目录 1,原理概述 2,代码改进 新增一个convnextv2.py文件,增加以下代码 修改部分 第二步:在yolo.py中加入以下代码 然后在 在yolo.py中配置找到./models/yolo.py文件下里的parse_model函数,将类名加入进去 参考代码 YOLOv7网络配置文件 1,原理概述 原文:https://…

openinstall鸿蒙SDK再升级,功能全面支持HarmonyOS NEXT

万众期待的鸿蒙操作系统HarmonyOS NEXT即将发布&#xff0c;国产自主的全场景智能操作系统诞生&#xff0c;将为生态伙伴共创共享创造新蓝海&#xff0c;鸿蒙生态的加速构建&#xff0c;也有望催生出互联网生态的第三极。 作为首批鸿蒙生态伙伴&#xff0c;openinstall在App渠…

这些主流的财务管理软件,你用过哪款?

在当今的商业环境中&#xff0c;财务管理面临着诸多棘手的痛点问题&#xff1a; 数据的准确性与及时性难以保证&#xff0c;手工录入易出错且数据更新常不及时&#xff1b; 预算管理困难重重&#xff0c;编制不合理且执行监控难&#xff1b; 财务风险管控不足&#xff0c;应…

Cannot read properties of undefined (reading ‘upgrade‘)

前端开发工具&#xff1a;VSCODE 报错信息&#xff1a; INFO Starting development server...10% building 2/2 modules 0 active ERROR TypeError: Cannot read properties of undefined (reading upgrade)TypeError: Cannot read properties of undefined (reading upgrade…

k8s中,pod生命周期,初始化容器,容器探针,事件处理函数,理解其设计思路及作用

k8s中&#xff0c;为什么要设计pod 平台直接管理容器不是挺好的吗 为什么要以pod为单位进行管理&#xff0c; 然后把容器放在pod里面 那么有pod和没pod的区别是什么 也就是pod提供了什么作用 这个可以考虑从pod生命周期管理的角度去思考 如图&#xff0c;pod主容器在运行…

无限大薄板的电场

单块无限大薄板两端的电场 单块无限大的薄板&#xff0c;如果上面带有均匀分布的电荷&#xff0c;就会在薄板的两侧产生电场&#xff0c;电场大小与距离平板的位置无关&#xff0c;方向与平板垂直&#xff0c;如果平板带正电荷&#xff0c;则电场方向向外指向两侧&#xff0c;…

【性能优化】低配starRocks常驻内存优化

背景说明 由于服务器的实际资源小于starRocks官方的配置&#xff0c;导致starRocks在无任务的情况下&#xff0c;常驻内存偏高&#xff0c;可用于查询的资源变小。 官方文档 实际部署的集群一般是4C8G和8C16G&#xff0c;be的配置不达标 为了解决单次查询内存不足的问题&…

史上最详细论文word排版格式指导保姆级教学!

一、前言 首先&#xff0c;每个学校的论文排版格式都是不太相同的&#xff0c;但大体上都是相似的。 正常来说&#xff0c;论文的排版操作是十分枯燥并且重复的&#xff0c;但是word中的样式工具使得论文排版会变得容易。 接下来我将以某个学校论文格式要求为例&#xff0c;…

python socket编程

socket socket&#xff08;套接字&#xff09;是进程间通信的工具&#xff0c;好比现实生活中的插座&#xff0c;所有家电想要工作都是基于插座进行&#xff0c;进程之间想要进行网络通信需要socket socket负责进程之间的网络数据传输&#xff0c;好比数据的搬运工 2个进程之…

动态规划入门题目->使用最小费用爬楼梯

1.题目&#xff1a; 2.解析&#xff1a; 做题模式&#xff1a; 步骤一&#xff1a;找状态转移方程 步骤二&#xff1a;初始化 步三&#xff1a;填表 步骤四&#xff1a;返回-> dp[n] dp[i]表示到达 i 位置最小花费 逻辑&#xff1a;要爬到楼顶先找到 i 位置 &#xff0c; 要…

高通Android 12 push framework.jar和service.jar

1、Android framework.jar和service.jar替换注意事项 2、单编 adb push service.jar脚本 如下 adb root adb disable-verity adb remountadb push services.jar system/framework adb push services.jar.prof system/framework adb push oat/arm64/services.art /system/fram…

SpringBoot日志集成-LogBack

Log4J&#xff1a;最早的Java日志框架之一&#xff0c;由Apache基金会发起&#xff0c;提供灵活而强大的日志记录机制JDK自带的日志框架&#xff1a;java.util.logging.Logg&#xff0c;是JDK1.4之后提供的日志API&#xff0c;已淘汰logback&#xff1a; logback一个开源的日志…

delphi制作漂亮的农历窗体(IntraWeb+Layui的完美结合)

delphi制作漂亮的农历窗体&#xff08;IntraWebLayui的完美结合&#xff09; 不需要安装服务器&#xff0c;Apache和IIS都不需要&#xff0c;自带企业级服务器。 运行exe服务器就架好了&#xff0c;直接打开手机浏览器或者电脑浏览器&#xff0c;网页就出来了&#xff0c;如果…

sqli-lab靶场学习(四)——Less11-14(post方法)

前言 第1-10关都是get方法&#xff0c;本关开始进入post方法。其实post也好get也好&#xff0c;本质都差不多&#xff0c;使用的技巧也基本相同。 Less11 第11关打开是一个输入用户名密码的界面 显然登陆对话框会使用post方式提交&#xff0c;这里我们尝试在Username一栏通过…

时序预测 | Python实现KAN+LSTM时间序列预测

时序预测 | Python实现KAN+LSTM时间序列预测 目录 时序预测 | Python实现KAN+LSTM时间序列预测预测效果基本介绍程序设计预测效果 基本介绍 时序预测 | KAN+LSTM时间序列预测(Python) KAN作为这两年最新提出的机制,目前很少人用,很适合作为时间序列预测的创新点,可以结合…

CSS01-语法规范、基础选择器

一、CSS语法规范 示例&#xff1a; 二、CSS的基础选择器 选择器(选择符)就是根据不同需求把不同的标签选出来这就是选择器的作用。 简单来说&#xff0c;就是选择标签用的。 选择器的分类&#xff1a; 1、标签选择器 2、类选择器&#xff08;开发最常用&#xff09; 长字符命名…

误差不到1毫米的WGS84与CGCS2000坐标转换工具

我们在《WGS84与CGCS2000坐标的精密转换方法》一文中为你分享了一个WGS84与CGCS2000坐标的精密转换纯理论性的方法。 现在&#xff0c;再为你分享一个据说是误差不到1毫米的WGS84与CGCS2000坐标的转换工具&#xff0c;请从文末查看该工具的领取方法。 WGS84与CGCS2000坐标转换…

信息学奥赛的最佳启蒙阶段是小学还是初中?

信息学奥赛&#xff08;NOI&#xff09;近年来越来越受家长和学生的关注&#xff0c;尤其是在编程教育不断升温的背景下&#xff0c;信息学竞赛成为了许多家庭的教育选择之一。家长们往往关心的是&#xff1a;孩子应该在什么年龄段开始接触信息学竞赛&#xff0c;才能打下坚实的…

如何让 Android 的前端页面像 iOS 一样“优雅”?

作者:方英杰&#xff08;崇之&#xff09; 最近在调研前端页面适配 Android 端异形屏的方案&#xff0c;调研过程中发现了一些比较有意思的点&#xff0c;本文主要是做一个总结。 一、提出问题 首先&#xff0c;我们需要知道 Android 上的前端适配面临着什么问题。 问题其实很…

台式机通过笔记本上网

概述: ①将wifi共享给网口 ②网口配置成自协商IP和DNS即可 一、背景 由于台式机只有网口&#xff0c;没得wifi网卡&#xff0c;因此想通过笔记本连wifi,再通过网线将笔记本和台式机连接起来&#xff0c;从而实现台式机通过笔记本的wifi上网&#xff0c;即让笔记本当台式机的…