Как вы индексируете и используете текущие и предыдущие значения столбца для вычисления следующего значения столбца в функции pandas .apply? - PullRequest
1 голос
/ 06 августа 2020

Я пытаюсь создать функцию, которая вычисляет значения трейлинг-стопа с использованием значений Close и ATR из pandas фрейма данных.

Фрейм данных для справки выглядит следующим образом:

            High    Low     Open    Close       ATR 
Date                                
2020-06-01  5.88    5.67    5.73    5.87        0.210000    
2020-06-02  6.00    5.83    5.96    5.90        0.207143    
2020-06-03  6.27    5.92    5.99    6.19        0.218776    
2020-06-04  6.58    6.12    6.20    6.57        0.236006    
2020-06-05  7.50    7.02    7.24    7.34        0.285577    
2020-06-08  7.74    7.37    7.53    7.53        0.293750    
2020-06-09  7.44    7.05    7.22    7.24        0.307053    
2020-06-10  7.34    6.77    7.33    6.81        0.325835    
2020-06-11  6.46    6.04    6.07    6.13        0.357561

Как я хочу, чтобы это выглядело:


            High    Low     Open    Close       ATR         ATR_TS
Date                                
2020-06-01  5.88    5.67    5.73    5.87        0.210000    5.135000
2020-06-02  6.00    5.83    5.96    5.90        0.207143    5.175000
2020-06-03  6.27    5.92    5.99    6.19        0.218776    5.424286
2020-06-04  6.58    6.12    6.20    6.57        0.236006    5.743980
2020-06-05  7.50    7.02    7.24    7.34        0.285577    6.340481
2020-06-08  7.74    7.37    7.53    7.53        0.293750    6.501876
2020-06-09  7.44    7.05    7.22    7.24        0.307053    6.501876
2020-06-10  7.34    6.77    7.33    6.81        0.325835    6.501876
2020-06-11  6.46    6.04    6.07    6.13        0.357561    7.381464

Моя псевдофункция / logi c на данный момент выглядит так:

def atr_ts(close, atr):
    bigatr = atr*3.5
    buysell = 1 
    stop[i-1] = 0  
    
    if buysell > 0:
        stop = close - bigatr
        stop = max(stop, stop[i-1])
        if close < stop:
            stop = close + bigatr
            buysell = -1

    elif buysell < 0:
        stop = close + bigatr
        stop = min(stop, stop[i-1])
        if close > stop:
            stop = close - bigatr
            buysell = 1
        
            
    return stop

df['ATR_TS'] = df.apply(lambda col: atr_ts(col['Close'], col['ATR']), axis = 1)

Итак, мой вопрос, как сделать Я индексирую значения предыдущего стопа (ATR_TS), которые рассчитываются этой функцией, чтобы вычислить значение следующего стопа, при этом значение первого стопа равно 0? Если кто-то видит лучшее решение этой проблемы без использования pandas .apply, поделитесь им.

Я новичок в программировании в целом, поэтому приношу свои извинения, если не хватает ясности.

Спасибо вам так много.

1 Ответ

0 голосов
/ 06 августа 2020

Это не будет окончательным решением, так как я не понимаю, почему последнее значение ATR_TS = 7.381464, хотя я знаю, как вы рассчитали это значение. Я создал ряд столбцов для визуализации способа «pandoni c» для выполнения некоторых вычислений, используя .shift() и .cumsum() для сравнений по строкам. Взгляните на столбцы и мой снимок экрана и объясните, как получить последнее значение, но в окончательном решении нет необходимости во всех этих столбцах:

df['bigatr'] = (df['ATR'] * 3.5)
df['Stop1a'] = df['Close'] - (df['ATR'] * 3.5)
df['Stop2a'] = df.shift()['Close'] - (df.shift()['ATR'] * 3.5)
df['Stop3a'] = df[['Stop1a','Stop2a']].max(axis=1)
df['Stop1b'] = df['Close'] + (df['ATR'] * 3.5)
df['Stop2b'] = df.shift()['Close'] + (df.shift()['ATR'] * 3.5)
df['Stop3b'] = df[['Stop1b','Stop2b']].min(axis=1)
df['cuma'] = (df['Stop1a'] > df.shift()['Stop1a']).cumsum()
df['cumb'] = (df['Stop1b'] < df.shift()['Stop1b']).cumsum()
df['ATR_TSa'] = df.groupby((df['Stop1a'] > df.shift()['Stop1a']).cumsum())['Stop1a'].transform('first')
df['ATR_TSb'] = df.groupby((df['Stop1b'] < df.shift()['Stop1b']).cumsum())['Stop1b'].transform('first')
df

введите описание изображения здесь

Как видите, окончательное решение - это все значения ['ATR_TSa'], обведенные в red, и значение df['ATR_TSb'], обведенное в blue в последней строке.

РЕДАКТИРОВАТЬ # 1 - Согласно комментарию OP, последний лог c для решения вышеуказанной проблемы - это добавить:

 df['ATR_TS'] = np.where((df['Close'] < df['ATR_TSa']), df['ATR_TSb'], df['ATR_TSa'])

Теперь, ниже здесь, я предоставлю более краткое решение:

df['Stop1a'] = df['Close'] - (df['ATR'] * 3.5)
df['Stop1b'] = df['Close'] + (df['ATR'] * 3.5)
a = df.groupby((df['Stop1a'] > df.shift()['Stop1a']).cumsum())['Stop1a'].transform('first')
b = df.groupby((df['Stop1b'] <= df.shift()['Stop1b']).cumsum())['Stop1b'].transform('first')
df['ATR_TS'] = np.where((df['Close'] < a), b, a)
df = df.drop(['Stop1a','Stop1b'], axis=1)
df


Out[1]: 
         Date  High   Low  Open  Close       ATR    ATR_TS
0  2020-06-01  5.88  5.67  5.73   5.87  0.210000  5.135000
1  2020-06-02  6.00  5.83  5.96   5.90  0.207143  5.175000
2  2020-06-03  6.27  5.92  5.99   6.19  0.218776  5.424284
3  2020-06-04  6.58  6.12  6.20   6.57  0.236006  5.743979
4  2020-06-05  7.50  7.02  7.24   7.34  0.285577  6.340480
5  2020-06-08  7.74  7.37  7.53   7.53  0.293750  6.501875
6  2020-06-09  7.44  7.05  7.22   7.24  0.307053  6.501875
7  2020-06-10  7.34  6.77  7.33   6.81  0.325835  6.501875
8  2020-06-11  6.46  6.04  6.07   6.13  0.357561  7.381463
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...