2016-12-28 3 views
1

Я играю с действительно красивым кодом @piRSquared, и этот код можно увидеть ниже.Наклонная зависимость - изменение функционального кода

Я добавил еще одно условие if row[col2] == 4000, и это видно только один раз в дополнительной колонке, которую я добавил. Как и ожидалось, этот дополнительный код имеет функцию, которая дает только одну строку, поскольку условие видно только один раз.

Мой вопрос заключается в том, как изменить код, чтобы получить другую строку после перемещения >= move_size.

Желаемый результат - две строки. Один, когда row['B'] == 4000 (по мере создания кода), а другой, когда видят движение >= move_size в Col A. Я рассматриваю их как запись и выход в трей, поэтому было бы неплохо иметь идентификатор заказа в другом столбце фрейма данных df['C'] согласно желаемому результату, показанному ниже.

код из оригинального поста: функция

#starting python community conventions 
import numpy as np 
import pandas as pd 

# n is number of observations 
n = 5000 

day = pd.to_datetime(['2013-02-06']) 
# irregular seconds spanning 28800 seconds (8 hours) 
seconds = np.random.rand(n) * 28800 * pd.Timedelta(1, 's') 
# start at 8 am 
start = pd.offsets.Hour(8) 
# irregular timeseries 
tidx = day + start + seconds 
tidx = tidx.sort_values() 

s = pd.Series(np.random.randn(n), tidx, name='A').cumsum() 
s.plot() 

Генератор с небольшой модификацией:

def mover_df(df, col,col2, move_size=10): 
    ref = None 
    for i, row in df.iterrows(): 
     #added test condition for new col2 signal column 
     if row[col2] == 4000: 
      if ref is None or (abs(ref - row.loc[col]) >= move_size): 
       yield row 
       ref = row.loc[col] 

Генерация данных

df = s.to_frame() 
df['B'] = range(0,len(df)) 

moves_df = pd.concat(mover_df(df, 'A','B', 3), axis=1).T 

Выход по току:

        A   B 
2013-02-06 14:30:43.874386317 -50.136432 4000.0 

Желаемый результат:

(Значения в перевалы A,B на втором ряду будет то, что код генерирует, я только что добавили случайные значения, чтобы показать формат я «заинтересован в. Col C является торговой идентификатор и для каждых двух строк это будет увеличивать +1)

        A   B  C 
2013-02-06 14:30:43.874386317 -50.136432 4000.0 1 
2013-02-06 14:30:43.874386317 -47.136432 6000.0 1 

Я привязывался к этому часу в течение нескольких часов (не помогает детям, которые бегают по дому, теперь школьные каникулы ...) и ценят любую помощь. Было бы фантастически получить информацию от @piRSquared, но высоко ценит, что люди заняты.

ответ

1

Я бы редактировать mover_df как этот
примечание:
Я изменил 4000 условие % 1000 == 0 дать несколько больше образцов

def mover_df(df, move_col, look_col, move_size=10): 
    ref, seen = None, False 
    for i, row in df.iterrows(): 
     #added test condition for new col2 signal column 
     look_cond = row[look_col] % 1000 == 0 
     if look_cond and not seen: 
      yield row 
      ref, seen = row.loc[move_col], True 
     elif seen: 
      move_cond = (abs(ref - row.loc[move_col]) >= move_size) 
      if move_cond: 
       yield row 
       ref, seen = None, False 


df = s.to_frame() 
df['B'] = range(0,len(df)) 

moves_df = pd.concat(mover_df(df, 'A','B', 3), axis=1).T 

print(moves_df) 

             A  B 
2013-02-06 08:00:03.264481639 0.554390  0.0 
2013-02-06 08:04:26.609855185 -2.479520 35.0 
2013-02-06 09:38:07.962175581 -15.042391 1000.0 
2013-02-06 09:40:50.737806497 -18.385956 1026.0 
2013-02-06 11:13:03.018013689 -29.074125 2000.0 
2013-02-06 11:14:30.980633575 -32.221009 2019.0 
2013-02-06 12:49:41.432845325 -35.048040 3000.0 
2013-02-06 12:50:28.098114592 -38.881795 3012.0 
2013-02-06 14:27:15.008225195 13.437165 4000.0 
2013-02-06 14:27:32.790466500 9.513736 4003.0 

РИСКОВАННОЙ
Это будет продолжать искать выход, пока не будет найдено, или вы дойдете до конца dataframe, даже если вы достигнете другой потенциальной точки входа. Смысл, в моем примере, я смотрю каждые 1000 строк и вхожу. Затем я ищу, когда движение больше 10 и выйдет. Если я не нахожу ход выше 10 до того, как выйдет следующий 1000-рядный рынок, я проигнорирую этот маркер 1000 строк и продолжу поиск выхода.

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

+0

Еще раз спасибо @piRSquared Caveat. Очень приятно получать отзывы от профессионала в области финансов, который так хорош с Python! Существуют ли какие-либо подходы, которые я должен исследовать для проведения такого базового тестирования? Легко получить сигналы с помощью np.where и аналогичных фильтров - именно такой тип целевого и стоп-лосс-анализа я считаю более сложным. Я рассматриваю только простые внутридневные стратегии. – ade1e

+1

Обычно, когда я иду по дороге, создавая инструмент для бэктестинга, я задаю много и много вопросов. Трудно предсказать их все впереди (хотя мы стараемся). Я получаю, где вы идете с очень высокого уровня. Но без всяких подробностей, мне нечего добавить. Как всегда, задавайте множество вопросов, когда сталкиваетесь с проблемами. Я постараюсь помочь, когда смогу. – piRSquared

2

У меня не слишком много опыта с генераторами или пандами, но это работает? Мои данные имеют разный выход из-за случайного семени, поэтому я не уверен.

Я изменил генератор, чтобы включить альтернативный случай, учитывая, что первый столбец row[col2] == 4000, поэтому вызов генератора дважды должен дать оба значения:

def mover_df(df, col, col2, move_size=10, found=False): 
    ref = None 
    for i, row in df.iterrows(): 
     #added test condition for new col2 signal column 
     if row[col2] == 4000: 
      if ref is None or (abs(ref - row.loc[col]) >= move_size): 
       yield row 
       found = True # flag that we found the first row we want 
       ref = row.loc[col] 
     elif found: # if we found the first row, find the second meeting the condition 
      if ref is None or (abs(ref - row.loc[col]) >= move_size): 
       yield row 

И тогда вы можете использовать его как это:

data_generator = mover_df(df, 'A', 'B', 3) 
moves_df = pd.concat([data.next(), data.next()], axis=1).T 
+0

Большое спасибо. Я отметил ответ. – ade1e

Смежные вопросы