<jupyter_start><jupyter_text>Выделенные риск-факторы1. Фондовый риск — риск снижения цены акций; __индекс РТС и МОЕКС__2. Процентный риск — риск изменения процентных ставок; __процентные ставки__3. Валютный риск — риск изменения курсов валют; __курс доллара и курс юаня__4. Товарный риск — риск изменения цен товаров; __цены на нефть__  Стохастическая модель динамики<jupyter_code>import numpy as np
import pandas as pd
import os
from scipy.interpolate import CubicSpline
class Portfolio():
    def __init__(self, bonds, shares, cur, risk):
        self.bonds = bonds
        self.shares = shares
        self.cur = cur
        self.risk = risk
        self.price = 0
        
    # Посчитать цену портфеля в определённый день
    def countPriceInDate(self, date):
        res = 0
        
        for i in self.bonds:
            res += i[3] * i[1]['<CLOSE>'].loc[date]
            
        for i in self.shares:
            res += i[3] * i[1]['<CLOSE>'].loc[date]
            
        
    # Посчитать объём портфеля в уе
    def countInitialValue(self):
        for i in range(len(self.bonds)):
            amount = self.bonds[i][2] / self.bonds[i][1]['<CLOSE>'][0]
            self.bonds[i] = (*self.bonds[i], amount)
            
        for i in range(len(self.shares)):
            amount = self.shares[i][2] / self.shares[i][1]['<CLOSE>'][0]
            self.shares[i] = (*self.shares[i], amount)
            
        for i in range(len(self.cur)):
            amount = self.cur[i][2] / self.cur[i][1]['<CLOSE>'][0]
            self.cur[i] = (*self.cur[i], amount)
# Загрузка данных в класс
shares = ['./shares/AFLT_160101_200101.csv', 
          './shares/GAZP_160101_200101.csv',
          './shares/GMKN_160101_200101.csv', 
          './shares/KMAZ_160101_200101.csv', 
          './shares/LKOH_160101_200101.csv', 
          './shares/PIKK_160101_200101.csv', 
          './shares/MGNT_160101_200101.csv', 
          './shares/RBCM_160101_200101.csv', 
          './shares/ROSN_160101_200101.csv', 
          './shares/SBER_160101_200101.csv']

shares_name = [i[9:13] for i in shares]

# Нужно интерполировать
bonds = ['./bonds/SU26212RMFS9_160101_200101.csv',
         './bonds/SU26205RMFS3_160101_200101.csv',
         './bonds/SU26207RMFS9_160101_200101.csv', 
         './bonds/SU26209RMFS5_160101_200101.csv', 
         './bonds/SU26211RMFS1_160101_200101.csv']

bonds_name = [i[8:20] for i in bonds]

currencies = ['./index/USD_RUB.csv', './index/CNY_RUB.csv']

currencies_name = [i[8:15] for i in currencies]

indexes = ['./index/ICE.BRN_160101_200101.csv', 
           './index/IMOEX_160101_200101.csv', 
           './index/RTSI_160101_200101.csv']

indexes_name = ['Brent', 'MOEX', 'RTSI']

zero_bond = './zerobond.csv'

days = 1010
risk_df = pd.read_csv(shares[0], index_col='<DATE>').drop(['<TICKER>', '<PER>', '<TIME>', '<HIGH>', '<LOW>', '<VOL>', '<OPEN>'], axis=1)
risk_df.index = pd.to_datetime(risk_df.index)
k = 1
for i in shares[1:]:
    tmp = pd.read_csv(i, index_col='<DATE>') \
            .drop(['<TICKER>', '<PER>', '<TIME>', '<HIGH>', '<LOW>', '<VOL>', '<OPEN>'], axis=1) \
            .rename(columns={'<CLOSE>': shares_name[k]})
    tmp.index = pd.to_datetime(tmp.index)
    risk_df = risk_df.join(tmp, how='left')
    k += 1
    
