CViM / src / model / SFC / firms.jl
firms.jl
Raw
"""
Define firms' actions.
"""

"""
    prev_vars!(agent::Firm) → nothing

Update firms' previous variables.
"""
function prev_vars!(agent::Firm)
    agent.GDP_prev = agent.GDP
    agent.deposits_prev = agent.deposits
    agent.loans_prev = agent.loans
    agent.wages_prev = agent.wages
    agent.inventories_prev = agent.inventories
    return nothing
end

"""
    inventories!(agent::Firm) → agent.inventories

Firms make their inventories decisions (buffer variable).
"""
function inventories!(agent::Firm) # id
    agent.inventories += (agent.loans - agent.loans_prev) - (agent.deposits - agent.deposits_prev) + agent.networth
    return agent.inventories
end


"""
    consumption!(agent::Firm, model) → agent.consumption

Firms update their customers' consumption. The inflow of consumption is then updated for the matching bank.
"""
function consumption!(agent::Firm, model)
    agent.consumption = sum(model[a].consumption for a in agent.customers)
    if !ismissing(agent.belongToBank)
        model[agent.belongToBank].flow += agent.consumption
    end
    return agent.consumption
end

"""
    production!(agent::Firm, g, n_f) → agent.GDP

Firms produce and update national GDP.
"""
function production!(agent::Firm, g, n_f)
    agent.GDP = g / n_f + (agent.inventories - agent.inventories_prev) + agent.consumption
    return agent.GDP
end

"""
    wages!(agent::Firm, model) → agent.wages

Firms pay wages. Wages are paid to households and the corresponding inflow is updated for hhs' banks. Firms' outflow of wages is 
updated to firms' matching banks.
"""
function wages!(agent::Firm, model)
    agent.wages = agent.GDP / (1 + model.ρ)
    for id in agent.customers
        model[id].wages = agent.wages / length(agent.customers)
        model[model[id].belongToBank].flow += model[id].wages
    end
    if !ismissing(agent.belongToBank)
        model[agent.belongToBank].flow -= agent.wages
    end
    return agent.wages
end

"""
    deposits!(agent::Firm, gd) → agent.deposits

Firms update their deposit holdings at the bank as a proportion of previous period wages.
"""
function deposits!(agent::Firm, model)
    agent.deposits = model.gd * agent.wages_prev
    model[agent.belongToBank].deposits += agent.deposits
    return agent.deposits
end

"""
    repayment!(agent::Firm, model) → agent.repayment

Firms repay part of their previous loans to the corresponding bank.
"""
function repayment!(agent::Firm, model)
    if agent.loans_prev != 0.0
        agent.repayment = agent.loans_prev * model.γ
        model[agent.belongToBank].repayment += agent.repayment
        agent.defaulted_loans = 0.1 * agent.loans_prev
        model[agent.belongToBank].defaulted_loans += agent.defaulted_loans
    end
    return agent.repayment, agent.defaulted_loans
end

"""
    profits!(agent::Firm) → agent.profits

Firms compute their profits which are then distributed to households.
"""
function profits!(agent::Firm) # id
    agent.profits = agent.GDP - agent.wages + agent.deposits_interests - agent.loans_interests
    return agent.profits
end

"""
    interests_payments!(agent::Firm, model) → agent.loans_interests, agent.deposits_interests   

Firms update their interests payments and receipts from previous period loans and deposits.
"""
function interests_payments!(agent::Firm, model)
    agent.loans_interests = (agent.loans_prev) * model[agent.belongToBank].ilf_rate_prev
    model[agent.belongToBank].loans_interests += agent.loans_interests
    agent.deposits_interests = agent.deposits_prev * model[agent.belongToBank].id_rate_prev
    model[agent.belongToBank].deposits_interests += agent.deposits_interests
    return agent.loans_interests, agent.deposits_interests
end

"""
    update_lev!(agent::Firm, change_rates_firms, pref) → agent.lev

Update leverage dependent on current interest rates. If credit rates are higher (lower) than in the previous period, 
desired leverage decreases (increases).
"""
function update_lev!(agent::Firm, change_rates_firms, pref)
    change_rates_firms == 0.0 && return
    if change_rates_firms > 0.0 && change_rates_firms > 1e-06
        agent.lev -= agent.lev * pref
    elseif change_rates_firms < 0.0 && abs(change_rates_firms) > 1e-06
        agent.lev += agent.lev * pref
    end
    return agent.lev
end

"""
    loans_demand!(agent::Firm) → agent.loans_demand

Firms define their demand for loans based on past wages and desired leverage.
"""
function loans_demand!(agent::Firm)
    agent.loans_demand = agent.lev * agent.wages_prev
    return agent.loans_demand
end

"""
    loans!(agent::Firm, model) → agent.loans

Firms receive loans from the corresponding bank based on their demand for loans and the bank's liquidity preference.
"""
function loans!(agent::Firm, model)
    agent.loans = agent.loans_demand * model[agent.belongToBank].liq_pref
    model[agent.belongToBank].loans += agent.loans
    return agent.loans
end

"""
    networth!(agent::Firm) → agent.networth

Firms update their networth.
"""
function networth!(agent::Firm)
    agent.networth += agent.defaulted_loans - agent.repayment
    return agent.networth
end

"""
    current_balance!(agent::Firm) → agent.balance_current

Update firms' current balances for SFC checks.
"""
function current_balance!(agent::Firm)
    agent.balance_current = agent.GDP + agent.deposits_interests - agent.wages - agent.profits - agent.loans_interests #- agent.repayment
    return agent.balance_current
end

"""
    capital_balance!(agent::Firm) → agent.balance_capital

Update firms' capital balances for SFC checks.
"""
function capital_balance!(agent::Firm)
    agent.balance_capital = (agent.loans - agent.loans_prev) - (agent.deposits - agent.deposits_prev) - (agent.inventories - agent.inventories_prev) + agent.networth
    return agent.balance_capital
end
"""
    SFC!(agent::Firm, model) → model

Define firms' SFC actions and update their accounting.
"""
function SFC!(agent::Firm, model)
    CViM.capital_balance!(agent)
    return model
end