AI量化框架:我们为何要重新造轮子?

01 为何要造轮子

星球群里,今天大家在讨论一个问题:这么多量化框架和平台,为何还要自己造一个轮子,应该把精力放在选股、择时、因子、策略等等才对呀?

这个讨论很有意思。其实我也不断告诉我自己,不能陷入工程师思维,为造轮子而造轮子。仔细回想起来,从pyalgotrade,backtrader, pybroker,还有AI量化的qlib我都深度用过,写过策略,而且呢,还细细读过它们的代码。另外平台型的产品如聚宽,bigquant等都尝试过策略。

第三方平台好处是数据全,不用自己找数据,缺点就是慢。对于我们要不断尝试策略,优化因子的过程,这个速度是非常重要的。且不说如果你真要实盘的策略,放在第三方平台是肯定不放心的; 还有一点就是你若想到了平台未实现的功能,那要扩展起来就几乎不可能了。

再说开源框架,有几个成熟的框架着实不错,各有各的优点。

但是仍然无法完全满足我的诉求,因此,我决定取它们所有人的精华,自己整合一个。毕竟AI量化是一辈子的事业,所以“磨刀不误砍柴功”。

希望我们的框架做到几个点:

1、一定要快,可以缓存数据、因子、模型,回测结果等,并行计算,向量化加速等。

2、支持传统量化。——这一点qlib就不满足。

3、兼容机器学习量化,支持WFA前向滚动式训练回测。——只有qlib满足,pyBroker有一点,但它是一个symbol一个model,不符合诉求。支持调参,因子扩展等。

4、环境可以扩展支持强化学习。——目前也只有qlib支持。或者像tensortrade,finRL-meta这样的专用框架。

5、支持“积木式”快速策略开发。

所以,有点像 pybroker+qlib+bt(支持积木式)

02 数据加载

传统回测平台,基础数据与指标是分开的,比如backtrader和pybroker。但这在机器学习里就非常麻烦了,机器学习随便就搞上百个因子,这要用indicator,那就太麻烦了,这里我们会参考qlib的dataset加载数据,自动计算因子,以及自动标注数据—— 为里我们实现了自己的因子表达式计算引擎。

一堆因子自动计算与数据标注自动完成,传统量化框架需要一个个添加indicator,这对于机器学习而言,太麻烦,不好维护。

图片

03 架构设计

Portfolio有点类似我之前的Account的定位,但叫Portfolio更加合适,说白了包括了cash和投资组合。做多:buy/sell, 做空:short/cover。好在我们不是做通过框架,当前市场我们不需要做空,先可以不支持。止损单先期都可以不支持。

ExecContext是执行上下文,有Portfolio的实例引用,有curr_bar=传统量化需要用当天的curr_ba_df, curr_df=当天及之前所有的bar,这个风险平价计算权重时需要用,或者滚动机器学习时需要用。

ExecContext产生交易信号,所有都产生完成后,统计执行订单。这里写策略就不必关心下单顺序,比如“先卖后买”。

之前我的简化模型,不太心收盘价,只关心收益率,这样做非常简单。但就没有办法计算某一个trade,成本是多少,持仓多久,交易胜率之类的,因此,这里把pybroker里的逻辑学习过来,也不复杂。

# 当日收盘合,要根据se_bar更新一次及市值,再进行交易——次日开盘交易(这里有滑点)。
def update_bar(self, date: np.datetime64, se_bar: pd.Series):

    # 当前的cash部分
    total_equity = self.cash
    total_market_value = total_equity
    total_margin = 0.0

    for s, pos in self.long_positions.items():
        close = None
        # 这里不同市场,比如海外市场,可能不存在的,不存在变化率就是0.0, 即不变
        if s in se_bar.index:
            close = se_bar[s]

        if close:
            pos.equity = pos.shares * close
            pos.market_value = pos.equity
            pos.close = close
            pos.pnl = _calculate_pnl(close, pos.entries, "long")
        total_equity += pos.equity
        total_market_value += pos.equity

    self.equity = total_equity
    self.market_value = total_market_value
    self.margin = total_margin

    bar = PortfolioBar(
        date=date,
        cash=self.cash,
        equity=self.equity,
        market_value=self.market_value,
        margin=self.margin,
        pnl=self.market_value - self._initial_market_value,
        # fees=self.fees,
    )
    self.bars.append(bar)

交易环境上下文,不像pyBroker分成多个context,直接一个context,传入当前可获得的所有数据:

像线上回测平台那个order_target_percent这种好用的函数,是一定要实现的:

import numpy as np

from quant.portfolio import Portfolio
import numpy as np
import pandas as pd


class ExecContext:
    def __init__(self,
                 date: np.datetime64,
                 portfolio: Portfolio,
                 bar_df: pd.Series,
                 hist_df: pd.DataFrame
                 ):
        self.date = date
        self.portfolio = portfolio
        self.bar_df = bar_df
        self.hist_df = hist_df

    def _get_symbol_price(self, symbol):
        price = self.bar_df.loc[symbol]['close']
        return price

    def _calc_target_shares(self, symbol, target_percent) -> float:
        cash = self.portfolio.cash
        price = self._get_symbol_price(symbol)
        shares = int(cash / price)
        return shares

    def order_target_percent(self, symbol, target_percent):
        target_shares = self._calc_target_shares(symbol, target_percent)
        if symbol in self.portfolio.long_positions.keys():
            shares = self.portfolio.long_positions[symbol].shares
            if target_shares > shares:
                self.portfolio.buy(self.date, symbol, target_shares-shares
                                   , self._get_symbol_price(symbol))
            else:
                self.portfolio.sell(self.date, symbol, shares - target_shares
                                    , self._get_symbol_price(symbol))

        else:
            self.portfolio.buy(self.date, symbol, target_shares, self._get_symbol_price(symbol))

周末基本把框架刷了一下,写一个量化框架其实并不难,主要是为了研究因子与策略要顺手。

发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/104118
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!

(0)
股市刺客的头像股市刺客
上一篇 2024 年 7 月 29 日
下一篇 2024 年 7 月 29 日

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注