Backtrader官方中文文档

代码有所删减,完整版及在线运行可访问Backtrader官方中文文档

一. backtrader介绍

  1. 制定策略
  • 1.1 确定潜在的可调参数
  • 1.2 实例化您在策略中需要的指标
  • 1.3 写下进入/退出市场的逻辑
  1. 创建Cerebro引擎(西班牙语大脑的意思)
  • 2.1 注入策略
  • 2.2 使用cerebro.adddata加载回测数据
  • 2.3 执行cerebro.run
  • 2.4 使用cerebro.plot绘制可视化图表

backtrader是高度可配置的,希望大家发现其中的乐趣。

二. backtrader安装

基本要求是: Python 2.7 Python 3.2 / 3.3 / 3.4 / 3.5 如有绘图需求,则要求 Matplotlib> = 1.4.1

!pip install backtrader -i https://mirrors.cloud.tencent.com/pypi/simple
Looking in indexes: https://mirrors.cloud.tencent.com/pypi/simple
Requirement already satisfied: backtrader in /opt/conda/lib/python3.6/site-packages (1.9.76.123)
[33mWARNING: You are using pip version 20.3.3; however, version 21.3.1 is available.
You should consider upgrading via the '/opt/conda/bin/python -m pip install --upgrade pip' command.[0m

三. backtrader快速开始

3.1 折线

交易数据(Data Feeds)、技术指标(Indicators)和策略(Strategies)都是折线(Line)。 折线(Line)是由一系列的点组成的。

通常交易数据(Data Feeds)包含以下几个组成部分: 开盘价( Open)、最高价(High)、最低价(Low)、收盘价(Close)、成交量(Volume)、持仓量(OpenInterest)等。 比如:所有的开盘价( Open)按时间组成一条折线(Line),那么一组交易数据(Data Feeds)就 应该包含了6条折线(Line)。

再加上时间(DateTime)一共有7条折线(Line)。时间,一般用作一组交易数据的主键。

3.2 索引从0开始

当访问一条折线(Line)的数据时,会默认从下标为0的位置开始,最后一个数据通过下标-1来获取。这样的设计和Python的迭代器是一致的,所以折线(Line)是可以迭代遍历的。

例如:创建一个简单移动平均值的策略(均值策略): self.sma = SimpleMovingAverage(…)
访问此移动平均线的当前值的最简单方法:av = self.sma[0]
所以在回测过程中,无需知道已经处理了多少条/分钟/天/月,“0”一直指向当前值。

按照Python遍历数组的方式,用下标-1来访问最后一个值: previous_value = self.sma[-1] 同理:-2、-3下标也是可以照常使用。

3.3 从0到100

先跑一个基本框架

import backtrader as bt
import time
# 创建Cerebro引擎  
cerebro = bt.Cerebro() 
#Cerebro引擎在后台创建broker(经纪人),系统默认资金量为10000 
# 引擎运行前打印期出资金  
print('组合期初资金: %.2f' % cerebro.broker.getvalue()) 
cerebro.run() 
# 引擎运行后打期末资金  
print('组合期末资金: %.2f' % cerebro.broker.getvalue())
组合期初资金: 10000.00
组合期末资金: 10000.00

3.4 设定现金

在金融世界中,可以肯定的是,只有Losser才以1万开始。让我们更改现金并再次运行该示例。

#导入backtrader框架  
import backtrader as bt 
# 创建Cerebro引擎  
cerebro = bt.Cerebro() 
# Cerebro引擎在后台创建broker(经纪人),系统默认资金量为10000 
# 设置投资金额100000.0 
cerebro.broker.setcash(100000.0) 
# 引擎运行前打印期出资金  
print('组合期初资金: %.2f' % cerebro.broker.getvalue()) 
cerebro.run() 
# 引擎运行后打期末资金  
print('组合期末资金: %.2f' % cerebro.broker.getvalue())
组合期初资金: 100000.00
组合期末资金: 100000.00

3.5 加入交易数据

拥有现金是一件快乐的事,这一切背后最终的目的就是: 不动一根手指,就能让自动化策略通过操作资产的交易数据来增加现金。 无数据,不快乐,让我们继续加入交易数据。

import datetime # 
import os.path # 路径管理  
import sys # 获取当前运行脚本的路径 (in argv[0]) 
#导入backtrader框架  
import backtrader as bt 
 
# 创建Cerebro引擎  
cerebro = bt.Cerebro() 
# Cerebro引擎在后台创建broker(经纪人),系统默认资金量为10000 

# 获取当前运行脚本所在目录  
modpath = os.path.dirname(os.path.abspath(sys.argv[0])) 
# 拼接加载路径  
datapath = os.path.join(modpath, '/home/mw/input/backtrader7822/orcl-1995-2014.txt') 

# 创建交易数据集  
data = bt.feeds.YahooFinanceCSVData( 
    dataname=datapath, 
    # 数据必须大于fromdate 
    fromdate=datetime.datetime(2000, 1, 1), 
    # 数据必须小于todate 
    todate=datetime.datetime(2000, 12, 31),
    reverse=False) 
# 加载交易数据  
cerebro.adddata(data) 

# 设置投资金额100000.0 
cerebro.broker.setcash(100000.0) 
# 引擎运行前打印期出资金  
print('组合期初资金: %.2f' % cerebro.broker.getvalue()) 
cerebro.run() 
# 引擎运行后打期末资金  
print('组合期末资金: %.2f' % cerebro.broker.getvalue())
组合期初资金: 100000.00
组合期末资金: 100000.00

代码量略有增加,因为我们添加了:找出数据文件所在的路径通过datetime对象过滤我们想要操作的数据

注意: Yahoo的价格数据有点非主流,它是以时间倒序排列的。datetime.datetime()中的reversed=True参数是将顺序反转一次,这样就得到了我们想要的正序数据。

3.6 第一个策略

资金和交易数据都有了,探险即将开始。让我们给策略加点代码,打印出每天的”收盘价”。 DataSeries(交易数据的基类)对象,可以直接访问到 OHLC (开盘价、最高价、最低价、收盘价)等数据。这使我们打印数据很方便。

import datetime # 
import os.path # 路径管理  
import sys # 获取当前运行脚本的路径 (in argv[0]) 
#导入backtrader框架  
import backtrader as bt 

# 创建策略继承bt.Strategy 
class TestStrategy(bt.Strategy): 

    def log(self, txt, dt=None): 
        # 记录策略的执行日志  
        dt = dt or self.datas[0].datetime.date(0) 
        print('%s, %s' % (dt.isoformat(), txt)) 

    def __init__(self): 
        # 保存收盘价的引用  
        self.dataclose = self.datas[0].close 

    def next(self): 
        # 记录收盘价  
        self.log('Close, %.2f' % self.dataclose[0]) 
        
# 创建Cerebro引擎  
cerebro = bt.Cerebro() 
# Cerebro引擎在后台创建broker(经纪人),系统默认资金量为10000 
# 为Cerebro引擎添加策略  
cerebro.addstrategy(TestStrategy) 
# 获取当前运行脚本所在目录
modpath = os.path.dirname(os.path.abspath(sys.argv[0])) 
# 拼接加载路径  
datapath = os.path.join(modpath, '/home/mw/input/backtrader7822/orcl-1995-2014.txt') 
# 创建交易数据集  
data = bt.feeds.YahooFinanceCSVData( dataname=datapath, 
                                    # 数据必须大于fromdate 
                                    fromdate=datetime.datetime(2000, 1, 1), 
                                    # 数据必须小于todate 
                                    todate=datetime.datetime(2000, 12, 31), 
                                    reverse=False) 
                                    # 加载交易数据  

cerebro.adddata(data)
# 设置投资金额100000.0 
cerebro.broker.setcash(100000.0) 
# 引擎运行前打印期出资金  
print('组合期初资金: %.2f' % cerebro.broker.getvalue()) 
cerebro.run() 
# 引擎运行后打期末资金  
print('组合期末资金: %.2f' % cerebro.broker.getvalue())
组合期初资金: 100000.00
2000-01-03, Close, 26.27
2000-01-04, Close, 23.95
2000-01-05, Close, 22.68
2000-01-06, Close, 21.35
2000-01-07, Close, 22.99
2000-01-10, Close, 25.74
2000-01-11, Close, 24.99
2000-01-12, Close, 23.49
2000-01-13, Close, 23.36
2000-01-14, Close, 23.75
2000-01-18, Close, 24.74
2000-01-19, Close, 25.41
2000-01-20, Close, 26.35
2000-01-21, Close, 26.55
2000-01-24, Close, 24.10
2000-01-25, Close, 25.10
2000-01-26, Close, 24.49
2000-01-27, Close, 23.04
2000-01-28, Close, 21.07
2000-01-31, Close, 22.22
2000-02-01, Close, 24.02
2000-02-02, Close, 24.16
2000-02-03, Close, 25.21
2000-02-04, Close, 25.71
2000-02-07, Close, 26.66
2000-02-08, Close, 26.49
2000-02-09, Close, 26.66
2000-02-10, Close, 27.71
2000-02-11, Close, 26.55
2000-02-14, Close, 27.66
2000-02-15, Close, 27.30
2000-02-16, Close, 27.24
2000-02-17, Close, 27.41
2000-02-18, Close, 26.05
2000-02-22, Close, 26.38
2000-02-23, Close, 28.05
2000-02-24, Close, 27.55
2000-02-25, Close, 31.41
2000-02-28, Close, 30.52
2000-02-29, Close, 33.02
2000-03-01, Close, 31.80
2000-03-02, Close, 30.47
2000-03-03, Close, 33.36
2000-03-06, Close, 33.69
2000-03-07, Close, 33.33
2000-03-08, Close, 36.97
2000-03-09, Close, 37.36
2000-03-10, Close, 36.30
2000-03-13, Close, 35.02
2000-03-14, Close, 34.25
2000-03-15, Close, 34.97
2000-03-16, Close, 36.44
2000-03-17, Close, 35.50
2000-03-20, Close, 34.75
2000-03-21, Close, 35.89
2000-03-22, Close, 37.39
2000-03-23, Close, 38.64
2000-03-24, Close, 38.69
2000-03-27, Close, 39.33
2000-03-28, Close, 38.50
2000-03-29, Close, 36.69
2000-03-30, Close, 34.88
2000-03-31, Close, 34.72
2000-04-03, Close, 34.19
2000-04-04, Close, 33.77
2000-04-05, Close, 34.80
2000-04-06, Close, 36.55
2000-04-07, Close, 38.75
2000-04-10, Close, 36.69
2000-04-11, Close, 34.41
2000-04-12, Close, 32.52
2000-04-13, Close, 31.99
2000-04-14, Close, 27.80
2000-04-17, Close, 33.27
2000-04-18, Close, 35.11
2000-04-19, Close, 33.16
2000-04-20, Close, 31.49
2000-04-24, Close, 32.22
2000-04-25, Close, 33.61
2000-04-26, Close, 32.11
2000-04-27, Close, 34.38
2000-04-28, Close, 35.55
2000-05-01, Close, 35.44
2000-05-02, Close, 34.61
2000-05-03, Close, 33.72
2000-05-04, Close, 33.02
2000-05-05, Close, 34.16
2000-05-08, Close, 32.16
2000-05-09, Close, 32.02
2000-05-10, Close, 30.08
2000-05-11, Close, 32.19
2000-05-12, Close, 32.99
2000-05-15, Close, 34.25
2000-05-16, Close, 35.22
2000-05-17, Close, 34.77
2000-05-18, Close, 32.49
2000-05-19, Close, 31.16
2000-05-22, Close, 30.16
2000-05-23, Close, 27.85
2000-05-24, Close, 28.57
2000-05-25, Close, 29.55
2000-05-26, Close, 29.80
2000-05-30, Close, 32.99
2000-05-31, Close, 31.97
2000-06-01, Close, 34.63
2000-06-02, Close, 35.66
2000-06-05, Close, 36.00
2000-06-06, Close, 34.27
2000-06-07, Close, 35.58
2000-06-08, Close, 36.64
2000-06-09, Close, 36.77
2000-06-12, Close, 35.83
2000-06-13, Close, 36.33
2000-06-14, Close, 35.13
2000-06-15, Close, 36.69
2000-06-16, Close, 36.41
2000-06-19, Close, 38.25
2000-06-20, Close, 38.27
2000-06-21, Close, 38.33
2000-06-22, Close, 36.25
2000-06-23, Close, 35.36
2000-06-26, Close, 36.77
2000-06-27, Close, 36.58
2000-06-28, Close, 36.89
2000-06-29, Close, 35.97
2000-06-30, Close, 37.39
2000-07-03, Close, 35.66
2000-07-05, Close, 32.16
2000-07-06, Close, 33.63
2000-07-07, Close, 33.75
2000-07-10, Close, 32.97
2000-07-11, Close, 32.16
2000-07-12, Close, 33.22
2000-07-13, Close, 33.69
2000-07-14, Close, 33.86
2000-07-17, Close, 33.86
2000-07-18, Close, 32.99
2000-07-19, Close, 32.80
2000-07-20, Close, 34.75
2000-07-21, Close, 33.55
2000-07-24, Close, 33.36
2000-07-25, Close, 33.80
2000-07-26, Close, 34.13
2000-07-27, Close, 33.38
2000-07-28, Close, 32.19
2000-07-31, Close, 33.44
2000-08-01, Close, 32.52
2000-08-02, Close, 32.52
2000-08-03, Close, 34.44
2000-08-04, Close, 36.27
2000-08-07, Close, 36.41
2000-08-08, Close, 36.91
2000-08-09, Close, 36.19
2000-08-10, Close, 35.61
2000-08-11, Close, 36.08
2000-08-14, Close, 36.64
2000-08-15, Close, 36.14
2000-08-16, Close, 36.11
2000-08-17, Close, 37.33
2000-08-18, Close, 36.16
2000-08-21, Close, 37.00
2000-08-22, Close, 37.16
2000-08-23, Close, 36.86
2000-08-24, Close, 37.66
2000-08-25, Close, 37.64
2000-08-28, Close, 38.58
2000-08-29, Close, 39.03
2000-08-30, Close, 39.25
2000-08-31, Close, 40.44
2000-09-01, Close, 41.19
2000-09-05, Close, 40.50
2000-09-06, Close, 39.69
2000-09-07, Close, 40.56
2000-09-08, Close, 38.50
2000-09-11, Close, 37.11
2000-09-12, Close, 35.30
2000-09-13, Close, 36.39
2000-09-14, Close, 37.78
2000-09-15, Close, 34.83
2000-09-18, Close, 34.01
2000-09-19, Close, 35.27
2000-09-20, Close, 35.55
2000-09-21, Close, 35.11
2000-09-22, Close, 35.91
2000-09-25, Close, 35.02
2000-09-26, Close, 35.33
2000-09-27, Close, 35.52
2000-09-28, Close, 36.24
2000-09-29, Close, 35.02
2000-10-02, Close, 35.02
2000-10-03, Close, 30.91
2000-10-04, Close, 30.30
2000-10-05, Close, 30.38
2000-10-06, Close, 30.08
2000-10-09, Close, 29.69
2000-10-10, Close, 28.74
2000-10-11, Close, 27.69
2000-10-12, Close, 28.02
2000-10-13, Close, 31.69
2000-10-16, Close, 30.74
2000-10-17, Close, 29.96
2000-10-18, Close, 29.85
2000-10-19, Close, 32.36
2000-10-20, Close, 31.35
2000-10-23, Close, 30.30
2000-10-24, Close, 31.85
2000-10-25, Close, 30.58
2000-10-26, Close, 30.30
2000-10-27, Close, 30.41
2000-10-30, Close, 28.13
2000-10-31, Close, 29.35
2000-11-01, Close, 27.91
2000-11-02, Close, 26.30
2000-11-03, Close, 26.96
2000-11-06, Close, 24.85
2000-11-07, Close, 23.63
2000-11-08, Close, 22.07
2000-11-09, Close, 24.18
2000-11-10, Close, 22.63
2000-11-13, Close, 22.01
2000-11-14, Close, 25.24
2000-11-15, Close, 25.68
2000-11-16, Close, 24.35
2000-11-17, Close, 25.63
2000-11-20, Close, 22.01
2000-11-21, Close, 21.24
2000-11-22, Close, 19.85
2000-11-24, Close, 21.46
2000-11-27, Close, 20.57
2000-11-28, Close, 20.15
2000-11-29, Close, 20.35
2000-11-30, Close, 23.57
2000-12-01, Close, 23.52
2000-12-04, Close, 25.07
2000-12-05, Close, 28.02
2000-12-06, Close, 26.85
2000-12-07, Close, 25.18
2000-12-08, Close, 26.74
2000-12-11, Close, 28.41
2000-12-12, Close, 27.35
2000-12-13, Close, 25.24
2000-12-14, Close, 24.46
2000-12-15, Close, 25.41
2000-12-18, Close, 28.46
2000-12-19, Close, 27.24
2000-12-20, Close, 25.35
2000-12-21, Close, 26.24
2000-12-22, Close, 28.35
2000-12-26, Close, 27.52
2000-12-27, Close, 27.30
2000-12-28, Close, 27.63
2000-12-29, Close, 25.85
组合期末资金: 100000.00

有人说股市有风险,看起来不像啊。 一些解释说明:
框架在调用init时,该策略已经具有一个数据列表datas,这是标准的Python列表,可以按插入顺序访问数据。 列表中的第一个数据 self.datas[0]是用于交易操作,并且策略中的所有元素都是由框架的系统时钟进行同步的。 由于只需访问收盘价数据,于是使用 self.dataclose = self.datas[0].close将第一条价格数据的收盘价赋值给新变量。 系统时钟当经过一个 K线柱的时候,策略的next()方法就会被调用一次。这一过程 将一直循环,直到其他指标信号出现为止。此时,便会输出最终结果。关于这些,后继内容会讲到。

3.7 给策略加点逻辑

如果K线收盘价出现三连跌,则买入。

import datetime # 
import os.path # 路径管理  
import sys # 获取当前运行脚本的路径 (in argv[0]) 
#导入backtrader框架  
import backtrader as bt 
# 创建策略继承bt.Strategy

class TestStrategy(bt.Strategy): 
    def log(self, txt, dt=None): 
        # 记录策略的执行日志  
        dt = dt or self.datas[0].datetime.date(0) 
        print('%s, %s' % (dt.isoformat(), txt))

    def __init__(self): 
        # 保存收盘价的引用  
        self.dataclose = self.datas[0].close

    def next(self):
        # 记录收盘价  
        self.log('Close, %.2f' % self.dataclose[0]) 
        # 今天的收盘价 < 昨天收盘价  
        if self.dataclose[0] < self.dataclose[-1]: 
            # 昨天收盘价 < 前天的收盘价  
            if self.dataclose[-1] < self.dataclose[-2]:
                # 买入  
                self.log('买入, %.2f' % self.dataclose[0])
                self.buy()
# 创建Cerebro引擎  
cerebro = bt.Cerebro() 
# Cerebro引擎在后台创建broker(经纪人),系统默认资金量为10000 
# 为Cerebro引擎添加策略  
cerebro.addstrategy(TestStrategy) 
# 获取当前运行脚本所在目录  
modpath = os.path.dirname(os.path.abspath(sys.argv[0])) 
# 拼接加载路径  
datapath = os.path.join(modpath, '/home/mw/input/backtrader7822/orcl-1995-2014.txt') 
# 创建交易数据集  
data = bt.feeds.YahooFinanceCSVData( 
                                dataname=datapath,
                                # 数据必须大于fromdate 
                                fromdate=datetime.datetime(2000, 1, 1),  
                                # 数据必须小于todate 
                                todate=datetime.datetime(2000, 12, 31), 
                                reverse=False) 
# 加载交易数据  
cerebro.adddata(data) 
# 设置投资金额100000.0 
cerebro.broker.setcash(100000.0) 
# 引擎运行前打印期出资金  
print('组合期初资金: %.2f' % cerebro.broker.getvalue()) 
cerebro.run() 
# 引擎运行后打期末资金  
print('组合期末资金: %.2f' % cerebro.broker.getvalue())
组合期初资金: 100000.00
2000-01-03, Close, 26.27
2000-01-04, Close, 23.95
2000-01-05, Close, 22.68
2000-01-05, 买入, 22.68
2000-01-06, Close, 21.35
2000-01-06, 买入, 21.35
2000-01-07, Close, 22.99
2000-01-10, Close, 25.74
2000-01-11, Close, 24.99
2000-01-12, Close, 23.49
2000-01-12, 买入, 23.49
2000-01-13, Close, 23.36
2000-01-13, 买入, 23.36
2000-01-14, Close, 23.75
2000-01-18, Close, 24.74
2000-01-19, Close, 25.41
2000-01-20, Close, 26.35
2000-01-21, Close, 26.55
2000-01-24, Close, 24.10
2000-01-25, Close, 25.10
2000-01-26, Close, 24.49
2000-01-27, Close, 23.04
2000-01-27, 买入, 23.04
2000-01-28, Close, 21.07
2000-01-28, 买入, 21.07
2000-01-31, Close, 22.22
2000-02-01, Close, 24.02
2000-02-02, Close, 24.16
2000-02-03, Close, 25.21
2000-02-04, Close, 25.71
2000-02-07, Close, 26.66
2000-02-08, Close, 26.49
2000-02-09, Close, 26.66
2000-02-10, Close, 27.71
2000-02-11, Close, 26.55
2000-02-14, Close, 27.66
2000-02-15, Close, 27.30
2000-02-16, Close, 27.24
2000-02-16, 买入, 27.24
2000-02-17, Close, 27.41
2000-02-18, Close, 26.05
2000-02-22, Close, 26.38
2000-02-23, Close, 28.05
2000-02-24, Close, 27.55
2000-02-25, Close, 31.41
2000-02-28, Close, 30.52
2000-02-29, Close, 33.02
2000-03-01, Close, 31.80
2000-03-02, Close, 30.47
2000-03-02, 买入, 30.47
2000-03-03, Close, 33.36
2000-03-06, Close, 33.69
2000-03-07, Close, 33.33
2000-03-08, Close, 36.97
2000-03-09, Close, 37.36
2000-03-10, Close, 36.30
2000-03-13, Close, 35.02
2000-03-13, 买入, 35.02
2000-03-14, Close, 34.25
2000-03-14, 买入, 34.25
2000-03-15, Close, 34.97
2000-03-16, Close, 36.44
2000-03-17, Close, 35.50
2000-03-20, Close, 34.75
2000-03-20, 买入, 34.75
2000-03-21, Close, 35.89
2000-03-22, Close, 37.39
2000-03-23, Close, 38.64
2000-03-24, Close, 38.69
2000-03-27, Close, 39.33
2000-03-28, Close, 38.50
2000-03-29, Close, 36.69
2000-03-29, 买入, 36.69
2000-03-30, Close, 34.88
2000-03-30, 买入, 34.88
2000-03-31, Close, 34.72
2000-03-31, 买入, 34.72
2000-04-03, Close, 34.19
2000-04-03, 买入, 34.19
2000-04-04, Close, 33.77
2000-04-04, 买入, 33.77
2000-04-05, Close, 34.80
2000-04-06, Close, 36.55
2000-04-07, Close, 38.75
2000-04-10, Close, 36.69
2000-04-11, Close, 34.41
2000-04-11, 买入, 34.41
2000-04-12, Close, 32.52
2000-04-12, 买入, 32.52
2000-04-13, Close, 31.99
2000-04-13, 买入, 31.99
2000-04-14, Close, 27.80
2000-04-14, 买入, 27.80
2000-04-17, Close, 33.27
2000-04-18, Close, 35.11
2000-04-19, Close, 33.16
2000-04-20, Close, 31.49
2000-04-20, 买入, 31.49
2000-04-24, Close, 32.22
2000-04-25, Close, 33.61
2000-04-26, Close, 32.11
2000-04-27, Close, 34.38
2000-04-28, Close, 35.55
2000-05-01, Close, 35.44
2000-05-02, Close, 34.61
2000-05-02, 买入, 34.61
2000-05-03, Close, 33.72
2000-05-03, 买入, 33.72
2000-05-04, Close, 33.02
2000-05-04, 买入, 33.02
2000-05-05, Close, 34.16
2000-05-08, Close, 32.16
2000-05-09, Close, 32.02
2000-05-09, 买入, 32.02
2000-05-10, Close, 30.08
2000-05-10, 买入, 30.08
2000-05-11, Close, 32.19
2000-05-12, Close, 32.99
2000-05-15, Close, 34.25
2000-05-16, Close, 35.22
2000-05-17, Close, 34.77
2000-05-18, Close, 32.49
2000-05-18, 买入, 32.49
2000-05-19, Close, 31.16
2000-05-19, 买入, 31.16
2000-05-22, Close, 30.16
2000-05-22, 买入, 30.16
2000-05-23, Close, 27.85
2000-05-23, 买入, 27.85
2000-05-24, Close, 28.57
2000-05-25, Close, 29.55
2000-05-26, Close, 29.80
2000-05-30, Close, 32.99
2000-05-31, Close, 31.97
2000-06-01, Close, 34.63
2000-06-02, Close, 35.66
2000-06-05, Close, 36.00
2000-06-06, Close, 34.27
2000-06-07, Close, 35.58
2000-06-08, Close, 36.64
2000-06-09, Close, 36.77
2000-06-12, Close, 35.83
2000-06-13, Close, 36.33
2000-06-14, Close, 35.13
2000-06-15, Close, 36.69
2000-06-16, Close, 36.41
2000-06-19, Close, 38.25
2000-06-20, Close, 38.27
2000-06-21, Close, 38.33
2000-06-22, Close, 36.25
2000-06-23, Close, 35.36
2000-06-23, 买入, 35.36
2000-06-26, Close, 36.77
2000-06-27, Close, 36.58
2000-06-28, Close, 36.89
2000-06-29, Close, 35.97
2000-06-30, Close, 37.39
2000-07-03, Close, 35.66
2000-07-05, Close, 32.16
2000-07-05, 买入, 32.16
2000-07-06, Close, 33.63
2000-07-07, Close, 33.75
2000-07-10, Close, 32.97
2000-07-11, Close, 32.16
2000-07-11, 买入, 32.16
2000-07-12, Close, 33.22
2000-07-13, Close, 33.69
2000-07-14, Close, 33.86
2000-07-17, Close, 33.86
2000-07-18, Close, 32.99
2000-07-19, Close, 32.80
2000-07-19, 买入, 32.80
2000-07-20, Close, 34.75
2000-07-21, Close, 33.55
2000-07-24, Close, 33.36
2000-07-24, 买入, 33.36
2000-07-25, Close, 33.80
2000-07-26, Close, 34.13
2000-07-27, Close, 33.38
2000-07-28, Close, 32.19
2000-07-28, 买入, 32.19
2000-07-31, Close, 33.44
2000-08-01, Close, 32.52
2000-08-02, Close, 32.52
2000-08-03, Close, 34.44
2000-08-04, Close, 36.27
2000-08-07, Close, 36.41
2000-08-08, Close, 36.91
2000-08-09, Close, 36.19
2000-08-10, Close, 35.61
2000-08-10, 买入, 35.61
2000-08-11, Close, 36.08
2000-08-14, Close, 36.64
2000-08-15, Close, 36.14
2000-08-16, Close, 36.11
2000-08-16, 买入, 36.11
2000-08-17, Close, 37.33
2000-08-18, Close, 36.16
2000-08-21, Close, 37.00
2000-08-22, Close, 37.16
2000-08-23, Close, 36.86
2000-08-24, Close, 37.66
2000-08-25, Close, 37.64
2000-08-28, Close, 38.58
2000-08-29, Close, 39.03
2000-08-30, Close, 39.25
2000-08-31, Close, 40.44
2000-09-01, Close, 41.19
2000-09-05, Close, 40.50
2000-09-06, Close, 39.69
2000-09-06, 买入, 39.69
2000-09-07, Close, 40.56
2000-09-08, Close, 38.50
2000-09-11, Close, 37.11
2000-09-11, 买入, 37.11
2000-09-12, Close, 35.30
2000-09-12, 买入, 35.30
2000-09-13, Close, 36.39
2000-09-14, Close, 37.78
2000-09-15, Close, 34.83
2000-09-18, Close, 34.01
2000-09-18, 买入, 34.01
2000-09-19, Close, 35.27
2000-09-20, Close, 35.55
2000-09-21, Close, 35.11
2000-09-22, Close, 35.91
2000-09-25, Close, 35.02
2000-09-26, Close, 35.33
2000-09-27, Close, 35.52
2000-09-28, Close, 36.24
2000-09-29, Close, 35.02
2000-10-02, Close, 35.02
2000-10-03, Close, 30.91
2000-10-04, Close, 30.30
2000-10-04, 买入, 30.30
2000-10-05, Close, 30.38
2000-10-06, Close, 30.08
2000-10-09, Close, 29.69
2000-10-09, 买入, 29.69
2000-10-10, Close, 28.74
2000-10-10, 买入, 28.74
2000-10-11, Close, 27.69
2000-10-11, 买入, 27.69
2000-10-12, Close, 28.02
2000-10-13, Close, 31.69
2000-10-16, Close, 30.74
2000-10-17, Close, 29.96
2000-10-17, 买入, 29.96
2000-10-18, Close, 29.85
2000-10-18, 买入, 29.85
2000-10-19, Close, 32.36
2000-10-20, Close, 31.35
2000-10-23, Close, 30.30
2000-10-23, 买入, 30.30
2000-10-24, Close, 31.85
2000-10-25, Close, 30.58
2000-10-26, Close, 30.30
2000-10-26, 买入, 30.30
2000-10-27, Close, 30.41
2000-10-30, Close, 28.13
2000-10-31, Close, 29.35
2000-11-01, Close, 27.91
2000-11-02, Close, 26.30
2000-11-02, 买入, 26.30
2000-11-03, Close, 26.96
2000-11-06, Close, 24.85
2000-11-07, Close, 23.63
2000-11-07, 买入, 23.63
2000-11-08, Close, 22.07
2000-11-08, 买入, 22.07
2000-11-09, Close, 24.18
2000-11-10, Close, 22.63
2000-11-13, Close, 22.01
2000-11-13, 买入, 22.01
2000-11-14, Close, 25.24
2000-11-15, Close, 25.68
2000-11-16, Close, 24.35
2000-11-17, Close, 25.63
2000-11-20, Close, 22.01
2000-11-21, Close, 21.24
2000-11-21, 买入, 21.24
2000-11-22, Close, 19.85
2000-11-22, 买入, 19.85
2000-11-24, Close, 21.46
2000-11-27, Close, 20.57
2000-11-28, Close, 20.15
2000-11-28, 买入, 20.15
2000-11-29, Close, 20.35
2000-11-30, Close, 23.57
2000-12-01, Close, 23.52
2000-12-04, Close, 25.07
2000-12-05, Close, 28.02
2000-12-06, Close, 26.85
2000-12-07, Close, 25.18
2000-12-07, 买入, 25.18
2000-12-08, Close, 26.74
2000-12-11, Close, 28.41
2000-12-12, Close, 27.35
2000-12-13, Close, 25.24
2000-12-13, 买入, 25.24
2000-12-14, Close, 24.46
2000-12-14, 买入, 24.46
2000-12-15, Close, 25.41
2000-12-18, Close, 28.46
2000-12-19, Close, 27.24
2000-12-20, Close, 25.35
2000-12-20, 买入, 25.35
2000-12-21, Close, 26.24
2000-12-22, Close, 28.35
2000-12-26, Close, 27.52
2000-12-27, Close, 27.30
2000-12-27, 买入, 27.30
2000-12-28, Close, 27.63
2000-12-29, Close, 25.85
组合期末资金: 99740.45

若干个买入操作被执行,所以余额在减少。 细心的朋友可能会问,买了多少?买的什么?订单怎么被执行的?BackTrader框架替我们做了这些事: 如果没有指定的话, self.datas[0]即是标的物当前交易数据。 交易数量 =仓位数量,默认值等于1,后面例子我们会修改此参数。

订单被以”市价”成交了。 Broker(经纪人,之前提到过)使用了下一个交易日的开盘价,因为是broker在当前的交日易收盘后天提交的订单,下一个交易日开盘价是他接触到的第一个价格。 这里没有为订单设置佣金费,后边会加上。

3.8 不光有买入,还得有卖出

在知道如何买入(做多)之后,需要知道如何卖出,并且还需要了解该策略是否在市场中。 Strategy类有一个变量position保存当前持有的资产数量(可以理解为金融术语中的头寸), buy()和sell()会返回被创建的订单(尚未执行的), 订单状态的更改将通过 notify方法通知给策略Strategy。

卖出逻辑也很简单: 5个K线柱后(第6个K线柱)不管涨跌都卖。 请注意,这里没有指定具体时间,而是指定的柱的数量。一个柱可能代表 1分钟、1小时、1天、1星期等等,这取决于你价格数据文件里一条数据代表的周期。 虽然我们知道每个柱代表一天,但策略并不知道。

因为买入的时候,用的是交易日,所以这里应翻译为:5个交易日(第6个交易日)不管涨跌都卖。

另外,当还有头寸的时候,就不再买入了。

注意: 没有将柱的下标传给 next()方法,怎么知道已经经过了5个柱了呢? 这里用了 Python的len()方法获取它Line数据的长度。 交易发生时记下它的长度,后边比较大小,看是否经过了5个柱。

import datetime # 
import os.path # 路径管理  
import sys # 获取当前运行脚本的路径 (in argv[0]) 
#导入backtrader框架  
import backtrader as bt 
# 创建策略继承bt.Strategy 
class TestStrategy(bt.Strategy): 
    def log(self, txt, dt=None): 
        # 记录策略的执行日志  
        dt = dt or self.datas[0].datetime.date(0) 
        print('%s, %s' % (dt.isoformat(), txt))

    def __init__(self): 
    # 保存收盘价的引用  
        self.dataclose = self.datas[0].close 
        # 跟踪挂单  
        self.order = None 

    def notify_order(self, order): 
        if order.status in [order.Submitted, order.Accepted]: 
            # broker 提交/接受了,买/卖订单则什么都不做  
            return
        # 检查一个订单是否完成  
        # 注意: 当资金不足时,broker会拒绝订单  
        if order.status in [order.Completed]: 
            if order.isbuy(): 
                self.log('已买入, %.2f' % order.executed.price) 
            elif order.issell(): 
                self.log('已卖出, %.2f' % order.executed.price) 

            # 记录当前交易数量  
            self.bar_executed = len(self) 

        elif order.status in [order.Canceled, order.Margin, order.Rejected]: 
            self.log('订单取消/保证金不足/拒绝') 
            
        # 其他状态记录为:无挂起订单  
        self.order = None 


    def next(self): 
        # 记录收盘价  
        self.log('Close, %.2f' % self.dataclose[0]) 

        # 如果有订单正在挂起,不操作  
        if self.order: 
            return 

        # 如果没有持仓则买入  
        if not self.position: 
            # 今天的收盘价 < 昨天收盘价  
            if self.dataclose[0] < self.dataclose[-1]: 
                # 昨天收盘价 < 前天的收盘价  
                if self.dataclose[-1] < self.dataclose[-2]: 
                    # 买入  
                    self.log('买入, %.2f' % self.dataclose[0]) 
                    # 跟踪订单避免重复  
                    self.order = self.buy() 
        else: 
            # 如果已经持仓,且当前交易数据量在买入后5个单位后  
            if len(self) >= (self.bar_executed + 5): 
                # 全部卖出  
                self.log('卖出, %.2f' % self.dataclose[0]) 
                # 跟踪订单避免重复  
                self.order = self.sell() 

# 创建Cerebro引擎  
cerebro = bt.Cerebro() 
# Cerebro引擎在后台创建broker(经纪人),系统默认资金量为10000 
# 为Cerebro引擎添加策略  
cerebro.addstrategy(TestStrategy) 
# 获取当前运行脚本所在目录  
modpath = os.path.dirname(os.path.abspath(sys.argv[0])) 
# 拼接加载路径  
datapath = os.path.join(modpath, '/home/mw/input/backtrader7822/orcl-1995-2014.txt') 
# 创建交易数据集  
data = bt.feeds.YahooFinanceCSVData( 
                                dataname=datapath, 
                                # 数据必须大于fromdate 
                                fromdate=datetime.datetime(2000, 1, 1), 
                                # 数据必须小于todate 
                                todate=datetime.datetime(2000, 12, 31), 
                                reverse=False) 
# 加载交易数据  
cerebro.adddata(data) 
# 设置投资金额100000.0 
cerebro.broker.setcash(100000.0) 
# 引擎运行前打印期出资金  
print('组合期初资金: %.2f' % cerebro.broker.getvalue()) 
cerebro.run() 
# 引擎运行后打期末资金  
print(
  • 10
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: backtrader是一个开源的Python框架,用于开发和回测交易策略。它支持多种数据源,并提供了大量的技术指标和内置策略来方便用户开发交易策略。 backtrader官方中文文档是为中国的backtrader用户提供的一个帮助手册,旨在帮助用户更好地理解和使用backtrader框架。该文档包含了backtrader的安装与配置、基本概念、数据源和数据导入、指标计算、策略开发等多个方面,结合实例演示,帮助用户掌握backtrader的使用方法。 其中,文档的基本概念和框架介绍部分为用户提供了backtrader的核心理念和组件,这是理解整个框架的基础;数据源和数据导入部分为用户介绍了在backtrader中如何使用不同的数据源,以及如何对数据进行处理;指标计算部分详细介绍了backtrader框架内置的各种常用技术指标的用法;策略开发部分则为用户提供了一个实例,演示如何使用backtrader框架来开发交易策略和进行回测。 总之,backtrader官方中文文档是一个系统、全面的帮助手册,为用户提供了backtrader框架的各个方面的详细介绍和实例演示,帮助用户更加轻松地掌握和应用backtrader框架。 ### 回答2: backtrader是一款Python编写的开源交易策略框架。该框架的官方中文文档提供了详细的代码注释、示例代码和运行效果等,方便用户快速了解和使用该框架。 该文档提供了详细的搭建和安装方式,并包含了backtrade的使用入门和高级使用模式。其中,文档分为三部分,包括基础部分、扩展和高级部分和多个代码示例。 基础部分主要介绍了backtrader的基础概念及使用方法,包括数据的获取、回测和交易订单等。这个部分的示例代码涵盖了backtrader的主要功能,以帮助用户了解代码的基本结构和用法。 扩展和高级部分介绍了backtrader更高级的特性和使用方式,如定制化指标和数据源。同时也展示了如何使用backtrader结合机器学习和深度学习模型进行交易策略的研究和开发。此部分内容是适合有一定编程基础和需求的用户学习的。 多个代码示例部分的文档提供了多个不同的交易策略代码示例,适合用户进行实战感受和练习。该部分代码的实现方式较为清晰,方便用户借鉴学习。 总体来说,backtrader官方中文文档说明详尽,论述清晰,对初学者和高级用户都有较高的参考价值和使用意义。 ### 回答3: backtrader是一个受欢迎的Python框架,用于开发和回测交易策略。它的官方中文文档包含了完整的说明和指南,对于中文读者来说非常方便。 文档以简洁、直观的方式讲解了backtrader的核心概念,包括数据源、指标、信号和策略等。此外,文档中还提供了丰富的代码片段和示例,为读者提供了深入理解backtrader的实际应用和实现方法。 在文档中,也提供了详细的API文档,包括数据管理、指标计算、交易信号生成、策略编写等方面的接口。这使得读者可以快速找到所需的功能,并更好地利用backtrader的优势。 总之,backtrader官方中文文档是一个非常有用的资源,为中文用户提供了便利和支持。不仅可以帮助新手快速上手backtrader,也可以让有经验的用户更好地探索和利用backtrader的潜力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值