资源加载中... loading...

基于生猪品种的基差套利策略

Author: ianzeng123, Created: 2024-04-24 16:57:11, Updated: 2024-06-11 17:28:08

img

在金融市场中,基差套利策略一直以其稳定的盈利性和相对低风险性备受关注。而针对生猪品种的基差套利策略,更是在农产品市场中独具特色。生猪作为人类饮食的重要组成部分,其价格波动不仅受到市场供求关系、季节因素等影响,还受到政策、疫情等多重因素的影响。因此,基于生猪品种的基差套利策略在当前的市场环境下具有广阔的发展前景和巨大的投资价值。

基差套利策略通过分析期货价格与现货价格之间的差价(即基差),寻找价格偏离正常水平的机会,从而实现买低卖高或者卖高买低的交易,获取稳定的利润。而生猪品种的基差套利策略则是在这个基础上,针对生猪产业特点进行深入研究和分析,从而更精准地把握市场机会。

首先,生猪产业的周期性特征对基差套利策略的执行具有重要影响。生猪养殖周期相对稳定,而生猪价格波动往往受到养殖周期的影响,因此基于养殖周期的基差套利策略可以更好地把握生猪价格的波动规律,实现更加精准的交易决策。

其次,生猪产业受季节因素和供需关系的影响较大。随着季节变化和市场需求的波动,生猪价格也会出现相应的波动。基于季节性和供需关系的基差套利策略可以通过对季节性因素和市场供需关系的分析,把握价格波动的规律,实现更加准确的交易预测。

此外,生猪产业还受到政策、疫情等因素的影响。政策调控和疫情爆发都会对生猪市场产生重大影响,从而引发生猪价格的波动。基于政策和疫情因素的基差套利策略可以通过及时获取政策信息和疫情动态,做出相应的交易决策,降低交易风险,实现更好的收益。

综上所述,基于生猪品种的基差套利策略具有很高的实践价值和应用前景。通过深入分析生猪产业的周期性特征、季节性因素、供需关系以及政策、疫情等因素,结合基差套利策略的执行逻辑和方法,可以有效地把握生猪价格的波动规律,实现稳定的盈利。因此,对于投资者来说,研究和掌握基于生猪品种的基差套利策略具有重要意义,不仅可以为投资者带来丰厚的回报,还可以为生猪产业的稳定发展做出贡献。

期现套利方法

期现套利的核心原理是,同一个商品在同一个时间点只能有一个价格,期货到了交割时间就变成现货,所以在临近交割时会强制回归。这个与跨期套利完全不同,跨期套利是两个不同交割月的合约,到期时也就是两个不同月份的现货,当然可以是两个价格。

  • 基差 = 期货价格 - 现货价格

期现套利最大的特点是理论上无风险,主要是根据基差状态,计算利润区间。如果基差过大,就可以买入现货,同时做空期货,等待基差重新归零,就可以期货和现货双边平仓,赚取基差的利润。

因为增值税的存在(现货交易通常有 17%~20%的增值税),所以基差一般维持在正常的水平。我们可以计算基差的布林带阈值,当基差超过上线的时候,证明期货价格过高,进行卖出的操作;当回归到布林带中线,进行相应的平仓;与此对立,当基差下穿下线的时候,证明期货期货价格过低,进行买入的操作,同样当回归到布林带中线,进行多头的平仓。

  • 基差超过布林带上线,空头开仓;
  • 基差回归布林带中线,空头平仓;
  • 基差超过布林带下线,多头开仓;
  • 基差回归布林带中线,多头平仓;

策略逻辑

下面我们具体使用代码将具体的程序化交易进行实现。首先注册并登陆优宽量化官网,点击控制中心,点击策略库+新建策略。在左上角下拉菜单中选择Python,并填入策略的名字。

第一步:编写策略框架

# 策略主函数
def onTick():
    pass

# 策略入口
def main():
    while True:  # 进入循环模式
        onTick()  # 执行策略主函数
        Sleep(1000 * 60 * 60 * 24)  # 策略休眠一天

