Heerozh / spectre

GPU-accelerated Factors analysis library and Backtester
GNU General Public License v3.0
627 stars 108 forks source link

universe池生成的位置疑问。 #20

Closed quant2008 closed 9 months ago

quant2008 commented 9 months ago

您好,以下例子中,股池universe 生成是放在初始化方法中一次性生成的。这个能达到每天迭代时,当日股池动态变化的效果吗?在zipline中,股池是在pipeline中,然后再每日before_trading中触法重新计算,相当于每日重新生成股池。不知spectre的处理方案是否同样效果?

from spectre import factors, trading
from spectre.data import ArrowLoader
import pandas as pd, math

class MyAlg(trading.CustomAlgorithm):
    def initialize(self):
        # your factors
        risk_free_rate = 0.04 / 252
        excess_logret = factors.LogReturns() - math.log(1 + risk_free_rate)
        universe = factors.AverageDollarVolume(win=120).top(100)

        # Barra MOMENTUM Risk Factor
        ema126 = factors.EMA(half_life=126, inputs=[excess_logret])
        rstr = ema126.shift(11).sum(252)
        MOMENTUM = rstr.zscore(mask=universe)

        # Barra Volatility Risk Factor
        ema42 = factors.EMA(half_life=42, inputs=[excess_logret])
        dastd = factors.STDDEV(252, inputs=[ema42])
        VOLATILITY = dastd.zscore(mask=universe)

        # setup engine
        engine = self.get_factor_engine()
        engine.to_cuda()
        engine.set_filter( universe )
        engine.add( (MOMENTUM + VOLATILITY).to_weight(), 'alpha_weight' )

        # schedule rebalance before market close
        self.schedule_rebalance(trading.event.MarketClose(self.rebalance, offset_ns=-10000))

        # simulation parameters
        self.blotter.capital_base = 1000000
        self.blotter.set_commission(percentage=0, per_share=0.005, minimum=1)
        # self.blotter.set_slippage(percentage=0, per_share=0.4)

    def rebalance(self, data: 'pd.DataFrame', history: 'pd.DataFrame'):
        data = data.fillna(0)
        self.blotter.batch_order_target_percent(data.index, data.alpha_weight)

        # closing asset position that are no longer in our universe.
        removes = self.blotter.portfolio.positions.keys() - set(data.index)
        self.blotter.batch_order_target_percent(removes, [0] * len(removes))

        # record data for debugging / plotting
        self.record(aapl_weight=data.loc['AAPL', 'alpha_weight'],
                    aapl_price=self.blotter.get_price('AAPL'))

    def terminate(self, records: 'pd.DataFrame'):
        # plotting results
        self.plot(benchmark='SPY')

        # plotting the relationship between AAPL price and weight
        ax1 = records.aapl_price.plot()
        ax2 = ax1.twinx()
        records.aapl_weight.plot(ax=ax2, style='g-')

loader = ArrowLoader('./prices/yahoo/yahoo.feather')
%time results = trading.run_backtest(loader, MyAlg, '2014-01-01', '2019-01-01')
Heerozh commented 9 months ago

这个不是zipline,并不是对标的,只是看上去像,概念完全不同

quant2008 commented 9 months ago

可以理解为,你的程序每天股池也是当天市值前100的吗?也就是也是动态的吗? 如果是这样,我觉得你这个程序太棒了。

Heerozh commented 9 months ago

对,但不是你理解的那样,你试一下就知道啦