2016-07-08 17 views
4

株のリストの在庫情報を取得するためのスクリプトを作成しました。関係する株式(groupbyのグループ)については、私はMACDを計算する必要があります。は、python pandas経由でMACDを計算することができません

在庫の価格を他のものと混ぜないように、私はパンダグループを使用します。

# -*- coding: utf-8 -*- 

import pandas as pd 
from pandas.io.data import DataReader 
import numpy as np 
import time 
from io import StringIO 

runstart = time.time()  # Start script timer 

stocklist = ['nflx','mmm'] 
tickers = [] 
days_backtest=102 # MA98 kræver 102 d for at virke! 
end = pd.Timestamp.utcnow() 
start = end - days_backtest * pd.tseries.offsets.BDay() 

    # Fetch stockinfo 
def GetStock(stocklist, start, end, csv_file_all='alltickers_ohlc.csv'): 
    ''' 
    Fetches stock-info for analysis of each ticker in stocklist 
    ''' 
    print('\nGetting Stock-info from Yahoo-Finance') 
    for ticker in stocklist: 
     r = DataReader(ticker, "yahoo", 
         start = start, end = end) 
     # add a symbol column 
     r['Ticker'] = ticker 
     tickers.append(r) 
    # concatenate all the dfs 
    df_all = pd.concat(tickers) 

    # add col without space in adj close 
    df_all['Adj_Close'] = df_all['Adj Close'] 
    #define df with the columns that i need    These can be put back in df_all 
    df_all = df_all[['Ticker','Adj_Close','Volume']] #'Adj Close','Open','High','Low', 

    # round to 2 dig. 
# df_all['Open'] = np.round(df_all['Open'], decimals=2) 
# df_all['High'] = np.round(df_all['High'], decimals=2) 
# df_all['Low'] = np.round(df_all['Low'], decimals=2) 
# df_all['Adj Close'] = np.round(df_all['Adj Close'], decimals=2) 
    df_all['Adj_Close'] = np.round(df_all['Adj_Close'], decimals=2) 

# # Test the first 3 rows of each group for 'Difference' col transgress groups... 
# df_all_test = df_all.groupby('Ticker').head(27).reset_index().set_index('Date') 
# print ('\n df_all_test (27d summary from df) (Output)\n',df_all_test,'\n') 

    # saving to a csv # 
    df_all.reset_index().sort(['Ticker', 'Date'], ascending=[1,1]).set_index('Ticker').to_csv(csv_file_all, date_format='%Y/%m/%d') 
# df_all.sort_index(inplace=True) # Sorts rows from date, mingling tickers - not wanted 
    print('========= Picked up new stockinfo (df_all) \n') 
# print ('df_all.tail (Input)\n',df_all.tail(6),'\n') 
    print(70 * '-') 
# print(df_all) 

    return df_all 

def moving_average(group, n=9, type='simple'): 
    """ 
    compute an n period moving average. 
    type is 'simple' | 'exponential' 
    """ 
    group = np.asarray(df_['Adj_Close']) 
    if type == 'simple': 
     weights = np.ones(n) 
    else: 
     weights = np.exp(np.linspace(-1., 0., n)) 

    weights /= weights.sum() 

    a = np.convolve(group, weights, mode='full')[:len(group)] 
    a[:n] = a[n] 
    return a 
# return pd.DataFrame({'MCD_Sign':a}) 

def moving_average_convergence(group, nslow=26, nfast=12): 
    """ 
    compute the MACD (Moving Average Convergence/Divergence) using a fast and slow exponential moving avg' 
    return value is emaslow, emafast, macd which are len(x) arrays 
    """ 
    emaslow = moving_average(group, nslow, type='exponential') 
    emafast = moving_average(group, nfast, type='exponential') 
# return emaslow, emafast, emafast - emaslow 

    return pd.DataFrame({'emaSlw': emaslow, 
        'emaFst': emafast, 
        'MACD': emafast - emaslow}) 


if __name__ == '__main__': 

    ### Getstocks 
    df_all = GetStock(stocklist, start, end) 
    ### Sort DF 
    df_all.reset_index().sort(['Ticker', 'Date'], ascending=[1,1]).set_index('Ticker') 

    ### groupby screeener (filtering to only rel ticker group) 
    df_ = df_all.set_index('Ticker', append=True) 
    ''' Calculating all the KPIs via groupby (filtering pr ticker)''' 
    grouped = df_.groupby(level=1).Adj_Close  
    nslow = 26 
    nfast = 12 
    nema = 9 

    df_[['emaSlw', 'emaFst', 'MACD']] = df_.groupby(level=1).Adj_Close.apply(moving_average_convergence) 
    df_['MCD_Sign'] = df_.groupby(level=1).Adj_Close.apply(moving_average) 

    print ('(Output df)\n',df_,'\n') 

    df = df_.reset_index('Ticker')  
    # Test the last row of each group for new numbers pr group... 
    df_test = df.groupby('Ticker').tail(1).reset_index().set_index('Date') 
    print ('df_test (summary from df) (Output)\n',df_test,'\n') 

すべてのMACD番号の列には結果が表示されません。だからどこかで計算が遅くなる。間違って何が起こっているか私は...のよう見当もつかない

出力ラインのPRの株式ティッカー:君たちの

df_test (summary from df) (Output) 
      Ticker Adj_Close Volume emaSlw emaFst MACD MCD_Sign 
Date                 
2016-07-07 nflx  95.10 9902700  NaN  NaN NaN  NaN 
2016-07-07 mmm  174.87 1842300  NaN  NaN NaN  NaN 

どれ...先端!?

答えて

6

だから、ここに本当に必要なものより多くの仕事をしたように見えます。答えは少しシンプルです。あなた自身の移動平均関数を定義する必要はありません。これは実際にあなたの問題の原因となっています。

変更moving_averageへ:

def moving_average(group, n=9): 
    sma = pd.rolling_mean(group, n) 
    return sma 

変更moving_average_converganceへ:

def moving_average_convergence(group, nslow=26, nfast=12): 
    emaslow = pd.ewma(group, span=nslow, min_periods=1) 
    emafast = pd.ewma(group, span=nfast, min_periods=1) 
    result = pd.DataFrame({'MACD': emafast-emaslow, 'emaSlw': emaslow, 'emaFst': emafast}) 
    return result 

N.B.私はここに「MACD」を最初に付けました。なぜなら、それがどのようにリストされているにもかかわらず、DataFrameは列をアルファベット順に並べ替えるからです。

最後に変更:

df_[['emaSlw', 'emaFst', 'MACD']] = df_.groupby(level=1).Adj_Close.apply(moving_average_convergence) 

へ:

それを行う必要があります
df_[['MACD', 'emaSlw', 'emaFst']] = df_.groupby(level=1).Adj_Close.apply(moving_average_convergence) 

関連する問題