Example #1
0
def solve_portfolio_model(model, pf_names, order=2, lambda_name='lam', guess=None):

    from dolo.compiler.compiler_python import GModel
    if isinstance(model, GModel):
        model = model.model

    pf_model = model

    from dolo import Variable, Parameter, Equation
    import re

    n_states = len(pf_model.symbols_s['states'])
    states = pf_model.symbols_s['states']
    steady_states = [Parameter(v.name+'_bar') for v in pf_model.symbols_s['states']]
    n_pfs = len(pf_names)

    pf_vars = [Variable(v) for v in pf_names]
    res_vars = [Variable('res_'+str(i)) for i in range(n_pfs)]


    pf_parms = [Parameter('K_'+str(i)) for i in range(n_pfs)]
    pf_dparms = [[Parameter('K_'+str(i)+'_'+str(j)) for j in range(n_states)] for i in range(n_pfs)]

    from sympy import Matrix

    # creation of the new model

    import copy

    new_model = copy.copy(pf_model)

    new_model.symbols_s['controls'] += res_vars
    for v in res_vars + pf_vars:
        new_model.calibration_s[v] = 0


    new_model.symbols_s['parameters'].extend(steady_states)
    for p in pf_parms + Matrix(pf_dparms)[:]:
        new_model.symbols_s['parameters'].append(p)
        new_model.calibration_s[p] = 0

    compregex = re.compile('(.*)<=(.*)<=(.*)')

    to_be_added_1 = []
    to_be_added_2 = []

    expressions = Matrix(pf_parms) + Matrix(pf_dparms)*( Matrix(states) - Matrix(steady_states))

    for n,eq in enumerate(new_model.equations_groups['arbitrage']):
        if 'complementarity' in eq.tags:
            tg = eq.tags['complementarity']
            [lhs,mhs,rhs] = compregex.match(tg).groups()
            mhs = new_model.eval_string(mhs)
        else:
            mhs = None
        if mhs in pf_vars:
            i = pf_vars.index(mhs)
            neq = Equation(mhs, expressions[i])
            neq.tag(**eq.tags)
            eq_res = Equation(eq.gap, res_vars[i])
            eq_res.tag(eq_type='arbitrage')
            to_be_added_2.append(eq_res)
            new_model.equations_groups['arbitrage'][n] = neq
            to_be_added_1.append(neq)

    # new_model.equations_groups['arbitrage'].extend(to_be_added_1)
    new_model.equations_groups['arbitrage'].extend(to_be_added_2)
    new_model.update()

    print("number of equations {}".format(len(new_model.equations)))
    print("number of arbitrage equations {}".format( len(new_model.equations_groups['arbitrage'])) )

    print('parameters_ordering')
    print("number of parameters {}".format(new_model.symbols['parameters']))
    print("number of parameters {}".format(new_model.parameters))


    # now, we need to solve for the optimal portfolio coefficients
    from trash.dolo.numeric.perturbations_to_states import approximate_controls

    dr = approximate_controls(new_model)
    print('ok')

    import numpy

    n_controls = len(model.symbols_s['controls'])

    def constant_residuals(x, return_dr=False):
        d = {}
        for i in range(n_pfs):
            p = pf_parms[i]
            v = pf_vars[i]
            d[p] = x[i]
            d[v] = x[i]
        new_model.set_calibration(d)
            # new_model.parameters_values[p] = x[i]
            # new_model.init_values[v] = x[i]
        if return_dr:
            dr = approximate_controls(new_model, order=1, return_dr=True, lambda_name='lam')
            return dr
        X_bar, X_s, X_ss = approximate_controls(new_model, order=2, return_dr=False, lambda_name="lam")

        return X_bar[n_controls-n_pfs:n_controls]


    if guess is not None:
        x0 = numpy.array(guess)
    else:
        x0 = numpy.zeros(n_pfs)

    print('Zero order portfolios')
    print('Initial guess: {}'.format(x0))
    print('Initial error: {}'.format( constant_residuals(x0) ))

    portfolios_0 = solver(constant_residuals, x0)
    print('Solution: {}'.format(portfolios_0))
    print('Final error: {}'.format( constant_residuals(portfolios_0) ))

    if order == 1:
        dr = constant_residuals(portfolios_0, return_dr=True)
        return dr

    def dynamic_residuals(X, return_dr=False):
        x = X[:,0]
        dx = X[:,1:]
        d = {}
        for i in range(n_pfs):
            p = pf_parms[i]
            v = pf_vars[i]
            d[p] = x[i]
            d[v] = x[i]
            for j in range(n_states):
                d[pf_dparms[i][j]] = dx[i,j]
        new_model.set_calibration(d)
        if return_dr:
            dr = approximate_controls(new_model, order=2, lambda_name='lam')
            return dr
        else:
            [X_bar, X_s, X_ss, X_sss] = approximate_controls(new_model, order=3, return_dr=False, lambda_name='lam')
            crit = numpy.column_stack([
                X_bar[n_controls-n_pfs:n_controls],
                X_s[n_controls-n_pfs:n_controls,:],
            ])
            return crit



    y0 = numpy.column_stack([x0, numpy.zeros((n_pfs, n_states))])
    print('Initial error:')
    err = (dynamic_residuals(y0))

    print( abs(err).max() )
    portfolios_1 = solver(dynamic_residuals, y0)

    print('First order portfolios : ')
    print(portfolios_1)

    print('Final error:')
    print(dynamic_residuals(portfolios_1))

    dr = dynamic_residuals(portfolios_1, return_dr=True)

    # TODO: remove coefficients of criteria

    return dr
