-3

也就是说,我正在寻找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
4

4 回答 4

2

使用itertools.groupby,将一组相同的元素组合成一行:

import itertools
any(len(list(g)) >= 5 and k == True for k, g in itertools.groupby(lst))
于 2013-01-06T17:08:01.207 回答
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
于 2013-01-06T17:07:43.733 回答
0

如果我正确阅读了您的问题,那么您只对布尔计数感兴趣,而不是对连续的 True 值感兴趣。此外,您正在研究 aList而不是任何可迭代的。如果是这种情况,您可以简单地使用计数。我建议您将序列转换为 List 以确保您的结果在任何可迭代对象中都是一致的

def true_row(row):
    return list(row).count(True) >= 5

正如 OP 所解释的,他需要 5 个连续的布尔确认,在这种情况下,我会建议一种普通的循环和计数技术,它具有短路机制,可以在遇到连续 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
于 2013-01-06T17:41:59.383 回答
0

这是一个为简单而设计的答案

def five_true(L):
    for i in range(len(L) - 5):
        if L[i:i + 5] == [True] * 5:
            return True
    return False
于 2013-01-06T17:46:37.237 回答