from tqsdk import TargetPosTask,TqApi,TqSim
from tqsdk.tafunc import ma
from tqsdk.ta import SAR,ATR,BOLL,MA
SYMBOL = ‘DCE.p2101’
long_stop = []
short_stop = []
af = 0
Acceleration = 0.05
mark_high = []
mark_low = []
api = TqApi()
position = api.get_position(SYMBOL)
klines = api.get_kline_serial(SYMBOL,300)
target_pos = TargetPosTask(api,SYMBOL)
quote = api.get_quote(SYMBOL)
current_price = klines[‘close’].iloc[-1]
def ma_lines(quote,klines):
n1 = MA(klines,5)
n2 = MA(klines,10)
n3 = MA(klines,20)
ma_n1 = n1.ma.iloc[-1]
ma_n2 = n2.ma.iloc[-1]
ma_n3 = n3.ma.iloc[-1]
#print(ma_n1,ma_n2,ma_n3)
return ma_n1,ma_n2,ma_n3
def boll_lines(quote,klilnes):
boll = BOLL(klines,26,2)
mid = boll[‘mid’].iloc[-1]
top = boll[‘top’].iloc[-1]
bottom = boll[‘bottom’].iloc[-1]
#print(mid,top,bottom)
return mid,top,bottom
def hs_atr(quote,klines):
atr = ATR(klines,14)
return atr
ma_n1,ma_n2,ma_n3 = ma_lines(quote,klines)
mid,top,bottom = boll_lines(quote,klines)
atr = hs_atr(quote,klines)
while True:
api.wait_update()
if api.is_changing(klines.iloc[-1],’datetime’):
ma_n1,ma_n2,ma_n3 = ma_lines(quote,klines)
mid,top,bottom = boll_lines(quote,klines)
atr = hs_atr(quote,klines)
current_price = klines[‘close’].iloc[-1]
print(‘5分钟:%2f,10分钟:%2f,20分钟:%2f,中轨:%2f’ %(ma_n1,ma_n2,ma_n3,mid))
if position.pos_long > 0:
print(‘记录的最高价:%2f,K线最高价:%2f’%(mark_high[-1],klines.high.iloc[-2]))
mark_high.append(max(mark_high[-1],klines.high.iloc[-2]))
if mark_high[-1] > mark_high[-2] and af < 0.2:
af = af + min(Acceleration,0.2 – af)
long_stop = long_stop + af * (mark_high[-1] – long_stop)
print(‘多头止盈线:%2f’ %long_stop.iloc[-1])
elif position.pos_short > 0:
print(‘记录的最低价:%2f,K线最低价:%2f’%(mark_low[-1],klines.low.iloc[-2]))
mark_low.append(min(mark_low[-1],klines.low.iloc[-2]))
if mark_low[-1] < mark_low[-2] and af < 0.2:
af = af + min(Acceleration,0.2 – af)
short_stop = short_stop – af * (short_stop – mark_low[-1])
print(‘空头止盈线:%2f’ %short_stop.iloc[-1])
if api.is_changing(quote,’last_price’):
if position.pos_long == 0 and position.pos_short == 0:
if (ma_n1 > ma_n2) and (ma_n2 > ma_n3) and (current_price > mid):
print(‘做多时机,开多’)
target_pos.set_target_volume(2)
mark_high.append(klines.high.iloc[-2])
long_stop = klines.low.iloc[-2] – atr.iloc[-1] * 1.2
af = Acceleration
elif (ma_n1 < ma_n2) and (ma_n2 < ma_n3) and (current_price < mid):
print(‘做空时机,开空’)
target_pos.set_target_volume(-2)
mark_low.append(klines.low.iloc[-2])
short_stop = klines.high.iloc[-2] + atr.iloc[-1] * 1.2
af = Acceleration
elif position.pos_long > 0 and quote.last_price < long_stop[-1]:
target_pos.set_target_volume(0)
print(‘多头平仓’)
long_stop = 0
short_stop = 0
af = 0
mark_high.clear()
mark_low.clear()
print(mark_high,mark_low)
elif position.pos_short > 0 and quote.last_price > short_stop[-1]:
target_pos.set_target_volume(0)
print(‘空头平仓’)
long_stop = 0
short_stop = 0
af = 0
mark_high.clear()
mark_low.clear()
print(mark_high,mark_low)
api.close()
刚才试着跑了一下,并没有报错。
我觉得,这个报错可能是在58行或者66行
58行 mark_high[-1] > mark_high[-2]
66行 mark_low[-1] < mark_low[-2]
假设当天空仓开多,到76行addend一个值。
现在是持仓状态,到57行再addend一个值,
58行mark_high[-1] > mark_high[-2]刚好ok。
但是,当隔夜持仓。第二天重新启动程序的时候,
11行 mark_high = []
57行 addend一个值
58行 mark_high[-2] 就会报错:list index out of range
所以,你可以试试把mark_high等保存到本地,请参见此贴https://www.shinnytech.com/question/6364/
另提个建议:
1.
就我而言,计算K线后我会取[-2]的值。[-1]是当天K线数据,在收盘前它都可能改变,比如某个时刻ma1>ma2,但下一个时刻可能ma1<ma2,这种情况如果发生在一根K线内肯定不是我想要的交易信号和结果。
2.
40行 return atr.atr.iloc[-2] # 当然[-1]也是可以的。但不建议用atr参与后面的计算,因atr是一个序列,此例中并不需要用到整个序列
77行 long_stop = klines.low.iloc[-2] – atr * 1.2
84行 short_stop = klines.high.iloc[-2] + atr * 1.2
69行 print(‘空头止盈线:%2f’ %short_stop)
97行 elif position.pos_short > 0 and quote.last_price > short_stop:
67行 elif position.pos_long > 0 and quote.last_price < long_stop:
61行 print(‘多头止盈线:%2f’ %long_stop)
3.
mark_high,mark_low推荐用字典保存,可能会高效一点点
大概就是这样了