quantopian系列—Algorithm( 四 )


Pipeline是在一个特殊的计算窗口中计算的 , 其结果被缓存 , pipeline_output()只是简单地读取Pipeline的结果 , 这是一个快速的操作 , 所以它是一个计算成本低廉的操作 。
你可以在同一个算法中使用多个Pipeline 。 要做到这一点 , 你可以在一个算法中定义多个Pipeline , 并将每个Pipeline附加在不同的名称下 。
后期处理计算
有时 , 在使用Pipeline输出为交易决策提供信息之前 , 您可能希望对Pipeline输出进行操作或转换 。 例如 , 你可能有一个自定义的计算 , 而这个计算不能很容易地表示为Pipeline的自定义因子 。 在这种情况下 , 你应该使用before_trading_start()将计算定义为Pipeline输出的后处理步骤 。
before_trading_start()是一个可选的方法 , 每天被调用一次 , 在市场开盘前 , 但在当天的Pipeline计算完毕后 。before_trading_start()是一个通用函数 , 有5分钟的时间限制 。 它是执行每天一次计算的好地方 , 比如对Pipeline输出进行后处理步骤 。
像预定函数一样 , before_trading_start()接受两个参数:Context和数据 。 这些参数分别对应AlgorithmContext和BarData的实例 。

  • BarData查询
除了通过Pipeline访问每日数据外 , 您还可以在算法中访问分钟级的定价和交易量数据 。 分钟级定价和交易量数据在Pipeline中不可用 , 但可以通过BarData方法检索 。
任何通过 schedule_function()调度的函数都必须定义接受两个参数:Context和data 。 数据参数提供了一个BarData的实例 , 它有几个方法可以用来检索分钟频率定价和交易量数据 。 这意味着你可以在任何预定函数中使用BarData方法 。
一般来说 , 计算应该尽可能地在Pipeline中进行(这要快得多) 。 然而 , BarData提供的方法允许你访问在Pipeline中无法获得的微小频率数据 。 通过BarData方法 , 您可以
  1. 获取当前分钟内任何资产的开盘/最高/最低/收盘/成交量(OHLCV)值 。
  2. 获取任何资产的OHLCV值的历史窗口 。
  3. 检查某项资产的最后已知价格数据是否过时 。
提供给预定函数的BarData实例知道您的算法的模拟时间/日期 , 并使用该时间进行内部计算 。
BarData上的所有方法都接受一个Asset或Asset对象的列表 , 价格取值方法也接受一个OHLCV(open、high、low、close、volume)字段或OHLCV字段的列表 。 你的算法可以通过传递多个资产或多个字段来批量查询 , 这样Quantopian就能更快地将这些数据传递给你的算法 。
如果您请求的分钟数据历史记录超过了一天的开始时间(通常是9:31AM) , 那么history()函数将从前一天结束后获取剩余的分钟条 。 例如 , 如果您在股票日历的上午10:00要求60分钟的价格数据 , 那么前30个价格将是前一个交易日结束后的价格 , 接下来的30个将是当前上午的价格 。
Quantopian的价格数据是从2002年1月2日开始的 。 任何在该日期之前延伸的价格数据调用都会引起异常 。
再平衡一旦你有了算法的Pipeline输出 , 下一步就是构建一个投资组合 。 在算法开发的这一步 , 你将使用你算法的Pipeline输出来定义一个投资组合优化问题 , 并构建你的投资组合 。
这在你的算法中应该放在哪里?你的算法的投资组合构建逻辑应该在一个定期函数中执行 。 这允许你控制你的策略的再平衡频率 。
  • 下订单
在你的算法中 , 最好的下单方式是Optimize 。 Optimize允许你通过定义一个投资组合优化问题 , 将你的投资组合从一个状态移动到另一个状态 。 要使用Optimize构建一个投资组合 , 需要定义一个目标、一组约束条件 , 并将它们都传递给order_optimal_portfolio() 。
手动下订单
除了使用order_optimal_portfolio()下单外 , 算法还可以使用API参考中列出的函数进行手动下单 , 其中最受欢迎的是order_target_percent() 。
如果你要使用手动下单 , 你应该知道订单的两个重要特性 。 首先 , 所有未结订单在交易日结束时都会被取消 。 如果您想在下一个交易日尝试填补被取消的订单 , 您将不得不为剩余的金额手动打开一个新的订单 。 其次 , 您可以花费的现金数量没有限制 。 即使一个订单会让你变成负现金 , 回测器也不会阻止你 。 这取决于算法是否确保它的订单量不会超过它所持有的现金量(假设这是期望的行为) 。 这种类型的控制最好使用投资组合object来完成 , 如下所述:
  • 投资组合对象
你的投资组合代表了你目前持有的所有资产 。 每个算法正好有一个投资组合 。 你可以通过context.portfolio来访问你算法中的Portfolio对象 。 请注意 , Portfolio有很多属性 , 你可以用这些属性来获取你的算法的投资组合的当前状态的信息 。