Найти минимальное значение между текущим и предыдущим пересечениями скользящих средних в пандах - PullRequest
0 голосов
/ 16 января 2019

У меня есть большой фрейм данных о ценах на акции с df.columns = ['open','high','low','close']

Определение проблемы: Когда происходит пересечение EMA, я упоминаю df ['cross'] = cross. Каждый раз, когда происходит кроссовер, если мы помечаем текущий кроссовер как кроссовер4, я хочу проверить, является ли минимальное значение df ['low'] между кроссовером 3 и 4 БОЛЬШЕ, чем минимальное значение df ['low'] между кроссовером 1 и 2. Я попытался написать код, основанный на помощи, которую я получил от «Герки» до сих пор. Я проиндексировал переход и нашел минимальные значения между последовательными переходами. Таким образом, каждый раз, когда происходит кроссовер, его нужно сравнивать с предыдущими 3 кроссоверами, и мне нужно проверить MIN (CROSS4, CROSS 3)> MIN (CROSS2, CROSS1).

Я был бы очень признателен, если бы вы, ребята, могли бы помочь мне завершить.

import pandas as pd    
import numpy as np    
import bisect as bs

data = pd.read_csv("Nifty.csv")    
df = pd.DataFrame(data)    

df['5EMA'] = df['Close'].ewm(span=5).mean()    
df['10EMA'] = df['Close'].ewm(span=10).mean()    
condition1 = df['5EMA'].shift(1) < df['10EMA'].shift(1)    
condition2 = df['5EMA'] > df['10EMA']    
df['cross'] = np.where(condition1 & condition2, 'cross', None)    
cross_index_array = df.loc[df['cross'] == 'cross'].index

def find_index(a, x):    
    i = bs.bisect_left(a, x)    
    return a[i-1]

def min_value(x):
    """Find the minimum value of 'Low' between crossovers 1 and 2, crossovers 3 and 4, etc..."""    
    cur_index = x.name    
    prev_cross_index = find_index(cross_index_array, cur_index)    
    return df.loc[prev_cross_index:cur_index, 'Low'].min()

df['min'] = None    
df['min'][df['cross'] == 'cross'] = df.apply(min_value, axis=1)    
print(df)

Ответы [ 2 ]

0 голосов
/ 17 января 2019

Если я правильно понимаю ваш вопрос, вам нужно динамическое «скользящее окно», по которому можно рассчитать минимальное значение. Предполагая, что ваш индекс является индексом по умолчанию, то есть он отсортирован в порядке возрастания, вы можете попробовать следующий подход:

import pandas as pd
import numpy as np
from bisect import bisect_left

df = pd.DataFrame({'open': [1, 2, 3, 4, 5],
                   'high': [5, 6, 6, 5, 7],
                   'low': [1, 3, 2, 4, 4],
                   'close': [3, 5, 3, 5, 6]})

При этом используются те же данные выборки, что и для mommermi, но с низким значением на третий день, измененным на 2, поскольку третий день также должен быть включен в "скользящее окно".

df['day'] = np.where(df['close'] > df['open'], 'bull', None)

Мы вычисляем столбец day, используя векторизованную операцию numpy, которая должна быть немного быстрее.

bull_index_array = df.loc[df['day'] == 'bull'].index

Мы храним значения индекса строк (дней), которые мы пометили как быки.

def find_index(a, x):
    i = bisect_left(a, x)
    return a[i-1]

Bisect из базовой библиотеки позволит нам эффективно найти индекс предыдущего бычьего дня. Для этого требуется, чтобы индекс был отсортирован по умолчанию.

def min_value(x):
    cur_index = x.name
    prev_bull_index = find_index(bull_index_array, cur_index)
    return df.loc[prev_bull_index:cur_index, 'low'].min()

Далее мы определяем функцию, которая будет создавать наше «динамическое» скользящее окно, разрезая исходный кадр данных по предыдущему и текущему индексу.

df['min'] = df.apply(min_value, axis=1)

Наконец, мы применяем функцию min_value построчно к кадру данных, получая это:

    open    high    low     close   day     min
0   1       5       1       3       bull    NaN
1   2       6       3       5       bull    1.0
2   3       6       2       3       None    2.0
3   4       5       4       5       bull    2.0
4   5       7       4       6       bull    4.0
0 голосов
/ 16 января 2019

Это должно сработать:

import pandas as pd

df = pd.DataFrame({'open': [1, 2, 3, 4, 5],
                   'high': [5, 6, 6, 5, 7],
                   'low': [1, 3, 3, 4, 4],
                   'close': [3, 5, 3, 5, 6]})

df['day'] = df.apply(lambda x: 'bull' if (
    x['close'] > x['open']) else None, axis=1)

df['min'] = None
df['min'][df['day'] == 'bull'] = pd.rolling_min(
    df['low'][df['day'] == 'bull'], window=2)

print(df)

#    close  high  low  open   day   min
# 0      3     5    1     1  bull   NaN 
# 1      5     6    3     2  bull     1
# 2      3     6    3     3  None  None
# 3      5     5    4     4  bull     3
# 4      6     7    4     5  bull     4

Открыто для комментариев!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...