索引和切片 #
索引:0 和 -1 #
在 Backtrader
中,Line
代表着一组按时间顺序排列的点。这些点在策略执行期间动态生成,可以通过索引来访问。
使用索引访问 Line
#
访问当前值: 使用 0
索引访问当前的线值,如 self.data.close[0]
获取当前收盘价。
class MyStrategy(bt.Strategy):
def next(self):
print(self.data.close[0]) # 当前的收盘价
访问前值: 使用负数索引访问之前的值,如 self.data.close[-1]
获取上一条数据的收盘价。
class MyStrategy(bt.Strategy):
def next(self):
if self.data.close[0] > self.data.close[-1]:
print("今天的收盘价高于昨日的收盘价")
索引的意义:
0
索引指向当前时刻的值,-1
指向上一个时刻的值,以此类推。- 负数索引指向历史数据点,这对于时间序列分析和策略中的数据回溯非常有用。
简单示例:
class MyStrategy(bt.Strategy):
def next(self):
# 比较今天的收盘价和昨天的收盘价
if self.data.close[0] > self.data.close[-1]:
print("今天的收盘价更高")
else:
print("今天的收盘价更低")
在这个示例中,self.data.close[0]
是今天的收盘价,self.data.close[-1]
是昨天的收盘价。
切片 #
Backtrader
不支持对 Line
对象的切片操作,这是为了保持设计的一致性。切片适用于普通的 Python 数组,但在 Backtrader
中,Line
对象是动态增长的,因此切片的使用存在一定的限制。
为什么不支持切片 #
首先是 Line
的设计上要保持一致性。
Line
对象上的数据是通过索引(如 0
和 -1
)动态访问,基于时间序列进行数据处理。切片在此情况下并不适用,因为线的数据是按时间顺序排列的。
而常规可索引对象的切片是什么样的?
对于普通的 Python 对象,切片操作如下:
my_list = [1, 2, 3, 4, 5]
sliced_list = my_list[1:3] # 返回 [2, 3]
Backtrader
中的 Line
对象更像一个流式数据源,不能直接进行切片。
如何获取线的某些点 #
虽然 Line
不支持切片,但你仍然可以使用 get()
方法来获取线的一部分数据。例如:
# 获取最后 10 个数据点
myslice = self.my_sma.get(size=10) # 获取最近的 10 个值
这允许我们拿到指定数量的历史数据,且是按时间顺序拿到最近的数据。
延迟索引 #
在 Backtrader
中,延迟索引允许你在 __init__
阶段访问历史数据,而无需手动使用负索引。通常情况下,[]
操作符用于在 next
阶段提取数据值,而通过延迟索引,可以在初始化阶段引用历史数据,并生成可以在 next
方法中直接使用的 Lines
对象。
举个例子,如果你想比较前一日的收盘价与当前的简单移动平均线(SMA),你不需要在每次迭代中手动进行比较,而可以通过预先生成的 Lines
对象来实现:
初始化时使用延迟索引 #
在 __init__
方法中,你可以通过延迟索引定义需要的历史数据。例如,比较前一天的收盘价和当前的移动平均值:
class MyStrategy(bt.Strategy):
params = dict(period=20)
def __init__(self):
self.movav = btind.SimpleMovingAverage(self.data, period=self.p.period)
self.cmpval = self.data.close(-1) > self.movav # 比较前一日收盘价与当前20日均线
这里,self.data.close(-1)
通过延迟索引获取前一天的收盘价,self.movav
是当前的20日简单移动平均线。self.cmpval
是一个新的 Lines
对象,保存了每次比较的结果。
在 next
方法中使用延迟数据
#
在 next
方法中,你可以直接使用 Lines
对象的值进行逻辑判断。self.cmpval[0]
会返回当前条件是否成立:
class MyStrategy(bt.Strategy):
def next(self):
if self.cmpval[0]: # 如果前一日收盘价高于当前移动平均线
print("前一日收盘价高于当前简单移动平均线")
延迟索引的工作原理 #
self.data.close(-1)
使用延迟索引从历史数据中提取前一天的收盘价。这个语法会返回一个 Line
对象,但它是延迟的,即相对于当前时刻,它表示的是前一个时间点的 Line
。
语句 self.data.close(-1) > self.movav
会生成一个新的 Line
对象,该对象在 next
方法中返回 1
(条件为真)或 0
(条件为假),使你在 next
方法可直接使用比较结果。
通过这种方式,Backtrader
提供了更简洁和灵活的方式来引用和比较历史数据,而不需要手动管理索引,从而简化了策略的编写和逻辑实现。