旅游网站后台管理系统青峰集团响应式网站

web/2025/10/9 9:37:41/文章来源:
旅游网站后台管理系统,青峰集团响应式网站,微信 分享网站开发,网站制作好了怎么上传原文#xff1a;www.backtrader.com/ 概念 平台概念 原文#xff1a;www.backtrader.com/docu/concepts/ 这是平台某些概念的集合。它试图收集可在使用平台时有用的信息片段。 开始之前 所有小代码示例都假设以下导入可用#xff1a; import backtrader as bt import ba… 原文www.backtrader.com/ 概念 平台概念 原文www.backtrader.com/docu/concepts/ 这是平台某些概念的集合。它试图收集可在使用平台时有用的信息片段。 开始之前 所有小代码示例都假设以下导入可用 import backtrader as bt import backtrader.indicators as btind import backtrader.feeds as btfeeds注意 访问子模块的另一种替代语法如指标和数据源 import backtrader as bt然后 thefeed bt.feeds.OneOfTheFeeds(...) theind bt.indicators.SimpleMovingAverage(...)数据源 - 传递它们 与平台工作的基础将通过策略完成。这些将获得数据源。平台最终用户不需要关心接收它们 数据源被自动提供为策略的成员变量以数组形式和数组位置的快捷方式 策略派生类声明和运行平台的快速预览 class MyStrategy(bt.Strategy):params dict(period20)def __init__(self):sma btind.SimpleMovingAverage(self.datas[0], periodself.params.period)...cerebro bt.Cerebro()...data btfeeds.MyFeed(...) cerebro.adddata(data)...cerebro.addstrategy(MyStrategy, period30)...注意以下内容 策略的__init__方法未接收到*args或**kwargs仍然可以使用它们。 存在成员变量self.datas其为包含至少一个项目的数组/列表/可迭代对象希望至少有一个项目否则将引发异常。 是的。数据源被添加到平台上它们将按照它们被添加到系统中的顺序显示在策略内部。 注意 这也适用于指标如果最终用户开发自己的自定义指标或者查看某些现有指标参考的源代码时。 数据源的快捷方式 可以直接使用附加自动成员变量访问 self.datas 数组项 self.data目标为self.datas[0] self.dataX目标为self.datas[X] 然后的示例 class MyStrategy(bt.Strategy):params dict(period20)def __init__(self):sma btind.SimpleMovingAverage(self.data, periodself.params.period)...省略数据源 上述示例可以进一步简化为 class MyStrategy(bt.Strategy):params dict(period20)def __init__(self):sma btind.SimpleMovingAverage(periodself.params.period)...self.data已从SimpleMovingAverage的调用中完全移除。如果这样做指标在本例中为SimpleMovingAverage将接收正在创建的对象的第一个数据策略即self.data又名self.data0或self.datas[0] 几乎一切都是数据源 不仅数据源是数据也可以传递。指标和操作的结果也是数据。 在上一个示例中SimpleMovingAverage将self.datas[0]作为输入进行操作。具有操作和额外指标的示例 class MyStrategy(bt.Strategy):params dict(period120, period225, period310, period4)def __init__(self):sma1 btind.SimpleMovingAverage(self.datas[0], periodself.p.period1)# This 2nd Moving Average operates using sma1 as datasma2 btind.SimpleMovingAverage(sma1, periodself.p.period2)# New data created via arithmetic operationsomething sma2 - sma1 self.data.close# This 3rd Moving Average operates using something as datasma3 btind.SimpleMovingAverage(something, periodself.p.period3)# Comparison operators work too ...greater sma3 sma1# Pointless Moving Average of True/False values but valid# This 4th Moving Average operates using greater as datasma3 btind.SimpleMovingAverage(greater, periodself.p.period4)...基本上一旦被操作一切都会转换为可以用作数据源的对象。 参数 平台中的几乎每个其他class都支持参数的概念。 参数连同默认值声明为类属性元组的元组或类似字典的对象 关键字参数**kwargs被扫描以匹配参数如果找到则从**kwargs中删除它们并将值分配给相应的参数。 参数最终可以通过访问成员变量self.params简写self.p在类的实例中使用。 前面的快速策略预览已经包含了一个参数示例但为了冗余起见再次只关注参数。使用元组 class MyStrategy(bt.Strategy):params ((period, 20),)def __init__(self):sma btind.SimpleMovingAverage(self.data, periodself.p.period)并且使用一个dict class MyStrategy(bt.Strategy):params dict(period20)def __init__(self):sma btind.SimpleMovingAverage(self.data, periodself.p.period)行 再次平台上几乎每个其他对象都是Lines启用的对象。从最终用户的角度来看这意味着 它可以容纳一个或多个线系列其中线系列是一个值数组将这些值放在一起形成一条线。 一个line或lineseries的很好的例子是由股票收盘价形成的线。这实际上是价格演变的一个众所周知的图表表示称为Line on Close 平台的常规使用只关注访问lines。前面的迷你策略示例稍微扩展一下再次派上用场 class MyStrategy(bt.Strategy):params dict(period20)def __init__(self):self.movav btind.SimpleMovingAverage(self.data, periodself.p.period)def next(self):if self.movav.lines.sma[0] self.data.lines.close[0]:print(Simple Moving Average is greater than the closing price)已公开两个具有lines的对象 self.data 它有一个lines属性其中又包含一个close属性 self.movav 是一个SimpleMovingAverage指标 它有一个lines属性其中又包含一个sma属性 注 从这可以明显看出lines是有名称的。它们也可以按照声明顺序顺序访问但这只应在Indicator开发中使用 两个lines即close和sma都可以查询一个点索引 0以比较值。 有一种缩写访问行的方法存在 xxx.lines 可以缩短为 xxx.l xxx.lines.name 可以缩短为 xxx.lines_name 类似策略和指标的复杂对象提供了对数据线的快速访问 self.data_name 提供了对 self.data.lines.name 的直接访问 这也适用于编号的数据变量self.data1_name - self.data1.lines.name 此外线路名称可以直接访问 self.data.close 和 self.movav.sma 但是如果实际上正在访问行则该符号并不像之前的符号那样清晰。 不是 使用这两个后续符号设置/分配行不受支持 Lines声明 如果正在开发一个Indicator则必须声明该指标具有的lines。 正如与params一样这次以类属性的形式发生仅作为元组。不支持字典因为它们不按插入顺序存储事物。 对于简单移动平均线应该这样做 class SimpleMovingAverage(Indicator):lines (sma,)...注 如果将单个字符串传递给元组则元组中需要跟随声明的逗号否则字符串中的每个字母都将被解释为要添加到元组中的项目。这可能是 Python 语法出错的几个情况之一。 如前面的例子所示此声明在Indicator中创建了一个sma线可以在策略的逻辑中可能也可以由其他指标稍后访问以创建更复杂的指标。 对于开发而言有时以通用的非命名方式访问行是有用的这就是编号访问发挥作用的地方 self.lines[0] 指向 self.lines.sma 如果定义了更多行则可以使用索引 1、2 和更高的索引来访问它们。 当然还存在额外的简写版本 self.line 指向 self.lines[0] self.lineX 指向 self.lines[X] self.line_X 指向 self.lines[X] 在接收数据源的对象内这些数据源下方的行也可以通过数字快速访问 self.dataY 指向 self.data.lines[Y] self.dataX_Y 指向 self.dataX.lines[X]这是 self.datas[X].lines[Y] 的完整简化版本 在数据源中访问 lines 在数据源内部也可以访问 lines省略 lines。这使得使用像 close 价格这样的内容更加自然。 例如 data btfeeds.BacktraderCSVData(datanamemydata.csv)...class MyStrategy(bt.Strategy):...def next(self):if self.data.close[0] 30.0:...这似乎比也有效的更自然if self.data.lines.close[0] 30.0:。同样的情况不适用于带有以下理由的Indicators Indicator 可能有一个属性 close它保存一个中间计算结果稍后交付给实际的 lines也称为 close 在数据源的情况下不会进行任何计算因为它只是一个数据源。 行长度 行有一组点并在执行过程中动态增长因此可以随时通过调用标准的 Python len 函数来测量长度。 这适用于例如 数据源 策略 指标 数据源中存在另一个属性当数据 预加载 时适用 方法 buflen 该方法返回数据源可用的实际条形图数。 len 和 buflen 的区别 len 报告已处理了多少个条形图 buflen 报告为数据源加载了多少个条形图 如果两者返回相同的值则要么没有预加载数据要么条形图的处理已消耗所有预加载的条形图除非系统连接到实时数据源否则这将意味着处理结束 行和参数的继承 一种元语言用于支持参数和行的声明。为了使其与标准 Python 继承规则兼容已经尽一切努力。 参数继承 继承应该按预期工作 支持多重继承 从基类继承参数 如果多个基类定义了相同的参数则使用继承列表中最后一个类的默认值 如果在子类中重新定义了相同的参数则新的默认值将取代基类的默认值 行继承 支持多重继承 来自所有基类的行都会被继承。作为命名行如果相同的名称在基类中使用了多次则只会有一个版本的行 索引0 和 -1 行如前所述是线系列并在绘制时一起组成一条线就像沿时间轴连接所有收盘价一样 要在常规代码中访问这些点选择使用基于0的方法来获取/设置当前get/set即时。 策略只获取值。指标还设置值。 在之前的快速策略示例中next方法被简要看到 def next(self):if self.movav.lines.sma[0] self.data.lines.close[0]:print(Simple Moving Average is greater than the closing price)逻辑是通过应用索引0 获取移动平均值和当前收盘价的当前值。 注意 实际上对于索引0并且在应用逻辑/算术运算符时可以直接进行比较如下所示 if self.movav.lines.sma self.data.lines.close:...在文档后面看运算符的解释。 设置是用于开发时使用的例如一个 Indicator因为必须通过该指标设置当前输出值。 可以按以下方式计算当前获取/设置点的 SimpleMovingAverage def next(self):self.line[0] math.fsum(self.data.get(0, sizeself.p.period)) / self.p.period访问先前设置的点是按照 Python 为访问数组/可迭代时定义的-1进行建模 它指向数组的最后一项 平台将最后设置的项当前实时获取/设置点之前视为-1。 因此将当前close与前一个close进行比较是一个0 vs -1的事情。例如在策略中 def next(self):if self.data.close[0] self.data.close[-1]:print(Closing price is higher today)当然从-1之前设置的价格将使用-2、-3、...进行访问。 切片 backtrader不支持对lines对象进行切片这是一种设计决策遵循了[0]和[-1]索引方案。对于常规可索引的 Python 对象您会执行以下操作 myslice self.my_sma[0:] # slice from the beginning til the end但请记住在选择为0时……实际上是当前交付的值后面没有了。另外 myslice self.my_sma[0:-1] # slice from the beginning til the end再次……0是当前值-1是最新先前的交付值。这就是为什么在backtrader生态系统中从0 - -1切片没有意义的原因。 如果支持切片将如下所示 myslice self.my_sma[:0] # slice from current point backwards to the beginning或 myslice self.my_sma[-1:0] # last value and current value或 myslice self.my_sma[-3:-1] # from last value backwards to the 3rd last value获取一个切片 仍然可以获取具有最新值的数组。语法 myslice self.my_sma.get(ago0, size1) # default values shown这将返回一个具有1值size1的数组当前时刻0作为向后查找的起始点。 要从当前时间点获取 10 个值即最后 10 个值 myslice self.my_sma.get(size10) # ago defaults to 0当然数组具有您期望的顺序。最左边的值是最旧的值最右边的值是最新的值它是一个常规的 Python 数组而不是一个lines对象 要获取最后 10 个值仅跳过当前点 myslice self.my_sma.get(ago-1, size10)行延迟索引 []操作符语法用于在next逻辑阶段提取单个值。 Lines对象支持另一种符号通过延迟行对象在__init__阶段访问值。 假设逻辑的兴趣是将前一个close值与简单移动平均值的实际值进行比较。而不是在每个next迭代中手动执行可以生成一个预先定义的lines对象 class MyStrategy(bt.Strategy):params dict(period20)def __init__(self):self.movav btind.SimpleMovingAverage(self.data, periodself.p.period)self.cmpval self.data.close(-1) self.smadef next(self):if self.cmpval[0]:print(Previous close is higher than the moving average)在这里正在使用(delay)符号 这提供了一个close价格的副本但是延迟了-1。 比较self.data.close(-1) self.sma生成另一个lines对象如果条件为True则返回1如果为False则返回0 线耦合 运算符()可以像上面显示的那样与delay值一起使用以提供lines对象的延迟版本。 如果使用语法WITHOUT提供delay值则返回一个LinesCoupler lines对象。这旨在在操作datas具有不同时间框架的指标之间建立耦合。 具有不同时间框架的数据源具有不同的长度在其上操作的指标复制数据的长度。例如 每年的日数据源大约有 250 个柱状图 每年的周数据源有 52 个柱状图 尝试创建一个操作例如比较两个简单移动平均每个操作在上述引用的数据上运行会出现问题。不清楚如何将每日时间框架的 250 个柱状图与每周时间框架的 52 个柱状图匹配。 读者可以想象在后台进行date比较以找出一天 - 一周的对应关系但是 指标只是数学公式没有日期时间信息。 它们对环境一无所知只知道如果数据提供足够的值就可以进行计算。 ()空调用符号来拯救 class MyStrategy(bt.Strategy):params dict(period20)def __init__(self):# data0 is a daily datasma0 btind.SMA(self.data0, period15) # 15 days sma# data1 is a weekly datasma1 btind.SMA(self.data1, period5) # 5 weeks smaself.buysig sma0 sma1()def next(self):if self.buysig[0]:print(daily sma is greater than weekly sma1)在这里较大时间框架指标sma1与每日时间框架耦合为sma1()。这返回一个与sma0的更大柱状图兼容的对象并复制由sma1产生的值有效地将 52 周柱状图分散在 250 日柱状图中 运算符使用自然构造 为了实现“易用性”目标该平台允许在 Python 的约束条件下使用运算符。为了进一步增强这一目标运算符的使用已分为两个阶段。 第 1 阶段 - 运算符创建对象 即使没有明确指定示例已经展示了这一点。在像指标和策略这样的对象的初始化阶段__init__方法中运算符创建可以进行操作、分配或保留作为后续在策略逻辑评估阶段使用的对象。 再次展示了一个简单移动平均的潜在实现进一步分解为步骤。 简单移动平均指标__init__中的代码可能如下所示 def __init__(self):# Sum N period values - datasum is now a *Lines* object# that when queried with the operator [] and index 0# returns the current sumdatasum btind.SumN(self.data, periodself.params.period)# datasum (being *Lines* object although single line) can be# naturally divided by an int/float as in this case. It could# actually be divided by anothr *Lines* object.# The operation returns an object assigned to av which again# returns the current average at the current instant in time# when queried with [0]av datasum / self.params.period# The av *Lines* object can be naturally assigned to the named# line this indicator delivers. Other objects using this# indicator will have direct access to the calculationself.line.sma av在策略初始化期间展示了一个更完整的用例 class MyStrategy(bt.Strategy):def __init__(self):sma btind.SimpleMovinAverage(self.data, period20)close_over_sma self.data.close smasma_dist_to_high self.data.high - smasma_dist_small sma_dist_to_high 3.5# Unfortunately and cannot be overridden in Python being# a language construct and not an operator and thus a# function has to be provided by the platform to emulate itsell_sig bt.And(close_over_sma, sma_dist_small)在上述操作完成后sell_sig是一个Lines对象可以在策略的逻辑中稍后使用指示条件是否满足。 第二阶段 - 自然的运算符 让我们首先记住策略有一个next方法系统处理每个柱状图时都会调用该方法。这就是运算符实际处于第 2 阶段模式的地方。在前面的示例基础上构建 class MyStrategy(bt.Strategy):def __init__(self):self.sma sma btind.SimpleMovinAverage(self.data, period20)close_over_sma self.data.close smaself.sma_dist_to_high self.data.high - smasma_dist_small sma_dist_to_high 3.5# Unfortunately and cannot be overridden in Python being# a language construct and not an operator and thus a# function has to be provided by the platform to emulate itself.sell_sig bt.And(close_over_sma, sma_dist_small)def next(self):# Although this does not seem like an operator it actually is# in the sense that the object is being tested for a True/False# responseif self.sma 30.0:print(sma is greater than 30.0)if self.sma self.data.close:print(sma is above the close price)if self.sell_sig: # if sell_sig True: would also be validprint(sell sig is True)else:print(sell sig is False)if self.sma_dist_to_high 5.0:print(distance from sma to hig is greater than 5.0)不是一个非常有用的策略只是一个例子。在第 2 阶段运算符返回预期的值如果测试真实性则返回布尔值如果与浮点数比较则返回浮点数算术运算也是如此。 注意 请注意比较实际上并没有使用[]运算符。这是为了进一步简化事情。 if self.sma 30.0: … 比较self.sma[0]和30.0第 1 行和当前值 if self.sma self.data.close: … 比较self.sma[0]和self.data.close[0] 一些未被覆盖的运算符/函数 Python 不允许覆盖所有内容因此提供了一些函数来处理这些情况。 注意 仅在阶段 1 中使用以创建稍后提供值的对象。 运算符 and - And or - Or 逻辑控制 if - If 函数 any - Any all - All cmp - Cmp max - Max min - Min sum - Sum Sum实际上使用math.fsum作为底层操作因为平台使用浮点数并且应用常规的sum可能会影响精度。 reduce - Reduce 这些实用运算符/函数操作可迭代对象。可迭代对象中的元素可以是常规的 Python 数值类型整数浮点数…也可以是具有Lines的对象。 一个生成非常愚蠢买入信号的例子 class MyStrategy(bt.Strategy):def __init__(self):sma1 btind.SMA(self.data.close, period15)self.buysig bt.And(sma1 self.data.close, sma1 self.data.high)def next(self):if self.buysig[0]:pass # do something here很明显如果sma1高于最高价那么它必须高于收盘价。但重点是说明bt.And的用法。 使用bt.If class MyStrategy(bt.Strategy):def __init__(self):sma1 btind.SMA(self.data.close, period15)high_or_low bt.If(sma1 self.data.close, self.data.low, self.data.high)sma2 btind.SMA(high_or_low, period15)分解 在data.close上生成一个SMA周期为15 然后 bt.If如果sma的值大于close则返回low否则返回high 请记住当调用bt.If时并不会返回实际值。它返回一个Lines对象就像一个SimpleMovingAverage一样。 值将在系统运行时计算 生成的bt.If Lines对象然后被传递给第 2 个SMA有时会使用low价格有时会使用high价格进行计算 这些函数也接受数值。同样的例子稍作修改 class MyStrategy(bt.Strategy):def __init__(self):sma1 btind.SMA(self.data.close, period15)high_or_30 bt.If(sma1 self.data.close, 30.0, self.data.high)sma2 btind.SMA(high_or_30, period15)现在第 2 个移动平均值使用30.0或high价格执行计算取决于sma与close的逻辑状态 注意 值30在内部转换为一个伪可迭代对象始终返回30 操作平台 原文www.backtrader.com/docu/operating/ 线迭代器 为了参与操作平台使用线迭代器的概念。它们松散地模仿了 Python 的迭代器但实际上与它们毫不相关。 策略和指标都是线迭代器。 线迭代器的概念试图描述以下内容 一条线迭代器踢动从属线迭代器告诉它们迭代 然后线迭代器遍历其自己声明的命名行并设置值 迭代的关键就像普通的 Python 迭代器一样是 next 方法 它将被每次迭代调用。 线迭代器具有的并作为逻辑/计算基础的datas数组已经被平台移动到下一个索引除了数据重播 在满足线迭代器的最小周期时调用。稍后将详细介绍。 但因为它们不是常规迭代器所以还存在两种额外的方法 prenext 在满足最小周期的条件之前调用线迭代器。 nextstart 当满足最小周期的条件时仅调用一次线迭代器。 默认行为是将调用转发给next但如果需要的话当然可以重写。 指标的额外方法 为了加快操作速度指标支持一种称为 runonce 的批处理操作模式。这不是严格必需的一个next方法就足够了但它极大地减少了时间。 runonce 方法规则使得与索引 0 的点的获取/设置无效并依赖于直接访问保存数据的底层数组并为每个状态传递正确的索引。 定义的方法遵循 next 系列的命名 once(self, start, end) 在满足最小周期的条件时调用。必须在从内部数组的起始位置为零开始的 start 和 end 之间处理内部数组 preonce(self, start, end) 在满足最小周期之前调用。 oncestart(self, start, end) 当满足最小周期的条件时仅调用一次。 默认行为是将调用转发给once但如果需要的话当然可以重写。 最小周期 一张图值千言而在这种情况下可能还有一个例子。一个简单移动平均能够解释它 class SimpleMovingAverage(Indicator):lines (sma,)params dict(period20)def __init__(self):... # Not relevant for the explanationdef prenext(self):print(prenext:: current period:, len(self))def nextstart(self):print(nextstart:: current period:, len(self))# emulate default behavior ... call nextself.next()def next(self):print(next:: current period:, len(self))实例化可能如下所示 sma btind.SimpleMovingAverage(self.data, period25)简要解释 假设传递给移动平均的数据是标准数据源默认周期为1即数据源生成一个没有初始延迟的条形图。 然后**“period25”**实例化的移动平均将按以下方式调用其方法 prenext 24 次 nextstart 1 次依次调用next next 再次直到数据源耗尽 让我们来看一个致命的指标另一个简单移动平均值的a SimpleMovingAverage。实例化可能如下所示 sma1 btind.SimpleMovingAverage(self.data, period25)sma2 btind.SimpleMovingAverage(sma1, period20)现在发生的情况是 对于sma1也是如上所述 sma2正在接收一个数据源其最小周期为 25这是我们的sma1因此 sma2方法的调用方式如下 prenext首次调用 25 18 次总共 43 次 25 次让sma1产生其第 1 个合理值。 18 次累积额外的sma1值 总共 19 个值在 25 次调用后再加 1 次然后再加 18 次 nextstart然后调用 1 次轮流调用next next另外调用 n 次直到数据源耗尽 当系统已经处理了 44 个柱状时平台会调用next。 最小周期已自动调整为传入数据。 策略和指标遵循这种行为 只有当自动计算的最小周期已达到时才会调用next除了对nextstart的初始钩子调用 注意。 相同的规则适用于runonce批量操作模式的preonce、oncestart和once 注意。 最小周期行为可以被操纵尽管不建议这样做。如果希望使用在策略或指标中使用setminperiod(minperiod)方法 已启动并运行。 启动和运行至少涉及 3 个Lines对象 一个数据源 一个策略实际上是从策略派生的类 一个 Cerebro西班牙语中的“大脑”。 数据源 这些对象显然提供将通过应用计算直接和/或带有指标进行回测的数据。 该平台提供了几个数据源 几种 CSV 格式和一个通用的 CSV 阅读器 雅虎在线获取器 支持接收Pandas DataFrames和blaze对象 与Interacive Brokers、Visual Chart和Oanda一起的实时数据源。 该平台不对数据源的内容如时间段和压缩做任何假设。这些值连同名称可以供信息用途和高级操作例如数据源重采样将例如 5 分钟数据源转换为每日数据源。 设置 Yahoo Finance 数据源的示例 import backtrader as bt import backtrader.feeds as btfeeds...datapath path/to/your/yahoo/data.csvdata btfeeds.YahooFinanceCSVData(datanamedatapath,reversedTrue)显示了雅虎的可选reversed参数因为直接从雅虎下载的 CSV 文件从最新日期开始而不是从最旧日期开始。 如果您的数据跨越了大的时间范围则实际加载的数据可以限制如下 data btfeeds.YahooFinanceCSVData(datanamedatapath,reversedTruefromdatedatetime.datetime(2014, 1, 1),todatedatetime.datetime(2014, 12, 31))如果存在fromdate和todate都将被包含在数据源中。 如已提及的时间段、压缩和名称可添加 data btfeeds.YahooFinanceCSVData(datanamedatapath,reversedTruefromdatedatetime.datetime(2014, 1, 1),todatedatetime.datetime(2014, 12, 31)timeframebt.TimeFrame.Days,compression1,nameYahoo)如果数据已绘制则将使用这些值。 一个策略派生类 注意。 在继续之前并且为了更简化的方法请检查文档的Signals部分如果不希望子类化策略。 使用该平台的任何人的目标都是对数据进行回测这是在策略派生类内完成的。 至少有 2 种方法需要定制 __init__ next 在初始化过程中对数据和其他计算进行了创建和准备以后将应用逻辑。 稍后将调用next方法来应用每个数据条的逻辑。 注意 如果传递了不同时间框架因此具有不同的条形计数的数据源则将调用next方法以获取主数据传递给 cerebro 的第一个数据见下文它必须是具有较小时间框架的数据 注意 如果使用数据重播功能则将为相同的条形进行多次调用next方法因为条形的发展正在重播。 一个基本的派生自类的策略 class MyStrategy(bt.Strategy):def __init__(self):self.sma btind.SimpleMovingAverage(self.data, period20)def next(self):if self.sma self.data.close:self.buy()elif self.sma self.data.close:self.sell()策略具有其他方法或挂钩点可以重写 class MyStrategy(bt.Strategy):def __init__(self):self.sma btind.SimpleMovingAverage(self.data, period20)def next(self):if self.sma self.data.close:submitted_order self.buy()elif self.sma self.data.close:submitted_order self.sell()def start(self):print(Backtesting is about to start)def stop(self):print(Backtesting is finished)def notify_order(self, order):print(An order new/changed/executed/canceled has been received)start和stop方法应该是不言而喻的。与预期的一样并且遵循打印函数中的文本当策略需要通知时将调用notify_order方法。用例 请求购买或出售如下所示 购买/出售将返回一个order该订单将提交给经纪人。保留对此已提交订单的引用由调用者自行决定。 例如可以用它来确保如果订单仍未处理则不会提交新订单。 如果订单被接受/执行/取消/更改则经纪人将通过 notify 方法将状态更改例如执行大小通知回策略 快速入门指南在notify_order方法中有一个完整而实用的订单管理示例。 还可以使用其他策略类做更多事情 buy/sell/close 使用底层的broker和sizer向经纪人发送购买/出售订单 也可以通过手动创建订单并将其传递给经纪人来完成相同的操作。但是该平台旨在使使用它的人更容易。 close将获取当前的市场持仓并立即关闭它。 getposition或属性“position” 返回当前的市场持仓 setsizer/getsizer或属性“sizer” 这些允许设置/获取底层的 Stake Sizer。可以对提供相同情况的不同 Stake 的 Sizer 检查相同的逻辑固定大小与资本成比例指数 有很多文献但 Van K. Tharp 在这个领域有出色的书籍。 策略是Lines对象这些对象支持参数这些参数使用标准 Python kwargs 参数进行收集 class MyStrategy(bt.Strategy):params ((period, 20),)def __init__(self):self.sma btind.SimpleMovingAverage(self.data, periodself.params.period)......注意SimpleMovingAverage如何不再以固定值 20 进行实例化而是使用已为策略定义的参数“period”进行实例化。 一个 Cerebro 一旦数据源可用并且策略已定义Cerebro 实例就是将所有内容汇集在一起并执行操作的工具。实例化一个很容易 cerebro bt.Cerebro()如果没有特殊要求则默认情况下会进行处理。 创建默认经纪人 操作无佣金 数据源将被预加载 默认执行模式将是 runonce批量操作这是更快的模式 所有指标必须支持runonce模式以实现全速运行。平台中包含的指标可以。 自定义指标不需要实现 runonce 功能。Cerebro将模拟它这意味着那些不兼容 runonce 的指标将运行得更慢。但大部分系统仍将以批处理模式运行。 由于数据源已经可用策略也已经创建之前创建将它们组合在一起并使其运行的标准方法是 cerebro.adddata(data) cerebro.addstrategy(MyStrategy, period25) cerebro.run()请注意以下内容 数据源“实例”被添加 MyStrategy“类”被添加以及将传递给它的参数kwargs。 MyStrategy 的实例化将由 cerebro 在后台完成并且“addstrategy”中的任何 kwargs 将被传递给它 用户可以根据需要添加任意多的策略和数据源。策略如何相互通信以实现协调如果需要并不受平台的强制/限制。 当然Cerebro 提供了额外的可能性 决定预加载和操作模式 cerebro bt.Cerebro(runonceTrue, preloadTrue) 这里有一个约束runonce需要预加载如果不是批处理操作将无法运行。当然预加载数据源并不强制执行runonce setbroker / getbroker以及broker属性 如果需要可以设置自定义经纪人。实际经纪人实例也可以被访问 绘图。在常规情况下就像这样简单 cerebro.run() cerebro.plot() 绘图需要一些参数进行自定义 numfigs1 如果图表过于密集可以将其拆分为多个图表 plotterNone 可以传递自定义绘图器实例cerebro 将不会实例化默认绘图器 **kwargs - 标准关键字参数 这将传递给绘图器。 请查看绘图部分获取更多信息。 优化策略。 如上所述Cerebro 获得一个派生自 Strategy 的类而不是实例以及将在调用“run”时传递给它的关键字参数。 这样可以实现优化。相同的 Strategy 类将根据需要实例化多次并使用新参数。如果一个实例已经传递给 cerebro…这将是不可能的。 请求优化如下 cerebro.optstrategy(MyStrategy, periodxrange(10, 20)) 方法optstrategy具有与addstrategy相同的签名但会进行额外的管理工作以确保优化按预期运行。一个策略可能期望一个范围作为策略的正常参数而addstrategy不会对传递的参数做任何假设。 另一方面optstrategy将理解可迭代对象是一组值必须按顺序传递给每个 Strategy 类的实例化。 注意传递的不是单个值而是一系列值。在这个简单的情况下将尝试这个策略的 10 个值 10 - 1920 是上限。 如果开发了更复杂的策略并具有额外的参数它们都可以传递给optstrategy。必须不经过优化的参数可以直接传递而无需最终用户创建一个仅包含一个值的虚拟可迭代对象。例如 cerebro.optstrategy(MyStrategy, periodxrange(10, 20), factor3.5) optstrategy方法看到因子并在后台为具有单个元素的因子创建所需的虚拟可迭代对象例如 3.5 中的示例。 注意 交互式 Python shell 和某些类型的在Windows下的冻结可执行文件对 Python 的multiprocessing模块存在问题。 请阅读有关multiprocessing的 Python 文档。 大脑 Cerebro 原文www.backtrader.com/docu/cerebro/ 这个类是backtrader的基石因为它作为以下方面的中心点 收集所有输入数据源、行动者策略、旁观者观察员、评论者分析器和文档编制者写作者确保节目随时进行。 执行回测/或实时数据提供/交易 返回结果 提供对绘图设施的访问 收集输入 首先创建一个cerebro cerebro bt.Cerebro(**kwargs) 支持一些**kwargs来控制执行参见参考文献这些参数后来也可以应用于run方法 添加数据源 最常见的模式是cerebro.adddata(data)其中data已经实例化为数据源。例如 data bt.BacktraderCSVData(datanamemypath.days, timeframebt.TimeFrame.Days) cerebro.adddata(data) 重新采样和回放数据是可能的遵循相同的模式 data bt.BacktraderCSVData(datanamemypath.min, timeframebt.TimeFrame.Minutes) cerebro.resampledata(data, timeframebt.TimeFrame.Days) 或 data bt.BacktraderCSVData(datanamemypath.min, timeframebt.TimeFrame.Minutes) cerebro.replaydatadata(data, timeframebt.TimeFrame.Days) 系统可以接受任意数量的数据源包括混合常规数据与重新采样和/或重放数据。当然其中一些组合肯定毫无意义因此在能够组合数据时会应用一些限制时间对齐。请参阅数据-多时间框架、数据重新采样-重新采样和数据-重播部分。 添加Strategies 与已经是类实例的数据源不同cerebro直接接受Strategy类和传递给它的参数。背后的原理是在优化场景中该类将被实例化多次并传递不同的参数 即使没有运行优化该模式仍然适用 cerebro.addstrategy(MyStrategy, myparam1value1, myparam2value2) 当优化参数时必须添加为可迭代对象。详细说明请参见优化部分。基本模式 cerebro.optstrategy(MyStrategy, myparam1range(10, 20)) 运行MyStrategy 10 次其中myparam1的值从 10 到 19请记住Python 中的范围是半开放的20不会被包含 其他元素 还有一些其他元素可以添加以增强回测体验。查看相应的部分以了解详情。方法包括 addwriter addanalyzer addobserver或addobservermulti 更改经纪人 Cerebro 将在backtrader中使用默认经纪人但可以被覆盖 broker MyBroker() cerebro.broker broker # property using getbroker/setbroker methods 接收通知 如果数据源和/或经纪人发送通知或创建它们的存储提供程序它们将通过Cerebro.notify_store方法接收。有三3种处理这些通知的方法 通过addnotifycallback(callback)调用向cerebro实例添加回调。回调函数必须支持此签名 callback(msg, *args, **kwargs) 实际的msg、*args和**kwargs接收的内容是实现定义的完全取决于数据/经纪人/存储但一般可以期望它们是可打印的以便接收和实验。 在添加到cerebro实例的Strategy子类中覆盖notify_store方法。 签名notify_store(self, msg, *args, **kwargs) 子类Cerebro并覆盖notify_store与Strategy中的签名相同 这应该是最不受欢迎的方法 执行回测 有一个单一的方法可以做到这一点但它支持几个选项也可以在实例化时指定以决定如何运行 result cerebro.run(**kwargs)请参阅下面的参考文献了解可用的参数。 标准观察者 cerebro除非另有说明会自动实例化三个标准观察者 一个Broker观察者用于跟踪cash和value投资组合 一个Trades观察者应显示每次交易的有效性如何 一个Buy/Sell观察者应记录操作何时执行 如果希望更干净的绘图只需使用stdstatsFalse禁用它们 返回结果 cerebro在回测期间返回所创建的策略实例。这允许分析它们的操作因为可以访问策略中的所有元素 result cerebro.run(**kwargs)由run返回的result的格式取决于是否使用了优化使用optstrategy添加了一个策略 所有使用addstrategy添加的策略 result将是在回测期间运行的实例的list 使用optstrategy添加了 1 个或多个策略 result将是list的list。每个内部列表将包含每次优化运行后的策略 注意 优化的默认行为已更改为仅返回系统中存在的分析器以减轻跨计算机核心的消息传递负担。 如果希望返回完整的策略集请将参数optreturn设置为False 提供对绘图功能的访问 如果安装了matplotlib则可以绘制策略图。通常的模式是 cerebro.plot()请参阅下文的参考文献和绘图部分 回测逻辑 事物流程的简要概述 传递任何存储通知 要求数据源提供下一组 ticks/bars **版本更改**版本 1.9.0.99 中已更改新行为 数据源通过查看下一个将提供的datetime来同步。在新周期中尚未交易的数据源仍提供旧数据点而具有新数据的数据源则提供此数据以及指标的计算 旧行为在Cerebro中使用oldsyncTrue时保留 第 1 个插入系统的数据是datamaster系统将等待它提供一个 tick 其他数据源或多或少是datamaster的从属且 * If the next tick to deliver is newer (datetime-wise) than the onedelivered by the datamaster it will not be delivered* May return without delivering a new tick for a number of reasons 逻辑被设计为轻松同步多个数据源和具有不同时间框架的数据源 通知策略有关已排队的经纪人订单、交易和现金/价值的通知 告诉经纪人接受排队的订单并使用新数据执行待处理的订单 调用策略的 next 方法以使策略评估新数据并可能发出在经纪人中排队的订单 根据阶段策略/指标的最小周期要求可能在满足之前是 prenext 还是 nextstart。 在内部策略还会触发 observers、indicators、analyzers 和其他活动元素 告诉任何 writers 将数据写入其目标 注意 注意 在上述第 1 步中当 数据源 传递新的柱集时这些柱是 关闭 的。 这意味着数据已经发生了。 因此在第 4 步中策略发出的 订单 无法使用第 1 步的数据 执行。 这意味着订单将使用 x 1 的概念执行。 其中 x 是订单执行的柱时刻而 x 1 是下一个它是可能的订单执行的最早时刻 参考 类 backtrader.Cerebro() 参数 preload默认True 是否预加载传递给 cerebro 的不同 data feeds 用于策略 runonce默认True 在向量化模式下运行 Indicators 以加速整个系统。 策略和观察器将始终基于事件运行。 live默认False 如果没有数据通过数据的 islive 方法报告自身为 live但最终用户仍希望以 live 模式运行可以将此参数设置为 true 这将同时停用 preload 和 runonce。 对内存节省方案没有影响。 在向量化模式下运行 Indicators 以加速整个系统。 策略和观察器将始终基于事件运行。 maxcpus默认无-所有可用核心 同时使用多少核心进行优化 stdstats默认True 如果为 True默认观察者将被添加经纪人现金和价值、交易和买卖 oldbuysell默认False 如果 stdstats 为 True 并且观察者自动添加则此开关控制 BuySell 观察者的主要行为 False使用现代行为在低/高价格的下方/上方分别绘制买入/卖出信号以避免图表混乱 True使用已弃用的行为在给定时刻的订单执行的平均价格绘制买入/卖出信号。 这当然会在 OHLC 柱或 Cloe 柱上方绘制难以识别图的内容。 oldtrades默认False 如果 stdstats 为 True 并且观察者自动添加则此开关控制 Trades 观察者的主要行为 False使用现代行为其中所有数据的交易都用不同的标记绘制 True使用旧的交易观察器它使用相同的标记绘制交易仅在它们是正数还是负数时有所区别。 exactbars默认False 默认情况下每个值都会存储在内存中的一行中。 可能的值 * True or 1: all “lines” objects reduce memory usage to theautomatically calculated minimum period.If a Simple Moving Average has a period of 30, the underlying datawill have always a running buffer of 30 bars to allow thecalculation of the Simple Moving Average* This setting will deactivate preload and runonce* Using this setting also deactivates **plotting*** -1: datafreeds and indicators/operations at strategy level willkeep all data in memory.For example: a RSI internally uses the indicator UpDay tomake calculations. This subindicator will not keep all data inmemory* This allows to keep plotting and preloading active.* runonce will be deactivated* -2: data feeds and indicators kept as attributes of thestrategy will keep all points in memory.For example: a RSI internally uses the indicator UpDay tomake calculations. This subindicator will not keep all data inmemoryIf in the __init__ something likea self.data.close - self.data.high is defined, then awill not keep all data in memory* This allows to keep plotting and preloading active.* runonce will be deactivatedobjcache默认False 实验选项用于实现线条对象的缓存并减少它们的数量。从 UltimateOscillator 示例 bp self.data.close - TrueLow(self.data) tr TrueRange(self.data) # - creates another TrueLow(self.data)如果这是True则TrueRange内的第 2 个TrueLow(self.data)将与bp计算中的签名匹配。它将被重用。 边缘情况可能会发生其中这会使线条对象超出其最小周期并且导致故障因此已禁用。 writer默认False 如果设置为True将创建一个默认的 WriterFile它将打印到 stdout。它将被添加到策略中除了用户代码添加的任何其他写入器 tradehistory默认False 如果设置为True它将激活每个策略的每次交易的更新事件记录。这也可以通过策略方法set_tradehistory逐个策略地完成。 optdatas默认True 如果为True且正在优化并且系统可以preload并使用runonce数据预加载将仅在主进程中执行一次以节省时间和资源。 测试显示从在83秒的样本执行中移动到66秒的执行速度提高了约20%。 optreturn默认True 如果为True则优化结果将不是完整的Strategy对象以及所有datas、indicators、observers…而是具有以下属性的对象与Strategy中相同 * params (or p) the strategy had for the execution* analyzers the strategy has executed在大多数情况下只有分析器和与之相关的参数是评估策略性能所需的内容。如果需要对生成的值例如指标进行详细分析则关闭此选项。 测试显示执行时间提高了13% - 15%。与optdatas结合使用总增益增加到了优化运行的32%的总体加速。 oldsync默认False 从版本 1.9.0.99 开始多个数据的同步相同或不同的时间框架已更改为允许长度不同的数据。 如果希望保留旧的行为并将 data0 设置为系统的主要数据则将此参数设置为 true。 tz默认None 为策略添加全局时区。参数tz可以是 * None: in this case the datetime displayed by strategies will bein UTC, which has been always the standard behavior* pytz instance. It will be used as such to convert UTC times tothe chosen timezone* string. Instantiating a pytz instance will be attempted.* integer. Use, for the strategy, the same timezone as thecorresponding data in the self.datas iterable (0 woulduse the timezone from data0)cheat_on_open默认False 在调用策略的next_open方法之前将会调用它。这发生在next之前也发生在经纪人有机会评估订单之前。指标尚未重新计算。这允许发出一个订单该订单考虑了前一天的指标但使用open价格进行股份计算。 对于cheat_on_open订单执行还需要调用cerebro.broker.set_coo(True)或使用BackBroker(cooTrue)实例化一个经纪人其中coo代表 cheat-on-open或者将broker_coo参数设置为True。除非在下面禁用否则 Cerebro 将自动执行此操作。 broker_coo默认True 这将自动调用经纪人的set_coo方法并使用True来激活cheat_on_open执行。仅当cheat_on_open也为True时才执行。 quicknotify默认值False 经纪人通知将在下一个价格传递之前立即传递。 对于回测这没有任何影响但对于实时经纪人通知可能会在交付柱形图之前很久就发生了。 当设置为 True 时通知将尽快传递请参阅实时数据源中的 qcheck 设置为 False 以实现兼容性。 可能会更改为 True addstorecb(callback) 添加一个回调来获取将由 notify_store 方法处理的消息 回调函数的签名必须支持以下内容 callback(msg, *args, **kwargs) 实际接收到的 msg、*args 和 **kwargs 取决于实现完全依赖于 数据/经纪人/存储但通常应该期望它们是可打印的以便接收和实验。 notify_store(msg, *args, **kwargs) 在 cerebro 中接收存储通知 此方法可以在 Cerebro 的子类中重写 如果 name 不为 None则将其放入 data._name 中该参数用于装饰/绘图目的。 adddatacb(callback) adddata(data, nameNone) 向获取将由 notify_data 方法处理的消息添加一个回调 callback(data, status, *args, **kwargs) 实际接收到的 *args 和 **kwargs 取决于实现完全依赖于 数据/经纪人/存储但通常应该期望它们是可打印的以便接收和实验。 实际接收到的 msg、*args 和 **kwargs 取决于实现完全依赖于 数据/经纪人/存储但通常应该期望它们是可打印的以便接收和实验。 在 cerebro 中接收数据通知 此方法可以在 Cerebro 的子类中重写 回调函数的签名必须支持以下内容 notify_data(data, status, *args, **kwargs) 向组合中添加一个 Data Feed 实例。 添加一个 callback 来获取将由 notify_store 方法处理的消息 resampledata(dataname, nameNone, **kwargs) 向系统添加一个将由系统重新采样的 Data Feed 如果 name 不为 None则将其放入 data._name 中该参数用于装饰/绘图目的。 任何其他支持重新采样过滤器的 kwargs如 timeframe、compression、todate都将被透明地传递 replaydata(dataname, nameNone, **kwargs) 向系统添加一个将由系统重播的 Data Feed 如果 name 不为 None则将其放入 data._name 中该参数用于装饰/绘图目的。 任何其他支持回放过滤器的 kwargs如 timeframe、compression、todate都将被透明地传递 chaindata(*args, **kwargs) 将几个数据源串联成一个 如果 name 被传递为命名参数且不为 None则将其放入 data._name 中该参数用于装饰/绘图目的。 如果为 None则将使用第 1 个数据的名称 rolloverdata(*args, **kwargs) 将几个数据源链接到一个数据源中 如果将 name 作为命名参数传递并且不为 None则将放入 data._name 中用于装饰/绘图目的。 如果为 None则将使用第 1 个数据的名称 任何其他的 kwargs 将传递给 RollOver 类 addstrategy(strategy, *args, **kwargs) 将 Strategy 类添加到混合中以进行单次运行。实例化将在运行时发生。 args 和 kwargs 将像在实例化期间一样传递给策略。 返回用于引用其他对象如调整器的添加索引 optstrategy(strategy, *args, **kwargs) 将 Strategy 类添加到混合中以进行优化。实例化将在运行时发生。 args 和 kwargs 必须是可迭代的其中包含要检查的值。 示例如果一个策略接受一个参数 period为了优化目的optstrategy 的调用如下所示 cerebro.optstrategy(MyStrategy, period(15, 25)) 这将为值 15 和 25 执行优化。而 cerebro.optstrategy(MyStrategy, periodrange(15, 25)) 将使用 period 值 15 - 25因为 Python 中的范围是半开放的所以不包括 25执行 MyStrategy 如果传递了一个参数但不应该进行优化则调用如下 cerebro.optstrategy(MyStrategy, period(15,)) 请注意period 仍然传递为可迭代对象 … 只有 1 个元素 backtrader 将尝试识别诸如以下情况 cerebro.optstrategy(MyStrategy, period15) 并在可能的情况下创建内部伪可迭代对象 optcallback(cb) 将 callback 添加到将在每个策略运行时调用的回调列表中进行优化 签名cb(strategy) addindicator(indcls, *args, **kwargs) 将 Indicator 类添加到混合中。实例化将在传递的策略的运行时完成 addobserver(obscls, *args, **kwargs) 将 Observer 类添加到混合中。实例化将在运行时完成 addobservermulti(obscls, *args, **kwargs) 将 Observer 类添加到混合中。实例化将在运行时完成 它将每个“数据”系统中添加一次。一个用例是观察单个数据的买入/卖出观察者。 反例是 CashValue它观察系统范围的值 addanalyzer(ancls, *args, **kwargs) 将 Analyzer 类添加到混合中。实例化将在运行时完成 addwriter(wrtcls, *args, **kwargs) 将 Writer 类添加到混合中。实例化将在运行时在 cerebro 中完成 run(**kwargs) 执行回测的核心方法。传递给它的任何 kwargs 都会影响实例化时 Cerebro 的标准参数的值。 如果 cerebro 没有数据则该方法将立即退出。 它具有不同的返回值 对于无优化包含使用 addstrategy 添加的策略类实例的列表 用于优化包含使用addstrategy添加的 Strategy 类实例的列表的列表 runstop() 如果从策略内部或其他任何地方调用包括其他线程执行将尽快停止。 setbroker(broker) 为此策略设置特定的broker实例替换从 cerebro 继承的实例。 getbroker() 返回经纪人实例。 这也可以作为名为broker的property使用 绘图plotterNonenumfigs1iplotTruestartNoneendNonewidth16height9dpi300tightTrueuseNone**kwargs 在 cerebro 内部绘制策略 如果plotter为 None则会创建一个默认的Plot实例并在实例化期间将kwargs传递给它。 numfigs将绘图分成指定数量的图表如果需要可以减少图表密度 iplot如果为True并在notebook中运行则图表将内联显示 use将其设置为所需 matplotlib 后端的名称。它将优先于iplot start策略或datetime.date、datetime.datetime实例的日期时间线数组的索引指示绘图的开始 end策略的日期时间线数组的索引或datetime.date、datetime.datetime实例指示绘图的结束 width保存图形的英寸 height保存图形的英寸 dpi保存图形的每英寸点数的质量 tight仅保存实际内容而不是图形的框架 添加 sizer(sizercls*args**kwargs 添加一个Sizer类和 args它是添加到 cerebro 的任何策略的默认 sizer addsizer_byidx(idxsizercls*args**kwargs 按 idx 添加一个Sizer类。此 idx 是与addstrategy返回的兼容引用。只有由idx引用的策略将接收此大小 add_signal(sigtypesigcls*sigargs**sigkwargs 向系统添加一个信号稍后将其添加到SignalStrategy中。 signal_concurrent(onoff) 如果向系统添加信号并且将concurrent值设置为 True则将允许并发订单 signal_accumulate(onoff) 如果向系统添加信号并且将accumulate值设置为 True则在已经进入市场时进入市场将允许增加头寸 signal_strategy(stratcls*args**kwargs 添加一个可以接受信号的 SignalStrategy 子类 addcalendar(cal) 向系统添加全局交易日历。个别数据源可能具有覆盖全局日历的单独日历 cal可以是TradingCalendar的实例、字符串或pandas_market_calendars的实例。字符串将被实例化为PandasMarketCalendar需要系统中安装pandas_market_calendar模块。 如果传递的是 TradingCalendarBase 的子类而不是实例它将被实例化 addtz(tz) 这也可以通过参数tz完成 为策略添加全局时区。参数tz可以是 None在这种情况下策略显示的日期时间将为 UTC这一直是标准行为 pytz实例。将按此使用它将 UTC 时间转换为所选时区 string。将尝试实例化一个pytz实例。 integer。对于策略使用与self.datas可迭代对象中相应data相同的时区0将使用来自data0的时区 add_timer(when, offsetdatetime.timedelta(0), repeatdatetime.timedelta(0), weekdays[], weekcarryFalse, monthdays[], monthcarryTrue, allowNone, tzdataNone, stratsFalse, cheatFalse, *args, **kwargs) 安排定时器以调用notify_timer 参数 when (-) – 可以是 datetime.time实例见下文tzdata bt.timer.SESSION_START表示会话开始 bt.timer.SESSION_END表示会话结束 必须是datetime.timedelta实例的offset 用于偏移值when。与SESSION_START和SESSION_END结合使用时它具有有意义的用途用于指示诸如在会话开始后15 分钟调用定时器之类的事情。 必须是datetime.timedelta实例的repeat 指示如果在第 1 次调用后后续调用将在同一会话中按计划的repeat增量中安排 一旦定时器超过会话结束它将被重置为when的原始值 weekdays一个排序的可迭代对象其中的整数表示可以实际调用定时器的日期ISO 代码星期一为 1星期日为 7 如果未指定定时器将在所有日期上都处于活动状态。 weekcarry默认值False。如果为True且周几未见例如交易假期则定时器将在下一天执行即使在新的一周中 monthdays一个排序的可迭代对象其中的整数表示定时器必须执行的月份中的哪一天。例如每个月的第15天始终执行 如果未指定定时器将在所有日期上都处于活动状态 monthcarry默认值True。如果当天没有看到周末、交易假期则定时器将在下一个可用日期执行。 allow默认值None。一个回调函数接收一个datetime.date实例并返回True如果该日期允许定时器否则返回False tzdata可以是None默认值一个pytz实例或一个data feed实例。 Nonewhen按面值解释即使它不是 UTC也会处理它 pytz实例when将被解释为时区实例指定的本地时间。 data feed实例when将被解释为数据源实例的tz参数指定的本地时间。 注意 如果when是SESSION_START或SESSION_END且tzdata为None则系统中的第 1 个数据源也称为self.data0将用作查找会话时间的参考。 strats默认值False还会调用策略的notify_timer cheat默认为 False如果为 True则会在经纪人有机会评估订单之前调用计时器。例如在交易会话开始之前可以根据开盘价下订单。 *args: 任何额外的参数都将传递给 notify_timer。 **kwargs: 任何额外的关键字参数都将传递给 notify_timer。 返回值 创建的计时器 notify_timer(timer, when, *args, **kwargs) 接收计时器通知其中 timer 是由 add_timer 返回的计时器when 是调用时间。args 和 kwargs 是传递给 add_timer 的任何额外参数。 实际的 when 时间可能会晚一些但系统可能无法在之前调用计时器。该值是计时器值而不是系统时间。 add_order_history(orders, notifyTrue) 将订单历史记录添加到经纪人中以供性能评估直接执行 orders: 是一个可迭代对象例如列表、元组、迭代器、生成器其中每个元素也将是一个具有以下子元素的可迭代对象有 2 种格式 [datetime, size, price] 或 [datetime, size, price, data] 注意 必须按照日期时间升序排序或生成排序的元素。 其中 datetime 是一个 python date/datetime 实例或者是一个格式为 YYYY-MM-DD[THH:MM:SS[.us]] 的字符串方括号中的元素是可选的。 size 是一个整数买入为正卖出为负 price 是一个浮点数/整数 如果存在 data则可以采用以下任何值 None - 将使用第 1 个数据源作为目标。 integer - 将使用该索引对应的数据在Cerebro中的插入顺序。 string - 该名称的数据例如通过 cerebro.addata(data, namevalue) 分配将作为目标。 notify默认值True 如果设为 True则会通知系统中插入的第 1 个策略其会根据每个订单中的信息创建人工订单。 注意 隐含在描述中的是需要添加一个数据源该数据源是订单的目标。例如分析器需要追踪回报率。 节省内存 www.backtrader.com/docu/memory-savings/memory-savings/ 发布版本 1.3.1.92已经重新设计并完全实现了先前存在的节省内存方案尽管没有受到太多宣传并且使用较少。 backtrader曾经并将继续在内存较大的机器上开发并且与通过绘图提供的视觉反馈是一个必需的美好事物相结合使得设计决策变得容易将所有内容保存在内存中。 这个决定有一些缺点 用于数据存储的array.array在超过某些限制时必须分配和移动数据。 RAM 较少的机器可能会受到影响。 连接到可以在线运行数周/数月、提供数千秒/分钟分辨率 ticks 的实时数据源 后者比第一点更加重要因为另一个设计决定是为了 backtrader 必须是纯 Python以便在需要时在嵌入式系统中运行。 将来的一个场景可能是 backtrader 连接到第二台机器该机器提供实时数据源而 backtrader 本身运行在类似 Raspberry Pi 或甚至更有限的设备上如 ADSL 路由器AVM Frit!Box 7490带有 Freetz 映像 因此需要 backtrader 支持动态内存方案。现在 Cerebro 可以使用以下语义进行实例化或run exactbars默认值False 默认值为False每个存储在一行中的值都会保存在内存中。 可能的值 True或1所有“lines”对象将内存使用量减少到自动计算的最小周期。 如果简单移动平均值的周期为 30底层数据将始终具有 30 个条形图的运行缓冲区以允许计算简单移动平均值 此设置将停用preload和runonce。 使用此设置还会停用plotting。 -1在策略级别数据和指标/操作将保留所有数据在内存中。 例如RSI在内部使用指标UpDay进行计算。此子指标将不会将所有数据保存在内存中。 这允许保持plotting和preloading处于活动状态。 runonce将被停用。 -2作为策略属性保留的数据和指标将在内存中保存所有数据。 例如RSI在内部使用指标UpDay进行计算。此子指标将不会将所有数据保存在内存中。 如果在__init__中定义了类似 a self.data.close - self.data.high 这样的内容则a将不会将所有数据保存在内存中。 这允许保持plotting和preloading处于活动状态。 runonce将被停用。 一如既往一个例子胜过千言万语。一个示例脚本显示了差异。它针对 1996 年至 2015 年的 Yahoo 每日数据运行总共 4965 天。 注意 这只是一个小样本。每天交易 14 小时的 EuroStoxx50 期货在仅 1 个月的交易中将产生大约 18000 个 1 分钟的 K 线。 执行脚本 1^(st)以查看在不请求内存节省时使用了多少内存位置 $ ./memory-savings.py --save 0 Total memory cells used: 506430对于 1 级总储蓄 $ ./memory-savings.py --save 1 Total memory cells used: 2041天啊从五十万跌至2041。确实。系统中的每个lines对象都使用collections.deque作为缓冲区而不是array.array并且长度被限制在绝对需要的最小值以进行请求的操作。例如 在数据源上使用期间为30的SimpleMovingAverage策略。 在这种情况下将进行以下调整 数据源将具有30个位置的缓冲区这是SimpleMovingAverage产生下一个值所需的数量 SimpleMovingAverage将有一个1位置的缓冲区因为除非其他指标需要这些指标将依赖于移动平均线否则不需要保留较大的缓冲区。 注意 这种模式最吸引人且可能最重要的功能是所使用的内存量在脚本的整个生命周期内保持不变。 无论数据源的大小如何。 如果例如连接到长时间的实时数据源则这将非常有用。 但请注意 绘图不可用 还有其他的内存消耗来源随着时间的推移会积累比如策略生成的orders。 此模式只能在cerebro中的runonceFalse时使用。对于实时数据源这也是强制性的但在简单回测的情况下这比runonceTrue慢。 肯定有一个权衡点从而内存管理比逐步执行回测更昂贵但这只能由平台的最终用户在每个案例中进行判断。 现在是负级别。这些级别旨在在仍然节省相当数量的内存的同时保持绘图可用。第一级别-1 $ ./memory-savings.py --save -1 Total memory cells used: 184623在这种情况下指标的第 1 级别在策略中声明的那些保持其完整长度的缓冲区。但是如果这些指标依赖于其他指标这就是情况则子对象将被长度限制。在这种情况下我们已经从 506430个内存位置到- 184623 超过 50%的节省。 注意 当然array.array对象已被collections.deque所取代这在内存方面更昂贵尽管在操作方面更快。但是collections.deque对象相当小并且节省了大致计算的内存位置的使用。 现在是级别-2这也是为了节省在策略级别上声明的指标的内存这些指标已被标记为不需要绘制 $ ./memory-savings.py --save -2 Total memory cells used: 174695现在没有保存太多。这是因为一个单独的指标已被标记为不需要绘制TestInd().plotinfo.plot False 让我们看看来自最后一个示例的绘图 $ ./memory-savings.py --save -2 --plot Total memory cells used: 174695对于感兴趣的读者示例脚本可以生成对指标层次结构中遍历的每个行对象的详细分析。运行时启用绘图保存在-1 $ ./memory-savings.py --save -1 --lendetails -- Evaluating Datas ---- Data 0 Total Cells 34755 - Cells per Line 4965 -- Evaluating Indicators ---- Indicator 1.0 Average Total Cells 30 - Cells per line 30 ---- SubIndicators Total Cells 1 ---- Indicator 1.1 _LineDelay Total Cells 1 - Cells per line 1 ---- SubIndicators Total Cells 1 ... ---- Indicator 0.5 TestInd Total Cells 9930 - Cells per line 4965 ---- SubIndicators Total Cells 0 -- Evaluating Observers ---- Observer 0 Total Cells 9930 - Cells per Line 4965 ---- Observer 1 Total Cells 9930 - Cells per Line 4965 ---- Observer 2 Total Cells 9930 - Cells per Line 4965 Total memory cells used: 184623同样的但启用了最大节省1 $ ./memory-savings.py --save 1 --lendetails -- Evaluating Datas ---- Data 0 Total Cells 266 - Cells per Line 38 -- Evaluating Indicators ---- Indicator 1.0 Average Total Cells 30 - Cells per line 30 ---- SubIndicators Total Cells 1 ... ---- Indicator 0.5 TestInd Total Cells 2 - Cells per line 1 ---- SubIndicators Total Cells 0 -- Evaluating Observers ---- Observer 0 Total Cells 2 - Cells per Line 1 ---- Observer 1 Total Cells 2 - Cells per Line 1 ---- Observer 2 Total Cells 2 - Cells per Line 1第二个输出立即显示了数据源中的行数被限制为38个内存位置而不是完整数据源长度4965。 并且指标和观察者在可能的情况下被限制为1如输出的最后几行所示。 脚本代码和用法 在backtrader的源代码中可作为示例使用。用法 $ ./memory-savings.py --help usage: memory-savings.py [-h] [--data DATA] [--save SAVE] [--datalines][--lendetails] [--plot]Check Memory Savingsoptional arguments:-h, --help show this help message and exit--data DATA Data to be read in (default: ../../datas/yhoo-1996-2015.txt)--save SAVE Memory saving level [1, 0, -1, -2] (default: 0)--datalines Print data lines (default: False)--lendetails Print individual items memory usage (default: False)--plot Plot the result (default: False)代码 from __future__ import (absolute_import, division, print_function,unicode_literals)import argparse import sysimport backtrader as bt import backtrader.feeds as btfeeds import backtrader.indicators as btind import backtrader.utils.flushfileclass TestInd(bt.Indicator):lines (a, b)def __init__(self):self.lines.a b self.data.close - self.data.highself.lines.b btind.SMA(b, period20)class St(bt.Strategy):params ((datalines, False),(lendetails, False),)def __init__(self):btind.SMA()btind.Stochastic()btind.RSI()btind.MACD()btind.CCI()TestInd().plotinfo.plot Falsedef next(self):if self.p.datalines:txt ,.join([%04d % len(self),%04d % len(self.data0),self.data.datetime.date(0).isoformat()])print(txt)def loglendetails(self, msg):if self.p.lendetails:print(msg)def stop(self):super(St, self).stop()tlen 0self.loglendetails(-- Evaluating Datas)for i, data in enumerate(self.datas):tdata 0for line in data.lines:tdata len(line.array)tline len(line.array)tlen tdatalogtxt ---- Data {} Total Cells {} - Cells per Line {}self.loglendetails(logtxt.format(i, tdata, tline))self.loglendetails(-- Evaluating Indicators)for i, ind in enumerate(self.getindicators()):tlen self.rindicator(ind, i, 0)self.loglendetails(-- Evaluating Observers)for i, obs in enumerate(self.getobservers()):tobs 0for line in obs.lines:tobs len(line.array)tline len(line.array)tlen tdatalogtxt ---- Observer {} Total Cells {} - Cells per Line {}self.loglendetails(logtxt.format(i, tobs, tline))print(Total memory cells used: {}.format(tlen))def rindicator(self, ind, i, deep):tind 0for line in ind.lines:tind len(line.array)tline len(line.array)thisind tindtsub 0for j, sind in enumerate(ind.getindicators()):tsub self.rindicator(sind, j, deep 1)iname ind.__class__.__name__.split(.)[-1]logtxt ---- Indicator {}.{} {} Total Cells {} - Cells per line {}self.loglendetails(logtxt.format(deep, i, iname, tind, tline))logtxt ---- SubIndicators Total Cells {}self.loglendetails(logtxt.format(deep, i, iname, tsub))return tind tsubdef runstrat():args parse_args()cerebro bt.Cerebro()data btfeeds.YahooFinanceCSVData(datanameargs.data)cerebro.adddata(data)cerebro.addstrategy(St, datalinesargs.datalines, lendetailsargs.lendetails)cerebro.run(runonceFalse, exactbarsargs.save)if args.plot:cerebro.plot(stylebar)def parse_args():parser argparse.ArgumentParser(formatter_classargparse.ArgumentDefaultsHelpFormatter,descriptionCheck Memory Savings)parser.add_argument(--data, requiredFalse,default../../datas/yhoo-1996-2015.txt,helpData to be read in)parser.add_argument(--save, requiredFalse, typeint, default0,help(Memory saving level [1, 0, -1, -2]))parser.add_argument(--datalines, requiredFalse, actionstore_true,help(Print data lines))parser.add_argument(--lendetails, requiredFalse, actionstore_true,help(Print individual items memory usage))parser.add_argument(--plot, requiredFalse, actionstore_true,help(Plot the result))return parser.parse_args()if __name__ __main__:runstrat()

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

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

