diff --git a/Project.toml b/Project.toml index 09db539d..f479aab1 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "LightweightCharts" uuid = "d6998af1-87ca-4e7f-83d4-864c79a249fa" -version = "1.2.1" +version = "1.3.0" [deps] Serde = "db9b398d-9517-45f8-9a95-92af99003e0e" diff --git a/src/chart_data.jl b/src/chart_data.jl index 58b22725..fb5f4bf6 100644 --- a/src/chart_data.jl +++ b/src/chart_data.jl @@ -223,15 +223,6 @@ function lwc_convert_data!(data::T)::T where {T<:AbstractVector{<:AbstractChartD return data end -function lwc_convert_data( - timearray::AbstractVector{Tuple{D,T}}, -)::Vector{LWCSimpleChartData} where {D<:Union{Real,TimeType},T<:Real} - data::Vector{LWCSimpleChartData} = [ - LWCSimpleChartData(datetime2epochns(datetime), value) for (datetime, value) in timearray - ] - return lwc_convert_data!(data) -end - function lwc_convert_data( timearray::AbstractVector{Tuple{D,O,H,L,C}}, )::Vector{LWCCandle} where {D<:Union{Real,TimeType},O<:Real,H<:Real,L<:Real,C<:Real} @@ -241,6 +232,59 @@ function lwc_convert_data( return lwc_convert_data!(data) end +function lwc_convert_data(::Type{T}, timearray::AbstractVector) where {T<:AbstractChartData} + element_type = eltype(timearray) + V = if hasmethod(convert, (Type{Pair}, element_type)) + Pair + elseif hasmethod(convert, (Type{Tuple}, element_type)) + Tuple + else + throw(ErrorException("Type $element_type must have a `convert` method to Tuple type or Pair type.")) + end + + data = lwc_convert_data(T, V, timearray) + return lwc_convert_data!(data) +end + +function lwc_convert_data(::Type{LWCSimpleChartData}, ::Type{V}, timearray::AbstractVector)::Vector{LWCSimpleChartData} where {V} + return map(timearray) do element + datetime, value = convert(V, element) + return LWCSimpleChartData(datetime2epochns(datetime), value) + end +end + +function lwc_convert_data(::Type{LWCCandle}, ::Type{V}, timearray::AbstractVector)::Vector{LWCCandle} where {V} + return map(timearray) do element + candle = convert(V, element) + return if length(candle) == 2 + datetime, value = candle + open, high, low, close = if hasmethod(iterate, Tuple{typeof(value)}) + value + elseif hasmethod(convert, (Type{Tuple}, typeof(value))) + convert(Tuple, value) + else + throw(ErrorException( + """ + Invalid custom candlestick value data ($(typeof(value))). + Candlestick value must be iterable or convertable to Tuple{Real,Real,Real,Real}. + """ + )) + end + LWCCandle(datetime2epochns(datetime), open, high, low, close) + elseif length(candle) == 5 + datetime, open, high, low, close = candle + LWCCandle(datetime2epochns(datetime), open, high, low, close) + else + throw(ErrorException( + """ + Invalid custom candlestick data ($(eltype(timearray))). + Candle must be convertable to Tuple{Union{TimeType,Real},NTuple{4,Real}} or Tuple{Union{TimeType,Real},Real,Real,Real,Real} + """ + )) + end + end +end + function lwc_convert_data(time::D)::Int64 where {D<:Union{Real,TimeType}} return datetime2epochns(time) end diff --git a/src/charts.jl b/src/charts.jl index 1010c85d..a3162029 100644 --- a/src/charts.jl +++ b/src/charts.jl @@ -73,6 +73,13 @@ function prepare_data( return collect(zip(timestamps, values)) end +function prepare_data( + values::Vector{T}; +)::Vector{Tuple{Union{Real,TimeType},T}} where {T<:Real} + timestamps = [d + Second(1) for d in DateTime(1970):Second(1):DateTime(1970) + Second(length(values) - 1)] + return prepare_data(timestamps, values) +end + function prepare_data( timestamps::Vector{D}, open::Vector{O}, @@ -84,13 +91,6 @@ function prepare_data( return collect(zip(timestamps, open, high, low, close)) end -function prepare_data( - values::Vector{T}; -)::Vector{Tuple{Union{Real,TimeType},T}} where {T<:Real} - timestamps = [d + Second(1) for d in DateTime(1970):Second(1):DateTime(1970) + Second(length(values) - 1)] - return prepare_data(timestamps, values) -end - include("charts/line.jl") include("charts/baseline.jl") include("charts/area.jl") diff --git a/src/charts/area.jl b/src/charts/area.jl index 33f66cf5..7b573269 100644 --- a/src/charts/area.jl +++ b/src/charts/area.jl @@ -112,24 +112,26 @@ function lwc_area( end function lwc_area( - timearray::AbstractVector{Tuple{D,T}}; + timestamps::AbstractVector{D}, + values::AbstractVector{T}; kw... )::LWCChart where {D<:Union{Real,TimeType},T<:Real} - data = lwc_convert_data(timearray) + data = prepare_data(timestamps, values) return lwc_area(data; kw...) end function lwc_area( - timestamps::Vector{D}, - values::Vector{T}; + timearray::AbstractVector{T}; kw... -)::LWCChart where {D<:Union{Real,TimeType},T<:Real} - return lwc_area(prepare_data(timestamps, values); kw...) +)::LWCChart where {T<:Real} + data = prepare_data(timearray) + return lwc_area(data; kw...) end function lwc_area( - values::Vector{T}; + timearray::AbstractVector; kw... -)::LWCChart where {T<:Real} - return lwc_area(prepare_data(values); kw...) +)::LWCChart + data = lwc_convert_data(LWCSimpleChartData, timearray) + return lwc_area(data; kw...) end diff --git a/src/charts/bar.jl b/src/charts/bar.jl index 5f3b4d68..51619003 100644 --- a/src/charts/bar.jl +++ b/src/charts/bar.jl @@ -103,3 +103,15 @@ function lwc_bar( )::LWCChart where {D<:Union{Real,TimeType},O<:Real,H<:Real,L<:Real,C<:Real} return lwc_bar(lwc_convert_data(data); kw...) end + +function lwc_bar( + timestamp::AbstractVector{T}, + ohlc::AbstractVector{Tuple{O,H,L,C}}; + kw... +)::LWCChart where {T<:Union{TimeType,Real},O<:Real,H<:Real,L<:Real,C<:Real} + return lwc_bar(prepare_data(data); kw...) +end + +function lwc_bar(data::AbstractVector; kw...)::LWCChart + return lwc_bar(lwc_convert_data(LWCCandle, data); kw...) +end diff --git a/src/charts/baseline.jl b/src/charts/baseline.jl index ebe4e116..76d760ef 100644 --- a/src/charts/baseline.jl +++ b/src/charts/baseline.jl @@ -133,24 +133,26 @@ function lwc_baseline( end function lwc_baseline( - timearray::AbstractVector{Tuple{D,T}}; + timestamps::AbstractVector{D}, + values::AbstractVector{T}; kw... )::LWCChart where {D<:Union{Real,TimeType},T<:Real} - data = lwc_convert_data(timearray) + data = prepare_data(timestamps, values) return lwc_baseline(data; kw...) end function lwc_baseline( - timestamps::Vector{D}, - values::Vector{T}; + timearray::AbstractVector{T}; kw... -)::LWCChart where {D<:Union{Real,TimeType},T<:Real} - return lwc_baseline(prepare_data(timestamps, values); kw...) +)::LWCChart where {T<:Real} + data = prepare_data(timearray) + return lwc_baseline(data; kw...) end function lwc_baseline( - values::Vector{T}; + timearray::AbstractVector; kw... -)::LWCChart where {T<:Real} - return lwc_baseline(prepare_data(values); kw...) +)::LWCChart + data = lwc_convert_data(LWCSimpleChartData, timearray) + return lwc_baseline(data; kw...) end diff --git a/src/charts/candlestick.jl b/src/charts/candlestick.jl index 0498ba9c..d209d054 100644 --- a/src/charts/candlestick.jl +++ b/src/charts/candlestick.jl @@ -127,3 +127,15 @@ function lwc_candlestick( )::LWCChart where {D<:Union{Real,TimeType},O<:Real,H<:Real,L<:Real,C<:Real} return lwc_candlestick(lwc_convert_data(data); kw...) end + +function lwc_candlestick( + timestamp::AbstractVector{T}, + ohlc::AbstractVector{Tuple{O,H,L,C}}; + kw... +)::LWCChart where {T<:Union{TimeType,Real},O<:Real,H<:Real,L<:Real,C<:Real} + return lwc_candlestick(prepare_data(data); kw...) +end + +function lwc_candlestick(data::AbstractVector; kw...)::LWCChart + return lwc_candlestick(lwc_convert_data(LWCCandle, data); kw...) +end diff --git a/src/charts/histogram.jl b/src/charts/histogram.jl index 80401fab..14182868 100644 --- a/src/charts/histogram.jl +++ b/src/charts/histogram.jl @@ -64,24 +64,26 @@ function lwc_histogram( end function lwc_histogram( - timearray::AbstractVector{Tuple{D,T}}; + timestamps::AbstractVector{D}, + values::AbstractVector{T}; kw... )::LWCChart where {D<:Union{Real,TimeType},T<:Real} - data = lwc_convert_data(timearray) + data = prepare_data(timestamps, values) return lwc_histogram(data; kw...) end function lwc_histogram( - timestamps::Vector{D}, - values::Vector{T}; + timearray::AbstractVector{T}; kw... -)::LWCChart where {D<:Union{Real,TimeType},T<:Real} - return lwc_histogram(prepare_data(timestamps, values); kw...) +)::LWCChart where {T<:Real} + data = prepare_data(timearray) + return lwc_histogram(data; kw...) end function lwc_histogram( - values::Vector{T}; + timearray::AbstractVector; kw... -)::LWCChart where {T<:Real} - return lwc_histogram(prepare_data(values); kw...) +)::LWCChart + data = lwc_convert_data(LWCSimpleChartData, timearray) + return lwc_histogram(data; kw...) end diff --git a/src/charts/line.jl b/src/charts/line.jl index 507831eb..1f34a95d 100644 --- a/src/charts/line.jl +++ b/src/charts/line.jl @@ -104,24 +104,26 @@ function lwc_line( end function lwc_line( - timearray::AbstractVector{Tuple{D,T}}; + timestamps::AbstractVector{D}, + values::AbstractVector{T}; kw... )::LWCChart where {D<:Union{Real,TimeType},T<:Real} - data = lwc_convert_data(timearray) + data = prepare_data(timestamps, values) return lwc_line(data; kw...) end function lwc_line( - timestamps::Vector{D}, - values::Vector{T}; + timearray::AbstractVector{T}; kw... -)::LWCChart where {D<:Union{Real,TimeType},T<:Real} - return lwc_line(prepare_data(timestamps, values); kw...) +)::LWCChart where {T<:Real} + data = prepare_data(timearray) + return lwc_line(data; kw...) end function lwc_line( - values::Vector{T}; + timearray::AbstractVector; kw... -)::LWCChart where {T<:Real} - return lwc_line(prepare_data(values); kw...) +)::LWCChart + data = lwc_convert_data(LWCSimpleChartData, timearray) + return lwc_line(data; kw...) end