: DiasÚteis em Qualquer Calendário
Grupy-SP—julho/2015
Wilson Freitas
bizdays(https://pypi.python.org/pypi/bizdays/v0.2.0)
http://aboutwilson.net (http://aboutwilson.net)@aboutwilson (http://www.twitter.com/aboutwilson)
Sobre mim
Wilson Freitas
quantfísicocorredorpadeiro
Background
Sistemas ComplexosFinanças QuantitativasMatemática
Programação
R, Python, MATLAB, C/C++
MotivaçãoO mercado financeiro brasileiro possui diversas particularidas que complicam a simples tarefa decalcular os preços dos ativos financeiros.
liquidação de contratos de dólar com a cotação do dia anteriorcontratos com vencimento fixo ao contrário do resto do mundo que negocia prazosfixosregras absurdas para definição de vencimentose ...vigência do contrato em dias úteis, para diferentes calendáriosentre outras
Aqui vamos falar sobre como os desafios de lidar com dias úteis foram vencidos utilizandoPython.
Contagem de dias úteisNo Brasil as taxas de juros são calculadas em dias úteisHerança do período inflacionárioO problema é que com as taxas de juros apuradas em dias úteis força que todos osdemais contratos sigam a mesma convenção:
contratos futuros, títulos públicos, opçõesDiferentes mercados diferentes regras:
Mercado de derivativos (antiga BM&F) possui um calendário de feriadosMercado de ações (antiga Bovespa) possui outro calendárioContratos de moedas utilizam dias corridos
Problema: diferentes ativos precisam lidar com a contagem de dias de forma diferente
Módulo python-bizdays
História
A contagem em dias foi desenvolvida para o módulo
bizdays nasceu em R em set/2013Foi portado para Python em seguida
Objetivos
Objetivo 1: realizar operações com dias úteis!Objetivo 2: fazer uma coisa tão simples de usar quanto a função NETWORKDAYS doExcelObjetivo 3: Poder lidar com mais de 1 calendário sem if
python-fixedincome(https://github.com/wilsonfreitas/python-fixedincome)
bizdays in action
In [1]: from bizdays import Calendar
holidays = ['2015-01-01', '2015-02-16', '2015-02-17', '2015-04-03', '2015-04-21', '2015-05-01', '2015-06-04', '2015-09-07', '2015-10-12', '2015-11-02', '2015-11-15', '2015-12-25', '2016-01-01']cal = Calendar(holidays=holidays, weekdays=['Sunday', 'Saturday'])
In [2]: # Dia do Trabalho é dia útil?cal.isbizday('2015-05-01')
Out[2]: False
In [3]: # 12/07/2015 (domingo) é dia útil?cal.isbizday('2015-07-12')
Out[3]: False
In [4]: # 03/08/2015 (sengunda-feira) é dia útil?cal.isbizday('2015-08-03')
Out[4]: True
In [5]: # Quantidade de dias úteis no ano:cal.bizdays('2015-01-01', '2015-12-31')
Out[5]: 249
In [6]: # Quantidade de dias úteis até hoje:cal.bizdays('2015-01-01', '2015-07-16')
Out[6]: 133
In [7]: # Todos os dias úteis em um período, pex primeira quinzena de abrillist(cal.seq('2015-04-01', '2015-04-15'))
Out[7]: [datetime.date(2015, 4, 1), datetime.date(2015, 4, 2), datetime.date(2015, 4, 6), datetime.date(2015, 4, 7), datetime.date(2015, 4, 8), datetime.date(2015, 4, 9), datetime.date(2015, 4, 10), datetime.date(2015, 4, 13), datetime.date(2015, 4, 14), datetime.date(2015, 4, 15)]
Cálculo de preços de ativos financeirosOs ativos financeiros tem data de vencimento fixa
Contratos Futuros de taxas de juros (DI1) expiram no dia 01 do mês devencimento
Use adjust_next (ou adjust_previous)
In [8]: refdate = '2015-03-12'maturity = '2015-05-01'
In [9]: cal.bizdays(refdate, maturity)
Out[9]: 33
In [10]: cal.adjust_next(maturity)
Out[10]: datetime.date(2015, 5, 4)
In [11]: cal.bizdays(refdate, cal.adjust_next(maturity))
Out[11]: 34
Também trabalha com vetores de datas (atributo vec :/)
In [12]: refdate = '2015-03-12'maturities = ['2015-05-01', '2015-06-01', '2015-08-01']
In [13]: list(cal.vec.adjust_next(maturities))
Out[13]: [datetime.date(2015, 5, 4), datetime.date(2015, 6, 1), datetime.date(2015, 8, 3)]
In [14]: list(cal.vec.bizdays(refdate, list(cal.vec.adjust_next(maturities))))
Out[14]: [34, 54, 98]
Manipulando curvas de taxas de juros
In [15]: import pandas as pd
Carregando um calendário em um arquivo
In [16]: !head -6 ANBIMA.cal
SaturdaySunday2000-01-012000-03-062000-03-072000-04-21
In [17]: cal252 = Calendar.load('ANBIMA.cal')cal360 = Calendar()
Carregando taxas de juros divulgadas pela BM&FBovespa
In [18]: url = 'http://www2.bmf.com.br/pages/portal/bmfbovespa/boletim1/TxRef1.asp'dfs = pd.read_html(url)curva = dfs[2].ix[2:]curva.columns = ['DC', 'Taxa_252', 'Taxa_360']curva.index = range(1, len(curva)+1)curva.dtypes
Out[18]: DC objectTaxa_252 objectTaxa_360 float64dtype: object
In [19]: curva.head()
Out[19]: DC Taxa_252 Taxa_360
1 1 1364 1340
2 8 1368 1472
3 15 1368 1438
4 16 1368 1473
5 19 1368 1335
Separando as curvas
Criar 2 curvas uma de taxas em dias corridos e outra em dias úteis.
In [20]: curva360 = pd.DataFrame({'DC': curva['DC'].apply(int), 'Taxa_360': curva['Taxa_252'].apply(lambda x: float(x)/100)})curva360.head(3)
Out[20]: DC Taxa_360
1 1 13.64
2 8 13.68
3 15 13.68
In [21]: refdate = '2015-07-15'dates = list(cal360.vec.offset(refdate, curva360['DC']))
curva252 = pd.DataFrame({'DU': list(cal252.vec.bizdays(refdate, dates)), 'Taxa_252': curva['Taxa_252'].apply(lambda x: float(x)/100)})curva252.head(3)
Out[21]: DU Taxa_252
1 1 13.64
2 6 13.68
3 11 13.68
Definindo vencimentos dos contratos
Maioria dos contratos futuros
Vencimento no primeiro dia de cada mês
In [22]: cal.getdate('first day', 2015, 1)
Out[22]: datetime.date(2015, 1, 1)
In [23]: cal.getdate('1st day', 2015, 5)
Out[23]: datetime.date(2015, 5, 1)
Contratos futuros de inflação
Vencimento do dia 15 de cada mês
In [24]: cal.getdate('15th day', 2015, 7)
Out[24]: datetime.date(2015, 7, 15)
Contratos futuros de soja
Vencimento nos segundos dias úteis
In [25]: cal.getdate('2nd bizday', 2015, 5)
Out[25]: datetime.date(2015, 5, 5)
Contratos futuros de boi gordo
Vencimento no último dia útil do mês
In [26]: cal.getdate('last bizday', 2015, 5)
Out[26]: datetime.date(2015, 5, 29)
Contratos futuros de café
Vencimento do sexto dia útil anterior ao último dia do mês
In [27]: cal.getdate('6th bizday before last day', 2015, 7)
Out[27]: datetime.date(2015, 7, 23)
Contratos futuros de índice (IBOVESPA)
Vencimento na quarta-feira mais próxima do dia 15 do mês
In [28]: cal.getdate('first wed after 15th day', 2015, 6)
Out[28]: datetime.date(2015, 6, 17)
In [29]: cal.getdate('first wed before 15th day', 2015, 6)
Out[29]: datetime.date(2015, 6, 10)
Wilson Freitas — http://blog.aboutwilson.net/ (http://blog.aboutwilson.net/)
github (https://github.com/wilsonfreitas)
@aboutwilson (http://www.twitter.com/aboutwilson)
Top Related