如何遍历具有多个输入的函数?

时间:2018-12-28 16:23:52

标签: python python-3.x function loops finance

我正在尝试从一个函数(下面的代码)中收集研究回报。不幸的是,我只能让它遍历所有日期,而不能遍历所有索引值。我尝试过的:

for i in index_c.iloc[:,1:]:
    for dt in MICH_CONSUMER_SENTIMENT['Date']:
        c=get_cum_returns(index_c,i,dt,6,5,'MXUS Index')
        cum_ret['index_return'].append(c[0])
        cum_ret['bench_return'].append(c[1])
        cum_ret['abnormal_return'].append(c[2])
        cum_ret['date'].append(dt)

我可以得到一个for循环工作:MICH_CONSUMER_SENTIMENT ['Date']:... 中的 for dt,这样它就将字典'cum_ret'中的一个索引的所有日期值附加到了。但是,如果我尝试循环日期和索引名,则会出现以下错误,并且仅将部分数据追加到字典中:

error

我该如何解决此问题,以便将所有值都附加到字典中?是否有解决此问题的替代方法?我敢肯定,只是我对Python相当陌生。

功能

def get_cum_returns(prices, sid, date, days_before, days_after, 
    benchmark_sid):
    """
    Calculates cumulative and abnormal returns for the sid & benchmark

    Parameters
    ----------
    prices : pd.DataFrame
        Pricing history DataFrame obtained from `get_pricing`. Index should
        be the datetime index and sids should be columns.
    sid : int or zipline.assets._assets.Equity object
        Security that returns are being calculated for.
    date : datetime object
        Date that will be used as t=0 for cumulative return calcuations. All
        returns will be calculated around this date.
    days_before, days_after : int
        Days before/after to be used to calculate returns for.
    benchmark :  int or zipline.assets._assets.Equity object

    Returns
    -------
    sid_returns : pd.Series
        Cumulative returns time series from days_before ~ days_after from date
        for sid
    benchmark_returns : pd.Series
        Cumulative returns time series for benchmark sid
    abnormal_returns : pd.Series
        Abnormal cumulative returns time series for sid compared against 
    benchmark
    """
    prices=index_c
    date=dt
    days_before, days_after=6,5
    sid=i
    benchmark_sid='MXUS Index'
    day_zero_index = prices.index.searchsorted(date)
    #print 'day_zero_index', day_zero_index
    starting_index = max(day_zero_index - days_before, 0)
    ending_index   = min(day_zero_index + days_after + 1, len(prices.index) - 1)

    if starting_index < 0 or ending_index >= len(prices.index):
        assert False #is this possible
        return None

    if sid == benchmark_sid:
        temp_price = prices.iloc[starting_index:ending_index,:].loc[:,[sid]]
    else:
        temp_price = prices.iloc[starting_index:ending_index,:].loc[:,[sid, 
    benchmark_sid]]

    beta = calc_beta(sid, benchmark_sid, temp_price)
    if beta is None:
        #print 'beta is None'
        return

    daily_ret = temp_price.pct_change().fillna(0)

    daily_ret['abnormal_returns'] = daily_ret[sid] - 
    beta*daily_ret[benchmark_sid]

    cum_returns = (daily_ret + 1).cumprod() - 1

    try:
        # If there's not enough data for event study,
        # return None
        cum_returns.index = range(starting_index - day_zero_index,
                                  ending_index - day_zero_index)
    except e:
        print ('exception', e)
        return None

    sid_returns      = cum_returns[sid] - cum_returns[sid].iloc[0]
    bench_returns    = cum_returns[benchmark_sid] - 
    cum_returns[benchmark_sid].iloc[0]
    abnormal_returns = cum_returns['abnormal_returns'] - 
    cum_returns['abnormal_returns'].iloc[0]

    return sid_returns, bench_returns, abnormal_returns

非常感谢所有帮助。

致谢,贾卡

1 个答案:

答案 0 :(得分:0)

错误消息告诉您问题所在:

'NoneType' object is not subscriptable

您的函数有时会返回None,即:如果捕获到异常。但是您的循环然后不会检查c是否为None,而是尝试将其下标,即:假装它是一个列表。