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

news2024/9/28 0:32:48

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 norm

mean_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 pd

def 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'] = 0
    stock_df = stock_df[['open','high','low','close','volume','openinterest']]
    return stock_df


myStockList = ['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 np

df['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 mpf

add_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.ndarray

print(type(buy_list))
print(type(sell_list))

----------------------------
<class 'list'>
<class 'numpy.ndarray'>

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

import mplfinance as mpf

add_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.0
    
    total_times = 0
    win_times = 0
    buyPrice = 0
    
    for index, row in df.iterrows():
        if row.crs_up == True:
            buyPrice = row.close
        if row.crs_dn == True and buyPrice!=0:
            total_times += 1
            df.loc[index,'profit'] = round(row.close - buyPrice,2)
            
            if row.close -buyPrice >0:
                win_times +=1
                
    pct = (win_times/total_times)*100
    profit = 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 talib

df['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.coloradmin.cn/o/2171658.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用ESPnet的 setup_anaconda.sh安装脚本一步到位,配置conda虚拟环境

使用ESPnet的 setup_anaconda.sh安装脚本一步到位&#xff0c;配置conda虚拟环境 前言 ESPnet&#xff08;End-to-End Speech Processing Toolkit&#xff09;是一款用于语音识别、语音合成等任务的开源端到端语音处理工具包。为了在不同系统上快速配置ESPnet开发环境&#x…

Serverless and Go

本篇内容是根据2019年8月份Serverless and Go音频录制内容的整理与翻译, Johnny、Mat、Jaana 和特邀嘉宾 Stevenson Jean-Pierre 讨论了 Go 世界中的Serverless。什么是Serverless&#xff0c;Serverless适用于哪些用例&#xff0c;有哪些权衡&#xff0c;以及如何在Serverles…

AI芯片WT2605C赋能厨房家电,在线对话操控,引领智能烹饪新体验:尽享高效便捷生活

在智能家居的蓬勃发展中&#xff0c;智能厨电作为连接科技与生活的桥梁&#xff0c;正逐步渗透到每一个现代家庭的厨房中。蒸烤箱作为智能厨电的代表&#xff0c;以其丰富的功能和高效的性能&#xff0c;满足了人们对美食的多样化追求。然而&#xff0c;面对众多复杂的操作功能…

每日OJ_牛客_OR59字符串中找出连续最长的数字串_双指针_C++_Java

目录 牛客_OR59字符串中找出连续最长的数字串 题目解析 C代码1 C代码2 C代码3 Java代码 牛客_OR59字符串中找出连续最长的数字串 字符串中找出连续最长的数字串_牛客题霸_牛客网 题目解析 双指针&#xff1a; 遍历整个字符串&#xff0c;遇到数字的时候&#xff0c;用双…

字符编码发展史4 — Unicode与UTF-8

上一篇《字符编码发展史3 — GB2312/Big5/GBK/GB18030》我们讲解了ANSI编码中的GB2312/Big5/GBK/GB18030。本篇我们将继续讲解字符编码的第三个发展阶段中的Unicode与UTF-8。 2.3. 第三个阶段 国际化 前面提到的第二个阶段&#xff0c;各个国家和地区各自为政&#xff0c;纷纷…

并发编程---线程与进程

业务场景&#xff1a;小明去理发店理发。 小明去理发店理发&#xff0c;完成理发需要吹&#xff0c;剪&#xff0c;洗、理的过程。由这个场景我们引用进程和线程这两个 概念。 一.进程 1.什么是进程 进程是具有独立功能的程序关于某个数据集合上的一次运行活动&#xff0c;是…

【docker】debian中配置docker(2024年9月)

首先Follow了一下菜鸟教程&#xff0c;然后遇到了curl的问题。 curl存在的问题 参见这篇文章。其中用到了vim进行编辑&#xff0c;笔者的环境是windows10putty&#xff0c;vim的粘贴操作参考这篇文章。 修改之后的curl没有问题了&#xff0c;成功把脚本下载下来了。 但是在…

LD2 Scalable Heterophilous Graph Neural Network with Decoupled Embeddings

Neurips 24 推荐指数&#xff1a; #paper/⭐⭐⭐ 领域&#xff1a;可扩展图&#xff0c;大图加速 整个文章的理论部分比较多&#xff0c;尽量尽我所能避开一些额外公式。详细文章&#xff0c;见链接 模型架构 如图&#xff0c;整个模型分为与计算和训练两部分。本文的精华在于…

Docker网络、数据卷及安全优化

目录 一、Docker网络 1、原生bridge网络 2、host网络 3、none网络 4、docker自定义桥接网络 1、Docker自定义网络 2、不同自定义网络通信 3、joined容器网络 5、Docker容器内外网访问 1、容器访问外网 2、外网访问容器 6、macvlan网络实现跨主机通信 二、Docker数据…

Ubuntu下Kafka安装及使用

Kafka是由Apache软件基金会开发的一个开源流处理平台&#xff0c;同时也是一个高吞吐量的分布式发布订阅消息系统。它由Scala和Java编写&#xff0c;具有多种特性和广泛的应用场景。 Kafka是一个分布式消息系统&#xff0c;它允许生产者&#xff08;Producer&#xff09;发布消…

Spring Ioc底层原理代码详细解释

文章目录 概要根据需求编写XML文件&#xff0c;配置需要创建的bean编写程序读取XML文件&#xff0c;获取bean相关信息&#xff0c;类&#xff0c;属性&#xff0c;id前提知识点Dom4j根据第二步获取到的信息&#xff0c;结合反射机制动态创建对象&#xff0c;同时完成属性赋值将…

【移植】标准系统方案之扬帆移植案例

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 持续更新中…… 本文章是基于瑞芯微RK3399芯片的yangfan开发板&#xff0c;进行标准…

一些写论文必须要知道的神仙级网站!芝士AI(paperzz)

说实话&#xff0c;写论文真的是挺头疼&#xff0c;尤其到了毕业季的时候&#xff0c;没有过任何写作毕业论文的经验的毕业生而言更是如此&#xff0c;相信大家都有过这种状态&#xff0c;不知从何下笔&#xff0c;还需要面对论文进度的压力&#xff0c;并且时常需要寻找各种资…

HDF5文件浏览软件--H5View

概述 H5View是一款轻量级桌面软件&#xff0c;旨在提供用户友好的界面以读取和展示 HDF5 文件中的数据结构。该软件允许用户查看文件的数据目录和数据集&#xff0c;并支持将选定的数据集导出为多种格式。 功能特点 读取 HDF5 文件 支持打开和读取 HDF5 格式的文件。显示文件…

Lenovo SR850服务器亮黄灯维修和升级CPU扩展模块

佛山市三水区某高校1台Lenovo Thinksystem SR850服务器黄灯故障到现场检修 和 升级3号和4号CPU。加强服务器的计算性能&#xff1b; 故障情况是该学校it管理员这一天看到这台SR850服务器前面板亮了一个黄灯&#xff0c;但是目前系统运行正常&#xff0c;出于安全考虑&#xff0…

JavaFX 如何加载系统资源

简介 问题描述&#xff1a;JavaFX 加载图片资源异常&#xff0c;即使路径正确 如何解决&#xff1a;使用反射 API 如何解决 import javafx.scene.image.Image; import org.junit.jupiter.api.Test;import java.util.Objects;public class ImageTest {Testvoid name() {Image…

golang web笔记-1.创建Web Server和Handler请求

1. 创建http web server的两个方法 1.1. 方式一&#xff1a;http.ListenAndServe(addr string, handler Handler) addr string&#xff1a;监听地址&#xff0c;如果为"" ,那么就是所有网络接口的80接口handler Handler&#xff1a;如果为nil&#xff0c;那么就是D…

TypeScript 设计模式之【状态模式】

文章目录 状态模式&#xff1a;优雅切换的交通信号灯状态模式的奥秘状态模式有什么利与弊?如何使用状态模式来优化你的系统代码实现案例状态模式的主要优点状态模式的主要缺点状态模式的适用场景总结 状态模式&#xff1a;优雅切换的交通信号灯 当你站在繁忙的十字路口&#…

RabbitMQ 实验入门

使用 spring-amqp 实验 发布订阅模型 fanoutExchange 实验 实验步骤&#xff1a; 编写定义 队列 和 交换机 绑定关系的代码创建接口&#xff0c;模拟生产者&#xff0c;方便调试&#xff08;接受参数 队列名、路由键、[消息]&#xff09;定义消费者 代码示例&#xff1a; C…

证件照制作小程序源码

预览&#xff1a; 证件照制作小程序官方有推出对应的api接口&#xff0c;也有demo示例&#xff0c;大家有需要的可以直接拿 证件照规格列表 接口地址&#xff1a;https://api.zheyings.cn/item/list 请求方式&#xff1a;POST(application/x-www-form-urlencoded) 返回格式&…