k = 0
for i in bonds:
    tmp = pd.read_csv(i, index_col='<DATE>') \
            .drop(['<TICKER>', '<PER>', '<TIME>', '<HIGH>', '<LOW>', '<VOL>', '<OPEN>'], axis=1) \
            .rename(columns={'<CLOSE>' : bonds_name[k]})
    tmp.index = pd.to_datetime(tmp.index)
    risk_df = risk_df.join(tmp, how='left')
    k += 1
    
k = 0
for i in currencies:
    tmp = pd.read_csv(i, index_col='Date') \
            .drop(['Open', 'High', 'Low', 'Change %'], axis=1) \
            .rename(columns={'Price' : currencies_name[k]})
    tmp.index = pd.to_datetime(tmp.index)
    risk_df = risk_df.join(tmp, how='left')
    k += 1
    
k = 0
for i in indexes:
    tmp = pd.read_csv(i, index_col='<DATE>') \
            .drop(['<TICKER>', '<PER>', '<TIME>', '<HIGH>', '<LOW>', '<VOL>', '<OPEN>'], axis=1) \
            .rename(columns={'<CLOSE>' : indexes_name[k]})
    tmp.index = pd.to_datetime(tmp.index)
    risk_df = risk_df.join(tmp, how='left')
    k += 1

risk_df = risk_df.rename(columns={'<CLOSE>' : shares_name[0]})

zero_bond_df = pd.read_csv(zero_bond, sep=';', index_col='Date')
zero_bond_df.index = pd.to_datetime(zero_bond_df.index)

