Skip to content

Commit

Permalink
Update to add @cash and @stock macros (#15)
Browse files Browse the repository at this point in the history
* Update to add @cash and @stock macros

* Change README master->main
  • Loading branch information
ScottPJones authored Jul 1, 2020
1 parent c536ca2 commit 23206aa
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 47 deletions.
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ keywords = ["Finance", "Asset"]
license = "MIT"
desc = "Financial assets"
authors = ["Eric Forgy <[email protected]>", "ScottPJones <[email protected]>"]
version = "0.8.0"
version = "0.9.0"

[deps]
Currencies = "0fd90b74-7c1f-579e-9252-02cd883047b9"
Expand All @@ -13,7 +13,7 @@ Instruments = "2a4f3d17-849a-48a1-809e-d780c70a95a0"

[compat]
Currencies = ">= 0.17"
Instruments = ">= 0.7"
Instruments = ">= 0.8"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Expand Down
35 changes: 13 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,10 @@
[pkg-url]: https://github.com/JuliaFinance/Assets.jl.git

[julia-url]: https://github.com/JuliaLang/Julia
[julia-release]:https://img.shields.io/github/release/JuliaLang/julia.svg

[release]: https://img.shields.io/github/release/JuliaFinance/Assets.jl.svg
[release-date]: https://img.shields.io/github/release-date/JuliaFinance/Assets.jl.svg

[license-img]: http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat
[license-url]: LICENSE.md
[travis-url]: https://travis-ci.com/JuliaFinance/Assets.jl
[travis-s-img]: https://travis-ci.com/JuliaFinance/Assets.jl.svg
[travis-m-img]: https://travis-ci.com/JuliaFinance/Assets.jl.svg?branch=main

[contrib]: https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat
[travis-img]: https://travis-ci.com/JuliaFinance/Assets.jl.svg

[codecov-url]: https://codecov.io/gh/JuliaFinance/Assets.jl
[codecov-img]: https://codecov.io/gh/JuliaFinance/Assets.jl/branch/master/graph/badge.svg
[codecov-img]: https://codecov.io/gh/JuliaFinance/Assets.jl/branch/main/graph/badge.svg

| **Julia Version** | **Unit Tests** | **Coverage** |
|:------------------:|:---------------------:|:---------------------:|
| [![][julia-release]][julia-url] | [![][travis-s-img]][travis-url] | [![][codecov-img]][codecov-url]
| Julia Latest | [![][travis-m-img]][travis-url] | [![][codecov-img]][codecov-url]
[![][travis-img]][travis-url] [![][codecov-img]][codecov-url]

# Assets

Expand All @@ -35,12 +19,14 @@ It also provides a specialized `Position` for `Cash` that uses the currency's mi

When a currency is thought of as a financial instrument (as opposed to a mere label), we choose to refer to it as "Cash" as it would appear in a balance sheet. This package implements the `Cash` instrument with parameter `S` being the 3-character ISO 4217 alpha label of the currency as a `Symbol` and an integer `N` representing the number of decimal places in the currency (typically 0, 2 or 3).

Short constants are set up, matching the ISO 4217 names, so that you can use `USD` instead of `Cash{:USD,2}`.
The @cash macro will set up short constants, matching the ISO 4217 names, so that you can use `USD` instead of `Cash{:USD,2}`.

One can also use the `cash` string macro, i.e. `cash"GBP"`, to refer to a particular Cash type.

For example:

```julia
julia> using Assets: JPY, USD, JOD
julia> @cash JPY, USD, JOD

julia> JPY
Cash{:JPY,0}
Expand All @@ -63,7 +49,7 @@ Although `Cash` is a singleton type, other financial instruments may contain var
A `Position` represents an amount of ownership of a financial instrument. For example, Microsoft stock

```julia
const MSFT = stock(:MSFT,:USD)
const MSFT = stock(:MSFT,USD)
```
is a financial instrument. A position could be 1,000 shares of `MSFT` and can be represented in one of two ways:

Expand All @@ -79,6 +65,11 @@ julia> 1000MSFT
1000MSFT
```

The `stock` string macro can also be used, for example:
`stock"MSFT"`
or
`stock"GSK"gbp` (to indicate a stock, GlaxoSmithKline, denominated in British Pounds).

Similarly, cash positions can be constructed as

```julia
Expand Down
56 changes: 36 additions & 20 deletions src/Assets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ module Assets
using Currencies, FixedPointDecimals, Instruments
import Currencies: symbol, currency, unit, code, name

export Cash, Stock, cash, stock, @cash_str, @stock_str
export Cash, cash, @cash_str, @cash
export Stock, stock, @stock_str, @stock

"""
`Cash` is an implementation of `Instrument` represented by a singleton type,
Expand All @@ -45,39 +46,54 @@ name(::Type{<:Cash{S}}) where {S} = name(S)
currency(::Type{<:Cash{S}}) where {S} = currency(S)

macro cash_str(str)
:( cash(Symbol($(esc(str)))) )
:( cash(Symbol($(esc(uppercase(str))))) )
end

function Position{Cash{C,N}}(a) where {C,N}
macro cash(syms)
args = syms isa Expr ? syms.args : [syms]
for nam in args
lownam = Symbol(lowercase(string(nam)))
Base.eval(__module__, :( const $nam = cash($(QuoteNode(nam))) ) )
Base.eval(__module__, :( const $lownam = $nam() ) )
end
end

function Position{S}(amt) where {C,N,S<:Cash{C,N}}
T = FixedDecimal{Int,N}
Position{Cash{C,N},T}(T(a))
Position{S,T}(T(amt))
end

"""
`Stock` is an implementation of a simple `Instrument` represented by a singleton type
with a stock symbol and currency, e.g. `Stock{:MSFT,:USD}`.
with a stock symbol and currency, e.g. `Stock{:MSFT,ccy"USD"}`.
The currency can be omitted and it will default to USD, e.g. `Stock(:MSFT)`.
"""
struct Stock{S,C} <: Instrument{S,C}
Stock(sym::Symbol, ccy::Symbol=:USD) = new{sym,currency(ccy)}()
Stock(sym::Symbol, ::Type{T}) where {T<:Currency} = new{sym,T}()
struct Stock{S,C} <: Instrument{S,Currency}
Stock(sym::Symbol, ccy::Type{<:Currency}=Currency(:USD)) = new{sym,currency(ccy)}()
Stock(sym::Symbol, pos::Type{<:Cash}) = new{sym,currency(pos)}()
end
stock(sym::Symbol, ccy::Type{<:Currency}=Currency(:USD)) = typeof(Stock(sym, currency(ccy)))
stock(sym::Symbol, pos::Type{<:Cash}) = typeof(Stock(sym, currency(pos)))

"""
Return the singleton type for a particular general stock, given it's symbol.
Defaults to USD for the currency
"""
stock(sym::Symbol, ccy::Symbol=:USD) = Stock{sym,currency(ccy)}
stock(sym::Symbol, ::Type{T}) where {T<:Currency} = Stock{sym,T}
symbol(::Type{Stock{S,C}}) where {S,C} = S
currency(::Type{Stock{S,C}}) where {S,C} = C

macro stock_str(str, ccy="USD")
:( stock(Symbol($(esc(str))), $(esc(currency(Symbol(uppercase(ccy))))) ) )
end

macro stock_str(str,ccy="USD")
:( stock(Symbol($(esc(str))),Symbol($(esc(ccy)))) )
macro stock(syms)
args = syms isa Expr ? syms.args : [syms]
for nam in args
lownam = Symbol(lowercase(string(nam)))
Base.eval(__module__, :( const $nam = stock($(QuoteNode(nam))) ) )
Base.eval(__module__, :( const $lownam = $nam() ) )
end
end

# Set up short names for all of the currencies (as Cash instrument types).
# This is really done as a convenience
for (s,(ccy,u,c,n)) in Currencies.allpairs()
@eval const $s = cash($ccy)
function Position{S}(amt) where {S<:Stock}
T = FixedDecimal{Int,4}
Position{S,T}(T(a))
end

end # module Assets
6 changes: 3 additions & 3 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using Assets, Currencies, Instruments, FixedPointDecimals

using Assets: USD, EUR, JPY, JOD, CNY
using Currencies: currency, symbol, unit, code, name

@cash USD, EUR, JPY, JOD, CNY

using Test

# Check that some basic currencies have been loaded correctly
Expand All @@ -25,7 +25,7 @@ end
@testset "All currencies" begin
for sym in Currencies.allsymbols()
ccy = Currency{sym}()
ct = Base.eval(Assets, sym)
ct = cash(sym)
@test ct == cash(typeof(ccy))
@test ct == cash(sym)
@test currency(ct) == typeof(ccy)
Expand Down

0 comments on commit 23206aa

Please sign in to comment.