因为很多量化在线平台目前还不支持期货交易,且KD指标对大盘和热门大盘股有着较高的准确性,故此策略选取'0700.HKEX'为标的股票,HSI.HKEX为参考标准。
策略逻辑:
当kt-1>80,dt-2>80, jt>100时,股价创50日新高,KDJ指标未创新高,卖出
当kt-1<20,dt-2<20, jt<0 时,股价创50日新低,KDJ指标未创新低,买入
来源:郑宏韬. KDJ指标在证券投资分析中的应用[J]. 中国证券期货, 2012(7):14-14.
import numpy as np
import pandas as pd
from pandas import DataFrame
import talib as ta
# 选取腾讯控股
instruments = ['0700.HKEX']
# 开始时间
start_date = '2011-11-08'
# 结束时间
end_date = '2017-11-08'
# 策略比较参考标准,恒生指数
benchmark = 'HSI.HKEX'
# 初始化账户
def initialize(context):
context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5)) # 设置手续费,买入成本为万分之三,卖出为千分之1.3
def handle_data(context, data):
k = instruments[0] # 标的为字符串格式
sid = context.symbol(k) # 将标的转化为equity格式
price = data.current(sid, 'price') # 最新价格
cash = context.portfolio.cash # 现金
cur_position = context.portfolio.positions[sid].amount # 持仓
curr= data.current(sid,'price')
indicators={} #指标
hp=data.history(sid, 'high', 50, '1d')
lp=data.history(sid, 'low', 50, '1d')
cp=data.history(sid, 'close', 50, '1d')
indicators['k'],indicators['d']=ta.STOCH(np.array(hp,dtype='f8'),np.array(lp,dtype='f8'),np.array(cp,dtype='f8'),fastk_period=9,slowk_period=3,slowk_matype=0,slowd_period=3,slowd_matype=0)
indicators['j']=np.array(indicators['k'])*3-np.array(indicators['d'])*2
indicators['closePrice']=cp
indicators=pd.DataFrame(indicators)#将字典形式转化为dataframe格式
k_min=float(indicators.loc[:,['k']].min())
d_min=float(indicators.loc[:,['d']].min())
j_min=float(indicators.loc[:,['j']].min())
k_max=float(indicators.loc[:,['k']].max())
d_max=float(indicators.loc[:,['d']].max())
j_max=float(indicators.loc[:,['j']].max())
# 交易逻辑
if indicators.iloc[-1]['k'] > 80 and indicators.iloc[-2]['d'] > 80 :
if indicators.iloc[-1]['k'] < indicators.iloc[-1]['d'] and indicators.iloc[-2]['k'] > indicators.iloc[-2]['d']:
if curr > data.history(sid, 'price', 50, '1d').max():
if indicators.iloc[-1]['k']<k_max and indicators.iloc[-1]['d']<d_max:
if indicators.iloc[-1]['j']<j_max:#kdj 未创新高
if cur_position >= 0:
context.order_target_percent(sid, 0)
elif indicators.iloc[-1]['k'] < 20 and indicators.iloc[-2]['d'] < 20 :
if indicators.iloc[-1]['k'] > indicators.iloc[-1]['d'] and indicators.iloc[-2]['k'] < indicators.iloc[-2]['d']:
if curr < data.history(sid, 'price', 50, '1d').min():
if indicators.iloc[-1]['k'] >k_min:
if indicators.iloc[-1]['d'] > d_min :
if indicators.iloc[-1]['j']>j_min:#kdj 未创新低
if cash >= 0:
number = (int((cash / curr) / 100)) * 100
if number > 0:
context.order_target_percent(sid, number)
m=M.trade.v3(
instruments=instruments,
start_date=start_date,
end_date=end_date,
initialize=initialize,
handle_data=handle_data,
order_price_field_buy='open', # 以开盘价买入
order_price_field_sell='open', # 以开盘价卖出
capital_base=1000000, # 本金
benchmark=benchmark,
)