Рассчитать рост стоимости портфеля в Python / Pandas / Django - PullRequest
0 голосов
/ 05 августа 2020

У меня есть этот набор данных:

                YAR.OL     NHY.OL  ...      DNB.OL     SBO.OL
date                               ...                       
1986-03-13         NaN        NaN  ...         NaN        NaN
1986-03-14         NaN        NaN  ...         NaN        NaN
1986-03-17         NaN        NaN  ...         NaN        NaN
1986-03-18         NaN        NaN  ...         NaN        NaN
1986-03-19         NaN        NaN  ...         NaN        NaN
...                ...        ...  ...         ...        ...
2020-07-24  377.799988  26.740000  ...  144.500000  51.000000
2020-07-27  381.799988  26.350000  ...  142.199997  50.599998
2020-07-28  382.399994  26.490000  ...  142.000000  50.200001
2020-07-29  377.899994  26.389999  ...  142.100006  50.799999
2020-07-30  372.000000  25.049999  ...  137.149994  49.799999

И эти списки, содержащие торговую информацию:

ticker_list = ['YAR.OL', 'NHY.OL', 'TSLA', 'MSFT', 'STB.OL', 'DNB.OL', 'SBO.OL']
transaction_price_list = [100.0, 21.0, 1850.0, 100.0, 100.0, 100.0, 40.0]
transaction_date_list = [datetime.date(2020, 6, 17), datetime.date(2020, 5, 12), datetime.date(2020, 6, 9), datetime.date(2020, 7, 23), dt.datetime.date(2020, 3, 11), dt.datetime.date(2002, 2, 13), dt.datetime.date(2020, 2, 18)]
trade_volum_list = [10, 194, 10, 10, 10, 100, 10]

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

Мой код выглядит так:

def portfolio_growth(self, ticker_list, transaction_price_list, transaction_date_list, trade_volum_list):

    df = self.dataset_creator(ticker_list)
    new_df = pd.DataFrame(index=df.index)
    df.index = pd.to_datetime(df.index)
    
    for ticker, price, dates, volume in zip(ticker_list, transaction_price_list, transaction_date_list, trade_volum_list):

        first_date_to_str = str(dates)
        first_date_to_dt = dt.datetime.strptime(first_date_to_str, '%Y-%m-%d')
        first_date_to_date = first_date_to_dt.date()

        s = df[ticker]

        new_df[ticker] = s.loc[first_date_to_date::] * volume
        new_df[first_date_to_date,ticker] = price * volume

    first_date = min(transaction_date_list)
    sum_df = new_df.sum(axis=1)
    sum_df = sum_df.loc[first_date::]
    portfolio_df = pd.DataFrame(index=sum_df.index)
    portfolio_df['Portfolio_Value'] = sum_df


    return portfolio_df

Однако я не могу правильно рассчитать это. Когда я распечатываю файлfolio_df, я получаю взамен этот фрейм данных.

            Portfolio_Value
date                       
2002-02-13     39952.730011
2002-02-14     40076.180099
2002-02-15     40076.180099
2002-02-19     40057.179855
2002-02-20     40095.170044
...                     ...
2020-07-24     76590.759861
2020-07-27     77568.399464
2020-07-28     76927.159840
2020-07-29     77127.960266
2020-07-30     76285.898682

13 февраля 2002 г. стоимость портфеля должна быть 1000, так как я покупаю 10 MSFT по 100 каждый. И та же ошибка повторяется на протяжении всего метода.

Мне удалось сделать это в excel: Расчеты в Excel

Как мне записать этот код в Python? И как это будет работать, если будет еще и ордер на продажу?

Я знаю, что это может быть много, я очень ценю любую помощь, которую могу получить. Спасибо :)

Сокращение примера до 2 акций и 5 дней.

                YAR.OL     NHY.OL  
date                                                      
2020-07-24  377.799988  26.740000 
2020-07-27  381.799988  26.350000 
2020-07-28  382.399994  26.490000  
2020-07-29  377.899994  26.389999  
2020-07-30  372.000000  25.049999  

Списки сделок:

ticker_list = ['YAR.OL', 'NHY.OL']
transaction_price_list = [370, 26]
transaction_date_list = [datetime.date(2020, 7, 24), datetime.date(2020, 7, 28)]
trade_volum_list = [10, 15]

1 Ответ

1 голос
/ 05 августа 2020

Согласно обсуждению, вот мое решение. Не слишком элегантно, но вроде работает:

Вот ваши данные:

    import pandas as pd
    import datetime
    import numpy as np


    price_df = pd.DataFrame({'price_date': [datetime.datetime(2020, 7, 24), datetime.datetime(2020, 7, 25) ,
                                     datetime.datetime(2020, 7, 26), datetime.datetime(2020, 7, 27), 
                                    datetime.datetime(2020, 7, 28), datetime.datetime(2020, 7, 29), 
                            datetime.datetime(2020, 7, 30)], 'A' : np.linspace(1,100, 7), 
                            'B' : np.linspace(100,200, 7)})
    
    
    ticker_list = ['A', 'B', 'A']
    transaction_price_list  = [10,15, 70 ]
    transaction_date_list = [datetime.datetime(2020, 7, 24),
                             datetime.datetime(2020, 7, 28), 
                            datetime.datetime(2020, 7, 30)]
    trade_volum_list = [10, 15, -5]
    

Некоторые преобразования:

    trade_df = pd.DataFrame({'ticker':ticker_list,
                             'transact_price': transaction_price_list, 
                             'transact_date':transaction_date_list,
                            'trade_vol' : trade_volum_list})


    
    trade_df['purchase_indicator'] = trade_df.trade_vol/abs(trade_df.trade_vol)
    trade_df.loc[trade_df.purchase_indicator == -1, 'purchase_indicator'] =0
    
    
    final_df = pd.DataFrame(price_df.price_date)
    final_df['port_value'] = 0
    for el_ticker in set(ticker_list):
        temp_df_1 = trade_df.loc[trade_df.ticker == el_ticker, ]
        temp_df_2 = pd.merge(price_df[['price_date', el_ticker]],  temp_df_1, how = 'left',
               left_on='price_date', right_on='transact_date')
        
        temp_df_2.trade_vol.fillna(0, inplace= True)
        temp_df_2.purchase_indicator.fillna(0, inplace= True)
        temp_df_2.transact_price.fillna(0, inplace= True)
        
        temp_df_2['shares'] = temp_df_2.trade_vol.cumsum()
        temp_df_2['price_choice'] = (temp_df_2.purchase_indicator) * temp_df_2.transact_price + (1- temp_df_2.purchase_indicator) * temp_df_2[el_ticker]
        temp_df_2['value']  = temp_df_2.price_choice * temp_df_2.shares
    
        final_df.port_value = final_df.port_value + temp_df_2.value
    
    final_df


price_date  port_value
0   2020-07-24  100.0
1   2020-07-25  175.0
2   2020-07-26  340.0
3   2020-07-27  505.0
4   2020-07-28  895.0
5   2020-07-29  3585.0
6   2020-07-30  3500.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...