Example #2
0
def solve_risky_ss(model, X_bar, X_s, verbose=False):

    import numpy
    from dolo.compiler.function_compiler import compile_function
    import time
    from dolo.compiler.compiler_functions import simple_global_representation

    parms = model.calibration['parameters']
    sigma = model.calibration['covariances']

    sgm = simple_global_representation(model)

    states = sgm['states']
    controls = sgm['controls']
    shocks = sgm['shocks']
    parameters = sgm['parameters']
    f_eqs = sgm['f_eqs']
    g_eqs = sgm['g_eqs']

    g_args = [s(-1) for s in states] + [c(-1) for c in controls] + shocks
    f_args = states + controls + [v(1)
                                  for v in states] + [v(1) for v in controls]
    p_args = parameters

    g_fun = compile_function(g_eqs, g_args, p_args, 2)
    f_fun = compile_function(f_eqs, f_args, p_args, 3)

    epsilons_0 = np.zeros((sigma.shape[0]))

    from numpy import dot
    from dolo.numeric.tensor import sdot, mdot

    def residuals(X, sigma, parms, g_fun, f_fun):

        import numpy

        dummy_x = X[0:1, 0]
        X_bar = X[1:, 0]
        S_bar = X[0, 1:]
        X_s = X[1:, 1:]

        [n_x, n_s] = X_s.shape

        n_e = sigma.shape[0]

        xx = np.concatenate([S_bar, X_bar, epsilons_0])

        [g_0, g_1, g_2] = g_fun(xx, parms)
        [f_0, f_1, f_2,
         f_3] = f_fun(np.concatenate([S_bar, X_bar, S_bar, X_bar]), parms)

        res_g = g_0 - S_bar

        # g is a first order function
        g_s = g_1[:, :n_s]
        g_x = g_1[:, n_s:n_s + n_x]
        g_e = g_1[:, n_s + n_x:]
        g_se = g_2[:, :n_s, n_s + n_x:]
        g_xe = g_2[:, n_s:n_s + n_x, n_s + n_x:]

        # S(s,e) = g(s,x,e)
        S_s = g_s + dot(g_x, X_s)
        S_e = g_e
        S_se = g_se + mdot(g_xe, [X_s, numpy.eye(n_e)])

        # V(s,e) = [ g(s,x,e) ; x( g(s,x,e) ) ]
        V_s = np.row_stack([S_s, dot(X_s, S_s)])  # ***

        V_e = np.row_stack([S_e, dot(X_s, S_e)])

        V_se = np.row_stack([S_se, dot(X_s, S_se)])

        # v(s) = [s, x(s)]
        v_s = np.row_stack([numpy.eye(n_s), X_s])

        # W(s,e) = [xx(s,e); yy(s,e)]
        W_s = np.row_stack([v_s, V_s])

        #return

        nn = n_s + n_x
        f_v = f_1[:, :nn]
        f_V = f_1[:, nn:]
        f_1V = f_2[:, :, nn:]
        f_VV = f_2[:, nn:, nn:]
        f_1VV = f_3[:, :, nn:, nn:]

        #        E = lambda v: np.tensordot(v, sigma,  axes=((2,3),(0,1)) ) # expectation operator

        F = f_0 + 0.5 * np.tensordot(
            mdot(f_VV, [V_e, V_e]), sigma, axes=((1, 2), (0, 1)))

        F_s = sdot(f_1, W_s)
        f_see = mdot(f_1VV, [W_s, V_e, V_e]) + 2 * mdot(f_VV, [V_se, V_e])
        F_s += 0.5 * np.tensordot(f_see, sigma, axes=(
            (2, 3), (0, 1)))  # second order correction

        resp = np.row_stack(
            [np.concatenate([dummy_x, res_g]),
             np.column_stack([F, F_s])])

        return resp

    #    S_bar = s_fun_init( numpy.atleast_2d(X_bar).T ,parms).flatten()
    #    S_bar = S_bar.flatten()
    S_bar = model.calibration['states']
    S_bar = np.array(S_bar)

    X0 = np.row_stack(
        [np.concatenate([np.zeros(1), S_bar]),
         np.column_stack([X_bar, X_s])])

    fobj = lambda X: residuals(X, sigma, parms, g_fun, f_fun)

    if verbose:
        val = fobj(X0)
        print('val')
        print(val)

    #    exit()

    t = time.time()

    sol = solver(fobj,
                 X0,
                 method='lmmcp',
                 verbose=verbose,
                 options={
                     'preprocess': False,
                     'eps1': 1e-15,
                     'eps2': 1e-15
                 })

    if verbose:
        print('initial guess')
        print(X0)
        print('solution')
        print sol
        print('initial residuals')
        print(fobj(X0))
        print('residuals')
        print fobj(sol)
        s = time.time()

    if verbose:
        print('Elapsed : {0}'.format(s - t))
        #sol = solver(fobj,X0, method='fsolve', verbose=True, options={'preprocessor':False})

    norm = lambda x: numpy.linalg.norm(x, numpy.inf)
    if verbose:
        print("Initial error: {0}".format(norm(fobj(X0))))
        print("Final error: {0}".format(norm(fobj(sol))))

        print("Solution")
        print(sol)

    X_bar = sol[1:, 0]
    S_bar = sol[0, 1:]
    X_s = sol[1:, 1:]

    # compute transitions
    n_s = len(states)
    n_x = len(controls)
    [g, dg, junk] = g_fun(np.concatenate([S_bar, X_bar, epsilons_0]), parms)
    g_s = dg[:, :n_s]
    g_x = dg[:, n_s:n_s + n_x]

    P = g_s + dot(g_x, X_s)

    if verbose:
        eigenvalues = numpy.linalg.eigvals(P)
        print eigenvalues
        eigenvalues = [abs(e) for e in eigenvalues]
        eigenvalues.sort()
        print(eigenvalues)

    return [S_bar, X_bar, X_s, P]
