【问题标题】:Python - Pandas Dataframe - data not matching sourcePython - Pandas Dataframe - 数据与源不匹配
【发布时间】:2016-06-20 18:08:51
【问题描述】:

我正在尝试使用来自雅虎的月度股票数据来分析模式。出于某种原因,该程序在数据框中为特定股票 (ATVI) 吐出的月度回报与实际雅虎网站的回报不匹配。我比较了 2015 年期间的月度回报,并包括了平均增加和减少的列以及每个列的出现次数。

雅虎链接:https://finance.yahoo.com/q/hp?s=ATVI&a=00&b=1&c=2015&d=11&e=31&f=2015&g=m

我的代码:

from datetime import datetime
from pandas_datareader import data, wb
import pandas_datareader.data as web
import pandas as pd
from pandas_datareader._utils import RemoteDataError
import csv
import sys
import os
import time

class MonthlyChange(object):
    months = { 0:'JAN', 1:'FEB', 2:'MAR', 3:'APR', 4:'MAY',5:'JUN', 6:'JUL', 7:'AUG', 8:'SEP', 9:'OCT',10:'NOV', 11:'DEC' }

def __init__(self,month):
    self.month = MonthlyChange.months[month-1]
    self.sum_of_pos_changes=0
    self.sum_of_neg_changes=0
    self.total_neg=0
    self.total_pos=0
def add_change(self,change):
    if change < 0:
        self.sum_of_neg_changes+=change
        self.total_neg+=1
    elif change > 0:
        self.sum_of_pos_changes+=change
        self.total_pos+=1
def get_data(self):
    if self.total_pos == 0:
        return (self.month,0.0,0,self.sum_of_neg_changes/self.total_neg,self.total_neg)
    elif self.total_neg == 0:
        return (self.month,self.sum_of_pos_changes/self.total_pos,self.total_pos,0.0,0)
    else:
        return (self.month,self.sum_of_pos_changes/self.total_pos,self.total_pos,self.sum_of_neg_changes/self.total_neg,self.total_neg)


for ticker in ['ATVI']: 

try:

    data = web.DataReader(ticker.strip('\n'), "yahoo", datetime(2015,01,1), datetime(2015,12,31))
    data['ymd'] = data.index
    year_month = data.index.to_period('M')
    data['year_month'] = year_month
    first_day_of_months = data.groupby(["year_month"])["ymd"].min()
    first_day_of_months = first_day_of_months.to_frame().reset_index(level=0)
    last_day_of_months = data.groupby(["year_month"])["ymd"].max()
    last_day_of_months = last_day_of_months.to_frame().reset_index(level=0)
    fday_open = data.merge(first_day_of_months,on=['ymd'])
    fday_open = fday_open[['year_month_x','Open']]
    lday_open = data.merge(last_day_of_months,on=['ymd'])
    lday_open = lday_open[['year_month_x','Open']]

    fday_lday = fday_open.merge(lday_open,on=['year_month_x'])
    monthly_changes = {i:MonthlyChange(i) for i in range(1,13)}
    for index,ym, openf,openl in fday_lday.itertuples():
        month = ym.strftime('%m')
        month = int(month)
        diff = (openf-openl)/openf
        monthly_changes[month].add_change(diff)

    changes_df = pd.DataFrame([monthly_changes[i].get_data() for i in monthly_changes],columns=["Month","Avg Inc.","Inc","Avg.Dec","Dec"])


    print ticker
    print changes_df

【问题讨论】:

    标签: python pandas logic yahoo-finance


    【解决方案1】:

    要获得平均每日涨/跌价格变动,您可以:

    from pandas_datareader.data import DataReader
    
    data = DataReader('ATVI', "yahoo", datetime(2015, 1, 1), datetime(2015, 12, 31))[['Open', 'Close']]
    open = data.Close.resample('M').first() # get the open of the first day, assign date of last day of month
    close = data.Close.resample('M').last()  # get the close of the last day, assign date of last day of month
    returns = close.subtract(open).div(open) # calculate returns
    

    得到:

    Date
    2014-01-31   -0.052020
    2014-02-28    0.134232
    2014-03-31    0.047131
    2014-04-30   -0.032866
    2014-05-31    0.040561
    2014-06-30    0.081474
    2014-07-31   -0.007539
    2014-08-31    0.049020
    2014-09-30   -0.124263
    2014-10-31   -0.031083
    2014-11-30    0.066503
    2014-12-31   -0.042755
    2015-01-31    0.038251
    2015-02-28    0.103644
    2015-03-31   -0.022366
    2015-04-30    0.017387
    2015-05-31    0.095879
    2015-06-30   -0.046850
    2015-07-31    0.042863
    2015-08-31    0.121865
    2015-09-30    0.108758
    2015-10-31    0.124919
    2015-11-30    0.089384
    2015-12-31    0.003630
    Freq: M, Name: Close, dtype: float64
    

    要按月计算平均值,您可以:

    returns.groupby(returns.index.month).mean()
    

    得到:

    1    -0.006884
    2     0.118938
    3     0.012383
    4    -0.007739
    5     0.068220
    6     0.017312
    7     0.017662
    8     0.085442
    9    -0.007752
    10    0.046918
    11    0.077943
    12   -0.019563
    

    【讨论】:

    • 我正在寻找数据框中的平均增加/平均减少列,以匹配我使用上面发布的网站的月度数据获得的回报。返回=(开-关)/开
    • Open/Close中查看平均差异的更新。
    • @Stefan,感谢您的帮助。老实说,我不知道把你的代码放在我的哪里。您可以修改我发布的代码吗?另外,我希望根据当月第一天的开盘价和当月最后一天的收盘价获得回报(抱歉,如果之前不清楚)return =(最后一天的收盘价-开盘价)第一天)/第一天开盘 然后取每个月的平均值 --> 如果周期是 2 年,那么(2014 年 7 月 + 2015 年 7 月)/2 = 平均回报率
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-19
    • 2017-07-29
    • 1970-01-01
    • 1970-01-01
    • 2020-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多