Quant Buffet放轻松,别过度思虑

原油的开盘区间突破策略

登录后收藏

学术论文

策略概要

投资范围包括美国原油期货。该策略使用两个阈值来开立头寸:当价格上涨超过开盘价的1.6524%时,开立多头头寸;当价格下跌低于-1.5784%时,开立空头头寸。这些阈值是根据历史时期每日平均回报的均值和标准差计算得出的,使用正态分布设置突破这些水平的5%概率。阈值每日重新计算,头寸在每个交易日结束时以收盘价平仓。

II. 策略合理性

ORB过滤器策略依赖于动量,即资产价格上涨往往会继续上涨,下跌的价格会继续下跌。它也可以用收缩-扩张(C-E)原则来解释,该原则指出市场在温和和大幅价格波动时期之间交替。ORB策略识别并利用扩张日。该研究考察了2001年至2011年期间,在此期间相对较高的波动性可能有助于该策略的盈利能力。这一时间框架有助于解释该策略在这些年间由于有利的市场条件而取得的成功。

回测表现

索提诺比率-0.108
胜率45%

完整 Python 代码

import numpy as np
from AlgorithmImports import *
class OpeningRangeBreakoutCrudeOil(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2010, 1, 1)
self.SetCash(100000)
self.period:int = 21
self.treshhold_value:int = 2
self.future:Future = self.AddFuture(Futures.Energies.CrudeOilWTI, \
                    Resolution.Minute, \
                    dataNormalizationMode=DataNormalizationMode.BackwardsRatio, \
                    contractDepthOffset=0)
self.symbol:Symbol = self.future.Symbol
self.daily_ret:RollingWindow = RollingWindow[float](self.period)

self.recent_open:float = 0

self.day_close_flag:bool = False
self.day_open_flag:bool = False
self.market:Symbol = self.AddEquity('SPY', Resolution.Daily).Symbol
self.Schedule.On(self.DateRules.EveryDay(self.market), self.TimeRules.BeforeMarketClose(self.market, 1), self.DayClose)
self.Schedule.On(self.DateRules.EveryDay(self.market), self.TimeRules.AfterMarketOpen(self.market, 1), self.DayOpen)

def OnData(self, data: Slice) -> None:
# close
if self.day_close_flag:
    self.day_close_flag = False
    self.Liquidate()
    if self.symbol in data and data[self.symbol]:
        close:float = data[self.symbol].Close
        if close != 0 and self.recent_open != 0 and close != self.recent_open:
            todays_ret:float = close / self.recent_open - 1
            self.daily_ret.Add(todays_ret)
            if self.daily_ret.IsReady:
                daily_returns:List[float] = list(self.daily_ret)
                mean:float = np.mean(daily_returns)
                std:float = np.std(daily_returns)
        
                high_threshhold:float = mean + self.treshhold_value * std
                low_threshhold:float = mean - self.treshhold_value * std
                
                if todays_ret > high_threshhold:
                    if not self.Portfolio.Invested:
                        self.MarketOrder(self.future.Mapped, 1)
                elif todays_ret < low_threshhold:
                    if not self.Portfolio.Invested:
                        self.MarketOrder(self.future.Mapped, -1)
    
    self.recent_open = 0

# open
if self.day_open_flag:
    self.day_open_flag = False
    if self.symbol in data and data[self.symbol]:
        self.recent_open = data[self.symbol].Open
def DayClose(self) -> None:
self.day_close_flag = True

def DayOpen(self) -> None:
self.day_open_flag = True