第一步编写策略框架,策略框架是两个函数,main函数是策略的入口,主要功能是交易之前的预处理,程序会先从main函数开始执行,然后进入无限循环模式,重复执行onTick函数,onTick函数是策略的主函数,主要执行核心代码。

第二步:增加图表功能

# 全局变量
# 期现图表
cfgA = {
    "extension": {
        "layout": 'single',
        "col": 6,
        "height": "500px",
    },
    "title": {
        "text": "期现图表"
    },
    "xAxis": {
        "type": "datetime"
    },
    "series": [{
        "name": "期货价格",
        "data": [],
    }, {
        "name": "现货价格",
        "data": [],
    }]
}

# 基差图表
cfgB = {
    "extension": {
        "layout": 'single',
        "col": 6,
        "height": "500px",
    },
    "title": {
        "text": "基差图表"
    },
    "xAxis": {
        "type": "datetime"
    },
    "series": [{
        "name": "基差价格",
        "data": [],
    }]
}

chart = Chart([cfgA, cfgB])  # 创建一个图表对象

# 策略主函数
def onTick():
    chart.add(0, [])  # 绘制图表
    chart.add(1, [])  # 绘制图表
    chart.add(2, [])  # 绘制图表
    chart.update([cfgA, cfgB])  # 更新图表

# 策略入口
def main():
    LogReset()  # 运行前先清空之前的 Log 日志信息
    chart.reset()  # 运行前先清空之前的图表信息
    while True:  # 进入循环模式
        onTick()  # 执行策略主函数
        Sleep(1000 * 60 * 60 * 24)  # 策略休眠一天

在这个策略中,一共创建了 2 个图表,并左右分布排列。其中左图cfgA是期现图表,包含期货价格和现货价格,右图cfgB是基差图表。然后创建一个chart对象。最后是在onTick函数中实时更新图表中的数据。

第三步:获取数据

我们一共需要获取三种数据:期货价格、现货价格、基差价格。获取期货价格很简单,直接使用SetContractType函数订阅期货品种,再使用GetRecords函数就可以获取 K 线的收盘价。

基差作为外部数据,当引入到策略当中需要一系列的繁杂操作(API获取,数据清理等),为了解决这一痛点,优宽量化开发的DATADATA平台已经内置了商品期货基本面数据,包括期货相关的各种宏观数据。因此我们首先需要在DATADATA平台编写Sql代码,获取基本面数据。

打开DATADATA平台,点击创建图表,写入sql代码,保存数据,然后点击铅笔按钮,设置自动更新,接着点击获取API。

WITH DATA1 AS (
    SELECT 
        *,
        EXTRACT(EPOCH FROM time)::bigint * 1000 AS time_milliseconds
    FROM 
        futures_data.basis 
    WHERE 
        product_name = '生猪' 
    ORDER BY 
        date
)

SELECT 
    time_milliseconds AS time, 
    date, 
    json_build_object('spot_price', spot_price) AS data 
FROM 
    DATA1;

通过设置“定时刷新”,我们运行策略可以获取最新的数据,基差数据是每日刷新的,因此定制刷新的频率为“每天”,基差时间更新的具体时间点为八点,所以选择时间为"08:00 - 09:00"就可以。

image

接着回到策略编写界面,使用GetData获取数据,里面填写的参数为上面设置完成的 API ,返回的是包含时间戳的字典数据,我们进行一下简单的处理。当检查到DATADATA平台数据更新,就可以获取最新的基差数据进行相应的画图和套利操作。

basisList = [] # 基差列表
obj = exchange.GetData("https://www.datadata.cn/api/v1/query/94af6e1e-2efa-4e0c-8c08-f7853b2bf969/data")
if obj["Data"] != pre_data:
    info = json.loads(obj["Data"])
    spot = info['spot_price']
    pre_data = obj["Data"]
    basis = futures_price - info['spot_price']
    basisList.append(basis)  # 基差列表数据的收集

第四步:计算基差上下限 获取到基差数据之后,进行基差数据的布林带上中下限阈值的计算。

if len(basisList) < pigPeriod + 2:
    return