risk_df = risk_df.join(zero_bond_df, how='left')
risk_df = risk_df.fillna(risk_df.mean(axis=0))
tmp = risk_df.diff()
temp = risk_df.iloc[:-1,:]
temp.index = tmp.iloc[1:,:].index
tmp = tmp.iloc[1:,:] / temp
def get_data():
    #Здесь - подгрузка и подготовка данных

    shares = ['./shares/AFLT_160101_200101.csv', 
              './shares/GAZP_160101_200101.csv',
              './shares/GMKN_160101_200101.csv', 
              './shares/KMAZ_160101_200101.csv', 
              './shares/LKOH_160101_200101.csv', 
              './shares/PIKK_160101_200101.csv', 
              './shares/MGNT_160101_200101.csv', 
              './shares/RBCM_160101_200101.csv', 
              './shares/ROSN_160101_200101.csv', 
              './shares/SBER_160101_200101.csv']

    shares_name = [i[9:13] for i in shares]

    # Нужно интерполировать
    bonds = ['./bonds/SU26212RMFS9_160101_200101.csv',
             './bonds/SU26205RMFS3_160101_200101.csv',
             './bonds/SU26207RMFS9_160101_200101.csv', 
             './bonds/SU26209RMFS5_160101_200101.csv', 
             './bonds/SU26211RMFS1_160101_200101.csv']

    bonds_name = [i[8:20] for i in bonds]

    currencies = ['./index/USD_RUB.csv', './index/CNY_RUB.csv']

    currencies_name = [i[8:15] for i in currencies]

    indexes = ['./index/IMOEX_160101_200101.csv', 
               './index/RTSI_160101_200101.csv', 
               './index/ICE.BRN_160101_200101.csv']

    indexes_name = ['MOEX', 'RTSI', 'Brent']

    zero_bond = './zerobond.csv'

    act_instruments = pd.read_csv(shares[0], index_col='<DATE>').drop(['<TICKER>', '<PER>', '<TIME>', '<HIGH>', '<LOW>', '<VOL>', '<OPEN>'], axis=1)
    act_instruments.index = pd.to_datetime(act_instruments.index)
    k = 1
    for i in shares[1:]:
        tmp = pd.read_csv(i, index_col='<DATE>') \
                .drop(['<TICKER>', '<PER>', '<TIME>', '<HIGH>', '<LOW>', '<VOL>', '<OPEN>'], axis=1) \
                .rename(columns={'<CLOSE>': shares_name[k]})
        tmp.index = pd.to_datetime(tmp.index)
        act_instruments = act_instruments.join(tmp, how='left')
        k += 1
        
    k = 0
    for i in bonds:
        tmp = pd.read_csv(i, index_col='<DATE>') \
                .drop(['<TICKER>', '<PER>', '<TIME>', '<HIGH>', '<LOW>', '<VOL>', '<OPEN>'], axis=1) \
                .rename(columns={'<CLOSE>' : bonds_name[k]})
        tmp.index = pd.to_datetime(tmp.index)
        act_instruments = act_instruments.join(tmp, how='left')
        k += 1

    act_instruments = act_instruments.rename(columns={'<CLOSE>' : shares_name[0]})
    act_instruments = act_instruments.fillna(act_instruments.mean(axis=0))
        
    act_risks = pd.read_csv(indexes[0], index_col='<DATE>').drop(['<TICKER>', '<PER>', '<TIME>', '<HIGH>', '<LOW>', '<VOL>', '<OPEN>'], axis=1)
    act_risks.index = pd.to_datetime(act_risks.index) 

    k = 1
    for i in indexes[1:]:
        tmp = pd.read_csv(i, index_col='<DATE>') \
                .drop(['<TICKER>', '<PER>', '<TIME>', '<HIGH>', '<LOW>', '<VOL>', '<OPEN>'], axis=1) \
                .rename(columns={'<CLOSE>' : indexes_name[k]})
        tmp.index = pd.to_datetime(tmp.index)
        act_risks = act_risks.join(tmp, how='left')
        k += 1

    k = 0
    for i in currencies:
        tmp = pd.read_csv(i, index_col='Date') \
                .drop(['Open', 'High', 'Low', 'Change %'], axis=1) \
                .rename(columns={'Price' : currencies_name[k]})
        tmp.index = pd.to_datetime(tmp.index)
        act_risks = act_risks.join(tmp, how='left')
        k += 1
    
    zero_bond_df = pd.read_csv(zero_bond, sep=';', index_col='Date')
    zero_bond_df.index = pd.to_datetime(zero_bond_df.index)
    act_risks = act_risks.join(zero_bond_df, how='left')
    act_risks = act_risks.fillna(act_risks.mean(axis=0))

    tmp = act_risks.diff()
    temp = act_risks.iloc[:-1,:]
    temp.index = tmp.iloc[1:,:].index
    r_risks = tmp.iloc[1:,:] / temp
    
    tmp = act_instruments.diff()
    temp = act_instruments.iloc[:-1,:]
    temp.index = tmp.iloc[1:,:].index
    r_instruments = tmp.iloc[1:,:] / temp

    # act_risks = pd.DataFrame() # реальные значения риск-факторов
    # act_instruments = pd.DataFrame() # реальные значения инструментов
    # r_risks = pd.DataFrame() # Риск-факторы, посчитанные в арифметических процентах
    # r_instruments = pd.DataFrame() # доходность инструментов, посчитанная в арифметических процентах

    return    r_risks, r_instruments, act_risks, act_instruments

