[Python] How to set a boolean flag True after entry and back to False after exit using Pandas...

Discussão em 'Python' iniciado por Stack, Maio 4, 2025.

  1. Stack

    Stack Membro Participativo

    I'm working with a Pandas DataFrame where I need to track a boolean flag (in_position)
    that becomes True after an entry_signal and resets to False only after an exit_signal.

    This must be done vectorized only — no loops — to support millions of rows efficiently.

    ✅ Expected behavior:

    • in_position should turn True only when entering a new state (after a clean entry)
    • It should stay True, even if additional entry_signals appear inside that position
    • It should return to False only after a valid exit_signal

    In other words, entry_signal values during an open position must be ignored.

    ❌ The problem:


    The issue seems to come from the way cumulative comparison works:

    df['in_position'] = df['final_entry'].cumsum() > df['final_exit'].cumsum()


    Even when both cumulative values reach 1, this comparison still evaluates to True on the row after the final_exit, because both values are equal, and > is no longer satisfied only on the same row, but not before it.

    This results in in_position remaining True until the next row — or forever if no new exit appears

    I understand that this is a side effect of how .cumsum() and > behave in vectorized logic.
    What I'm struggling with is:
    ➡️ How to replace this logic with a vectorized alternative that truly toggles the position on entry and resets it exactly at the exit?

    Any help would be appreciated!

    Minimal reproducible example:

    # Step 1: Create minimal dataset with relevant values
    data = {
    'Close': [110, 111, 112, 113, 114, 115, 116],
    'RSI_10': [None, 20, None, 41, 20, None, 61],
    'SMA_200': [100]*7,
    }
    index = pd.to_datetime([
    '2025-04-21', '2025-04-22', '2025-04-23',
    '2025-04-24', '2025-04-25', '2025-04-27', '2025-04-28'
    ])
    df = pd.DataFrame(data, index=index)

    # Step 2: Signals
    df['entry_signal'] = (df['RSI_10'] < 30) & (df['Close'] > df['SMA_200'])
    df['partial_exit_signal'] = df['RSI_10'] > 40
    df['exit_signal'] = df['RSI_10'] > 60

    # Step 3: Cumulative logic - the main problem
    entry_cumsum = df['entry_signal'].cumsum()
    exit_cumsum = df['exit_signal'].cumsum()

    in_position = entry_cumsum > exit_cumsum
    in_position_prev = in_position.shift(1).fillna(False).astype(bool)

    # Step 4: Final signals
    df['final_entry'] = df['entry_signal'] & ~in_position_prev
    df['partial_exit'] = df['partial_exit_signal'] & in_position_prev
    df['final_exit'] = df['exit_signal'] & in_position_prev
    df['in_position'] = in_position
    df['in_position_prev'] = in_position_prev

    print(df[['RSI_10', 'Close', 'entry_signal', 'final_entry', 'final_exit', 'in_position']])

    Continue reading...

Compartilhe esta Página