ATR止损
首先介绍一个指标: ATR指标。
真实波幅(ATR)主要应用于了解股价的震荡幅度和节奏,在窄幅整理行情中用于寻找突破时机。通常情况下股价的波动幅度会保持在一定常态下,但是如果有主力资金进出时,股价波幅往往会加剧。另外,在股价横盘整理、波幅减少到极点时,也往往会产生变盘行情。真实波幅(ATR)正是基于这种原理而设计的指标。
好了,总而言之,这是一个玄学指标。 玄学止损, Best 止损。 我们来看看这个玄学指标是怎么算的吧? 计算公式
Raw_ATR=max(|今日振幅|, |昨天收盘-今日最高价|,|昨天收盘-今日最低价|)# 未处理ATR 为这三个指标的最大值
ATR=moving_average (ATR ,N) #真实ATR 为 Raw_ATR 的N 日简单移动平均,默认N=22
根据这个指标, 我们能做很多有意思的策略。 这里就举一个例子: 吊灯止损。 伪码如下
计算每日, 某个股票的ATR。
if 现价<持有股票之后的最高价-3* ATR:
卖出止损
else:
继续持有
这里提供了 一个相当精彩的模板, 喜欢的话拿去玩吧...
'''
止损描述 :
计算ATR指标。 若当前价< 持仓最高价-3* ATR :
卖出止损。
套用方法:
0: 在 init 中设置你的 moving average ATR 周期: context.ATRperiod=22
1: 复制‘scheduler.run_daily(stoploss)’ 至 init
2: 复制 def stoploss , def createdic ,def findATR 到策略内
3: 在 order 之后加入 createdic(context,bar_dict,stock)
'''
# 可以自己import我们平台支持的第三方python模块,比如pandas、numpy等。
import pandas as pd
import numpy as np
import time
import math
import talib
import datetime
# 在这个方法中编写任何的初始化逻辑。context对象将会在你的算法策略的任何方法之间做传递。
def init(context):
context.to_buy = ('300033.XSHE','000025.XSHE')
context.ATRperiod=22# ATR 中moving average 的N 值,可自己调, 默认为22
update_universe(context.to_buy)
context.trigger=0
context.initSL=0.9
context.profit=0.2 # 当盈利大于20% 就将阶梯设为此价位。
context.maxvalue=pd.DataFrame()
# 实时打印日志
#scheduler.run_daily(stoploss)
logger.info("Interested at stock: " + str(context.to_buy))
scheduler.run_monthly(position,1)
scheduler.run_daily(stoploss)
def findATR(context,bar_dict,stock): # 玄学指标
close=history(context.ATRperiod+2,'1d','close')[stock][0:context.ATRperiod]
high=history(context.ATRperiod+2,'1d','high')[stock][1:context.ATRperiod+1]
low=history(context.ATRperiod+2,'1d','low')[stock][1:context.ATRperiod+1]
art1=high.values-low.values
art2=abs(close.values-high.values)
art3=abs(close.values-low.values)
art123=np.matrix([art1, art2,art3])
rawatr=np.array(art123.max(0)).flatten()
ATR=rawatr.sum()/len(rawatr)
print(str(rawatr)+'ATR='+str(rawatr))
print(str(stock)+'ATR='+str(ATR))
return ATR
def stoploss(context,bar_dict):
for stock in context.portfolio.positions:
high=bar_dict[stock].high
current=bar_dict[stock].last
bought_value=context.portfolio.positions[stock].bought_value#该股初始价值 单位(RMB)
stockdic=context.maxvalue[stock]
highest=stockdic[0]
del context.maxvalue[stock]
ATR=findATR(context,bar_dict,stock)
#currSP=context.initSPM*(1+math.floor((maxvalue/bought_value-1)/context.step)*context.increment) #阶梯止损算法 例: 该股市值增加10%, 止盈比例提高 5%
temp=pd.DataFrame({str(stock):[max(highest,high)]})
context.maxvalue=pd.concat([context.maxvalue,temp], axis=1, join='inner') # 更新其盘中最高价值和先阶段比例。
print(str(stock)+'的成本为:' +str( context.portfolio.positions[stock].average_cost) +', 最高价为:'+str(highest)+'ATR为:'+ str(ATR))
if bar_dict[stock].last<highest-3*ATR:
print('吊灯止损')
order_target_percent(stock,0)
del context.maxvalue[stock]
#logger.info ( type(market_value))
#logger.info(type(ontext.maxvalue[stock].values)))
pass
# 你选择的证券的数据更新将会触发此段逻辑,例如日或分钟历史数据切片或者是实时数据切片更新
def handle_bar(context, bar_dict):
# 开始编写你的主要的算法逻辑
# bar_dict[order_book_id] 可以拿到某个证券的bar信息
# context.portfolio 可以拿到现在的投资组合状态信息
# 使用order_shares(id_or_ins, amount)方法进行落单
# TODO: 开始编写你的算法吧!
#position(context,bar_dict)
#logger.info(type(context.now))
pass
def createdic(context,bar_dict,stock):
if stock not in context.maxvalue.columns:
temp=pd.DataFrame({str(stock):[0]})
context.maxvalue = pd.concat([context.maxvalue, temp], axis=1, join='inner')
print(context.maxvalue)
def position(context,bar_dict):
if len(context.to_buy)!=0:
for stock in context.to_buy:
createdic(context,bar_dict,stock)
order_target_percent(stock,1/len(context.to_buy))
else:
order_target_percent(stock,0)