from ...forall import *
#######################################################################################################################
# Портфельный анализ с невырожденной ковариационной матрицей
#######################################################################################################################
def PAN_1(n,s_a,s_b, r_ab): # 
    """Инвестор сформировал портфель из акций компаний А и В, затратив на приобретение акций А в `n`
    раз больше средств чем на покупку акций В.
    Ожидаемая доходность за период владения акциями А и В составляет `e_a`% и `e_b`%,
    при этом стандартное отклонение доходности равно `s_a`% и `s_b`%, соответственно.
    Найдите (в %) стандартное отклонение доходности портфеля инвестора,
    если известно, что коэффициент корреляции доходностей акций А и В равен `r_ab`.

    Args:
        n (int): во сколько раз акций А больше, чем В
        s_a (numerical): стандартное отклонение доходности акций А в %
        s_b (numerical): стандартное отклонение доходности акций B в %
        r_ab (numerical): коэффициент корреляции доходностей акций А и В
        
    ## Prints
       `answer` C запятой вместо точки и сокращением до соответствующего количества знаков после запятой

    Returns:
        `answer` (tuple): Соответствующая величина
    """
    from sympy import symbols, Eq, solve
    
    a, b = symbols('a b')

    # Задание системы уравнений
    eq1 = Eq(a, n * b)
    eq2 = Eq(a + b, 1)
    
    # Решение системы
    solution = solve((eq1, eq2), (a, b))
    a, b = solution[a], solution[b]

    var_a = s_a**2
    var_b = s_b**2
    
    var_rx = b**2*var_b + (n*b)**2*var_a + 2*(n*b)*b *s_a*s_b*r_ab
    
    print('стандартное отклонение в % = ' + rrstr(var_rx**0.5,2))
    
    return [var_rx**0.5]
######################################################################################################################
def PAN_2(e_a, e_b, e_c,s_a,s_b,s_c):
    """Ожидаемая доходность и стандартное отклонение доходности
    за период для акций компаний А, В, С составляют 
    `e_a`% `e_b`% `e_c`% и `s_a`% `s_b`% `s_c`%, соответственно.
    - Предполагая независимость доходностей акций А, В и С, найдите (в %)
    ожидаемую доходность портфеля, составленного из этих акций так,
    чтобы дисперсия его доходности была минимальной.

    Args:
        e_a (numerical): Ожидаемая доходность A
        e_b (numerical): Ожидаемая доходность B
        e_c (numerical): Ожидаемая доходность C
        s_a (numerical): стандартное отклонение доходности A
        s_b (numerical): стандартное отклонение доходности B
        s_c (numerical): стандартное отклонение доходности C

    ## Prints
       `answer` C запятой вместо точки и сокращением до соответствующего количества знаков после запятой

    Returns:
        `answer` (tuple): Соответствующая величина
    """
    from sympy import symbols, solve, diff
    
    a,b = symbols('a b')
    
    f = a**2 * s_a**2 + b**2* s_b**2 + (1-a-b)**2 * s_c**2

    # Partial derivatives
    f_a = diff(f, a)
    f_b = diff(f, b)

    critical_points = solve([f_a, f_b], (a, b))
    
    a,b, c = critical_points[a],critical_points[b], 1 - critical_points[a] - critical_points[b]
    
    E = a*e_a + b*e_b + c*e_c
    
    print('Ожидаемая доходность портфеля в % = ' + rrstr(E, 2))
    
    return  [E]
######################################################################################################################
def PAN_3(e_a,e_b,s_a,s_b, r_ab):
    """Математическое ожидание доходности акций компаний А и В составляет `e_a`% и `e_b`%, 
    при этом стандартное отклонение доходности равно `s_a`% и `s_b`%, соответственно. Также известен 
    коэффициент корреляции доходностей акций А и В, `r_ab`. Найдите (короткие позиции допускаются):
    - доли акций А и В в портфеле с минимальной дисперсией доходности;
    - ожидаемую доходность и стандартное отклонение доходности такого портфеля.

    Args:
        e_a (numerical): Математическое ожидание доходности акции компаний А
        e_b (numerical): Математическое ожидание доходности акции компаний В
        s_a (numerical): Стандартное отклонение доходности акции компаний А
        s_b (numerical): Стандартное отклонение доходности акции компаний В 
        r_ab (numerical): Коэффициент корреляции доходностей акций А и В

    ## Prints
        `answer` каждое значение по очереди.<br>C запятой вместо точки и сокращением до соответствующего количества знаков после запятой

    Returns:
        `answer` (tuple): Соответствующие величины
    """


    muA, muB = e_a/100, e_b/100
    sigmaA, sigmaB = s_a/100, s_b/100

    roAB = r_ab

    a = (sigmaB**2 - roAB*sigmaA*sigmaB) / (sigmaA**2 + sigmaB**2 - 2*roAB*sigmaA*sigmaB)
    b = 1-a
    muR = a*muA + b*muB
    VarR = (a**2)*(sigmaA**2) + (b**2)*(sigmaB**2) + 2*a*b*roAB*sigmaA*sigmaB

    answer = (a,b,muR*100,(VarR**0.5)*100)
    
    print('Доля А = ' + rrstr(answer[0],2) + '; доля В = ' + rrstr(answer[1],2))
    print('Ожидаемая доходность = ' + rrstr(answer[2],1) + '; стандартное отклонение = ' + rrstr(answer[3],1))

    return answer
#######################################################################################################################
PAN = [PAN_1,PAN_2,PAN_3]