输入/搜索内容
1
关注
183
关注者
如何从学术论文中获取策略灵感:隔夜反转策略实现
交流分享
创建于 2024-11-14 16:25:50  更新于 2024-11-19 13:22:04
 0
 1227

img

引言

在金融市场的复杂世界中,投资者和交易者不断寻找能够提供优势的策略。学术论文,尤其是那些深入探讨市场行为和策略表现的研究,可以成为这些策略灵感的丰富源泉。本文将聚焦于一种特定的交易策略——隔夜反转策略(overnight-intraday reversal strategy,简称CO-OC),这是一种基于证券隔夜回报率来预测其日内表现的策略。我们将探讨这种策略的原理、合理性、适用场景以及基本逻辑,以展示如何从学术研究中提炼出实际可行的交易策略。

img

策略原理

隔夜反转策略的核心在于捕捉隔夜(闭市到开市)回报率与随后日内(开市到闭市)回报率之间的反向关系。研究表明,购买隔夜回报率低的证券并卖出隔夜回报率高的证券,能够在多个主要资产类别中实现显著的日内回报和夏普比率,这些回报是传统日内反转策略的两到五倍。

合理性

隔夜反转策略的合理性基于以下几点:

  • 统计证据:研究提供了强有力的统计证据,支持该策略在多个资产类别中的有效性。
  • 经济机制:策略的成功归因于不同资产类别特定的市场流动性提供机制,尤其是市场制造者在面对隔夜回报率分散时的行为。
  • 风险调整后的表现:即使在考虑了多种风险因素后,该策略仍然显示出显著的超额回报,表明其回报不仅仅是风险的补偿。

适用场景

隔夜反转策略在全球多个资产类别中都显示出潜在的应用价值,包括但不限于股指期货、利率期货、商品期货和货币期货。该策略特别适用于寻求利用日内价格波动的交易者,以及在市场流动性发生变化时,如市场波动性增加或减少的情况下。

基本策略逻辑

  1. 信号生成:使用隔夜(闭市到开市)的回报率作为交易信号。
  2. 资产选择:购买隔夜回报率低的资产,卖出隔夜回报率高的资产。
  3. 持仓期间:在随后的日内(开市到闭市)期间持有这些头寸。
  4. 回报实现:在日内交易结束时实现利润或亏损。
  5. 风险控制:通过考虑市场流动性和资产类别特定的因素来调整策略,以控制潜在的风险。

通过深入分析学术论文,我们不仅能够理解隔夜反转策略的理论基础,还能够洞察其在实际交易中的应用。下文将详细探讨如何将这些学术理论转化为实际的交易策略。

策略实现

中国商品期货市场具有独特的交易特性和流动性,这为策略的实施提供了理想的测试环境。我们将在优宽量化平台进行策略的实现,这是一个为量化交易者提供强大工具和数据支持的平台。

