Skip to content

Commit

Permalink
first push
Browse files Browse the repository at this point in the history
  • Loading branch information
tbeason committed Apr 14, 2020
0 parents commit eb93bba
Show file tree
Hide file tree
Showing 14 changed files with 387 additions and 0 deletions.
1 change: 1 addition & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
comment: false
24 changes: 24 additions & 0 deletions .github/workflows/CompatHelper.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: CompatHelper

on:
schedule:
- cron: '00 00 * * *'

jobs:
CompatHelper:
runs-on: ${{ matrix.os }}
strategy:
matrix:
julia-version: [1.2.0]
julia-arch: [x86]
os: [ubuntu-latest]
steps:
- uses: julia-actions/setup-julia@latest
with:
version: ${{ matrix.julia-version }}
- name: Pkg.add("CompatHelper")
run: julia -e 'using Pkg; Pkg.add("CompatHelper")'
- name: CompatHelper.main()
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: julia -e 'using CompatHelper; CompatHelper.main()'
11 changes: 11 additions & 0 deletions .github/workflows/TagBot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: TagBot
on:
schedule:
- cron: 0 * * * *
jobs:
TagBot:
runs-on: ubuntu-latest
steps:
- uses: JuliaRegistries/TagBot@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
*.jl.cov
*.jl.*.cov
*.jl.mem
/deps/deps.jl
/docs/build
Manifest.toml
/docs
33 changes: 33 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
## Documentation: http://docs.travis-ci.com/user/languages/julia/
language: julia
dist: xenial
os:
- linux
- osx
julia:
- 1.0
- 1.1
- 1.2
- 1.3
- 1.4
- nightly
notifications:
email: false
git:
depth: 99999999

jobs:
## uncomment following lines to deploy documentation
# include:
# - stage: "Documentation"
# julia: 1.3
# os: linux
# script:
# - julia --project=docs -e 'using Pkg; Pkg.instantiate(); Pkg.develop(PackageSpec(path=pwd()))'
# - julia --project=docs --color=yes docs/make.jl
# after_success: skip
allow_failures:
- julia: nightly
after_success:
- julia --project=test/coverage -e 'using Pkg; Pkg.instantiate()'
- julia --project=test/coverage test/coverage/coverage.jl
22 changes: 22 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
The DailyTreasuryYieldCurve.jl package is licensed under the MIT "Expat" License:

> Copyright (c) 2020: Tyler Beason.
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all
> copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> SOFTWARE.
>
21 changes: 21 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name = "DailyTreasuryYieldCurve"
uuid = "9f24bdcd-220e-43b5-8e6d-85812fd68fcf"
authors = ["Tyler Beason <[email protected]>"]
version = "0.1.0"

[deps]
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
EzXML = "8f5d6c58-4d21-5cfd-889c-e3ad7ee6a615"
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
Missings = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"

[compat]
julia = "^1"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test"]
70 changes: 70 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# DailyTreasuryYieldCurve.jl

