该函数设计目的:保护既得利润,以N日内持仓股票最低盈利被突破为触发条件,所以持股时间最低为N日,为保证有效持股,N日之前亏损不会计入(该条件不需要的可以自己去掉)。函数以股票为输入,需要在自己的函数(持股或卖出判断)每日调用。需要自定义全局(JQ提交代码不能提交函数外的东东)。

函数怎么运行的:
为输入的股票(当然是自己的持仓的)建立一个长度为N的队列(FIFO,先进先出),比如,建仓股票A了,则新建队列{A:队列}的数据格式,然后每日调用将盈亏比例记录到队列当中,当队列长度达到N,就开始取队列中的最小值和新来的(就是第N+1天来的)盈亏比进行比较,新来的大,就把第一天的盈利数据删除,再把新来的记录进去。反之就触发卖出。如此,只要不触发卖出就继续持股,判断的始终是距离函数调用日期前N日的盈利,从而实现动态保护利润。

当然,该函数还可以改成你想的形式(自己实现咯):
比如:N日内平均利润被突破后触发卖出
比如:N日内最高利润回调多少后触发卖出
比如:最高利润达到一定范围回调触发卖出,最高利润10%回调3%就卖,20%回调6%就卖,30%回调10%就买等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#全局参数
#存储持股的字典{security:qu.Queue(maxsize = g.queue_longth )}
g.security_win_queue = {}
#N日长度定义
g.queue_longth = 12


def security_win_queue(context,security):
current_price = history(1, '1m', 'close', security).iloc[0].iloc[0]
# 获取买入平均价格
avg_cost = context.portfolio.positions[security].avg_cost
#盈利推入队列dd['bar'].append('quux')
win_percentage = (current_price - avg_cost)/avg_cost * 100
#若是新增,则例行初始化{security:queue}
if not g.security_win_queue.has_key(security):
g.security_win_queue[security] = qu.Queue(maxsize=g.queue_longth)

#没有记满,就继续记
if not g.security_win_queue[security].full():
#亏损的比例在持股初期不录入保证未突破止损线之前不卖出
if win_percentage > 0:
g.security_win_queue[security].put(win_percentage)
print(security,win_percentage,'qsize:',g.security_win_queue[security].qsize())
#满了则进行盈利比较
else:
#取N日最小值盈利
tmp_win_list = []
<!-- more -->
queue_size = g.security_win_queue[security].qsize()
for w in range(queue_size):
tmp_win_list.append(g.security_win_queue[security].get())

#排序盈利并取最小
sorted_tmp_win_list = sorted(tmp_win_list)
#排除最小值后把队列恢复。
minimum = sorted_tmp_win_list[0]
#排除最小值[0]
for w in range(1,queue_size):
g.security_win_queue[security].put(sorted_tmp_win_list[w])
if win_percentage < minimum:
#返回true则需要卖出否则返回false继续持有
return True
else:
#将新的盈利推入队列
g.security_win_queue[security].put(win_percentage)
return False