get_data()
risk_df
risk_df.diff()
t = 1
vol = [(-1 + np.sqrt(1 + (1 / 1009) * np.sum((log_risk_df[log_risk_df.columns[i]] - t*np.mean(log_risk_df[log_risk_df.columns[i]]))**2))) / (t/2) for i in range(len(log_risk_df.columns))]
vol
def get_index():
    moex_ind = pd.read_csv('./index/IMOEX_160101_200101.csv')
    rts_ind = pd.read_csv('./index/RTSI_160101_200101.csv')
    zerobond = pd.read_csv('./zerobond.csv', sep=';')
    
    weeks_in_month = (365/7)*(1/12)
    maturity_rub = [3,6,9,12,24,36,60,84,120,180,240,360,]
    maturity_rub= [i * weeks_in_month for i in maturity_rub]
    
    interpolate_rub = CubicSpline(maturity_rub, ds_rate_rub)
    
    interval_rub = np.arange(0, 54, 2)
    
    df_rub_int = pd.DataFrame(data={'maturity_rub_2weeks': interval_rub, 'rub_act': interpolate_rub(interval_rub)})
    
    df_rub_usd_int=pd.concat([df_usd_int, df_rub_int], axis=1, sort=False)
    df_rub_usd_int=df_rub_usd_int.drop(['maturity_rub_2weeks'], axis=1)
    df_rub_usd_int=df_rub_usd_int.rename(columns={"maturity_usd_2weeks":"maturity"})
    df_rub_usd_int['maturity_frac'] = df_rub_usd_int['maturity']/54

    # s=0.0134
    s=1/0.01442

    new_rates = pd.concat(
        [
            df_rub_usd_int,
            df_rub_usd_int.diff(1).rename(columns={x:x.replace('act','diff') for x in df_rub_usd_int.columns})
        ],
        axis=1)

    new_rates.fillna(0, inplace=True)
    new_rates['fx_act']=(s*(1+new_rates['usd_act']*0.01)/(1+new_rates['rub_act']*0.01))
    new_rates['fx_diff'] =new_rates['fx_act'].diff()


    curve_rub_act = new_rates.loc[1:,'rub_act']
    curve_usd_act = new_rates.loc[1:,'usd_act']
    curve_fx_act = new_rates.loc[1:,'fx_act']

    curve_rub_diff = new_rates.loc[1:,'rub_diff']
    curve_usd_diff = new_rates.loc[1:,'usd_diff']
    curve_fx_diff = new_rates.loc[1:,'fx_diff']
    init = new_rates.loc[0,['rub_act','usd_act','fx_act']]


    return  (
        curve_rub_act,
        curve_usd_act,
        curve_fx_act,
        curve_rub_diff,
        curve_usd_diff,
        curve_fx_diff,
        init)
    
    
    
    
    def stoch_wrapper(decomp):
        def make_stoch(num):
            sigma=[0.03, 0.0093, 0.11]
            stoch_generator = np.dot(np.random.normal(size=(num,3)),decomp)*sigma
            return stoch_generator
        return make_stoch

    
stoch_generator = stoch_wrapper(get_decomp())

def simulate_hull_white(
    sim_number = 10,):
    rub_alpha=0.03
    sigma=[0.03, 0.0093, 0.11]
    k_fx=0.015
    dt=14/365
    timesteps = 26

    (
        curve_rub,
        curve_rub_df,
        init
        ) = get_rates()


    results = np.zeros(shape=(timesteps+1, 3, sim_number))

    passed_time=0

    for sim_ix in range(sim_number):
        results[0, :, sim_ix] = init
        stochs = stoch_generator(timesteps+1)
        for i, (rate_rub, df_rub, stoch_tuple) in enumerate(zip(curve_rub,curve_rub_df, stochs)):
            
            passed_time += dt

            theta_rub = df_rub + rub_alpha * rate_rub + (sigma[0]**2) * (1 - np.exp(-2 * rub_alpha * passed_time)) / 2 * rub_alpha

            results[i + 1, 0, sim_ix] = (theta_rub - rub_alpha* results[:, 0, sim_ix].sum()) * dt + stoch_tuple[0]

    return results<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.17173465183353934, 'fraction_numerical': 0.060980634528224144, 'mean_word_length': 2.8103610675039246, 'pattern_counts': {'":': 1, '<': 90, '<?xml version=': 0, '>': 90, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '581146', 'license': 'MIT', 'n_tokens_mistral': 5280, 'n_tokens_neox': 4895, 'n_words': 754, 'path': 'Iriski.ipynb', 'repo_name': 'Penitto/risk_project1', 'size': '12135'}