Не совсем понятен вопрос, будем считать. что вы просто хоте использовать функционал pandas для поиска нужных значений, потому как в вашем коде вы его не используете почти совсем:
import pandas as pd
# чтение и подготовка данных
df = pd.read_csv("usdchf_07_2023_support.csv", index_col=0, delimiter='\t', usecols=["time",'open', 'high', 'low', 'close'])
df.index = pd.to_datetime(df.index)
df_res = df.loc[df.index.to_series().between('2023-07-03 15:00:00', '2023-07-07 15:00:00')]
# собственно, решение:
delta = 0.0005
df_res = df_res.assign(num_nearest =
df_res["low"].
apply(lambda x: abs(x-df_res.loc[:,"low"])
.le(delta).sum()))
print(df_res[df_res["num_nearest"] == df_res["num_nearest"]
.max()].drop_duplicates(subset="low"))
open high low close num_nearest
time
2023-07-03 17:00:00 0.89691 0.89769 0.89531 0.89613 37
2023-07-03 19:00:00 0.89567 0.89620 0.89541 0.89615 37
2023-07-04 14:00:00 0.89556 0.89630 0.89542 0.89591 37
2023-07-06 22:00:00 0.89601 0.89601 0.89548 0.89548 37
2023-07-07 08:00:00 0.89584 0.89601 0.89538 0.89594 37
то есть, у вас будет 5 значений low (не считая дубликатов) с нужными вам критериями.
UPDATE
Если нужно разбить данные по позициям, где close
пробивает или равно low
, то можно сделать так, например:
import pandas as pd
df = pd.read_csv("usdchf_07_2023_support.csv", index_col=0, delimiter='\t', usecols=["time",'open', 'high', 'low', 'close'])
df.index = pd.to_datetime(df.index)
df_res = df.loc[df.index.to_series().between('2023-07-03 15:00:00', '2023-07-07 15:00:00')]
res = pd.DataFrame()
for i,g in df_res.groupby(df_res["close"].le(df_res["low"]).cumsum()): # здесь le
# (меньше или равно), поскольку в примере, как я понял, нет close ниже low.
# Если нужно строго меньше, то замените на lt
g=g.assign(num_nearest =
g["low"].
apply(lambda x: abs(x-g.loc[:,"low"])
.le(delta).sum()))
res = pd.concat([res, g[g["num_nearest"] == g["num_nearest"].
max()].drop_duplicates(subset="low")])
print(res)
open high low close num_nearest
time
2023-07-04 01:00:00 0.89615 0.89645 0.89578 0.89637 6
2023-07-04 04:00:00 0.89630 0.89651 0.89565 0.89647 15
2023-07-05 01:00:00 0.89671 0.89710 0.89668 0.89702 14
2023-07-06 01:00:00 0.89813 0.89860 0.89808 0.89855 8
2023-07-06 03:00:00 0.89853 0.89898 0.89824 0.89870 8
2023-07-06 04:00:00 0.89873 0.89905 0.89832 0.89835 8
2023-07-06 05:00:00 0.89835 0.89850 0.89805 0.89837 8
2023-07-06 07:00:00 0.89843 0.89911 0.89835 0.89849 8
2023-07-07 14:00:00 0.89530 0.89559 0.89509 0.89558 15
в этом случае точек больше, но и расстояние до соседей меньше, и это расстояние не превышает расстояние до ближайших "пробивающих" close
.
** UPDATE 2 **
Узкое место алгоритма в том, что он в пределах выбранной группы не обращал внимание на строки в которых close
ниже low
в любой другой строке.
Вероятно, придется итерировать, что, как очевидно, не самое эффективное про времени занятие:
import pandas as pd
df = pd.read_csv("usdcad_H1_04_2023_support.csv", index_col=0, delimiter='\t', usecols=["time",'open', 'high', 'low', 'close'])
df_res = df.loc[df.index.to_series().between('2023-07-03 15:00:00', '2023-07-07 15:00:00')]
delta = 0.0005
res = pd.DataFrame()
for i, g in df_res.groupby(df_res["close"].le(df_res["low"]).cumsum()):
for row in g.itertuples():
r = g[(g["close"]<row[3]).cumsum()==0]
r=r.assign(num_nearest =
r["low"].
apply(lambda x: abs(x-r.loc[:,"low"])
.le(delta).sum()))
if len(r):
res = pd.concat([res, r[r["num_nearest"] == r["num_nearest"].
max()].drop_duplicates(subset="low")])
print(res)
получаем res:
open high low close num_nearest
time
2023-07-03 15:00:00 1.32500 1.32618 1.32444 1.32515 1
2023-07-03 15:00:00 1.32500 1.32618 1.32444 1.32515 2
2023-07-03 16:00:00 1.32515 1.32624 1.32425 1.32443 2
2023-07-03 15:00:00 1.32500 1.32618 1.32444 1.32515 5
2023-07-03 15:00:00 1.32500 1.32618 1.32444 1.32515 5
2023-07-03 15:00:00 1.32500 1.32618 1.32444 1.32515 2
2023-07-03 16:00:00 1.32515 1.32624 1.32425 1.32443 2
2023-07-03 15:00:00 1.32500 1.32618 1.32444 1.32515 1
2023-07-03 15:00:00 1.32500 1.32618 1.32444 1.32515 1
2023-07-03 15:00:00 1.32500 1.32618 1.32444 1.32515 1
2023-07-04 01:00:00 1.32458 1.32504 1.32436 1.32495 10
2023-07-04 03:00:00 1.32482 1.32499 1.32440 1.32488 10
2023-07-04 04:00:00 1.32489 1.32567 1.32457 1.32477 10
2023-07-04 07:00:00 1.32477 1.32539 1.32435 1.32519 10
2023-07-04 01:00:00 1.32458 1.32504 1.32436 1.32495 10
2023-07-04 03:00:00 1.32482 1.32499 1.32440 1.32488 10
2023-07-04 04:00:00 1.32489 1.32567 1.32457 1.32477 10
2023-07-04 07:00:00 1.32477 1.32539 1.32435 1.32519 10
2023-07-04 09:00:00 1.32539 1.32553 1.32330 1.32330 1
2023-07-04 10:00:00 1.32329 1.32400 1.32291 1.32328 5
2023-07-04 11:00:00 1.32328 1.32436 1.32293 1.32374 5
2023-07-04 10:00:00 1.32329 1.32400 1.32291 1.32328 5
2023-07-04 11:00:00 1.32328 1.32436 1.32293 1.32374 5
2023-07-04 10:00:00 1.32329 1.32400 1.32291 1.32328 5
2023-07-04 11:00:00 1.32328 1.32436 1.32293 1.32374 5
2023-07-04 10:00:00 1.32329 1.32400 1.32291 1.32328 5
2023-07-04 11:00:00 1.32328 1.32436 1.32293 1.32374 5
2023-07-04 10:00:00 1.32329 1.32400 1.32291 1.32328 5
2023-07-04 11:00:00 1.32328 1.32436 1.32293 1.32374 5
2023-07-04 10:00:00 1.32329 1.32400 1.32291 1.32328 5
2023-07-04 11:00:00 1.32328 1.32436 1.32293 1.32374 5
2023-07-04 10:00:00 1.32329 1.32400 1.32291 1.32328 5
2023-07-04 11:00:00 1.32328 1.32436 1.32293 1.32374 5
2023-07-04 17:00:00 1.32226 1.32244 1.32136 1.32136 1
2023-07-04 20:00:00 1.32194 1.32276 1.32172 1.32240 10
2023-07-04 20:00:00 1.32194 1.32276 1.32172 1.32240 10
2023-07-05 23:00:00 1.32816 1.32864 1.32790 1.32790 1
2023-07-07 07:00:00 1.33640 1.33664 1.33601 1.33641 16
2023-07-07 07:00:00 1.33640 1.33664 1.33601 1.33641 16
2023-07-05 23:00:00 1.32816 1.32864 1.32790 1.32790 1
2023-07-07 07:00:00 1.33640 1.33664 1.33601 1.33641 16
я практически уверен, что уже есть готовые средства для подобных подсчетов, надо только поискать. ну и опять же, алгоритм надо бы проверить.