CTA策略【量化理论】
CTA策略演变史
全称:Commodity Trading Advisor (商品交易顾问)
CTA最开始是指通过为客户提供期权、期货方面的交易建议,或者直接通过受管理的期货账户参与实际交易,来获得收益的机构或个人。
随着市场的发展,市场对CTA的理解普遍发生了改变,它已不再是商品期货,而是基于量价的趋势跟踪策略——无论是商品期货、金融期货,还是股票、外汇,只要是有历史公开量价的二级市场,都可以成为CTA策略运作的市场。
在国内市场中,期货相比股票交易起来的限制较小(t+0交易且可以做空),因此推荐用期货来学习
趋势跟踪策略是CTA的重要组成部分,通俗来讲就是追涨杀跌,该假说核心的理论就是利用在股市中明显存在的非理性狂热和羊群效应,在市场情绪明显不是很好的情况下在置信区间内持有股票,以达到收割韭菜的目的,客观来讲,这种量化策略客观上实现了一件事:使得股价更加稳定且符合实际价值,降低了市场情绪对股价造成的影响
相关指标类型
国内大量的量化CTA都是利用了技术指标来构建量化策略,大体上,这些量化指标可以分为三类:
(1):趋势型:例如MACD、SAR用于趋势跟踪策略
(2):超买超卖型:和追涨杀跌的趋势型恰相反,用KDJ、RSI等指标来描述并捕捉趋势行情的终结
(3):能量型:从成交量的角度来考察价格变动的力量,常用于辅助判断信号的强度,比如VOL、OBV等
有关跳空定义的处理方法
在进行较长时间的回测时,在换月时会遇到假跳空的问题,这是由于期货合约到期后,新的合约和原来的合约存在一个比较大的价差
对于这种假跳空的情况,一般会采用三种处理方法1.使用期货合成指数来回测2.对跳空进行复权处理3.不使用主力合约,而是使用单独月份的合约来进行分析
1.使用合成指数进行回测:
对某一品种的各个月赋予权重,计算出一个综合性指标,用于代表该产品的整体走势,计算指数时,算法一般都会保证其连续性,不会出现假跳空的现象。
方法缺点:指数并非真实存在的价格数据而产生误差;指数的计算公式往往不是透明的
2.进行复权算法处理:
复权算法分为两个维度,可以分为加减复权和乘除复权,也可以分为前复权和后复权,所谓加减复权就是指对跳空产生的价差加减平移:
假设你持有以下期权组合:
• 买入一个行权价为50的看涨期权,价格为5元。
• 卖出一个行权价为60的看涨期权,价格为2元。
• 初始价差为3元(5 - 2)。
如果市场情况发生变化:
• 加价差:你可能会卖出一个行权价为70的看涨期权,价格为1元,新的价差变为4元(5 - 1)。
• 减价差:你可能会买入一个行权价为55的看涨期权,价格为3元,新的价差变为2元(5 - 3)。
• 平移:你可能会将行权价从50和60调整为60和70,但保持价差宽度不变。
例如本来的收盘价:1010,1000,1200,1170——其中,1000到1200就是由假跳空导致的,这时我们就把后面的两个序列减去200,得到新的收盘价:1010,1000,1000,930,这种处理方法的优点是价格序列整体简洁,缺点是收益率会出现偏差,要让收益率不会出现偏差,我们可以采用乘除复权法,也就是在原来的数字上乘上一个因子,比如在刚刚举例的1010,1000,1200,1170序列当中,就可以把后面的两个数字乘上(1/1.2)这样就得到了连续时收益率不变的新序列1010,1000,1000,975
前复权就是对前面的数据复权,后复权就是对后面的数据复权
法三的主要缺点是容易造成数据损失
在这里给大家介绍一个比较成熟的库:ta-lib,其本身是基于c语言开发的技术指标库,现在也提供Python包装后的库,下载此库时,在windows中建议使用预编译的二进制安装包/anaconda:
其函数主要分为如下十组:
·Overlap Studies(可叠加指标)
·Momentum Indicators(动量指标)
·Volume Indicators(成交量指标)
·Volatility Indicators(波动率指标)
·Price Transform(价格变换)
·Cycle Indicators(周期指标)
·Pattern Recognition(模式识别)
·Statistic Functions(统计函数)
·Math Transform(数学变换)
·Math Operators(数学运算符)
ta-lib有两种方法计算指标(Function API和Abstract API)
其中函数式API提供了一种轻量级的调用方式,例如:
output = talib.SMA(close)
可以简单计算其移动平均
from talib import MA_Type
upper, middle, lower = talib.BBANDS(close, matype=MA_Type.T3)
可以计算其布林线
output = talib.MOM(close, timeperiod=5)
timeperiod来指定计算周期
一般而言,一个合理的CTA策略往往以趋势跟踪为主,以反转指标和能量指标为辅,取趋势指标T、反转指标R、能量指标E
定义趋势当中最常用的方法有两种(T+表示多头信号,T-表示空头信号):
1.突破:高于或低于先前几期的最高价或最低价,就是向上突破或向下突破
2.穿越:短期均线上穿/下穿长期均线
当涨的太高,股市很容易会出现回调的情况,此时一些常见的指标高于某一值,我们就可以称目前的情况为超买,为R-空头信号;低于某值为超卖,为R+多头信号
能量指标E,比如OBV:当日价格低于昨日价格,那么当日OBV就是本日值+前一日OBV值(且本日值小于零,为交易量*-1)
import pandas as pd
import numpy as np
import talib as ta
import matplotlib.pyplot as plt
# 示例数据加载(请替换为实际数据)
data = pd.read_csv('your_data.csv', index_col='Date', parse_dates=True)
data = data[['Open', 'High', 'Low', 'Close', 'Volume']]
# 参数设置
fast_ma_period = 10 # 快速均线周期
slow_ma_period = 50 # 慢速均线周期
bbands_period = 20 # 布林线周期
std_dev = 2 # 布林线标准差
# 计算OBV(能量指标E)
data['OBV'] = ta.OBV(data['Close'], data['Volume'])
# 计算布林线(反转指标R)
data['BB_UP'], data['BB_MID'], data['BB_LOW'] = ta.BBANDS(data['Close'], timeperiod=bbands_period, nbdevup=std_dev, nbdevdn=std_dev)
# 计算均线(趋势指标T)
data['MA_Fast'] = ta.SMA(data['Close'], timeperiod=fast_ma_period)
data['MA_Slow'] = ta.SMA(data['Close'], timeperiod=slow_ma_period)
# 生成信号
data['Signal'] = 0 # 初始化信号
# 基于OBV和布林线的反转信号
data.loc[(data['OBV'] > data['OBV'].shift(1)) & (data['Close'] < data['BB_LOW']), 'Signal'] = 1 # 买入信号
data.loc[(data['OBV'] < data['OBV'].shift(1)) & (data['Close'] > data['BB_UP']), 'Signal'] = -1 # 卖出信号
# 基于均线的趋势信号
data.loc[data['MA_Fast'] > data['MA_Slow'], 'Signal'] = 1 # 均线多头,增强买入信号
data.loc[data['MA_Fast'] < data['MA_Slow'], 'Signal'] = -1 # 均线空头,增强卖出信号
# 简单的交易逻辑
data['Position'] = data['Signal'].shift(1) # 当前持仓状态
data['Strategy_Return'] = data['Position'] * data['Close'].pct_change() # 策略收益率
# 绘制结果
plt.figure(figsize=(14, 8))
plt.plot(data['Close'], label='Close Price')
plt.plot(data['MA_Fast'], label='Fast MA')
plt.plot(data['MA_Slow'], label='Slow MA')
plt.plot(data['BB_UP'], label='BB_UP')
plt.plot(data['BB_MID'], label='BB_MID')
plt.plot(data['BB_LOW'], label='BB_LOW')
plt.scatter(data.index[data['Signal'] == 1], data['Close'][data['Signal'] == 1], color='green', label='Buy Signal')
plt.scatter(data.index[data['Signal'] == -1], data['Close'][data['Signal'] == -1], color='red', label='Sell Signal')
plt.legend()
plt.title('CTA Strategy with OBV, BBands, and MA')
plt.show()
# 输出策略绩效
cumulative_return = (1 + data['Strategy_Return']).cumprod() - 1
print("Cumulative Return:", cumulative_return.iloc[-1])
指标总体策略
空仓时,若出现T+,则开多仓;若出现T-,则开空仓。
当前是多头时,若出现T-,则平多反手开空;T+若出现R-,则平多不开新仓。
当前是空头时,若出现T+,则平空反手开多;T-若出现R+,则平空不开新仓。
所有的信号均可以用能量E超过某阈值m来辅助,只有当E有效时,信号才有效。