Example #3
0
def solve_risky_ss(model, X_bar, X_s, verbose=False):

    import numpy
    from dolo.compiler.function_compiler import compile_function
    import time
    from dolo.compiler.compiler_functions import simple_global_representation


    parms = model.calibration['parameters']
    sigma = model.calibration['covariances']

    sgm = simple_global_representation(model)

    states = sgm['states']
    controls = sgm['controls']
    shocks = sgm['shocks']
    parameters = sgm['parameters']
    f_eqs = sgm['f_eqs']
    g_eqs = sgm['g_eqs']


    g_args = [s(-1) for s in states] + [c(-1) for c in controls] + shocks
    f_args = states + controls + [v(1) for v in states] + [v(1) for v in controls]
    p_args = parameters



    g_fun = compile_function(g_eqs, g_args, p_args, 2)
    f_fun = compile_function(f_eqs, f_args, p_args, 3)


    epsilons_0 = np.zeros((sigma.shape[0]))

    from numpy import dot
    from dolo.numeric.tensor import sdot,mdot

    def residuals(X, sigma, parms, g_fun, f_fun):

        import numpy

        dummy_x = X[0:1,0]
        X_bar = X[1:,0]
        S_bar = X[0,1:]
        X_s = X[1:,1:]

        [n_x,n_s] = X_s.shape

        n_e = sigma.shape[0]

        xx = np.concatenate([S_bar, X_bar, epsilons_0])

        [g_0, g_1, g_2] = g_fun(xx, parms)
        [f_0,f_1,f_2,f_3] = f_fun( np.concatenate([S_bar, X_bar, S_bar, X_bar]), parms)

        res_g = g_0 - S_bar

        # g is a first order function
        g_s = g_1[:,:n_s]
        g_x = g_1[:,n_s:n_s+n_x]
        g_e = g_1[:,n_s+n_x:]
        g_se = g_2[:,:n_s,n_s+n_x:]
        g_xe = g_2[:, n_s:n_s+n_x, n_s+n_x:]


        # S(s,e) = g(s,x,e)
        S_s = g_s + dot(g_x, X_s)
        S_e = g_e
        S_se = g_se + mdot(g_xe,[X_s, numpy.eye(n_e)])


        # V(s,e) = [ g(s,x,e) ; x( g(s,x,e) ) ]
        V_s = np.row_stack([
            S_s,
            dot( X_s, S_s )
        ])    # ***

        V_e = np.row_stack([
            S_e,
            dot( X_s, S_e )
        ])

        V_se = np.row_stack([
            S_se,
            dot( X_s, S_se )
        ])

        # v(s) = [s, x(s)]
        v_s = np.row_stack([
            numpy.eye(n_s),
            X_s
        ])


        # W(s,e) = [xx(s,e); yy(s,e)]
        W_s = np.row_stack([
            v_s,
            V_s
        ])

        #return

        nn = n_s + n_x
        f_v = f_1[:,:nn]
        f_V = f_1[:,nn:]
        f_1V = f_2[:,:,nn:]
        f_VV = f_2[:,nn:,nn:]
        f_1VV = f_3[:,:,nn:,nn:]


        #        E = lambda v: np.tensordot(v, sigma,  axes=((2,3),(0,1)) ) # expectation operator

        F = f_0 + 0.5*np.tensordot(  mdot(f_VV,[V_e,V_e]), sigma, axes=((1,2),(0,1))  )

        F_s = sdot(f_1, W_s)
        f_see = mdot(f_1VV, [W_s, V_e, V_e]) + 2*mdot(f_VV, [V_se, V_e])
        F_s += 0.5 * np.tensordot(f_see, sigma,  axes=((2,3),(0,1)) ) # second order correction

        resp = np.row_stack([
            np.concatenate([dummy_x,res_g]),
            np.column_stack([F,F_s])
        ])

        return resp

    #    S_bar = s_fun_init( numpy.atleast_2d(X_bar).T ,parms).flatten()
    #    S_bar = S_bar.flatten()
    S_bar = model.calibration['states']
    S_bar = np.array(S_bar)

    X0 = np.row_stack([
        np.concatenate([np.zeros(1),S_bar]),
        np.column_stack([X_bar,X_s])
    ])

    fobj = lambda X: residuals(X,  sigma, parms, g_fun, f_fun)

    if verbose:
        val = fobj(X0)
        print('val')
        print(val)

    #    exit()

    t = time.time()

    sol = solver(fobj,X0, method='lmmcp', verbose=verbose, options={'preprocess':False, 'eps1':1e-15, 'eps2': 1e-15})

    if verbose:
        print('initial guess')
        print(X0)
        print('solution')
        print sol
        print('initial residuals')
        print(fobj(X0))
        print('residuals')
        print fobj(sol)
        s = time.time()


    if verbose:
        print('Elapsed : {0}'.format(s-t))
        #sol = solver(fobj,X0, method='fsolve', verbose=True, options={'preprocessor':False})

    norm = lambda x: numpy.linalg.norm(x,numpy.inf)
    if verbose:
        print( "Initial error: {0}".format( norm( fobj(X0)) ) )
        print( "Final error: {0}".format( norm( fobj(sol) ) ) )

        print("Solution")
        print(sol)

    X_bar = sol[1:,0]
    S_bar = sol[0,1:]
    X_s = sol[1:,1:]

    # compute transitions
    n_s = len(states)
    n_x = len(controls)
    [g, dg, junk] = g_fun( np.concatenate( [S_bar, X_bar, epsilons_0] ), parms)
    g_s = dg[:,:n_s]
    g_x = dg[:,n_s:n_s+n_x]

    P = g_s + dot(g_x, X_s)


    if verbose:
        eigenvalues = numpy.linalg.eigvals(P)
        print eigenvalues
        eigenvalues = [abs(e) for e in eigenvalues]
        eigenvalues.sort()
        print(eigenvalues)

    return [S_bar, X_bar, X_s, P]