atr是什么意思的缩写(CTA策略之 - ATR&RSI策略)
ATR&RSI策略主要依靠两个技术指标生成交易信号,即ATR指标和RSI指标。
Part1:ATR指标
ATR指标
平均真实波动范围(Average true range),简称ATR指标,是由韦尔德(J.Welles Wilder)发明的,ATR指标主要是用来衡量市场波动的强烈度,即为了显示市场变化率的指标。注意,这一指标主要用来衡量价格的波动,并不能直接反映价格走向及其趋势稳定性。
这一指标对于长期持续边幅移动的时段是非常典型的,这一情况通常发生在市场的顶部,或者是在价格巩固期间。根据这个指标来进行预测的原则可以表达为:该指标价值越高,趋势改变的可能性就越高;该指标的价值越低,趋势的移动性就越弱。当ATR线上升时,意味着资产的波动性在增加。当ATR线下降时,意味着资产的波动性在减少。ATR不会显示资产移动的方向。
ATR值较高,表明波动较高;ATR较低较低,表明波动较低。
含义是:K线的最高、最低与前一根k线的收盘价,两两最差的绝对值最大值。
计算公式:
MAX(MAX((HIGH-LOW),ABS(REF(CLOSE,1)-HIGH)),ABS(REF(CLOSE,1)-LOW))
ATR指标计算逻辑
首先计算出TR(即当天的真实波幅),下图中#1,#2,#2为市场出现跳空高开和跳空低开的情况。TR在当日最高价与最低价,当日最高价与昨日最收盘价,当日最低价与昨日收盘价这3种情况中取最大值。
由于一天的TR缺乏效率以及代表性,韦尔德用ATR来更好地衡量市场的波动性;一般而言,市场常用的数据周期是14以及21,这意味着如果投资者在日图看ATR,14 = 14天;如果是在周图看ATR,14 = 14周。ATR的计算公式如下:
ATR = (前13天的TR + 当天的TR)/ 14
ATR指标信号判断
除了通过ATR数值大小来直接判断市场波动性大小外,也可以通过对比当天平均真实波幅(ATR)和过去N天平均波幅(ATRMa)来判断市场波动性趋势。
- 当ATR>ATRMa,说明市场波动性增大,趋势正在增强
- 当ATR<ATRMa,说明市场波动性减少,趋势开始减弱
Part2:RSI指标
RSI指标
相对强弱指标(Relative Strength Index),简称RSI指标,也是由J.Welles Wilder 发明的。RSI指标是根据市场上供求关系平衡的原理,通过比较一段时期内单个标的物价格的涨跌的幅度或整个市场的指数的涨跌的大小来分析判断市场上多空双方买卖力量的强弱程度,从而判断未来市场走势的一种技术指标。
简单来说,是一种用来评估「买卖盘双方力道强弱」情况的技术指标,买家是代表金钱的力量,卖家是代表持货的力量。当买方力量稍逊,价格就会向下发展;相反,当卖方力量不足,价格就会向上发展。
计算公式:
RSI指标信号判断
一般而言,RSI 以50为中界线,大于50视为多头行情,小于50视为空头行情。
当RSI>70时,属于超买状态,后续行情有可能出现回调或转势,应该卖出;
当RSI<30时,属于超卖状态,短期反弹概率较高,建议买入。
RSI指标缺点
- RSI 指标在高档或低档有时会有钝化的现象,因此会发生过早卖出或买进。
- RSI 只能作为一个警告讯号,并不意味着市场必然朝这个方向发展,尤其在市场剧烈震荡时,超卖还有超卖,超买还有超买,这时须参考其他指标综合分析,像是利用长天期的RSI均线与RSI线的关系来作买卖讯号判断,不能单独依赖RSI的讯号而作出买卖决定。
- 背离走势的讯号通常者都是事后历史,而且在背离走势发生之后,行情并无反转的现象。有时背离一,二次才真正反转,因此这方面研判须不断分析历史资料以提高经验。
- 由于 RSI 是一种比率的指标,因此在趋势分析的能力上会较弱。
- 盘势进入横盘整理时,长短天期的RSI也容易形成重复交叉的情形。
Part3:ATR&RSI策略
该策略的思想用简单的话来讲就是,用ATR指标和RSI指标双管齐下来选择入场点。具体如下:
多单入场:ATR大于它的N周期的均值,并且RSI大于RSI的买入控制线;
空单入场:ATR大于他的N周期的均值,并且RSI小于RSI的卖空控制线。
该策略只用到2个技术指标:ATR指标用于过滤,当ATR>ATRMa时,显示市场波动性增大,趋势正在增强。只有在市场出现趋势的时候做单(追涨杀跌),盈利的机会才会增大。RSI指标则是用于产生交易信号,当RSI>规定上限时,开仓做多,反之,当RSI<规定下限时,开仓做空。开仓之后就需要考虑如何盈利离场或者止损离场,这个策略用的是固定百分比点位的移动止损。例如:70这个点位开仓后,行情一路走高至100这个日高点,移动止损设了99%,当行情开始回落时,会在99这个点位自动平仓离场,从而把握住了29点的盈利。
总结一下哦:AtrRsi策略的三大要素
信号:RSI指标
过滤:ATR指标
出场:固定百分百点位移动止损离场
Part4:VNPY实现ATR&RSI策略
from vnpy.app.cta_strategy import (
CtaTemplate,
StopOrder,
TickData,
BarData,
TradeData,
OrderData,
BarGenerator,
ArrayManager,
)
class AtrRsiStrategy(CtaTemplate):
""""""
author = "用Python的交易员"
atr_length = 22 # 计算ATR指标的窗口数
atr_ma_length = 10 # 计算ATR均线的窗口数
rsi_length = 5 # 计算RSI的窗口数
rsi_entry = 16 # RSI的开仓信号
trailing_percent = 0.8 # 百分比移动止损
fixed_size = 1 # 每次交易的数量
atr_value = 0
atr_ma = 0
rsi_value = 0
rsi_buy = 0
rsi_sell = 0
intra_trade_high = 0
intra_trade_low = 0
parameters = [
"atr_length",
"atr_ma_length",
"rsi_length",
"rsi_entry",
"trailing_percent",
"fixed_size"
]
variables = [
"atr_value",
"atr_ma",
"rsi_value",
"rsi_buy",
"rsi_sell",
"intra_trade_high",
"intra_trade_low"
]
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
""""""
super().__init__(cta_engine, strategy_name, vt_symbol, setting)
self.bg = BarGenerator(self.on_bar)
self.am = ArrayManager()
def on_init(self):
"""
Callback when strategy is inited.
"""
self.write_log("策略初始化")
self.rsi_buy = 50 + self.rsi_entry
self.rsi_sell = 50 - self.rsi_entry
self.load_bar(10)
def on_start(self):
"""
Callback when strategy is started.
"""
self.write_log("策略启动")
def on_stop(self):
"""
Callback when strategy is stopped.
"""
self.write_log("策略停止")
def on_tick(self, tick: TickData):
"""
Callback of new tick data update.
"""
self.bg.update_tick(tick)
def on_bar(self, bar: BarData):
"""
Callback of new bar data update.
"""
self.cancel_all()
# 保存K线数据
am = self.am
am.update_bar(bar)
if not am.inited:
return
# 计算指标数值
atr_array = am.atr(self.atr_length, array=True)
self.atr_value = atr_array[-1]
self.atr_ma = atr_array[-self.atr_ma_length:].mean()
self.rsi_value = am.rsi(self.rsi_length)
# 当前无仓位
if self.pos == 0:
self.intra_trade_high = bar.high_price
self.intra_trade_low = bar.low_price
# ATR数值上穿其移动平均线,说明行情短期内波动加大
# 即处于趋势的概率较大,适合CTA开仓
if self.atr_value > self.atr_ma:
# 使用RSI指标的趋势行情时,会在超买超卖区钝化特征,作为开仓信号
if self.rsi_value > self.rsi_buy:
# 这里为了保证成交,选择超价5个整指数点下单
self.buy(bar.close_price + 5, self.fixed_size)
elif self.rsi_value < self.rsi_sell:
self.short(bar.close_price - 5, self.fixed_size)
# 持有多头仓位
elif self.pos > 0:
# 计算多头持有期内的最高价,以及重置最低价
self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
self.intra_trade_low = bar.low_price
# 计算多头移动止损
long_stop = self.intra_trade_high * \
(1 - self.trailing_percent / 100)
# 发出本地止损委托
self.sell(long_stop, abs(self.pos), stop=True)
# 持有空头仓位
elif self.pos < 0:
self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
self.intra_trade_high = bar.high_price
# 计算空头移动止损
short_stop = self.intra_trade_low * \
(1 + self.trailing_percent / 100)
self.cover(short_stop, abs(self.pos), stop=True)
# 发出状态更新事件
self.put_event()
def on_order(self, order: OrderData):
"""
Callback of new order data update.
"""
pass
def on_trade(self, trade: TradeData):
"""
Callback of new trade data update.
"""
self.put_event()
def on_stop_order(self, stop_order: StopOrder):
"""
Callback of stop order update.
"""
pass
继承了CtaTemplate,ATR指标初始化需要用到22天数据,即22天以后才能产生ATR值;而ATR移动平均(ATRMa)则是统计10天内的平均值。RSI指标规定初始化需要用到5天数据,16是开仓的阈值:当RSI>50+16,即RSI>66时,开仓做多,当RSI<34时,开仓做空。这里并不用市场公认的RSI高于80做多,RSI低于20做空,因为用的人多了,交易信号已经失效。fixedSize=1意味着每次开平仓操作只交易1手。
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
""""""
super().__init__(cta_engine, strategy_name, vt_symbol, setting)
self.bg = BarGenerator(self.on_bar)
self.am = ArrayManager()
上述代码是策略类初始化,定义引擎类型、策略名称、关注的合约代码、设置参数,初始化一个K线合成器和一个K线和技术指标的容器。
def on_init(self):
"""
Callback when strategy is inited.
"""
self.write_log("策略初始化")
self.rsi_buy = 50 + self.rsi_entry
self.rsi_sell = 50 - self.rsi_entry
self.load_bar(10)
上述代码是策略初始化的时候,我们要定好rsi的多空阈值。
def on_tick(self, tick: TickData):
"""
Callback of new tick data update.
"""
self.bg.update_tick(tick)
def on_bar(self, bar: BarData):
"""
Callback of new bar data update.
"""
self.cancel_all()
# 保存K线数据
am = self.am
am.update_bar(bar)
if not am.inited:
return
# 计算指标数值
atr_array = am.atr(self.atr_length, array=True)
self.atr_value = atr_array[-1]
self.atr_ma = atr_array[-self.atr_ma_length:].mean()
self.rsi_value = am.rsi(self.rsi_length)
# 当前无仓位
if self.pos == 0:
self.intra_trade_high = bar.high_price
self.intra_trade_low = bar.low_price
# ATR数值上穿其移动平均线,说明行情短期内波动加大
# 即处于趋势的概率较大,适合CTA开仓
if self.atr_value > self.atr_ma:
# 使用RSI指标的趋势行情时,会在超买超卖区钝化特征,作为开仓信号
if self.rsi_value > self.rsi_buy:
# 这里为了保证成交,选择超价5个整指数点下单
self.buy(bar.close_price + 5, self.fixed_size)
elif self.rsi_value < self.rsi_sell:
self.short(bar.close_price - 5, self.fixed_size)
# 持有多头仓位
elif self.pos > 0:
# 计算多头持有期内的最高价,以及重置最低价
self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
self.intra_trade_low = bar.low_price
# 计算多头移动止损
long_stop = self.intra_trade_high * \
(1 - self.trailing_percent / 100)
# 发出本地止损委托
self.sell(long_stop, abs(self.pos), stop=True)
# 持有空头仓位
elif self.pos < 0:
self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
self.intra_trade_high = bar.high_price
# 计算空头移动止损
short_stop = self.intra_trade_low * \
(1 + self.trailing_percent / 100)
self.cover(short_stop, abs(self.pos), stop=True)
# 发出状态更新事件
self.put_event()
上述代码是,接受tick行情后合成bar,然后在bar中运行主逻辑:也就是大于atr均值了,根据rsi做多空,并且跟踪止损。
on_bar解析:在开仓交易前,为了防止之前下的挂单在上1分钟没有成交,但是下一分钟可能已经调整了价格,就用cancelAll( )的方法立刻撤销之前未成交的所有委托,保证策略在当前这1分钟开始的时候整个状态是清晰和唯一的。本地化K线管理模块(am = self.am),以便其运行起来更快。若检测到K线管理模块还没有插入足够多的数据,即初始化状态为False,则直接返回不进行下面的操作;反之,计算ATR指标,ATR移动平均和RSI指标。
接着,仓位的计算解析:
- 当前无仓位,先初始化K线日高点和日低点的值,用的是当前K线的最高价和最低价。若ATR指标往上走超过了移动平均,说明趋势正在增强,市场波动越来越大,则用RSI指标来开仓操作了。RSI的判断标准是当其指标高于66时,发出买入委托,用超价5个点来保证能够成交,委托数量为1(fixedSize)。若RSI低于其卖出阈值,用低于市价5个点来保证成交;
- 当前持有多仓,用max()函数来统计当日K线达到的最高点,日低点则是直接更新当前K线最低价。移动止损设置为当K线达到日高点后,回落0.8%时用停止单(Stop Order)进行平仓离场;
- 当前持有空仓,用min()函数来统计当日K线达到的最低点,日高点则是直接更新当前K线最高价。移动止损设置为当K线达到日低点后,反弹0.8%时用停止单(Stop Order)进行平仓离场。
Part5:VNPY实现ATR&RSI策略回测
回测相关数据,这里你想用什么就用什么。注意!回测启动程序入口在这里:
#%%
#%%
from vnpy.app.cta_strategy.backtesting import BacktestingEngine, OptimizationSetting
from vnpy.app.cta_strategy.strategies.atr_rsi_strategy import (
AtrRsiStrategy,
)
from datetime import datetime
#%%
#%%
engine = BacktestingEngine()
engine.set_parameters(
vt_symbol="IF88.CFFEX",
interval="1m",
start=datetime(2019, 1, 1),
end=datetime(2019, 4, 30),
rate=0.3/10000,
slippage=0.2,
size=300,
pricetick=0.2,
capital=1_000_000,
)
engine.add_strategy(AtrRsiStrategy, {})
#%%
#%%
engine.load_data()
engine.run_backtesting()
df = engine.calculate_result()
engine.calculate_statistics()
engine.show_chart()
#%%
setting = OptimizationSetting()
setting.set_target("sharpe_ratio")
setting.add_parameter("atr_length", 3, 39, 1)
setting.add_parameter("atr_ma_length", 10, 30, 1)
engine.run_ga_optimization(setting)
该demo程序用的symbol是IF88.CFFEX。好了,我们可以用该策略跑历史回测哦,无论你用哪个symbol,做完回测了请把回测曲线图作业交给楼主吧,看看你是否掌握了该策略的回测。实盘上,一些机构都在使用它,该策略思路比较好理解,在某些品种上还是取得了相对还可以的收益率。
相关文章
-
二句三年得指的是什么意思(“苦吟诗人”贾岛)
2024-11-14 10:34:34
-
社会科学研究方法有哪些(社会科学研究方法导论)
2024-11-14 10:19:36
-
存款准备金利率下调对楼市的影响
2024-11-14 10:04:36
-
醍醐灌顶的意思及成语解释(“醍醐”是什么东西?)
2024-11-14 09:48:53
-
神秘集团公司——保利集团董事长是谁?
2024-11-14 09:34:03
-
海南社保查询方法(海南打工人如何查询自己的社会保险情况?)
2024-11-14 09:18:38