也就是说,我正在寻找一个函数true_row
,以便:
true_row([False, True, True, True, True, False, False])
返回False
但
true_row([True, True, True, True, True, False, False])
返回True
。
编辑:如果它有帮助,我已经附上了目前为止的完整代码:
position_open = False
def initialize(context):
context.stock = sid(26578)
context.open_hours = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
context.is_bullish = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]
context.first_check_minute = 1
context.second_check_minute = 57
def handle_data(context, data):
event_hour = data[context.stock].datetime.hour
event_minute = data[context.stock].datetime.minute
hour_open_price = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
hour_close_price = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
global position_open
# Hour 1 market direction checks
if event_hour == context.open_hours[0] and event_minute == context.first_check_minute:
hour_open_price[0] = data[context.stock].close_price
if event_hour == context.open_hours[0] and event_minute == context.second_check_minute:
hour_close_price[0] = data[context.stock].close_price
if hour_open_price[0] < hour_close_price[0]:
context.is_bullish[0] = True
if hour_open_price[0] > hour_close_price[0]:
context.is_bullish[0] = False
# Hour 2 market direction checks
if event_hour == context.open_hours[1] and event_minute == context.first_check_minute:
hour_open_price[1] = data[context.stock].close_price
if event_hour == context.open_hours[1] and event_minute == context.second_check_minute:
hour_close_price[1] = data[context.stock].close_price
if hour_open_price[1] < hour_close_price[1]:
context.is_bullish[1] = True
if hour_open_price[1] > hour_close_price[1]:
context.is_bullish[1] = False
# Same block repeated with different numbers x24 (edited out to reduce size)
# Make Trades? - I want to edit this to detect if context.is_bullish has 5 trues in a row without needing to manually make more if statements like the one already below
if event_hour in context.open_hours and context.is_bullish[0] == True and context.is_bullish[1] == True and context.is_bullish[2] == True and context.is_bullish[3] == True and context.is_bullish[4] == True and position_open == False:
order(context.stock,+1000)
log.info('Buy Order Placed')
position_open = True
if event_hour in context.open_hours and context.is_bullish[0] == False and position_open == True:
order(context.stock,-1000)
log.info('Buy Position Closed')
position_open = False
答案 0 :(得分:2)
使用itertools.groupby
,它将一组相同的元素分组:
import itertools
any(len(list(g)) >= 5 and k == True for k, g in itertools.groupby(lst))
答案 1 :(得分:1)
如果您有一个列表l
,则可以使用
('True' * 5) in ''.join(map(str, l))
换句话说,你的功能将是
def true_row(row):
return ('True' * 5) in ''.join(map(str, row))
>>> def true_row(row):
... return ('True' * 5) in ''.join(map(str, row))
...
>>> true_row([False, True, True, True, True, False, False])
False
>>> true_row([True, True, True, True, True, False, False])
True
答案 2 :(得分:0)
如果我正确地读了你的问题,你只对布尔值而不是连续的True值感兴趣。此外,您正在处理 List
而不是任何可迭代的。
如果是这种情况,您可以简单地使用计数。我建议你将序列转换为List以确保你的结果在任何可迭代的
def true_row(row):
return list(row).count(True) >= 5
击> <击> 撞击>
正如OP解释的那样,他需要连续5次布尔肯定,在这种情况下,我会建议一个简单的vanilla循环和计数技术,它有一个短路机制,当它遇到5个连续的True时就退出搜索。在我测试的1000个数据的随机样本上,它快了10倍。我怀疑你可能需要在相当长的时间内迭代数千个库存数据,所以这将非常有用。
def true_row(row, length = 5):
count = - length
for e in row:
if e:
count += 1
else:
count = -length
if not count:
return True
return False
>>> seq = (choice([True, False]) for _ in xrange(1000))
>>> def David(seq):
return any(len(list(g)) >= 5 and k == True for k, g in itertools.groupby(lst))
>>> def ARS(seq):
return ('True' * 5) in ''.join(map(str, row))
>>> t_ab = timeit.Timer(stmt = "true_row(seq)", setup = "from __main__ import true_row, seq")
>>> t_david = timeit.Timer(stmt = "David(seq)", setup = "from __main__ import David, seq, itertools")
>>> t_ars = timeit.Timer(stmt = "ARS(seq)", setup = "from __main__ import ARS, seq")
>>> t_ab.timeit(number=1000000)
0.3180467774861455
>>> t_david.timeit(number=1000000)
10.293826538349393
>>> t_ars.timeit(number=1000000)
4.2967059784193395
即使对于必须在整个序列上迭代的较小序列,这也是更快的
>>> seq = (choice([True, False]) for _ in xrange(10))
>>> true_row(seq)
False
>>> t_ab = timeit.Timer(stmt = "true_row(seq)", setup = "from __main__ import true_row, seq")
>>> t_david = timeit.Timer(stmt = "David(seq)", setup = "from __main__ import David, seq, itertools")
>>> t_ars = timeit.Timer(stmt = "ARS(seq)", setup = "from __main__ import ARS, seq")
>>> t_ab.timeit(number=1000000)
0.32354575678039055
>>> t_david.timeit(number=1000000)
10.270037445319304
>>> t_ars.timeit(number=1000000)
3.7353719451734833
答案 3 :(得分:0)
这是一个为简单而设计的答案
def five_true(L):
for i in range(len(L) - 5):
if L[i:i + 5] == [True] * 5:
return True
return False