2016-10-13 10 views
1

Я пытаюсь построить тренд следуя стратегии импульса портфеля на основе S & индекс P500 (momthly данные)Momentum портфель (тенденция ниже) кванта моделирования на панд

Я использовал фрактальный коэффициент эффективности Kaufmann, чтобы отфильтровать Whipsaw сигнал (http://etfhq.com/blog/2011/02/07/kaufmans-efficiency-ratio/)

Мне удалось кодировать, но это очень неуклюжий, поэтому мне нужен совет для лучшего кода.

Стратегия

  1. Получить данные S & P 500 индекса от Yahoo финансов
  2. соотношение эффективности Вычислить Кауфман на контрольный период Х (1, если закрыть> близко (п), 0)
  3. средних расчетное значение 2, от 1 до 12 периодов времени ---> Ежемесячный коэффициент распределения активов, коэффициент распределения 1 активов = наличные деньги (3% в год)

У меня возникли трудности с averagi ng от 1 до 12. Конечно, я знаю, что его можно просто реализовать для цикла, и это очень простая задача, но я потерпел неудачу.

Мне нужен более сжатый и утонченный код, любой может мне помочь?

а [ «meanfractal»] беспокоит меня в коде ниже ..

Благодаря

import pandas as pd 
import matplotlib.pyplot as plt 
import numpy as np 
import pandas_datareader.data as web 

def price(stock, start): 
    price = web.DataReader(name=stock, data_source='yahoo', start=start)['Adj Close'] 
    return price.div(price.iat[0]).resample('M').last().to_frame('price') 

a = price('SPY','2000-01-01') 

def fractal(a,p): 
    a['direction'] = np.where(a['price'].diff(p)>0,1,0) 
    a['abs'] = a['price'].diff(p).abs() 
    a['volatility'] = a.price.diff().abs().rolling(p).sum() 
    a['fractal'] = a['abs'].values/a['volatility'].values*a['direction'].values 
    return a['fractal'] 

def meanfractal(a): 
    a['meanfractal']= (fractal(a,1).values+fractal(a,2).values+fractal(a,3).values+fractal(a,4).values+fractal(a,5).values+fractal(a,6).values+fractal(a,7).values+fractal(a,8).values+fractal(a,9).values+fractal(a,10).values+fractal(a,11).values+fractal(a,12).values)/12 
    a['portfolio1'] = (a.price/a.price.shift(1).values*a.meanfractal.shift(1).values+(1-a.meanfractal.shift(1).values)*1.03**(1/12)).cumprod() 
    a['portfolio2'] = ((a.price/a.price.shift(1).values*a.meanfractal.shift(1).values+1.03**(1/12))/(1+a.meanfractal.shift(1))).cumprod() 
    a=a.dropna() 
    a=a.div(a.ix[0]) 
    return a[['price','portfolio1','portfolio2']].plot()   

print(a) 
plt.show() 

ответ

2

Вы могли бы упростить далее путем сохранения значений, соответствующих p в DF, а не вычисления для каждой серии отдельно, как показано:

def fractal(a, p): 
    df = pd.DataFrame() 
    for count in range(1,p+1): 
     a['direction'] = np.where(a['price'].diff(count)>0,1,0) 
     a['abs'] = a['price'].diff(count).abs() 
     a['volatility'] = a.price.diff().abs().rolling(count).sum() 
     a['fractal'] = a['abs']/a['volatility']*a['direction'] 
     df = pd.concat([df, a['fractal']], axis=1) 
    return df 

Затем вы можете назначить повторяющиеся операции переменной, время.

def meanfractal(a, l=12): 
    a['meanfractal']= pd.DataFrame(fractal(a, l)).sum(1,skipna=False)/l 
    mean_shift = a['meanfractal'].shift(1) 
    price_shift = a['price'].shift(1) 
    factor = 1.03**(1/l) 
    a['portfolio1'] = (a['price']/price_shift*mean_shift+(1-mean_shift)*factor).cumprod() 
    a['portfolio2'] = ((a['price']/price_shift*mean_shift+factor)/(1+mean_shift)).cumprod() 
    a.dropna(inplace=True) 
    a = a.div(a.ix[0]) 
    return a[['price','portfolio1','portfolio2']].plot() 

Результирующий участок получен:

meanfractal(a) 

Image

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

+1

Большое спасибо ... Было очень полезно –

+0

Когда я вычисляю элементную операцию между кадрами данных, иногда возникает ошибка, если я не кодирую «df.values», но, похоже, в вашем коде нет проблем, непосредственно работающих между dataframe (например, ['fractal'] = a ['abs']/a ['volatility'] * a ['direction']). Какая разница? –

+1

Хороший вопрос. Пока они являются частью одного и того же блока данных, вы можете выполнять арифметические операции посредством их трансляции. Проблема возникает, когда вы хотите размножить два элемента данных по одному или две серии из них, имеющих несоответствие в размерах, что приводит к возврату 'Dans'' DF'. В этих случаях вы должны преобразовать его в его «numpy», обратившись к атрибуту '.values'' DF's', который будет использоваться. –

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

  • Нет связанных вопросов^_^