javascript
// 定义两个数组,包含具有夜盘交易的商品期货合约代码 const nightContract2 = ['sc', 'ag', 'au', 'nr', 'bu', 'hc', 'rb', 'ru', 'sp', 'fu', 'CF', 'CY', 'FG', 'MA', 'PF', 'OI', 'RM', 'SR', 'TA', 'SA', 'a', 'b', 'c', 'cs', 'i', 'j', 'jm', 'l', 'm', 'p', 'pp', 'v', 'y', 'eg', 'rr', 'eb', 'pg', 'lu', 'PX', 'br', 'PR', 'SH', 'al', 'cu', 'ni', 'pb', 'sn', 'zn', 'ss', 'bc', 'ao']; const nightContract = ['hc', 'rb', 'ru', 'sp', 'FG', 'MA', 'PF', 'SR', 'TA', 'SA', 'c', 'i','jm', 'l', 'm', 'p', 'pp', 'v', 'y', 'eg', 'eb']; // 挑选流动性较高的具有夜盘的品种 // 主函数 function main() { // 为每个合约设置主力合约后缀“888” const products = nightContract.map(item => item + '888'); let longList = []; // 多头持仓列表 let shortList = []; // 空头持仓列表 let checklock = true; // 检查锁,用于控制策略运行的开始 let openlock = false; // 开仓锁,用于控制开仓操作的执行 const p = $.NewPositionManager(); // 创建一个新的持仓管理器实例 // 无限循环,持续运行策略 while (true) { // 检查交易所是否连接正常 if (!exchange.IO('status')) { Sleep(1000 * 10); // 如果连接不正常,等待10秒后继续检查 continue; } // 获取当前时间 const now = new Date(); const timeString = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`; const today = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`; // 如果时间是08:55且checklock为真,则获取目标合约列表并进行排名 if (timeString === '08:55' && checklock) { // 清空长短期列表 longList = []; shortList = []; // 遍历所有主力合约 products.forEach(product => { const records = exchange.GetRecords(product, PERIOD_D1); // 获取日K线数据 const nightr = records[records.length - 1]; // 获取最新的日K线数据 const rtime = _D(nightr.Time).substring(0, 10); // 获取日期 // 检查日期是否为今天 if (rtime !== today) return; // 计算开盘至收盘价之间的涨幅 const power = (nightr.Close - nightr.Open) / nightr.Open; // 如果涨幅大于1.5%,则加入空头列表;如果跌幅大于1.5%,则加入多头列表 if (power > 1.5 / 100) { shortList.push({ cursymbol: product, power }); } else if (power < -1.5 / 100) { longList.push({ cursymbol: product, power }); } }); // 对多头列表按涨幅从小到大排序,并取前5个 longList = longList.sort((a, b) => a.power - b.power).slice(0, 5); // 对空头列表按跌幅从大到小排序,并取前5个 shortList = shortList.sort((a, b) => b.power - a.power).slice(0, 5); // 将列表中的合约对象映射为合约代码 longList = longList.map(item => item.cursymbol); shortList = shortList.map(item => item.cursymbol); // 打印获取的每日开仓数据 Log('获取每日开仓数据', '#ff0000'); Log('日多:', longList); Log('日空:', shortList); checklock = false; // 释放checklock锁 openlock = true; // 设置openlock锁 } // 如果时间是09:00且openlock为真,则开仓 if (timeString === '09:00' && openlock) { // 对于多头列表中的合约,开多仓 longList.forEach(product => { p.OpenLong(product, 1); // 开1手多单 }); // 对于空头列表中的合约,开空仓 shortList.forEach(product => { p.OpenShort(product, 1); // 开1手空单 }); openlock = false; // 释放openlock锁 } // 获取当前持仓信息 var checkpos = exchange.GetPositions(); if (typeof(checkpos) === 'undefined') return; // 构建持仓信息表格 var talStatus = { type: "table", title: "持仓信息", cols: ["品种名称", "持仓方向", "持仓均价", "持仓数量", "持仓盈亏"], rows: [] }; // 如果有持仓,则添加到表格中 if(checkpos.length > 0){ for(var i of checkpos){ var color = i.Profit > 0 ? '#ff0000' : '#00ff00'; // 盈利为红色,亏损为绿色 talStatus.rows.push([i.Symbol, i.Type%2 == 0 ? '多头' : '空头', i.Price , i.Amount, i.Profit + color]); } LogStatus(talStatus); // 打印持仓信息 } else { LogStatus("当前无持仓信息",'#FF0000'); // 如果没有持仓,则打印无持仓信息 } // 如果时间是14:58且openlock为假,则平仓 if (timeString === '14:58' && !openlock) { // 平掉所有持仓 p.CoverAll(); checklock = true; // 设置checklock锁 } Sleep(1000 * 10); // 休眠10秒 } }

基本逻辑说明:

  1. 初始化:定义两个数组nightContract2nightContract,分别包含所有具有夜盘的合约和挑选出的流动性较高的合约,大家可以根据对不同品种的了解程度进行更多合约的筛选。products数组用于存储主力合约代码。

  2. 主函数main:在无限循环中,根据当前时间执行不同的操作。

  3. 08:55操作:如果时间为开盘前5分钟08:55,获取目标合约列表并根据前一日的开盘至收盘价涨幅进行排名,选择涨幅最大的5个合约作为空头目标,跌幅最大的5个合约作为多头目标。

  4. 09:00操作:如果时间为开盘整点时间09:00,根据上一步得到的目标合约列表开仓。

  5. 持仓信息:交易时间段内,实时获取并打印当前持仓信息。

  6. 14:58操作:如果时间为交易末尾时分14:58,平掉所有持仓,准备下一日的交易。

  7. 休眠:每10秒执行一次循环,以减少资源消耗并避免过度交易。

策略运行结果:

自2024年6月份起对策略进行回测,结果还算不错,赚了12415元。这个策略挺聪明的,知道什么时候该做多,什么时候该做空,具有一定的风险对冲能力。虽然现在这个版本还比较简单,但基本的框架还是可以使用的。有兴趣的朋友可以在此基础上增加更多功能模块,比如更精细的风险控制,让策略可以更加平稳运行。

img

感想:

怎么样?从一篇学术论文的灵感出发,到策略在优宽量化平台上的实现,这一路走来还挺有趣的。这不仅仅是一次学术到实践的跳跃,更像是一次头脑风暴的冒险。我们把那些复杂的理论简化成了几行代码,让它们在市场中跑了起来。现在这个策略还只是个雏形,期待大家在此基础上继续发挥创意,调调参数,或许下一个量化交易大师就是你!

参考文献:

Liu, Chun and Liu, Chun and Liu, Yang and Wang, Tianyu and Zhou, Guofu and Zhu, Yingzi, Overnight-Intraday Reversal Everywhere (December 31, 2016). Asian Finance Association (AsianFA) 2016 Conference, Available at SSRN: https://ssrn.com/abstract=2730304 or http://dx.doi.org/10.2139/ssrn.2730304

注: 本文仅做探索性尝试,不构成任何投资性建议。

评论
全部评论 (0)
暂无数据
暂无数据
  • 1
iPhone 下载
社区
回测系统
© 2015 - ∞ YouQuant 豫ICP备19046564号