FinanceRoutines.jl

Financial data routines for Julia
Log | Files | Refs | README | LICENSE

commit bde4eea811781ac1a5caf0f83cb3a71b6f29364c
parent 9de9220e4fa49fd8c4152bd07b64fa878bbdc9d1
Author: Erik Loualiche <eloualic@umn.edu>
Date:   Thu, 13 Oct 2022 18:43:03 -0500

First function(s)

Diffstat:
MProject.toml | 15++++++++++++---
MREADME.md | 6++++++
Msrc/FinanceRoutines.jl | 24+++++++++++++++++++++++-
Asrc/ImportFinanceData.jl | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtest/runtests.jl | 5+++++
5 files changed, 139 insertions(+), 4 deletions(-)

diff --git a/Project.toml b/Project.toml @@ -1,13 +1,22 @@ name = "FinanceRoutines" -uuid = "da951f97-d5c6-4b6a-8d83-777c3c337f5d" -authors = ["Erik Loualiche"] +uuid = "2e4c0fa2-b49b-4c8f-9592-485f04b9fc03" +authors = "Erik Loualiche <eloualic@umn.edu>" version = "0.1.0" +[deps] +CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" +DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +DataFramesMeta = "1313f7d8-7da2-5740-9ea0-a2ca25f37964" +Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" +Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +ZipFile = "a5390f91-8eb1-5f08-bee0-b1d1ffed6cea" + [compat] julia = "1" [extras] +Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["Test"] +test = ["Markdown", "Test"] diff --git a/README.md b/README.md @@ -1,3 +1,8 @@ # FinanceRoutines [![Build Status](https://github.com/eloualiche/FinanceRoutines.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/eloualiche/FinanceRoutines.jl/actions/workflows/CI.yml?query=branch%3Amain) + +## Functions + +1. Import Financial data + - `ImportFinanceData.jl`+ \ No newline at end of file diff --git a/src/FinanceRoutines.jl b/src/FinanceRoutines.jl @@ -1,5 +1,27 @@ module FinanceRoutines -# Write your package code here. + +# --------------------------------------------------------- +import Downloads +import ZipFile +import CSV +import DataFrames: DataFrame, rename! +import DataFramesMeta: DataFramesMeta, @subset!, @transform! +import Dates: Date +# --------------------------------------------------------- + + +# --------------------------------------------------------- +# Import functions +include("ImportFinanceData.jl") +# --------------------------------------------------------- + + +# --------------------------------------------------------- +# List of exported functions +export greet_FinanceRoutines # for debugging +export import_FF3 # read monthly FF3 +# --------------------------------------------------------- + end diff --git a/src/ImportFinanceData.jl b/src/ImportFinanceData.jl @@ -0,0 +1,93 @@ +# --------------------------------------------------------- +# ImportFinanceData.jl + +# Collection of functions that import +# financial data into julia +# --------------------------------------------------------- + + +# --------------------------------------------------------- +# List of exported functions +# export greet_FinanceRoutines # for debugging +# export import_FF3 # read monthly FF3 +# --------------------------------------------------------- + + +# --------------------------------------------------------- +function greet_FinanceRoutines() + println("Hello FinanceRoutines!") + return "Hello FinanceRoutines!" +end +# --------------------------------------------------------- + + +# --------------------------------------------------------- +function import_FF3() + + url_FF = "https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/ftp/F-F_Research_Data_Factors_CSV.zip" + + http_response = Downloads.download(url_FF); + z = ZipFile.Reader(http_response) ; + a_file_in_zip = filter(x -> match(r".*csv", lowercase(x.name)) != nothing, z.files)[1] + df_FF3 = copy(CSV.File(a_file_in_zip, header=3, footerskip=1) |> DataFrame); + close(z) + + rename!(df_FF3, [:dateym, :mktrf, :smb, :hml, :rf]); + @subset!(df_FF3, .!(ismissing.(:dateym))); + @subset!(df_FF3, .!(ismissing.(:mktrf))); + @transform!(df_FF3, :dateym = parse.(Int, :dateym) ) + @subset!(df_FF3, :dateym .>= 190000 ) + @transform!(df_FF3, + :date = Date.(div.(:dateym, 100), rem.(:dateym,100) ), + :mktrf = parse.(Float64, :mktrf), + :smb = parse.(Float64, :smb), + :hml = parse.(Float64, :hml), + :rf = parse.(Float64, :rf) ) + + return(df_FF3) +end +# --------------------------------------------------------- + + +# --------------------------------------------------------- +""" + import_FF3(frequency::Symbol) + +Download and import the Fama-French 3 Factors from Ken French website. + +If `frequency` is unspecified, import the monthly research returns. +If `frequency` is :daily, import the daily research returns. + +""" +function import_FF3(frequency::Symbol) + + if frequency==:monthly + return import_FF3() + + elseif frequency==:daily + url_FF = "https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/ftp/F-F_Research_Data_Factors_daily_CSV.zip" + + http_response = Downloads.download(url_FF); + + z = ZipFile.Reader(http_response) ; + a_file_in_zip = filter(x -> match(r".*csv", lowercase(x.name)) != nothing, z.files)[1] + df_FF3 = copy(CSV.File(a_file_in_zip, header=4, footerskip=1) |> DataFrame); + close(z) + + rename!(df_FF3, [:dateymd, :mktrf, :smb, :hml, :rf]); + @subset!(df_FF3, .!(ismissing.(:dateymd))); + @subset!(df_FF3, .!(ismissing.(:mktrf))); + @transform!(df_FF3, + :date = Date.(div.(:dateymd, 10000), + rem.(div.(:dateymd, 100), 100), rem.(:dateymd,100) ) + ) + + return(df_FF3) + + else + @warn "Frequency $frequency not known. Try :daily or leave blank for :monthly" + end + +end +# --------------------------------------------------------- + diff --git a/test/runtests.jl b/test/runtests.jl @@ -3,4 +3,9 @@ using Test @testset "FinanceRoutines.jl" begin # Write your tests here. + + # FOR DEBUGGING + @test FinanceRoutines.greet_FinanceRoutines() == "Hello FinanceRoutines!" + @test FinanceRoutines.greet_FinanceRoutines() != "Hello world!" + end