相关文章

一个公司多个网站做优化十大外贸电商平台

1. 题目 给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续、非空)子数组的数目。 示例: 输入:A [4,5,0,-2,-3,1], K 5 输出:7 解释: 有 7 个子数组满足其元素之和可被 K 5 整除&…

新浪云服务器做网站做阿里巴巴网站费用

引言 最近在阅读鸣嵩的一篇文章,数据库的下一场革命:S3 延迟已降至原先的 10%,云数据库架构该进化了 收获很多,过去时间也基于对象存储做过一些功能实现,特记录下。关于鸣嵩: 曹伟,花名鸣嵩&am…

网页代理网站百度收录效果好的网站

在命令行模式(CMD)下执行时,想获得执行参数,用以下变量: ParamCount:参数个数 ParamStr:为参数数组 如果想在执行完一个操作后在命令行作出相应提示,就应该在相应位置放入…

社区门户网站建设招标公告wordpress apk

在当今数据驱动的世界中,组织在保护存储在数据库中的机密数据并确保其完整性方面面临着越来越多的挑战。数据库审计通过提供全面的数据库活动监控方法,在应对这些挑战方面发挥着至关重要的作用。 数据库活动监控(Database Activity Monitori…

中国建设银行信用卡积分兑换网站自媒体图片素材网站

统一基金会,服务开发人员,推动开放 Web 技术发展jQuery 基金会和 Dojo 基金会今天宣布计划联合,旨在建立最大,最多样化和最全面的基金会,通过服务开发者,他们的项目,他们的社区来构建开放的 Web…

百度账号设置温州百度网站快速优化

基本概念 概述 支持动态更新防火墙规则 不重启即可创建、修改和删除规则 使用区域和服务来简化防火墙配置 区域 一组预定义的规则,防火墙策略集合(或策略模板) 把网络分配到不同的区域中,并为网络及其关联的网络接口或流量源…

淄博企业网站建设公司企业网站建设模版

每个区段与 superblock 的信息都可以使用 dumpe2fs 这个指令来查询的! 不过可惜的是,我们的 CentOS 7 现在是以 xfs 为默认文件系统, 所以目前你的系统应该无法使用 dumpe2fs 去查询任何文件系统的。 因为目前两个版本系统的根目录使用的文…

个人网站用什么域名好网站asp代码

首先在微信公众平台(网址:https://mp.weixin.qq.com)申请一个订阅号,然后在开发里找到开发者工具点击公众平台测试账号,在测试账号内进行微信开发实验。 1. 设置一个自己的有效的域名网址和TOKEN(就是暗号),TOKEN一定要与PHP代…

asp access网站架设教程桂林企业建站

在之前的练习作业中,我们改造了余额支付功能,在支付成功后利用RabbitMQ通知交易服务,更新业务订单状态为已支付。 但是大家思考一下,如果这里MQ通知失败,支付服务中支付流水显示支付成功,而交易服务中的订…

不同类型网站比较及网站域名设计微信开发社区平台

Java基础面试题 Java的特点 Java 与 C 的区别 JDK/JRE/JVM三者的关系 Java程序是编译执行还是解释执行? 面向对象和面向过程的区别? 面向对象有哪些特性? 数组到底是不是对象? Java的基本数据类型有哪些? 为什么不能用…

做微景观的网站百度快速排名

打开电脑的系统偏好设置 → 键盘 → 文本,如下图所示:

开源html5 网站模板个人养老保险可以补交吗

目录 前言 一、现场还原 二、问题诊断 三、问题原因 总结 前言 最近由于项目需要,在服务器上需要搭建Hbase完全分布式集群环境。开发环境,采用的是最小节点的方式进行搭建(即3个节点的模式)。资源环境列表如下: 序号…

网站建设对电子商务的意义天猫网站左侧导航是怎么做的

后台返回的时间字符串不是标准的时间而是计算机时间的时候,我们需要将它们转换为标准时间,再进行转换。 //字符串转为时间,时间格式自己定 NSString * time "1501776000"; //时间字符串 NSInteger num [time integerValue]; …

一个网站建设流程濮阳市建站公司

目录 do...while()循环 do语句的语法 do语句的特点 do while循环中的break和continue 练习 goto语句 do...while()循环 do语句的语法 do 循环语句; while(表达式); do语句的特点 循环至少执行一次,使用的场景有限,所以不是经常使用。 #inc…

网站关键词没排名怎么办制作网页的基本代码

保存token的最佳方式取决于具体的应用场景和需求。以下是几种常见的保存token的方式及其优缺点,以便您根据实际情况进行选择: HTTP Only Cookies: 优点:Cookies可以自动随HTTP请求发送,且HTTP Only属性可以防止JavaS…

网站在线预约模板网站建设初学

前面2张是电阻阻值表(E-96/0603/1%) 常见贴片电容的容值表

响应式门户网站模板专业论坛网站有哪些

一、MyBatis是什么? MyBatis 是一款开源的、轻量级的对象关系映射(ORM)框架,用于Java应用中的数据库持久层操作。它简化了与数据库之间的交互,让开发者可以更专注于编写SQL语句和关注业务逻辑,而不需要处理…

网站建设适合女生吗注册一家公司需要多少钱

关于 PIONIX: PIONIX 成立于 2021 年,总部位于德国巴特申博恩,已迅速成为该领域的推动者。PIONIX 牵头开发了 Linux 基金会能源项目 EVERest——一个尖端、免费、开源的充电站软件堆栈。值得注意的是,OCPP 是该计划的重要组成部分…

建设网站细节wordpress 英文链接

本专题主要介绍在求序列的经典问题上dp的应用。 我们上次用前缀和来解决,这次让我们用dp解决把 我们参考不下降子序列的思路,可以令f[i]为以i结尾的最大字段和,易得: f[i]max(a[i],a[i]f[i-1]); 下面是AC代码: #in…

想搭网站做软件首先要学设么网站建设毕业答辩ppt怎么写

使用 OpenAI 自定义 API 提高电商平台的推荐精度 一、引言 随着人工智能技术的不断发展,推荐系统在电商领域的应用越来越广泛。电商平台通过推荐系统向用户提供个性化的商品推荐,从而提高用户满意度和转化率。OpenAI 提供了自定义 API,使得…