![Lifecycle](https://img.shields.io/badge/lifecycle-experimental-orange.svg)<!--
![Lifecycle](https://img.shields.io/badge/lifecycle-maturing-blue.svg)
![Lifecycle](https://img.shields.io/badge/lifecycle-stable-green.svg)
![Lifecycle](https://img.shields.io/badge/lifecycle-retired-orange.svg)
![Lifecycle](https://img.shields.io/badge/lifecycle-archived-red.svg)
![Lifecycle](https://img.shields.io/badge/lifecycle-dormant-blue.svg) -->
[![Build Status](https://travis-ci.com/tbeason/DailyTreasuryYieldCurve.jl.svg?branch=master)](https://travis-ci.com/tbeason/DailyTreasuryYieldCurve.jl)
[![codecov.io](http://codecov.io/github/tbeason/DailyTreasuryYieldCurve.jl/coverage.svg?branch=master)](http://codecov.io/github/tbeason/DailyTreasuryYieldCurve.jl?branch=master)
<!--
[![Documentation](https://img.shields.io/badge/docs-stable-blue.svg)](https://tbeason.github.io/DailyTreasuryYieldCurve.jl/stable)
[![Documentation](https://img.shields.io/badge/docs-master-blue.svg)](https://tbeason.github.io/DailyTreasuryYieldCurve.jl/dev)
-->

This package does one thing: gets you daily yield curves from the [US Treasury](https://www.treasury.gov/resource-center/data-chart-center/interest-rates/Pages/TextView.aspx?data=yield). The data is served via an XML feed, but this package cleans it up into a `DataFrame` so that you can use it.


Structure of returned data for nominal curve:

| Column Name | Description |
| ---- | ---- |
| date | Date of yield curve |
| m1 | 1 month constant maturity rate |
| m2 | 2 month constant maturity rate |
| m3 | 3 month constant maturity rate |
| m6 | 6 month constant maturity rate |
| y1 | 1 year constant maturity rate |
| y2 | 2 year constant maturity rate |
| y3 | 3 year constant maturity rate |
| y5 | 5 year constant maturity rate |
| y7 | 7 year constant maturity rate |
| y10 | 10 year constant maturity rate |
| y20 | 20 year constant maturity rate |
| y30 | 30 year constant maturity rate |


Structure of returned data for real curve:

| Column Name | Description |
| ---- | ---- |
| date | Date of yield curve |
| y5 | 5 year constant maturity real rate |
| y7 | 7 year constant maturity real rate |
| y10 | 10 year constant maturity real rate |
| y20 | 20 year constant maturity real rate |
| y30 | 30 year constant maturity real rate |


Not all maturities were reported on every day.

# Example

```julia
using DailyTreasuryYieldCurve

df_rates = getyieldcurves()

df_realrates = getyieldcurves(;realrates=true)

```






## Disclaimer

This package is provided as-is and without guarantees. I am not affiliated with the US Treasury. Please cite the original source when using this data.
149 changes: 149 additions & 0 deletions src/DailyTreasuryYieldCurve.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
module DailyTreasuryYieldCurve

using Reexport
using EzXML
using HTTP
using Dates
using Missings
@reexport using DataFrames



export getyieldcurves





const DATAFEED = "http://data.treasury.gov/feed.svc/DailyTreasuryYieldCurveRateData"
const DATAFEEDREAL = "http://data.treasury.gov/feed.svc/DailyTreasuryRealYieldCurveRateData"

# these fields are provided by the feed (as of 20200413)
# note that we must use :m1 because :1m is not a valid symbol
const COLNAMES = [:id,:date,:m1,:m2,:m3,:m6,:y1,:y2,:y3,:y5,:y7,:y10,:y20,:y30,:y30dup]
const COLNAMESREAL = [:id,:date,:y5,:y7,:y10,:y20,:y30]








"""
`getyieldcurves(;real::Bool=false)`
Download the whole published history of daily US Treasury yield curves from the official data feed.
Optionally, pass a filename if you have already downloaded the data, eg. `getyieldcurves(fn::AbstractString)`.
By default, gets the nominal yield curve. Pass `realrates=true` to get the real yield curve. The nominal series starts in 1990, while the real series starts in 2003.
Returns a `DataFrame`.
"""
function getyieldcurves(;realrates::Bool=false)
if realrates
h = HTTP.get(DATAFEEDREAL)
else
h = HTTP.get(DATAFEED)
end
thexml = parsexml(String(h.body))
return _parseyieldcurves(thexml,realrates)
end


function getyieldcurves(fn::AbstractString;realrates::Bool=false)
thexml = readxml(fn)
return _parseyieldcurves(thexml,realrates)
end



"""
`_parseyieldcurves(thexml,realrates)`
Parser function for Treasury yield curve data. (unexported)
"""
function _parseyieldcurves(thexml,realrates)
if realrates
return _parserealcurves(thexml)
else
return _parsenominalcurves(thexml)
end
end

function _parsenominalcurves(thexml)
r = thexml.root
cnod=findall("/*/*/*[position()=7]",r)
@assert length(cnod) >= 1 "Rate XML parse error likely."

stripsplitstrip(s) = strip.(split(strip(s),"\n"))

strarr = map(stripsplitstrip,nodecontent.(cnod))
df=DataFrame(Tuple.(strarr))
@assert nrow(df) >= 1 "Rate XML parse error likely."

rename!(df,COLNAMES)
select!(df,Not([:id; :y30dup]))
for c in COLNAMES[2:end-1]
if c == :date
df[!,c] = Date.(parse.(DateTime,df[!,c]))
else
df[!,c] = passmissing(x->parse(Float64,x)).(replace(df[!,c],""=>missing))
end
end
sort!(df,:date)
return df
end


function _parserealcurves(thexml)
r = thexml.root
cnod=findall("/*/*/*[position()=7]",r)
@assert length(cnod) >= 1 "Rate XML parse error likely."


nodestr = nodecontent.(cnod)

function splitandfill(s)
spl = split(s)
L = length(spl)
L == length(COLNAMESREAL) && return spl

strvec = Vector{eltype(spl)}(undef,length(COLNAMESREAL))
for i in 1:length(COLNAMESREAL)
if i <= L
strvec[i] = spl[i]
else
strvec[i] = ""
end
end
return strvec
end

strarr = splitandfill.(nodestr)
df=DataFrame(Tuple.(strarr))
@assert nrow(df) >= 1 "Rate XML parse error likely."

rename!(df,COLNAMESREAL)
select!(df,Not(:id))
for c in COLNAMESREAL[2:end]
if c == :date
df[!,c] = Date.(parse.(DateTime,df[!,c]))
else
df[!,c] = passmissing(x->parse(Float64,x)).(replace(df[!,c],""=>missing))
end
end
sort!(df,:date)
return df
end









end # module
3 changes: 3 additions & 0 deletions test/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[deps]
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2 changes: 2 additions & 0 deletions test/coverage/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[deps]
Coverage = "a2441757-f6aa-5fb2-8edb-039e3f45d037"
12 changes: 12 additions & 0 deletions test/coverage/coverage-summary.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
####
#### Coverage summary, printed as "(percentage) covered".
####
#### Useful for CI environments that just want a summary (eg a Gitlab setup).
####

using Coverage
cd(joinpath(@__DIR__, "..", "..")) do
covered_lines, total_lines = get_summary(process_folder())
percentage = covered_lines / total_lines * 100
println("($(percentage)%) covered")
end
9 changes: 9 additions & 0 deletions test/coverage/coverage.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# only push coverage from one bot
get(ENV, "TRAVIS_OS_NAME", nothing) == "linux" || exit(0)
get(ENV, "TRAVIS_JULIA_VERSION", nothing) == "1.3" || exit(0)

using Coverage

cd(joinpath(@__DIR__, "..", "..")) do
Codecov.submit(Codecov.process_folder())
end
Loading

0 comments on commit eb93bba

Please sign in to comment.