量化回测框架

Posted on 2016-11-10 in Quant

让我们来设计一个真实的量化回测框架(开源框架-XQuant),由需求驱动,从简单到复杂,采用python开发。

回测框架大致分为两种:for-loop(轮询)和event-driven(事件驱动),前者进行向量化计算,速度更快,但不符合实盘交易的流程,后者采用逐个bar/tick读取数据,并产生交易信号的方式,利于统一回测和实盘的代码,部分解决“回测易、实盘难”的困境。虽然某些商业平台提供这样的回测框架,但速度往往很慢,底层架构也不透明,所以我自己在构建一整套回测体系。

主要特性

Version 0.2: 完整的事件驱动引擎和回测调度器,亚ms级处理速度 (2016年9月)

Version 0.3: 回测结果分析和策略评估、可视化、参数优化器等功能 (2016年10月)

Version 0.4: 支持股票和期货的滑点、手续费模型,logging功能 (2016年11月)

Version 0.5:回测结束强制平仓;可选回测区间;分品种交易记录 (2016年12月)

TODO:

Version 0.*: 模拟交易功能

Version 0.*: Web GUI可视化

Version 1.0: 支持实盘交易

策略示例

简单的移动双均线策略(Moving Average Cross Strategy)例子如下:

class MovingAverageCrossStrategy(Strategy):
"""
移动双均线策略
"""
    def __init__(self, bars, events, long_window=10, short_window=5):
        """
        初始化移动平均线策略
        """
        self.bars = bars
        self.symbol_list = self.bars.symbol_list
        self.events = events
        self.long_window = long_window
        self.short_window = short_window
        self.bought = {s: False for s in self.symbol_list}

    def calculate_signals(self, event):
        """
        当短期均线(如5日线)上穿长期均线(如10日线),买入;反之,卖出
        """
        if event.type == 'BAR':
            for s in self.symbol_list:
                bars = self.bars.get_latest_bars(s, N=self.long_window)
                if bars is not None and bars != [] and len(bars) >= self.long_window:
                    cols = ['symbol','datetime','open','high','low','close','volume']
                    df = pd.DataFrame(bars, columns=cols)
                    df['MA_long'] = df['close'].rolling(self.long_window).mean()
                    df['MA_short'] = df['close'].rolling(self.short_window).mean()
                    if df['MA_long'].iloc[-1] < df['MA_short'].iloc[-1] and \
                                    df['MA_long'].iloc[-2] > df['MA_short'].iloc[-2]:
                        if not self.bought[s]:
                            signal = SignalEvent(bars[-1][0],bars[-1][1], 'LONG')
                            self.events.put(signal)
                            self.bought[s] = True
                    elif df['MA_long'].iloc[-1] < df['MA_short'].iloc[-1] and \
                                    df['MA_long'].iloc[-2] < df['MA_short'].iloc[-2]:
                        if self.bought[s]:
                            signal = SignalEvent(bars[-1][0], bars[-1][1], 'EXIT')
                            self.events.put(signal)
                            self.bought[s] = False

完整的例子参考github·XQuant/demo中ma_cross_strategy.py文件。

可视化功能

XQuant自带可视化模块(基于matplotlib),某CTA策略回测结果的可视化:

XQuant可视化

更加强大而弹性的量化投资可视化库也在筹备和初期开发中,其将与XQuant无缝结合,期待ing~ :)

免责声明:仅供个人研究使用,不构成投资建议。如果感兴趣,欢迎联系我!