JuliaFinance / MarketObservables.jl

Provides standard types for financial markets
MIT License
5 stars 3 forks source link

Using parametric types #5

Open femtotrader opened 5 years ago

femtotrader commented 5 years ago

https://github.com/JuliaFinance/MarketObservables.jl/blob/392499db9d871707a65f550f481239c275dfc9e6/src/orderbook/base.jl#L7-L8

doesn't use parametric type but it should because volume can be integer or float

see https://github.com/JuliaFinance/MarketObservables.jl/pull/3#discussion_r277659286

roshii commented 5 years ago

Why not using Real instead?

volume::Real volume == zero(Real)

roshii commented 5 years ago

On an higher level, I'd proposed to using the following structure, keeping in mind that it would be used as something like Observable{MarketObservable}

MarketObservable
    |_ AbstractOrderBook
        |_ FiniteDepthOrderBook
        ...
    |_ Ticker
    |_ Trades
femtotrader commented 5 years ago

To my understanding, it's generally a bad idea to use abstract types

https://docs.julialang.org/en/v1/manual/performance-tips/index.html

Moreover type for volume can be different depending of the assets

Volume for shares is for example integer Volume for forex lots is decimal ...

roshii commented 5 years ago

I indeed suspected a performance implication... Parametric type it is then to cover both Float and Integer cases

femtotrader commented 5 years ago

I think we absolutely need to support volume of several types

see https://en.wikibooks.org/wiki/Introducing_Julia/Types

same for price so we don't have to be explicit about type to use here

It can be Float64, Int64 but also Decimal (to avoid rounding issue)

femtotrader commented 5 years ago

I personally don't use them... but some people may also want to use Unums!

femtotrader commented 5 years ago

I had a types.jl with the following content

const Price = Float64 #Nullable{Float64}
const Volume = Float64 #Nullable{Float64}
const Ticket = Integer #Nullable{Integer}
const Magic = Integer #Nullable{Integer}
const Slippage = Integer #Nullable{Integer}

null_price = NaN #Price()
null_volume = NaN #Volume()
null_datetime = DateTime(0)
null_ticket = -1 #Ticket()
null_magic = -1 #Magic()
null_slippage = -1 #Slippage()

function isnullprice(price::Price)
    isnan(price)
end

function isnullvolume(volume::Volume)
    isnan(volume)
end

function isnulldatetime(dt::DateTime)
    dt == null_datetime
end

function isnullmagic(magic::Magic)
    magic == null_magic
end

function isnullslippage(slippage::Slippage)
    slippage == null_slippage
end

but

const Price = Float64 #Nullable{Float64}
const Volume = Float64 #Nullable{Float64}

is definitely not the correct way of doing...

(that's why I'm not adding this to this repository)

femtotrader commented 5 years ago

I also had

abstract type AbstractPriceData{Tprice,Tvol} end

struct TickData{Tprice,Tvol} <: AbstractPriceData{Tprice,Tvol}
    ask::Tprice
    bid::Tprice
    volume::Tvol
end

struct BarData{Tprice,Tvol} <: AbstractPriceData{Tprice,Tvol}
    open::Tprice
    high::Tprice
    low::Tprice
    close::Tprice
    volume::Tvol
    adj_close::Tprice

    function BarData(open::Tprice, high::Tprice, low::Tprice, close::Tprice, volume::Tvol) where {Tprice, Tvol}
        new{Tprice,Tvol}(open, high, low, close, volume, close)
    end

    function BarData(open::Tprice, high::Tprice, low::Tprice, close::Tprice, volume::Tvol, adj_close::Tprice) where {Tprice, Tvol}
        new{Tprice,Tvol}(open, high, low, close, volume, adj_close)
    end
end

struct PriceTimedData
    time::DateTime
    data::AbstractPriceData
end

I have just add currently

abstract type AbstractPriceData{Tprice,Tvol} end

in this repository (types.jl) as it's required to compile

roshii commented 5 years ago

It can be Float64, Int64 but also Decimal (to avoid rounding issue)

I like the Decimal approach instead of Float. Exchanges do have decimal parameters in their API and so it will make setup easier while as you said, avoid rounding issues.

femtotrader commented 5 years ago

I think we should absolutely avoid to decide this now! and we should have our structs / functions able to manage any Number for Volume or Price

roshii commented 5 years ago

I personally don't use them... but some people may also want to use Unums!

I don't either, let's park it for now, we may still explore in the future

I think we should absolutely avoid to decide this now!

Agreed, nothing is set in stone, just brainstorming :)

femtotrader commented 5 years ago

Working with Decimal brings precision but it is sometimes at the expense of performance... if we can use Decimal or Float (or Integer) given context I think it's better

femtotrader commented 5 years ago

Similar code improvement than https://github.com/JuliaFinance/MarketObservables.jl/pull/10 should probably be done in

Unfortunately I can't spend more time on this this week... I let you @roshii have a look at this