def calc_estoq_apos_acumulado(estoques, periodo): # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() ids_apos = ['Apin', 'Atcn', 'Apid', 'Atcp', 'Ainv', 'Atce', 'Atcd'] # Adiciona o ano de 2014 na lista de anos anos = [2014] + periodo # Dicionário que armazena o Estoque acumulado est_acumulado = {} # As chaves do dicionário são as clientelas for clientela in ['UrbPiso', 'UrbAcim', 'Rur']: # Cria o DataFrame est_acumulado[clientela + 'H'] = pd.DataFrame(0.0, index=range(0, 91), columns=anos) est_acumulado[clientela + 'M'] = pd.DataFrame(0.0, index=range(0, 91), columns=anos) # Obtém todas as aposentadorias e faz o somatório por clientela, sexo e idade for beneficio in dados.get_id_beneficios(ids_apos): # Verifica se o estoque para o benefício existe if beneficio in estoques.keys(): sexo = beneficio[-1] if dados.get_clientela(beneficio) == clientela: est_acumulado[clientela + sexo] += estoques[beneficio] return est_acumulado
def calc_estoq_aux(est, prob, seg, periodo): # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() for benef in dados.get_id_beneficios(['Auxd', 'Auxa']): # Verifica se existe no Estoque if benef in est: sexo = benef[-1] id_seg = 'Ocup' + dados.get_clientela( benef) + sexo # ex: OcupUrbPisoH ou CaUrbH # Para os Rurais se utiliza toda a população (Fonte: planilhas do MF) if 'Rur' in benef: id_seg = 'PopRur' + sexo for ano in periodo: est[benef][ano] = seg[id_seg][ano] * prob[benef][ano] # Eq. 17 for benef in dados.get_id_beneficios(['Auxr']): # Verifica se existe no Estoque if benef in est: sexo = benef[-1] id_seg = 'Ocup' + dados.get_clientela( benef) + sexo # ex: OcupUrbPisoH ou CaUrbH # Para os Rurais se utiliza toda a população (Fonte: planilhas do MF) if 'Rur' in benef: id_seg = 'PopRur' + sexo for ano in periodo: # Cria uma nova entrada est[benef][ano] = 0 for idade in range(0, 91): # Na planilha são aplicados deslocamentos nas idades deslocamento = 0 if idade < 61 and sexo == 'H': deslocamento = 25 elif idade < 61 and sexo == 'M': deslocamento = 18 # Eq. 17 est[benef].loc[idade, ano] = seg[id_seg][ano][ idade + deslocamento] * prob[benef][ano][idade] # OBS: Nas planilhas o cálculo do deslocamento está errado para as URbAcimM (usa-se 25 ao invés de 18) return est
def calc_estoq_apos(est, conc, prob, seg, periodo): # Identificações das aposentadorias ids_apos = ['Apin', 'Atcn', 'Apid', 'Atcp', 'Ainv', 'Atce', 'Atcd'] # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() # Obtem as aposentadorias para todas as clientelas e sexos lista_benef = dados.get_id_beneficios(ids_apos) for benef in lista_benef: # Verifica se o beneficio existe no Estoque if benef in est: sexo = benef[-1] # Obtém o Sexo id_prob_morte = 'Mort' + sexo # ex: MortH id_fam = 'fam' + benef # fator de ajuste de mortalidade id_seg = 'Ocup' + dados.get_clientela( benef) + sexo # ex: OcupUrbPisoH ou CsmUrbH # Para os Rurais se utiliza toda a população (Fonte: planilhas do MF) if 'Rur' in benef: id_seg = 'PopRur' + sexo for ano in periodo: # Adiciona uma nova coluna (ano) no DataFrame com valores zero est[benef][ano] = 0 # 1 a 90 anos - Equação 11 da LDO de 2018 for idade in range(1, 91): est_ano_anterior = est[benef][ano - 1][idade - 1] prob_sobreviver = 1 - prob[id_prob_morte][ano][ idade] * prob[id_fam][ano][idade] entradas = seg[id_seg][ano][idade] * prob[benef][ano][idade] if idade == 90: est_ano_anterior = est[benef][ano - 1][ idade - 1] + est[benef][ano - 1][idade] # Eq. 11 est[benef].loc[ idade, ano] = est_ano_anterior * prob_sobreviver + entradas # Eq. 11 # Salva a quantidade de concessões para uso posterior conc[benef].loc[idade, ano] = entradas # Calculo para a idade zero est[benef].loc[0, ano] = seg[id_seg][ano][0] * prob[benef][ano][0] # Salva a quantidade de concessões para uso posterior conc[benef].loc[0, ano] = est[benef].loc[0, ano] return est
def calc_estoq_aux(est, prob, seg, periodo): # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() for benef in dados.get_id_beneficios(['Auxd', 'Auxa']): # Verifica se existe no Estoque if benef in est: sexo = benef[-1] id_seg = dados.get_id_segurados(benef) # ex: CsmUrbH for ano in periodo: est[benef][ano] = seg[id_seg][ano] * prob[benef][ano] # Eq. 17 for benef in dados.get_id_beneficios(['Auxr']): # Verifica se existe no Estoque if benef in est: sexo = benef[-1] id_seg = dados.get_id_segurados(benef) # ex: CsmUrbH for ano in periodo: # Cria uma nova entrada est[benef][ano] = 0 for idade in range(0, 91): # Na planilha são aplicados deslocamentos nas idades deslocamento = 0 if idade < 61 and sexo == 'H': deslocamento = 25 elif idade < 61 and sexo == 'M': deslocamento = 18 # Eq. 17 est[benef].loc[idade, ano] = seg[id_seg][ano][ idade + deslocamento] * prob[benef][ano][idade] # OBS: Nas planilhas o cálculo do deslocamento está errado para as URbAcimM (usa-se 25 ao invés de 18) return est
def calc_prob_aux_LDO2018(segurados, estoques, concessoes, periodo): probabilidades = {} # Dicionário que salvas as prob. para cada benefício ano_prob = periodo[0] - 1 # ano utilizado para cálculo # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() # O cálculo do Auxílio doença e diferente dos demais auxílios for beneficio in dados.get_id_beneficios(['Auxd']): # Verifica se o possui os dados de estoque e concessões do benefício if beneficio in estoques.keys() and beneficio in concessoes.keys(): conc = concessoes[beneficio][ano_prob] id_seg = dados.get_id_segurados(beneficio) seg_ano_ant = segurados[id_seg][ano_prob - 1] prob_auxd = conc / (seg_ano_ant + (conc / 2)) # Eq. 18 # Substitui os NaN por zero prob_auxd.fillna(0, inplace=True) probabilidades[beneficio] = prob_auxd # Calcula probabilidades de entrada em auxílios reclusão e acidente for beneficio in dados.get_id_beneficios(['Auxa', 'Auxr']): # Verifica se o possui os dados de estoque e concessões do benefício if beneficio in estoques.keys(): est = estoques[beneficio][ano_prob] id_seg = dados.get_id_segurados(beneficio) seg = segurados[id_seg][ano_prob] # OBS: para o caso do Auxr tem-se muitas divisões por zero, gerando inf prob_aux_ar = est / seg # Eq. 19 # Substitui os NaN por zero prob_aux_ar.fillna(0, inplace=True) probabilidades[beneficio] = prob_aux_ar return probabilidades
def calc_estoq_salMat(est, pop, seg, periodo): # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() # 2014, 2015, ... anos = [(periodo[0] - 1)] + periodo for benef in dados.get_id_beneficios('SalMat'): # Armazena valores do ano est_acumulado = pd.Series(index=anos) # Obtem o tipo de segurado a partir do benefício id_seg = dados.get_id_segurados(benef) # Os estoques de SalMat são agrupados por ano no modelo (não por idade) # OBS: O calculo dos estoques de SalMat não dependem da existência de estoques anteriores # Realiza projeção for ano in anos: est_acumulado[ano] = 0 # Cria um novo ano nascimentos = pop['PopIbgeM'][ano][0] + pop['PopIbgeH'][ano][0] # Acumula mulheres de 16 a 45 anos seg_16_45 = 0 pop_16_45 = 0 # O calculo para os rurais usa a População Rural e não os segurados rurais # OBS: o cálculo para os rurais ainda não bate com os da planilha do MF por causa do # cálculo da taxa de ruralização ser diferente if 'Rur' in benef: for idade in range(16, 46): seg_16_45 += pop['PopRurM'][ano][idade] pop_16_45 += pop['PopIbgeM'][ano][idade] else: for idade in range(16, 46): seg_16_45 += seg[id_seg][ano][idade] pop_16_45 += pop['PopIbgeM'][ano][idade] # Eq. 20 est_acumulado[ano] = (seg_16_45 / pop_16_45) * nascimentos # Cria uma nova entrada no dicionário para armazenar os estoques acumulados est[benef] = est_acumulado return est
def calc_prob_apos_MF(segurados, concessoes, periodo): probabilidades = {} # Dicionário que salvas as prob. para cada benefício ids_apos = ['Apin', 'Atcn', 'Apid', 'Atcp', 'Ainv', 'Atce', 'Atcd'] # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() # Obtém a lista de aposentadorias e itera sobre cada tipo for beneficio in dados.get_id_beneficios(ids_apos): # Verifica se existem dados de concessões do benefício if beneficio in concessoes.keys(): sexo = beneficio[-1] clientela = dados.get_clientela(beneficio) id_popOcup = 'Ocup' + clientela + sexo # OBS: Para clientela Rural utiliza-se toda a população if clientela == 'Rur': id_popOcup = 'PopRur' + sexo # OBS: A implementação descritas nas planilhas do DOC110/MF usa uma equação diferente da Eq. 16 # prob_entrada = concessoes/PopOcupada prob_entrada = concessoes[beneficio] / segurados[id_popOcup] # Trata divisões por zero prob_entrada.replace([np.inf, -np.inf], np.nan, inplace=True) # De acordo com as planilhas do DOC110/MF o valor do ano inicial da projeção (2015), deve ser igual a média dos anos anteriores prob_entrada[2015] = prob_entrada.loc[:, :2014].mean(axis=1) # Repete a última probabilidade(2015) nos anos seguintes(2016-2060) for ano in periodo[1:]: prob_entrada[ano] = prob_entrada[ano - 1] # Substitui os NaN (not a number) por zeros prob_entrada.fillna(0, inplace=True) # Adiciona no dicionário probabilidades[beneficio] = prob_entrada return probabilidades
def calc_prob_apos_LDO2018(segurados, concessoes, periodo): probabilidades = {} # Dicionário que salvas as prob. para cada benefício ids_apos = ['Apin', 'Atcn', 'Apid', 'Atcp', 'Ainv', 'Atce', 'Atcd'] # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() # Obtém a lista de aposentadorias e itera sobre cada tipo for beneficio in dados.get_id_beneficios(ids_apos): # Verifica se existem dados de concessões do benefício if beneficio in concessoes.keys(): # Cria o DataFrame prob_entrada = pd.DataFrame(0.0, index=range(0, 91), columns=([2014] + periodo)) # Eq. 16 # A versão da LDO trabalha com estoques (variável Q), porém o correto seriam os segurados ano_prob = periodo[0] - 1 # ano utilizado para cálculo (2014) id_segurado = dados.get_id_segurados(beneficio) prob_entrada[ano_prob] = concessoes[beneficio][ano_prob] / ( segurados[id_segurado][ano_prob - 1] + (concessoes[beneficio][ano_prob] / 2)) # Trata divisões por zero prob_entrada.replace([np.inf, -np.inf], np.nan, inplace=True) # Repete a última probabilidade(2014) nos anos seguintes(2015-2060) for ano in periodo: prob_entrada[ano] = prob_entrada[ano - 1] # Substitui os NaN (not a number) por zeros prob_entrada.fillna(0, inplace=True) # Adiciona no dicionário probabilidades[beneficio] = prob_entrada return probabilidades
def calc_despesas(despesas, estoques, concessoes, valCoBen, salarios, valMedBenef, probabilidades, nparcelas, resultados, parametros): periodo = parametros['periodo'] # Objeto criado para uso das funções da Classe LerTabelas dados = LerTabelas() ult_ano_estoq = periodo[0] - 1 # 2014 ##### Calcula despesa com o dados conhecidos (2011-2014) # O valor no banco de dados é mensal for beneficio in despesas.keys(): # Auxílio doença para os que recebem Acima do Piso if 'AuxdUrbAcim' in beneficio: despesas[beneficio] = valCoBen[beneficio] * nparcelas[beneficio] # Aposentadorias e Pensões para quem recebe acima do piso elif 'Acim' in beneficio: desp_dez = despesas[beneficio] # despesas dos mes de dezembro despesas[beneficio] = desp_dez * nparcelas[beneficio] # Demais auxílios elif 'Aux' in beneficio: qtd_benef = 0 if 'Auxd' in beneficio: qtd_benef = concessoes[beneficio][ult_ano_estoq] else: qtd_benef = estoques[beneficio][ult_ano_estoq] # OBS: Para o Auxílio-acidente a regra é 50% do valor do “Salário de Benefício” # fonte: http://www.previdencia.gov.br/servicos-ao-cidadao/informacoes-gerais/valor-beneficios-incapacidade/ if 'Auxa' in beneficio: valor_benef = salarios['salarioMinimo'][ult_ano_estoq] * 0.5 else: valor_benef = salarios['salarioMinimo'][ult_ano_estoq] npar = nparcelas[beneficio][ult_ano_estoq] # Calcula a despesa para cada benefício despesas[beneficio][ult_ano_estoq] = qtd_benef * valor_benef * npar # Demais tipos else: estoq_total = estoques[beneficio][ult_ano_estoq] estoq_total_ano_ant = estoques[beneficio][ult_ano_estoq - 1] valor_benef = salarios['salarioMinimo'][ult_ano_estoq] npar = nparcelas[beneficio][ult_ano_estoq] estoq_medio = ((estoq_total + estoq_total_ano_ant) / 2) # Calcula a despesa para cada benefício (Eq. 44) despesas[beneficio][ ult_ano_estoq] = estoq_medio * valor_benef * npar ##### Calcula despesas para clientelas Rurais, Urbanas e assistenciais que recebem o Piso (1 SM) ##### for clientela in ['Rur', 'Piso', 'Rmv', 'Loas']: beneficios = dados.get_id_beneficios(clientela) for beneficio in beneficios: # Pula o SalMat pois o calculo é diferente e feito posteriormente if 'SalMat' in beneficio: continue # Verifica se existe estoque para o beneficio if beneficio in estoques: for ano in periodo: # verifica se existe projeção para esse ano if ano in estoques[beneficio].columns: # Calculo para Auxílios if 'Aux' in beneficio: qtd_benef = estoques[beneficio][ano] valor_benef = salarios['salarioMinimo'][ano] # OBS: Para o Auxílio-acidente a regra é 50% do valor do “Salário de Benefício” # fonte: http://www.previdencia.gov.br/servicos-ao-cidadao/informacoes-gerais/valor-beneficios-incapacidade/ if 'Auxa' in beneficio: valor_benef = salarios['salarioMinimo'][ ano] * 0.5 npar = nparcelas[beneficio][ano] # Calcula a despesa para cada benefício despesas[beneficio][ ano] = qtd_benef * valor_benef * npar # Cálculo para os demais else: # Obtem o estoques do ano e do ano anterior estoq_total = estoques[beneficio][ano] estoq_total_ano_ant = estoques[beneficio][ano - 1] valor_benef = salarios['salarioMinimo'][ano] npar = nparcelas[beneficio][ano] # Calcula a despesa para cada benefício (Eq. 44) despesas[beneficio][ano] = ( (estoq_total + estoq_total_ano_ant) / 2) * valor_benef * npar ##### Calcula despesas para clientela Urbana que recebe acima do Piso ##### for beneficio in dados.get_id_beneficios('Acim'): # Pula o SalMat pois o calculo é diferente e feito posteriormente if 'SalMat' in beneficio: continue # Verifica se existem estoques if beneficio in estoques: sexo = beneficio[-1] # Caso o benefício seja uma Apos. por Tempo de # Contribuição Normal, Professor ou Especial # Eq. 49 e 50 #if ('tcn' in beneficio or 'tce' in beneficio or 'tcp' in beneficio): #fator_prev = 1 #ajuste = 1 #val_med_novos_ben = fator_prev * ajuste * salarios['SalMedSegUrbAcimPnad'+sexo] for ano in periodo: if ano in estoques[ beneficio].columns: # verifica se existe projeção para esse ano # Cálculo das despesas com os Auxílios if 'Aux' in beneficio: est_ano = estoques[beneficio][ano] vmb = valMedBenef[beneficio][ano] npar = nparcelas[beneficio][ano] # Eq. 46 despesas[beneficio][ano] = est_ano * vmb * npar else: # Cálculo para Aposentadorias e Pensões val_med_novos_ben = valMedBenef[beneficio] # Idade de 1 a 90 anos for idade in range(1, 91): # Para a idade de 90 anos if idade == 90: desp_anterior = despesas[beneficio][ano - 1][ idade - 1] + despesas[beneficio][ano - 1][idade] else: desp_anterior = despesas[beneficio][ano - 1][idade - 1] conc_anterior = concessoes[beneficio][ano - 1][idade - 1] # OBS: Acredito que o correto seria usar os segurados e nao a PopOcup # OBS: O rend_med_ocup_ant já inclui a taxa de reposição da Eq. 45 valor_med_conc_ant = val_med_novos_ben[ano - 1][idade - 1] npar = nparcelas[beneficio][ano] npar_ant = nparcelas[beneficio][ano - 1] prob_morte = probabilidades['Mort' + sexo][ano][idade] fam = probabilidades['fam' + beneficio][ano][idade] # Nas planilhas usa-se o termo Atualização Monetária reajuste = parametros['tx_reajuste_beneficios'][ ano] novas_conc = concessoes[beneficio][ano][idade] valor_med_conc = val_med_novos_ben[ano][idade] # Eq. 45 part1 = desp_anterior + conc_anterior * valor_med_conc_ant * ( npar_ant / 2) part2 = (1 - prob_morte * fam) * (1 + reajuste / 100) part3 = (novas_conc * valor_med_conc * (npar / 2)) despesas[beneficio].loc[ idade, ano] = part1 * part2 + part3 # Idade zero novas_conc = concessoes[beneficio][ano][0] valor_med_conc = val_med_novos_ben[ano][0] npar = nparcelas[beneficio][ano] despesas[beneficio].loc[ 0, ano] = novas_conc * valor_med_conc * (npar / 2) ##### Calcula despesas para o Salário Maternidade ##### for beneficio in dados.get_id_beneficios('SalMat'): # 2014-2060 anos = [periodo[0] - 1] + periodo # Verifica se existe estoque para o beneficio if beneficio in estoques: # Objeto do tipo Series que armazena as despesas acumuladas por ano desp_acumulada = pd.Series(0.0, index=anos) # Obtem o estoques acumulados do ano atual for ano in anos: estoq_total = estoques[beneficio][ano] # se a clientela for UrbAcim if 'Acim' in beneficio: valor_benef = valMedBenef['SalMatUrbAcimM'][ano] else: valor_benef = salarios['salarioMinimo'][ano] npar = nparcelas[beneficio][ano] # OBS: A LDO não descreve a equação para o calculo de despesas para o SalMat desp_acumulada[ano] = estoq_total * valor_benef * npar # Salva no DataFrame despesas[beneficio] = desp_acumulada ##### Calcula a despesa total ##### anos = [periodo[0] - 1] + periodo #2014-2060 desp_total = pd.Series( 0.0, index=anos) # Objeto do tipo Serie que armazena a despesa total for ano in anos: for beneficio in despesas.keys(): # Verifica se o benefício é do tipo Salário Maternidade # O objeto que armazena as despesas com Salário Maternidade é diferente if 'SalMat' in beneficio: if ano in despesas[ beneficio].index: # verifica se existe projeção para esse ano desp_total[ano] += despesas[beneficio][ano] else: # Calculo para os demais benefícios if ano in despesas[ beneficio].columns: # verifica se existe projeção para esse ano desp_total[ano] += despesas[beneficio][ano].sum() # Calcula a taxa de crescimento da Despesa tx_cres_desp = pd.Series(0.0, index=periodo) for ano in periodo: # pula o primeiro ano tx_cres_desp[ano] = desp_total[ano] / desp_total[ano - 1] - 1 resultados['despesas'] = desp_total resultados['tx_cres_despesa'] = tx_cres_desp return resultados
def calc_cessacoes_pensao(cessacoes, concessoes, probabilidades, periodo): # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() # Parte da Eq. 27 # OBS: Esses valores são diferentes dos descritos na Lei 13.135/2015 def get_ji(idade): if idade <= 23: return 3 elif idade >= 27 and idade <= 32: return 6 elif idade >= 37 and idade <= 39: return 10 elif idade >= 45 and idade <= 55: return 15 elif idade >= 61 and idade <= 63: return 20 else: return 0 # Calcula as cessações para cada tipo de pensão for beneficio in dados.get_id_beneficios(['Pe']): sexo = beneficio[-1] # Obtém o sexo a partir do nome do benefício # Verifica se existe dados de concessões do tipo B if beneficio in concessoes.keys(): for ano in periodo: # Essa regra só vale a partir de 2015 if ano < 2015: continue # Pula iteração # Cria nova entrada no Dataframe cessacoes[beneficio][ano] = 0 # Cessações são zero para i <= 2, pois (idade - ji) daria negativo for idade in range(3, 91): ji = get_ji(idade) # As pensões do tipo B só existem a partir de 2015 e se Ji igual 0 zero não tem cessações if (ano - ji) < 2015 or ji == 0: cessacoes[beneficio].loc[idade, ano] = 0 else: conc = concessoes[beneficio][ano - ji][idade - ji] produtorio = 1 k = idade - ji for i in range(k, idade + 1): pmorte = probabilidades['Mort' + sexo][ano - (i - k)][k] fator = probabilidades['fam' + beneficio][ano - (i - k)][k] produtorio *= (1 - pmorte * fator) # Eq. 27 cessacoes[beneficio].loc[idade, ano] = conc * produtorio return cessacoes
def calc_concessoes_pensao(populacao, concessoes, estoques, segurados, probabilidades, periodo): # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() # Obtém o conjunto de benefícios do tipo pensão lista_pensoes = dados.get_id_beneficios('Pe') # Obtém estoque acumulado de aposentadorias por ano, clientela, idade e sexo estoq_acum = calc_estoq_apos_acumulado(estoques, periodo) # Eq. 26 # Hipótese de que o diferencial de idade médio entre cônjuges é de 4 anos (pag. 45 LDO de 2018) Dit = 4 # Calcula concessões de pensões do tipo B for benef in lista_pensoes: sexo = benef[-1] # Obtém o Sexo sexo_oposto = 'M' if sexo == 'H' else 'H' # Obtém o oposto id_mort_sex_op = 'Mort' + sexo_oposto # ex: MortM # Sempre são usados os segurados do sexo masculino id_seg = dados.get_id_segurados(benef).replace( sexo, 'H') # Obtem o Id do segurado trocando o sexo clientela = dados.get_clientela(benef) id_prob_entr = benef.replace(sexo, sexo_oposto) for ano in periodo: # Tipo de Pensão válida a partir de 2015 if ano < 2015: continue # Pula anos inferiores a 2015 # Cria nova entrada no DataFrame concessoes[benef][ano] = 0 # Calcula concessões # Idades de 0 a 90 anos. for idade in range(0, 91): # Determina o valor de Dit baseado na idade (relação baseada nas planilhas do MF) if idade > 20 and idade < 87: Dit = 4 elif idade == 87: Dit = 3 elif idade == 88: Dit = 2 elif idade == 89: Dit = 1 else: Dit = 0 # A soma ou subtração depende do sexo if sexo == 'H': i_Dit = idade - Dit else: i_Dit = idade + Dit prob_entrada = probabilidades[id_prob_entr][i_Dit] pmort = probabilidades[id_mort_sex_op][ano][i_Dit] # Para os urbanos com idade de 15 anos e para os rurais utiliza-se toda a população por clientela simples (Urb ou Rur) if idade < 16 or clientela == 'Rur': clientela_simples = clientela[0:3] potGeradoresPensoes = populacao['Pop' + clientela_simples + sexo_oposto][ano][i_Dit] else: seg = segurados[id_seg][ano][i_Dit] est_ac = estoq_acum[clientela + sexo_oposto][ano][i_Dit] potGeradoresPensoes = seg + est_ac # Eq. 24 e 25 concessoes[benef].loc[ idade, ano] = prob_entrada * potGeradoresPensoes * pmort return concessoes
def calc_estoq_pensoes(populacao, est, concessoes, cessacoes, probabilidades, segurados, periodo): # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() # Obtém o conjunto de benefícios do tipo pensão lista_pensoes = dados.get_id_beneficios('Pe') ##### Calcula pensões do tipo A for benef in lista_pensoes: sexo = benef[-1] # Obtém o Sexo id_prob_morte = 'Mort' + sexo # ex: MortH id_fam = 'fam' + benef # fator de ajuste de mortalidade id_pens = benef + "_tipoA" # Cria um Id para pensão do tipo A # Copia o Dataframe est[id_pens] = est[benef] for ano in periodo: # Adiciona uma nova coluna (ano) no DataFrame com valores zero est[id_pens][ano] = 0 # Projeta pensões do tipo A # Como não se tem novas concessões desse tipo de pensão, calcula-se # somente nas idades de 1 a 89 anos. for idade in range(1, 90): est_ano_anterior = est[id_pens][ano - 1][idade - 1] probMorte = probabilidades[id_prob_morte][ano][idade] fam = probabilidades[id_fam][ano][idade] prob_sobreviver = 1 - (probMorte * fam) # Eq. 22 est[id_pens].loc[idade, ano] = est_ano_anterior * prob_sobreviver # Calculo para idade 90 est_ano_anterior = est[id_pens][ano - 1][89] + est[id_pens][ano - 1][90] id_prob_morte = 'MortH' id_fam = ('fam' + benef).replace(sexo, 'H') # para o primeiro ano de projeção (2015) a probMorte é para 89 anos if ano == periodo[0]: probMorte = probabilidades[id_prob_morte][ano][89] else: probMorte = probabilidades[id_prob_morte][ano][90] fam = probabilidades[id_fam][ano][90] prob_sobreviver = 1 - probMorte * fam est[id_pens].loc[90, ano] = est_ano_anterior * prob_sobreviver ##### Calcula pensões de tipo B - Equação 23 # Obtém projeções de concessões e cessações do tipo B concessoes = calc_concessoes_pensao(populacao, concessoes, est, segurados, probabilidades, periodo) cessacoes = calc_cessacoes_pensao(cessacoes, concessoes, probabilidades, periodo) for benef in lista_pensoes: sexo = benef[-1] # Obtém o Sexo id_prob_morte = 'Mort' + sexo # ex: MortH id_fam = 'fam' + benef # fator de ajuste de mortalidade id_pens = benef + "_tipoB" # Cria um Id para pensão do tipo B # Cria DataFrame para armazenar o estoque de Pensões do tipo B est[id_pens] = pd.DataFrame(0.0, index=range(0, 91), columns=[periodo[0] - 2, periodo[0] - 1] + periodo) # 2013-2060 - REVISAR - refatorar est[id_pens].index.name = "IDADE" # Projeta anos seguintes for ano in periodo: # Pula anos inferiores a 2015 if ano < 2015: continue # Projeta pensões do tipo B # Idades de 1 a 89 anos. for idade in range(1, 90): est_ano_anterior = est[id_pens][ano - 1][idade - 1] prob_sobreviver = 1 - probabilidades[id_prob_morte][ano][ idade] * probabilidades[id_fam][ano][idade] conc = concessoes[benef][ano][idade] cess = cessacoes[benef][ano][idade] # Eq. 23 est[id_pens].loc[ idade, ano] = est_ano_anterior * prob_sobreviver + conc - cess # Idade zero est[id_pens].loc[ 0, ano] = concessoes[benef][ano][0] - cessacoes[benef][ano][0] # Idade 90 est_ano_ant90 = est[id_pens][ano - 1][89] + est[id_pens][ano - 1][90] prob_sobr90 = 1 - probabilidades[id_prob_morte][ano][ 90] * probabilidades[id_fam][ano][90] conc90 = concessoes[benef][ano][90] cess90 = cessacoes[benef][ano][90] est[id_pens].loc[ 90, ano] = est_ano_ant90 * prob_sobr90 + conc90 - cess90 # Calcula total de pensões for benef in lista_pensoes: est[benef] = est[benef + "_tipoA"].add(est[benef + "_tipoB"]) # Eq. 21 return est
def calc_resultados(resultados, estoques, segurados, salarios, valMedBenef, dadosLDO, parametros): periodo = parametros['periodo'] ano_estoque = periodo[0] ###### Calcula receita e despesa sobre o PIB rec_pib = resultados['receitas'] / resultados['PIB'] desp_pib = resultados['despesas'] / resultados['PIB'] resultados['receitas_PIB'] = rec_pib * 100 resultados['despesas_PIB'] = desp_pib * 100 ###### Cálcula necessidade de Financiamento necess_fin = resultados['receitas'] - resultados['despesas'] necess_fin_pib = necess_fin / resultados['PIB'] resultados['resultado_financeiro'] = necess_fin resultados['resultado_financeiro_PIB'] = necess_fin_pib * 100 ###### Cálcula contribuintes, beneficiários e razão de dependência total_contribuintes = segurados['CsmUrbH'].sum() + segurados['CaUrbH'].sum( ) + segurados['CaUrbM'].sum() + segurados['CsmUrbM'].sum() total_beneficiarios = 0 total_aposentados = 0 # Soma os beneficiários de cada benefício - Todos os benefícios for b in estoques.keys(): # Pula os benefícios assistenciais e subtipos de pensões (tipo A e B) if 'Loas' in b or 'tipo' in b: continue total_beneficiarios += estoques[b].sum() # Soma a quantidade de beneficiários de aposentadorias tabelas = LerTabelas() # Ids aposentadorias ids_apos = ['Apin', 'Atcn', 'Apid', 'Atcp', 'Ainv', 'Atce', 'Atcd'] for b in tabelas.get_id_beneficios(ids_apos): # Verifica se o estoque para o benefício existe if b in estoques.keys(): total_aposentados += estoques[b].sum() # Salva a partir de 2014 resultados['contribuintes'] = total_contribuintes.loc[ano_estoque:] resultados['beneficiarios'] = total_beneficiarios.loc[ano_estoque:] resultados['aposentados'] = total_aposentados.loc[ano_estoque:] # Calcula a Razão de dependência previdenciária # OBS: No livro 2, o RDP considerava somente as aposentadorias resultados['RDP'] = resultados['aposentados'] / resultados['contribuintes'] ###### Cálcula salário médio, valor médio dos benefícios e a taxa de reposição salario_medio = (salarios['SalMedSegUrbAcimPnadH'].mean() + salarios['SalMedSegUrbAcimPnadM'].mean() + salarios['salarioMinimo']) / 3 soma_media_beneficios = 0 qtd_benef = 0 # Calcula a média dos valores dos beneficios for b in valMedBenef.keys(): # Pula a txReposicao - OBS: tirar essa variável daqui if 'txRep' in b: continue soma_media_beneficios += valMedBenef[b].mean() qtd_benef += 1 # Soma com o salário mínimo soma_media_beneficios += salarios['salarioMinimo'] qtd_benef += 1 # Salva a partir de 2014 resultados['salario_medio'] = salario_medio.loc[ano_estoque:] resultados['valor_medio_beneficios'] = soma_media_beneficios.loc[ ano_estoque:] / qtd_benef # Calcula a Taxa de Reposição resultados['taxa_reposicao'] = resultados[ 'valor_medio_beneficios'] / resultados['salario_medio'] aliquota = parametros['aliquota_media'] ###### Cálcula Indicador sintético da sustentabilidade resultados['ISS'] = (aliquota / 100) / (resultados['taxa_reposicao'] * resultados['RDP']) ###### Obtém resultados da LDO de 2018 # Receita, despesa e PIB da LDO rec_ldo = dadosLDO['Tabela_6.2']['Receita'] desp_ldo = dadosLDO['Tabela_6.2']['Despesa'] pib_ldo = dadosLDO['Tabela_6.2']['PIB'] # Receita e despesa sobre o PIB da LDO rec_ldo_pib = dadosLDO['Tabela_6.2']['Receita / PIB'] * 100 desp_ldo_pib = dadosLDO['Tabela_6.2']['Despesa / PIB'] * 100 resultados['receitas_PIB_LDO'] = rec_ldo_pib resultados['despesas_PIB_LDO'] = desp_ldo_pib ###### Calcula variação em relação a LDO de 2018 # Variação na despesa, receita e PIB com relação a LDO de 2018 em % erro_receita = 100 * (resultados['receitas'] - rec_ldo) / rec_ldo erro_despesa = 100 * (resultados['despesas'] - desp_ldo) / desp_ldo erro_pib = 100 * (resultados['PIB'] - pib_ldo) / pib_ldo # Erro na despesa e receita sobre o PIB erro_receita_pib = 100 * (resultados['receitas_PIB'] - rec_ldo_pib) / rec_ldo_pib erro_despesa_pib = 100 * (resultados['despesas_PIB'] - desp_ldo_pib) / desp_ldo_pib resultados['erro_receitas'] = erro_receita resultados['erro_despesas'] = erro_despesa resultados['erro_PIB'] = erro_pib resultados['erro_receitas_PIB'] = erro_receita_pib resultados['erro_despesas_PIB'] = erro_despesa_pib resultados['receitas_LDO'] = rec_ldo resultados['despesas_LDO'] = desp_ldo ###### Comparação com os dados de 2014 e 2015 do AEPS tabelas = LerTabelas() # Calcula o estoque total de aposentadorias e Pensões est_apos_total = pd.DataFrame(0.0, columns=estoques['AinvRurH'].columns, index=estoques['AinvRurH'].index) est_pens_total = est_apos_total.copy() # Para todas as aposentadorias for benef in tabelas.get_id_beneficios( ['Apin', 'Atcn', 'Atce', 'Atcp', 'Ainv']): if benef in estoques.keys(): est_apos_total += estoques[benef] # Para todas as Pensoes for benef in tabelas.get_id_beneficios(['Pens']): if benef in estoques.keys(): est_pens_total += estoques[benef] erros_aeps = pd.DataFrame( index=[2014, 2015], columns=['Receitas', 'Despesas', 'Aposentadorias', 'Pensões']) erros_aeps['Aposentadorias'] = (est_apos_total.sum() / dadosLDO['Aposentadorias AEPS']) - 1 erros_aeps['Pensões'] = (est_pens_total.sum() / dadosLDO['Pensões AEPS']) - 1 erros_aeps['Receitas'] = (resultados['receitas'] / dadosLDO['Receitas AEPS']) - 1 erros_aeps['Despesas'] = (resultados['despesas'] / dadosLDO['Despesas AEPS']) - 1 resultados['erros_AEPS'] = erros_aeps * 100 ###### Exporta todos os resultados para um arquivo CSV # Cria o DataFrame que irá armazena cada resultado em uma coluna todos_resultados = pd.DataFrame(index=range(ano_estoque, periodo[-1] + 1)) todos_resultados.index.names = ['ANO'] # Cria diretório caso não exista result_dir = ('resultados') if not os.path.isdir(result_dir): os.makedirs(result_dir) lista_resultados = list(resultados.keys()) lista_resultados.remove( 'erros_AEPS') # Remove o erro_AEPS pois já um DataFrame lista_resultados.sort() # Ordena a lista # Salva cada resultado como uma coluna do DataFrame for r in lista_resultados: todos_resultados[r] = resultados[r] # Salva o arquivo em formato CSV try: todos_resultados.to_csv((os.path.join(result_dir, 'resultados.csv')), sep=';', decimal=',') except: print('--> Erro ao salvar arquivo {}'.format( (os.path.join(result_dir, 'resultados.csv')))) return resultados
print(' {} = {}'.format(p, copia_parametros[p])) print('\nLendo arquivo de dados ... \n') #### Arquivo com os dados da Fazenda # Dados disponibilizados em: http://legis.senado.leg.br/comissoes/docsRecCPI?codcol=2093 # DOC nº 110 do Ministério da Fazenda do dia 22/06/2017 - Midia 21 arquivo = 'dados/dados_fazenda.xlsx' # Abri o arquivo dados = LerTabelas(arquivo) print('Carregando tabelas ...\n') # Lista de Ids dos beneficios ids_estoques = dados.get_id_beneficios([], 'Es') ids_concessoes = dados.get_id_beneficios([], 'Co') ids_cessacoes = dados.get_id_beneficios([], 'Ce') ids_despesas = dados.get_id_beneficios([], 'ValEs') ids_valConcessoesBen = dados.get_id_beneficios([], 'ValCo') # Obtem as tabelas e armazena nos dicionários correspondentes estoques = dados.get_tabelas(ids_estoques, logs, info=True) concessoes = dados.get_tabelas(ids_concessoes, logs, info=True) cessacoes = dados.get_tabelas(ids_cessacoes, logs, info=True) despesas = dados.get_tabelas(ids_despesas, logs) populacao = dados.get_tabelas(dados.ids_pop_ibge, logs) populacao_pnad = dados.get_tabelas(dados.ids_pop_pnad, logs) salarios = dados.get_tabelas(dados.ids_salarios, logs) valCoBen = dados.get_tabelas(ids_valConcessoesBen, logs)
def calc_resultados(resultados, despesas, estoques, segurados, salarios, valMedBenef, dadosLDO, parametros, mostrar=False): periodo = parametros['periodo'] ano_estoque = periodo[0] ###### Calcula receita e despesa sobre o PIB rec_pib = resultados['receitas'] / resultados['PIB'] desp_pib = resultados['despesas'] / resultados['PIB'] resultados['receitas_PIB'] = rec_pib * 100 resultados['despesas_PIB'] = desp_pib * 100 ###### Cálcula necessidade de Financiamento necess_fin = resultados['receitas'] - resultados['despesas'] necess_fin_pib = necess_fin / resultados['PIB'] resultados['resultado_financeiro'] = necess_fin resultados['resultado_financeiro_PIB'] = necess_fin_pib * 100 ###### Cálcula contribuintes, beneficiários e razão de dependência total_contribuintes = segurados['CsmUrbH'].sum() + segurados['CaUrbH'].sum() + segurados['CaUrbM'].sum() + segurados['CsmUrbM'].sum() total_beneficiarios = 0 total_beneficiarios_urb = 0 total_beneficiarios_rur = 0 total_aposentados = 0 # Soma os beneficiários de cada benefício - Todos os benefícios for b in estoques.keys(): # Pula os benefícios assistenciais e subtipos de pensões (tipo A e B) if 'Loas' in b or 'tipo' in b: continue elif 'Urb' in b: total_beneficiarios_urb += estoques[b].sum() else: total_beneficiarios_rur += estoques[b].sum() total_beneficiarios = total_beneficiarios_urb + total_beneficiarios_rur # Soma a quantidade de beneficiários de aposentadorias tabelas = LerTabelas() # Ids aposentadorias ids_apos= ['Apin', 'Atcn', 'Apid', 'Atcp', 'Ainv', 'Atce', 'Atcd'] for b in tabelas.get_id_beneficios(ids_apos): # Verifica se o estoque para o benefício existe if b in estoques.keys(): total_aposentados += estoques[b].sum() # Salva a partir de 2014 resultados['contribuintes'] = total_contribuintes.loc[ano_estoque:] resultados['beneficiarios'] = total_beneficiarios.loc[ano_estoque:] resultados['beneficiarios_urb'] = total_beneficiarios_urb.loc[ano_estoque:] resultados['beneficiarios_rur'] = total_beneficiarios_rur.loc[ano_estoque:] resultados['aposentados'] = total_aposentados.loc[ano_estoque:] # Calcula a Razão de dependência previdenciária # OBS: No livro 2, o RDP considerava somente as aposentadorias resultados['RDP'] = resultados['aposentados']/resultados['contribuintes'] ###### Cálcula salário médio, valor médio dos benefícios e a taxa de reposição salario_medio = (salarios['SalMedSegUrbAcimPnadH'].mean() + salarios['SalMedSegUrbAcimPnadM'].mean() + salarios['salarioMinimo'])/3 soma_media_beneficios = 0 qtd_benef = 0 # Calcula a média dos valores dos beneficios for b in valMedBenef.keys(): # Pula a txReposicao - OBS: tirar essa variável daqui if 'txRep' in b: continue soma_media_beneficios += valMedBenef[b].mean() qtd_benef += 1 # Soma com o salário mínimo soma_media_beneficios += salarios['salarioMinimo'] qtd_benef += 1 # Salva a partir de 2014 resultados['salario_medio'] = salario_medio.loc[ano_estoque:] resultados['valor_medio_beneficios'] = soma_media_beneficios.loc[ano_estoque:]/qtd_benef # Calcula a Taxa de Reposição resultados['taxa_reposicao'] = resultados['valor_medio_beneficios']/resultados['salario_medio'] aliquota = parametros['aliquota_media'] ###### Cálcula Indicador sintético da sustentabilidade resultados['ISS'] = (aliquota/100)/(resultados['taxa_reposicao'] * resultados['RDP']) ###### Obtém resultados da LDO de 2018 # Receita, despesa e PIB da LDO rec_ldo = dadosLDO['Tabela_6.2']['Receita'] desp_ldo = dadosLDO['Tabela_6.2']['Despesa'] pib_ldo = dadosLDO['Tabela_6.2']['PIB'] # Receita e despesa sobre o PIB da LDO rec_ldo_pib = dadosLDO['Tabela_6.2']['Receita / PIB'] * 100 desp_ldo_pib = dadosLDO['Tabela_6.2']['Despesa / PIB'] * 100 resultados['receitas_PIB_LDO'] = rec_ldo_pib resultados['despesas_PIB_LDO'] = desp_ldo_pib ###### Calcula variação em relação a LDO de 2018 # Variação na despesa, receita e PIB com relação a LDO de 2018 em % erro_receita = 100 * (resultados['receitas'] - rec_ldo) / rec_ldo erro_despesa = 100 * (resultados['despesas'] - desp_ldo) / desp_ldo erro_pib = 100 * (resultados['PIB'] - pib_ldo) / pib_ldo # Diferença na despesa e receita sobre o PIB erro_receita_pib = resultados['receitas_PIB'] - rec_ldo_pib erro_despesa_pib = resultados['despesas_PIB'] - desp_ldo_pib resultados['erro_receitas'] = erro_receita resultados['erro_despesas'] = erro_despesa resultados['erro_PIB'] = erro_pib resultados['erro_receitas_PIB'] = erro_receita_pib resultados['erro_despesas_PIB'] = erro_despesa_pib resultados['receitas_LDO'] = rec_ldo resultados['despesas_LDO'] = desp_ldo ###### Comparação com os dados de 2014 e 2015 do AEPS tabelas = LerTabelas() # Calcula o estoque total de aposentadorias e Pensões est_apos_total = pd.DataFrame(0.0, columns=estoques['AinvRurH'].columns,index=estoques['AinvRurH'].index) est_pens_total = est_apos_total.copy() # Para todas as aposentadorias for benef in tabelas.get_id_beneficios(['Apin', 'Atcn', 'Atce', 'Atcp', 'Ainv']): if benef in estoques.keys(): est_apos_total += estoques[benef] # Para todas as Pensoes for benef in tabelas.get_id_beneficios(['Pens']): if benef in estoques.keys(): est_pens_total += estoques[benef] erros_aeps = pd.DataFrame(index=[2014,2015], columns=['Receitas', 'Despesas', 'Aposentadorias', 'Pensões']) erros_aeps['Aposentadorias'] = (est_apos_total.sum() / dadosLDO['Aposentadorias AEPS']) - 1 erros_aeps['Pensões'] = (est_pens_total.sum() / dadosLDO['Pensões AEPS']) - 1 erros_aeps['Receitas'] = (resultados['receitas'] / dadosLDO['Receitas AEPS']) - 1 erros_aeps['Despesas'] = (resultados['despesas'] / dadosLDO['Despesas AEPS']) - 1 resultados['erros_AEPS'] = erros_aeps * 100 # Salva os resultados em arquivos CSV save_results(resultados, despesas, estoques, segurados, salarios, valMedBenef, parametros) # Se mostrar = True os resultados serão exibidos no Prompt if mostrar: print('RESULTADOS DA PROJEÇÃO: \n') print('Receita em 2018 = {}'.format(resultados['receitas'][2018])) print('Receita em 2060 = {}'.format(resultados['receitas'][2060])) print('Receita/PIB em 2060 = {}'.format(resultados['receitas_PIB'][2060])) print() print('Despesa em 2018 = {}'.format(resultados['despesas'][2018])) print('Despesa em 2060 = {}'.format(resultados['despesas'][2060])) print('Despesa/PIB em 2060 = {}'.format(resultados['despesas_PIB'][2060])) print() print('Resultado Financeiro em 2018 = {}'.format(resultados['resultado_financeiro'][2018])) print('Resultado Financeiro em 2060 = {}'.format(resultados['resultado_financeiro'][2060])) print('Resultado Financeiro/PIB em 2060 = {}'.format(resultados['resultado_financeiro_PIB'][2060])) print("\nVARIAÇÕES EM RELAÇÃO A LDO DE 2018:") print('Variação da Despesa em 2018 (%) = {}'.format(round(resultados['erro_despesas'][2018], 2))) print('Variação da Despesa em 2060 (%) = {}'.format(round(resultados['erro_despesas'][2060], 2))) print() print('Variação da Receita em 2018 (%) = {}'.format(round(resultados['erro_receitas'][2018], 2))) print('Variação da Receita em 2060 (%) = {}'.format(round(resultados['erro_receitas'][2060], 2))) print() print('Variação no PIB em 2018 (%) = {}'.format(round(resultados['erro_PIB'][2018], 2))) print('Variação no PIB em 2060 (%) = {}'.format(round(resultados['erro_PIB'][2060], 2))) print() print('Diferença na Receita/PIB em 2018 = {}'.format(resultados['erro_receitas_PIB'][2018])) print('Diferença na Receita/PIB em 2060 = {}'.format(resultados['erro_receitas_PIB'][2060])) print() print('Diferença na Despesa/PIB em 2018 = {}'.format(resultados['erro_despesas_PIB'][2018])) print('Diferença na Despesa/PIB em 2060 = {}'.format(resultados['erro_despesas_PIB'][2060])) print('\n') return resultados
def calc_fat_ajuste_mort_LDO2018(estoques, cessacoes, probMort, periodo): # ano utilizado para cálculo ano_prob = periodo[0] - 1 #2014 # Dicionário que armazena as probabilidades fat_ajuste = {} # Calculada para aposentadorias, pensões e assistênciais tags = [ 'Apin', 'Atcn', 'Apid', 'Atcp', 'Ainv', 'Atce', 'Atcd', 'Pens', 'LoasDef', 'LoasIdo', 'Rmv' ] # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() # Calcula o fator de ajuste para cada tipo de aposentadoria for beneficio in dados.get_id_beneficios(tags): sexo = beneficio[-1] # Verifica se existem dados de estoque e cessações do benefício if beneficio in estoques.keys() and beneficio in cessacoes.keys(): fat_ajuste['fam' + beneficio] = pd.DataFrame(1.0, index=range(0, 91), columns=([2014] + periodo)) for idade in range(1, 91): ces_ano_atual = cessacoes[beneficio][ano_prob][idade] est_ano_ant = estoques[beneficio][ano_prob - 1][idade] # OBS: Gera fam acima de 100 para alguns beneficios em idades baixas. # Isso ocorre devido a pmorte ser muito baixa e os estoques serem muito # pequenos ou zero.Ver pag. 18 do doc da fazenda # Taxa de cessações - Eq. 15 # Não existem dados de cessação para t > 2015, sendo assim, não faz # sentido ter o índice t nas Eq. 14 e 15. Diante disso, foi considerado # um t fixo em 2014 para toda a projeção. if ces_ano_atual == 0: tx_ces = 0 else: tx_ces = ces_ano_atual / (est_ano_ant + (ces_ano_atual / 2)) # Probabilidade de morte mort = probMort['Mort' + sexo][ano_prob][idade] # Salva a Série no dicionário - Eq. 14 fat_ajuste['fam' + beneficio][ano_prob][idade] = tx_ces / mort # Repete a última probabilidade(2014) nos anos seguintes(2015-2060) for ano in periodo: fat_ajuste['fam' + beneficio][ano] = fat_ajuste['fam' + beneficio][ano - 1] # Substitui os NaN por 1.0 fat_ajuste['fam' + beneficio].fillna(1.0, inplace=True) return fat_ajuste
def calc_prob_pensao_LDO2018(concessoes, segurados, estoque, prob_morte, periodo): # A LDO de 2018 não descreve como calcular as probabilidades para pensões # As equações abaixo são resultado de manipulações das Equações 24 e 25 da LDO # Onde-se isolou-se a variável v para se chegar na equação de calculo das probabilidades probabilidades = {} # Dicionário que salvas as prob. para cada benefício ano_estoque = periodo[0] - 1 # 2014 # Eq. 26: Dit = Idh - Idm # Hipótese de que o diferencial de idade médio entre cônjuges é de 4 anos (pag. 45 LDO de 2018) Dit = 4 lista = LerTabelas() est_apos_acumulado = calc_estoq_apos_acumulado(estoque, periodo) for beneficio in lista.get_id_beneficios('Pe'): # Cria Objeto do tipo Serie que armazena as probabilidades probabilidades[beneficio] = pd.Series(0.0, index=range(0, 91)) sexo = beneficio[-1] # Última letra do benefício sexo_oposto = 'M' if sexo == 'H' else 'H' # Obtém o oposto clientela = lista.get_clientela(beneficio) id_conc = beneficio.replace(sexo, sexo_oposto) # Troca o sexo do benefício id_segurados = lista.get_id_segurados(beneficio) # Para cada idade i for idade in range(0, 91): # A soma ou subtração depende do sexo if sexo == 'M': i_Dit = idade - Dit else: i_Dit = idade + Dit # Trata valores negativos e maiores que 90 para i_Dit if i_Dit < 0: i_Dit = 0 if i_Dit > 90: i_Dit = 90 conc = concessoes[id_conc][ano_estoque][idade] seg = segurados[id_segurados][ano_estoque][i_Dit] est_ac = est_apos_acumulado[clientela + sexo][ano_estoque][i_Dit] pmorte = prob_morte['Mort' + sexo][ano_estoque][i_Dit] # Se a quantidade de segurados e estoque for zero a prob daria infinito if seg == 0 and est_ac == 0: probPensao = 0 else: # Equação baseada nas Eq. 24 e 25 # OBS: Essa equação pode gerar probabilidades maiores que 1 para idades menores que 20 probPensao = conc / ((seg + est_ac) * pmorte) probabilidades[beneficio][i_Dit] = probPensao return probabilidades
def calc_n_parcelas(estoques, despesa, valMedBenef, periodo): # ano_estoq = periodo[0]-1 # 2014 dados = LerTabelas() # Dicionário que armazena o número médio de parcelas para tipo de beneficio n_parcelas = {} # 2014 ano_estoque = periodo[0] - 1 # 2014-2060 anos = [ano_estoque] + periodo # Aposentadorias Idade Normal for benef in dados.get_id_beneficios('Apin'): # Rurais e Urbanos tem valores diferentes if 'Rur' in benef: n_parcelas[benef] = pd.Series(13.0, index=anos) n_parcelas[benef].loc[periodo[0]] = 12.95 # 2015 n_parcelas[benef].loc[periodo[1]:] = 12.82 # 2016-2060 else: n_parcelas[benef] = pd.Series(13.0, index=anos) n_parcelas[benef].loc[periodo[0]] = 12.7 # 2014-2015 n_parcelas[benef].loc[periodo[1]:] = 12.95 # 2016-2060 # Aposentadorias TC Normal for benef in dados.get_id_beneficios('Atcn'): # Rurais e Urbanos tem valores diferentes if 'Rur' in benef: n_parcelas[benef] = pd.Series(13.0, index=anos) n_parcelas[benef].loc[periodo[0]:] = 12.92 # 2015-2060 else: n_parcelas[benef] = pd.Series(13.0, index=anos) n_parcelas[benef].loc[periodo[0]] = 11.7 # 2015 n_parcelas[benef].loc[periodo[1]:] = 12.0 # 2016-2060 # Aposentadorias Idade Deficiente for benef in dados.get_id_beneficios('Apid'): n_parcelas[benef] = pd.Series(13.0, index=anos) # 2014-2060 # Aposentadorias TC Professor for benef in dados.get_id_beneficios('Atcp'): # Rurais e Urbanos tem valores diferentes if 'Rur' in benef: n_parcelas[benef] = pd.Series(13.0, index=anos) # 2014-2060 else: n_parcelas[benef] = pd.Series(13.0, index=anos) n_parcelas[benef].loc[periodo[0]] = 13.46 # 2015 n_parcelas[benef].loc[periodo[1]:] = 14.5 # 2016-2060 # Aposentadorias Invalidez for benef in dados.get_id_beneficios('Ainv'): # Rurais e Urbanos tem valores diferentes if 'Rur' in benef: n_parcelas[benef] = pd.Series(13.0, index=anos) n_parcelas[benef].loc[periodo[0]] = 13.09 # 2015 n_parcelas[benef].loc[periodo[1]:] = 12.96 # 2016-2060 else: n_parcelas[benef] = pd.Series(13.0, index=anos) n_parcelas[benef].loc[periodo[0]] = 12.3 # 2015 n_parcelas[benef].loc[periodo[1]:] = 11.9 # 2016-2060 # Aposentadorias TC especial for benef in dados.get_id_beneficios('Atce'): # Rurais e Urbanos tem valores diferentes if 'Rur' in benef: n_parcelas[benef] = pd.Series(13.0, index=anos) # 2014-2060 else: n_parcelas[benef] = pd.Series(13.0, index=anos) n_parcelas[benef].loc[periodo[0]] = 12.5 # 2015 n_parcelas[benef].loc[periodo[1]:] = 13.6 # 2016-2060 # Aposentadorias TC Deficiente for benef in dados.get_id_beneficios('Atcd'): n_parcelas[benef] = pd.Series(13.0, index=anos) # 2014-2060 # Pensões for benef in dados.get_id_beneficios('Pe'): # Rurais e Urbanos tem valores diferentes if 'Rur' in benef: n_parcelas[benef] = pd.Series(13.0, index=anos) n_parcelas[benef].loc[periodo[0]] = 12.97 # 2015 n_parcelas[benef].loc[periodo[1]:] = 12.89 # 2016-2060 else: n_parcelas[benef] = pd.Series(13.0, index=anos) n_parcelas[benef].loc[periodo[0]] = 12.70 # 2015 n_parcelas[benef].loc[periodo[1]:] = 13.10 # 2016-2060 # Auxilios Doença for benef in dados.get_id_beneficios('Auxd'): # Rurais e Urbanos tem valores diferentes if 'Rur' in benef: n_parcelas[benef] = pd.Series(12.0, index=anos) n_parcelas[benef].loc[periodo[0]] = 11.83 # 2015-2015 n_parcelas[benef].loc[periodo[1]:] = 13.32 # 2016-2060 else: n_parcelas[benef] = pd.Series(12.0, index=anos) n_parcelas[benef].loc[periodo[0]] = 8.33 # 2015 n_parcelas[benef].loc[periodo[1]:] = 9.01 # 2016-2060 # Auxilios Acidente for benef in dados.get_id_beneficios('Auxa'): # Rurais e Urbanos tem valores diferentes if 'Rur' in benef: n_parcelas[benef] = pd.Series(12.0, index=anos) n_parcelas[benef].loc[periodo[0]] = 12.99 # 2015 n_parcelas[benef].loc[periodo[1]:] = 13.46 # 2016-2060 else: n_parcelas[benef] = pd.Series(12.0, index=anos) n_parcelas[benef].loc[periodo[0]] = 12.43 # 2015 n_parcelas[benef].loc[periodo[1]:] = 12.56 # 2016-2060 # Auxilios Reclusão for benef in dados.get_id_beneficios('Auxr'): # Rurais e Urbanos tem valores diferentes if 'Rur' in benef: n_parcelas[benef] = pd.Series(12.0, index=anos) n_parcelas[benef].loc[periodo[0]] = 12.06 # 2015 n_parcelas[benef].loc[periodo[1]:] = 12.18 # 2016-2060 else: n_parcelas[benef] = pd.Series(12.0, index=anos) n_parcelas[benef].loc[periodo[0]] = 12.31 # 2015 n_parcelas[benef].loc[periodo[1]:] = 14.03 # 2016-2060 # Salario Maternidade for benef in dados.get_id_beneficios('SalMat'): n_parcelas[benef] = pd.Series(4.0, index=anos) # 2014-2060 # Assistenciais LoasDef for benef in dados.get_id_beneficios('LoasDef'): n_parcelas[benef] = pd.Series(12.0, index=anos) n_parcelas[benef].loc[periodo[0]] = 12.05 # 2015 n_parcelas[benef].loc[periodo[1]:] = 12.00 # 2016-2060 # Assistenciais LoasIdo for benef in dados.get_id_beneficios('LoasIdo'): n_parcelas[benef] = pd.Series(12.0, index=anos) n_parcelas[benef].loc[periodo[0]] = 11.96 # 2015 n_parcelas[benef].loc[periodo[1]:] = 11.73 # 2016-2060 # Assistenciais RMV for benef in dados.get_id_beneficios('Rmv'): n_parcelas[benef] = pd.Series(12.0, index=anos) n_parcelas[benef].loc[periodo[0]] = 12.09 # 2015 n_parcelas[benef].loc[periodo[1]:] = 12.06 # 2016-2060 # for beneficio in estoques.keys(): # # Verifica se existe dados de despesa para o beneficio # if beneficio in despesa.keys(): # desp = despesa[beneficio][ano_estoq].sum() # est = estoques[beneficio][ano_estoq].sum() # vm = valMedBenef[beneficio][ano_estoq].mean() # n_parcelas[beneficio] = Dt/(vm*est) return n_parcelas
def calc_prob_aux(segurados, estoques, concessoes, periodo): probabilidades = {} # Dicionário que salvas as prob. para cada benefício ano_prob = periodo[0] - 1 # ano utilizado para cálculo (2014) # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() # De acordo com as planilhas do DOC110/MF # ProbAuxDoenca = Concedidos/popOcupada # ProbAuxAcidente = Estoque/popOcupada # ProbAuxReclusão = Estoque/popOcupada(somando a idade com 25) # O cálculo do Auxílio doença e diferente dos demais auxílios for beneficio in dados.get_id_beneficios(['Auxd']): # Verifica se o possui os dados de estoque e concessões do benefício if beneficio in estoques.keys() and beneficio in concessoes.keys(): id_seg = dados.get_id_segurados(beneficio) # ex: CsmUrbH # concessões conhecidas dos últimos 4 anos (2011-2014) conc = concessoes[beneficio].loc[:, (ano_prob - 3):] seg = segurados[id_seg].loc[:, (ano_prob - 3):] prob_auxd = conc / seg # Substitui os NaN por zero prob_auxd.replace([np.inf, -np.inf], np.nan, inplace=True) prob_auxd.fillna(0, inplace=True) # Remove colunas com todos os valores iguais a zero prob_auxd = prob_auxd.loc[:, (prob_auxd != 0).any(axis=0)] # Repete a última probabilidade(2014) nos anos seguintes(2015-2060) for ano in periodo: prob_auxd[ano] = prob_auxd[ano - 1] probabilidades[beneficio] = prob_auxd # Calcula probabilidades de entrada em auxílio acidente for beneficio in dados.get_id_beneficios(['Auxa']): # Verifica se o possui os dados de estoque e concessões do benefício if beneficio in estoques.keys(): id_seg = dados.get_id_segurados(beneficio) # ex: CsmUrbH # estoques conhecidos dos últimos 4 anos (2011-2014) est = estoques[beneficio].loc[:, (ano_prob - 3):] seg = segurados[id_seg].loc[:, (ano_prob - 3):] prob_auxa = est / seg # Substitui os inf e NaN por zero prob_auxa.replace([np.inf, -np.inf], np.nan, inplace=True) prob_auxa.fillna(0, inplace=True) # Remove colunas com todos os valores iguais a zero prob_auxa = prob_auxa.loc[:, (prob_auxa != 0).any(axis=0)] # para o ano seguinte ao do estoque (2015) a probabilidade é a média dos anos anteriores # OBS: Para algumas clientelas as Planilhas repetem o último ano prob_auxa[2015] = prob_auxa.loc[:, :2014].mean(axis=1) # Repete a última probabilidade(2015) nos anos seguintes(2016-2060) for ano in periodo[1:]: prob_auxa[ano] = prob_auxa[ano - 1] probabilidades[beneficio] = prob_auxa # Calcula probabilidades de entrada em auxílio reclusão for beneficio in dados.get_id_beneficios(['Auxr']): # Verifica se o possui os dados de estoque e concessões do benefício if beneficio in estoques.keys(): sexo = beneficio[-1] id_seg = dados.get_id_segurados(beneficio) # ex: CsmUrbH # Cria objeto do tipo DataFrame prob_auxr = pd.DataFrame(0.0, index=range(0, 91), columns=[ano_prob] + periodo) deslocamento = 0 for idade in range(0, 91): est = estoques[beneficio][ano_prob][idade] # Na planilha são aplicados deslocamentos nas idades if idade < 61 and sexo == 'H': deslocamento = 25 elif idade < 61 and sexo == 'M': deslocamento = 18 else: deslocamento = 0 id_seg = dados.get_id_segurados(beneficio) # ex: CsmUrbH # OBS: para o AuxReclusao o sexo utilizado na popOcup é sempre masculino if 'Rur' in id_seg: id_seg = 'RurH' seg = segurados[id_seg][ano_prob][idade + deslocamento] if seg == 0: prob_auxr[ano_prob][idade] = 0 else: prob_auxr[ano_prob][idade] = est / seg # Substitui os NaN por zero prob_auxr.replace([np.inf, -np.inf], np.nan, inplace=True) prob_auxr.fillna(0, inplace=True) # Repete a última probabilidade(2014) nos anos seguintes(2015-2060) for ano in periodo: prob_auxr[ano] = prob_auxr[ano - 1] probabilidades[beneficio] = prob_auxr return probabilidades
def calc_prob_pensao(concessoes, segurados, populacao, estoque, prob_morte, periodo): # A LDO de 2018 não descreve como calcular as probabilidades para pensões # As equações abaixo foram extraídas das planilhas do MF probabilidades = {} # Dicionário que salvas as prob. para cada benefício ano_estoque = periodo[0] - 1 # 2014 # Eq. 26: Dit = Idh - Idm # Hipótese de que o diferencial de idade médio entre cônjuges é de 4 anos (pag. 45 LDO de 2018) Dit = 4 lista = LerTabelas() est_apos_acumulado = calc_estoq_apos_acumulado(estoque, periodo) for beneficio in lista.get_id_beneficios('Pe'): # Cria Objeto do tipo Serie que armazena as probabilidades probabilidades[beneficio] = pd.Series(0.0, index=range(0, 91)) sexo = beneficio[-1] # Última letra do benefício sexo_oposto = 'M' if sexo == 'H' else 'H' # Obtém o oposto clientela = lista.get_clientela(beneficio) id_conc = beneficio.replace(sexo, sexo_oposto) # Troca o sexo do benefício # OBS: Sempre são usados os segurados do sexo masculino id_segurados = lista.get_id_segurados(beneficio).replace(sexo, 'H') # Para cada idade i for idade in range(0, 91): if idade > 20 and idade < 87: Dit = 4 elif idade == 87: Dit = 3 elif idade == 88: Dit = 2 elif idade == 89: Dit = 1 else: Dit = 0 # A soma ou subtração depende do sexo if sexo == 'M': i_Dit = idade + Dit else: i_Dit = idade - Dit # Trata valores negativos e maiores que 90 para i_Dit if i_Dit < 0: i_Dit = 0 if i_Dit > 90: i_Dit = 90 conc = concessoes[id_conc][ano_estoque][i_Dit] pmorte = prob_morte['Mort' + sexo][ano_estoque][idade] # Para os urbanos com idade de 15 anos e para os rurais utiliza-se toda a população por clientela simples (Urb ou Rur) if idade < 16 or clientela == 'Rur': clientela_simples = clientela[0:3] potGeradoresPensoes = populacao['Pop' + clientela_simples + sexo][ano_estoque][idade] else: seg = segurados[id_segurados][ano_estoque][idade] est_ac = est_apos_acumulado[clientela + sexo][ano_estoque][idade] potGeradoresPensoes = seg + est_ac # Evita divisões por zero if potGeradoresPensoes == 0: probPensao = 0 else: # Equação baseada nas Eq. 24 e 25 # OBS: Essa equação gera probabilidades maiores que 1 probPensao = conc / (potGeradoresPensoes * pmorte) probabilidades[beneficio][idade] = probPensao return probabilidades
def calc_fat_ajuste_mort(estoques, cessacoes, probMort, periodo): # ano utilizado para cálculo ano_prob = periodo[0] - 1 #2014 # Dicionário que armazena as probabilidades fat_ajuste = {} # Calculada para aposentadorias, pensões e assistênciais tags = [ 'Apin', 'Atcn', 'Apid', 'Atcp', 'Ainv', 'Atce', 'Atcd', 'Pens', 'LoasDef', 'LoasIdo', 'Rmv' ] # Cria o objeto dados que possui os IDs das tabelas dados = LerTabelas() # Calcula o fator de ajuste para cada tipo de aposentadoria for beneficio in dados.get_id_beneficios(tags): sexo = beneficio[-1] # Verifica se existem dados de estoque e cessações do benefício if beneficio in estoques.keys() and beneficio in cessacoes.keys(): # A Equação utilizada nas planilhas do MF é diferente da descrita na LDO de 2018 (Eq. 14 e 15) # fam = 1, se Cessações = 0 # fam = (Cessações/Estoque)/txMort txCes = cessacoes[beneficio] / estoques[beneficio] fam = txCes / probMort['Mort' + sexo] # Elimina colunas com dados ausentes fam.dropna(how='all', axis=1, inplace=True) # Elimina o ano de 2010 (não é utilizado nas planilhas) if 2010 in fam.columns: fam.drop(2010, axis=1, inplace=True) # Trata divisões por zero (gera o valo inf) fam.replace([np.inf, -np.inf], np.nan, inplace=True) # Garante que não existe valor zero fam.replace(0, 1.0, inplace=True) # Substitui os NaN por 1.0 fam.fillna(1.0, inplace=True) # Para o primeiro ano de projeção (2015), o FAM é igual a média dos anos anteriores # Exceto para os Rurais e assistenciais, onde o FAM é igual ao do ano anterior if dados.get_clientela(beneficio) == 'Rur' or 'Loas' in beneficio: fam[ano_prob + 1] = fam[ano_prob] else: fam[ano_prob + 1] = fam.loc[:, :ano_prob].mean(axis=1) # Para os anos seguintes o FAM é constante for ano in periodo[1:]: fam[ano] = fam[ano - 1] # Lógica usada nas planilhas do MF para as Pensões # Garante que o beneficiário pare de receber pensão aos 21 anos # fam = 1/ProbMorte if 'Pens' in beneficio: for ano in periodo: fam.loc[21, ano] = 1 / probMort['Mort' + sexo].loc[21, ano] # Salva no dicionário fat_ajuste['fam' + beneficio] = fam return fat_ajuste