Вопрос о циклическом переборе фрейма данных Pandas для алгоритма фондового рынка

#python #pandas

#python #pandas

Вопрос:

Я хочу проанализировать торговый алгоритм на исторических данных фондового рынка с помощью python pandas. Но я узнал, что использование зацикливания на больших наборах данных не очень быстрое — это невозможно с миллионами строк.

Итак, я начал с логической индексации. Но я не могу заставить его работать. У кого-нибудь есть подсказка? В моем примере 5 строк, но на самом деле у меня 2 миллиона строк.

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

 ## data set
timehourminute=['15:25','15:30','15:35','15:40','15:45']
close=[21.02,21.05,21.10,21.22, 21.17]
signal=[False,True,True,True,False]
position=[0,0,0,0,0]
data={'timehourminute':timehourminute,'close':close, 'signal':signal,'position':position}
df=pd.DataFrame.from_dict(data)

## if time = 15:30 and signal = True, buy $1000 worth of stocks
subset = (df.timehourminute=='15:30') amp; (df.signal==True)
df.loc[subset,'position']=(1000/df.close)

## if previous row has position, keep the position if the signal is still True
df['positionprev']=df.position.shift(1)
df.position = df.signal * df[['position','positionprev']].max(axis=1)
df.position = df.position.astype(int)
 

Результат таков:

 timehourminute  close  signal  position  positionprev
0          15:25  21.02   False         0           NaN
1          15:30  21.05    True        47      0.000000
2          15:35  21.10    True        47     47.505938
3          15:40  21.22    True         0      0.000000
4          15:45  21.17   False         0      0.000000
 

Проблема в том, что я хочу сохранить позицию до тех пор, пока сигнал не станет ложным. В этом примере сигнал длится 3 строки, но на самом деле он может длиться 1000 строк. Как мне получить значение 47, чтобы оно также оставалось в строке 3?

Ответ №1:

Я считаю, что вам нужны Series.mask пропущенные значения по условиям и прямое заполнение пропущенных значений:

 df['new'] = df.position.mask(df.signal amp; (df.position == 0)).ffill()
print (df)
  timehourminute  close  signal   position        new
0          15:25  21.02   False   0.000000   0.000000
1          15:30  21.05    True  47.505938  47.505938
2          15:35  21.10    True   0.000000  47.505938
3          15:40  21.22    True   0.000000  47.505938
4          15:45  21.17   False   0.000000   0.000000
 

Комментарии:

1. Это потрясающе, именно то, что я искал! Узнаете больше о маске и ffill