basisBoll = TA.BOLL(basisList, pigPeriod, 2)
exbasisBoll = TA.BOLL(basisList, pigPeriod, 3)

第五步:进行基差套利操作

前期信号指标计算完毕以后,当检查到实时基差上穿布林带上轨的时候,证明基差过大,进行期货空头开仓的操作;开仓完毕,当检查到回归布林带中轨,进行空头平仓。当检查到实时基差下穿布林带下轨,证明基差过小,进行多头开仓,回归中轨进行平仓。

if basis > basisBoll[0][-2] and mp == 0:
    p.OpenShort('lh888', 1)
    mp = -1
if mp == -1 and basis < basisBoll[1][-2]:
    p.Cover('lh888')
    mp = 0

if basis < basisBoll[2][-2] and mp == 0:
    p.OpenLong('lh888', 1)
    mp = 1
if mp == 1 and basis > basisBoll[1][-2]:
    p.Cover('lh888')
    mp = 0

策略回测效果

image

image

根据策略运行结果,可以看到在2024年1月至4月末,策略取得了良好的收益,证明生猪品种具有较平稳的基差回归特性,我们可以以此为依据进行相应的期现套利操作。

完整策略

import time
import json

# 全局变量
# 期现图表
cfgA = {
    "extension": {
        "layout": 'single',
        "col": 6,
        "height": "500px",
    },
    "title": {
        "text": "期现图表"
    },
    "xAxis": {
        "type": "datetime"
    },
    "series": [{
        "name": "期货价格",
        "data": [],
    }, {
        "name": "现货价格",
        "data": [],
    }
    ]
}
# 基差图表
cfgB = {
    "extension": {
        "layout": 'single',
        "col": 6,
        "height": "500px",
    },
    "title": {
        "text": "基差图表"
    },
    "xAxis": {
        "type": "datetime"
    },
    "series": [{
        "name": "基差价格",
        "data": [],
    }]
}

chart = Chart([cfgA, cfgB])  # 创建一个图表对象

pre_data = None
info = None
basis = None
basisList = []
mp = 0   

def onTick():
    global pre_data
    global info
    global basis
    global basisList
    global mp 

    p = ext.NewPositionManager()
    
    exchange.SetContractType("lh888")  # 订阅期货品种
    futures = _C(exchange.GetRecords)[-1]  # 获取最新K线数据
    futures_ts = futures.Time  # 获取最新K线期货时间戳
    futures_price = futures.Close  # 获取最新K线收盘价

    obj = exchange.GetData("https://www.datadata.cn/api/v1/query/94af6e1e-2efa-4e0c-8c08-f7853b2bf969/data")
    if obj["Data"] != pre_data:
        info = json.loads(obj["Data"])
        spot = info['spot_price']
        pre_data = obj["Data"]
        basis = info['spot_price'] - futures_price
        basisList.append(basis)

    chart.add(0, [futures_ts, futures_price])  # 绘制图表
    chart.add(1, [futures_ts, info['spot_price']])  # 绘制图表
    chart.add(2, [futures_ts, basis])  # 绘制图表
    chart.update([cfgA, cfgB])  # 更新图表

    if len(basisList) < pigPeriod + 2:
        return

    basisBoll = TA.BOLL(basisList, pigPeriod, 2)
    exbasisBoll = TA.BOLL(basisList, pigPeriod, 3)

    if basis > basisBoll[2][-2] and mp == 0:
        p.OpenLong('lh888', 1)
        mp = 1
    if mp == 1 and basis < basisBoll[1][-2]:
        p.Cover('lh888')
        mp = 0

    if basis < basisBoll[0][-2] and mp == 0:
        p.OpenShort('lh888', 1)
        mp = -1
    if mp == -1 and basis > basisBoll[1][-2]:
        p.Cover('lh888')
        mp = 0

# 策略入口
def main():
    LogReset()  # 运行前先清空之前的Log日志信息
    chart.reset()  # 运行前先清空之前的图表信息
    
    while True:  # 进入循环模式
        onTick()  # 执行策略主函数
        Sleep(1000 * 60 * 60 * 24)  # 策略休眠一天

更多内容