From f5dfd6a6338ddd9636dce79fef5b90a183481d82 Mon Sep 17 00:00:00 2001 From: eohne Date: Thu, 8 Aug 2024 12:49:52 +0100 Subject: [PATCH] update example docs, move from Plotly.js to Plots.jl --- docs/src/DataFramesetc.md | 206 +++++++++++++++++++++++++- docs/src/Plotting_Example.md | 269 +++++++++------------------------- docs/src/assets/CandleMin.svg | 159 +++++++++++++++++++- docs/src/assets/CompRaw.svg | 42 +++++- docs/src/assets/CompWI.svg | 48 +++++- docs/src/assets/ESGPlot.svg | 68 ++++++++- docs/src/assets/Holders.svg | 34 ++++- docs/src/assets/Income.svg | 83 +++++++++++ 8 files changed, 702 insertions(+), 207 deletions(-) create mode 100644 docs/src/assets/Income.svg diff --git a/docs/src/DataFramesetc.md b/docs/src/DataFramesetc.md index 2fc7db5..363362b 100644 --- a/docs/src/DataFramesetc.md +++ b/docs/src/DataFramesetc.md @@ -10,7 +10,30 @@ using DataFrames prices = get_prices("AAPL") DataFrame(prices) +``` + +### Broadcasting to get one DataFrame (stacked) +```julia +tickers=["AAPL","TSLA","F"] +prices = get_prices.(tickers,startdt="2024-01-01",enddt="2024-08-01") |> (x-> DataFrame.(x)) |> (x->vcat(x...)) +``` + +```julia +438×8 DataFrame + Row │ ticker timestamp open high low close adjclose vol + │ String DateTime Float64 Float64 Float64 Float64 Float64 Float64 +─────┼───────────────────────────────────────────────────────────────────────────────────────── + 1 │ AAPL 2024-01-02T14:30:00 186.658 187.945 183.407 185.64 185.152 8.2272e7 + 2 │ AAPL 2024-01-03T14:30:00 183.736 185.392 182.948 184.25 183.766 5.8261e7 + 3 │ AAPL 2024-01-04T14:30:00 181.671 182.609 180.405 181.91 181.432 7.17945e7 + 4 │ AAPL 2024-01-05T14:30:00 181.512 182.28 179.697 181.18 180.704 6.21396e7 + ⋮ │ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ + 436 │ F 2024-07-29T13:30:00 11.0085 11.0085 10.6344 11.01 10.8411 9.02616e7 + 437 │ F 2024-07-30T13:30:00 10.8608 10.9396 10.6147 10.84 10.6737 6.82735e7 + 438 │ F 2024-07-31T13:30:00 10.6934 10.8411 10.5556 10.82 10.654 7.43204e7 + 431 rows omitted ``` + ## TimeArray from TimeSeries If you use Julia 1.9 or newer you can just use a sink argument in `get_prices` instead. @@ -18,7 +41,7 @@ If you use Julia 1.9 or newer you can just use a sink argument in `get_prices` i using TimeSeries, YFinance get_prices(TimeArray,"AAPL") ``` -(runtime for this is about 80% faster than `yahoo(:INTC)` from MarketData.jl (median run time: 0.09s vs 0.41s) ) +(runtime for this is about 80% faster than `yahoo(:INTC)` from MarketData.jl) or alternatively @@ -48,6 +71,117 @@ end stock_price_to_time_array(prices) ``` +### Broadcast and create one TimeArray for the adjclose prices + + +```julia +tickers = ["AAPL","TSLA","F"] +prices = get_prices.((TimeArray,),tickers) +``` + +```julia +3-element Vector{TimeArray{Float64, 2, DateTime, Matrix{Float64}}}: + 5×6 TimeArray{Float64, 2, DateTime, Matrix{Float64}} 2024-08-01T13:30:00 to 2024-08-07T13:30:00 + 5×6 TimeArray{Float64, 2, DateTime, Matrix{Float64}} 2024-08-01T13:30:00 to 2024-08-07T13:30:00 + 5×6 TimeArray{Float64, 2, DateTime, Matrix{Float64}} 2024-08-01T13:30:00 to 2024-08-07T13:30:00 +``` + +Combine into one TimeArray: +```julia +prices=hcat(prices...) +``` + +```julia +5×18 TimeArray{Float64, 2, DateTime, Matrix{Float64}} 2024-08-01T13:30:00 to 2024-08-07T13:30:00 +┌─────────────────────┬────────┬────────┬────────┬────────┬──────────┬───────────┬────────┬────────┬────────┬─────────┬────────────┬───────────┬─────────┬─────────┬─────────┬───────── +│ │ open │ high │ low │ close │ adjclose │ vol │ open_1 │ high_1 │ low_1 │ close_1 │ adjclose_1 │ vol_1 │ open_2 │ high_2 │ low_2 │ close_ ⋯ +├─────────────────────┼────────┼────────┼────────┼────────┼──────────┼───────────┼────────┼────────┼────────┼─────────┼────────────┼───────────┼─────────┼─────────┼─────────┼───────── +│ 2024-08-01T13:30:00 │ 224.37 │ 224.48 │ 217.02 │ 218.36 │ 218.36 │ 6.2501e7 │ 227.69 │ 231.87 │ 214.33 │ 216.86 │ 216.86 │ 8.38619e7 │ 10.6934 │ 10.7525 │ 10.4473 │ 10.6 ⋯ +│ 2024-08-02T13:30:00 │ 219.15 │ 225.6 │ 217.71 │ 219.86 │ 219.86 │ 1.05569e8 │ 214.88 │ 216.13 │ 205.78 │ 207.67 │ 207.67 │ 8.28801e7 │ 10.3882 │ 10.3882 │ 9.84663 │ 10.0 ⋯ +│ 2024-08-05T13:30:00 │ 199.09 │ 213.5 │ 196.0 │ 209.27 │ 209.27 │ 1.19549e8 │ 185.22 │ 203.88 │ 182.0 │ 198.88 │ 198.88 │ 1.00309e8 │ 9.41338 │ 9.74816 │ 9.34445 │ 9.7 ⋯ +│ 2024-08-06T13:30:00 │ 205.3 │ 209.99 │ 201.07 │ 207.23 │ 207.23 │ 6.96605e7 │ 200.75 │ 202.9 │ 192.67 │ 200.64 │ 200.64 │ 7.37839e7 │ 9.63985 │ 9.70877 │ 9.53153 │ 9.7 ⋯ +│ 2024-08-07T13:30:00 │ 206.9 │ 213.64 │ 206.39 │ 209.82 │ 209.82 │ 6.34023e7 │ 200.77 │ 203.49 │ 191.48 │ 191.76 │ 191.76 │ 7.07614e7 │ 9.85 │ 9.98 │ 9.75 │ 9.7 ⋯ +└─────────────────────┴────────┴────────┴────────┴────────┴──────────┴───────────┴────────┴────────┴────────┴─────────┴────────────┴───────────┴─────────┴─────────┴─────────┴───────── + 3 columns omitted +``` + +Get the relevant column names (all columns that are called adjclose) +```julia +cidx = colnames(prices)[occursin.(r"adj",string.(colnames(prices)))] +``` + +``` +3-element Vector{Symbol}: + :adjclose + :adjclose_1 + :adjclose_2 +``` + +Select these columns +```julia +prices = prices[cidx] +``` + +```julia +5×3 TimeArray{Float64, 2, DateTime, Matrix{Float64}} 2024-08-01T13:30:00 to 2024-08-07T13:30:00 +┌─────────────────────┬──────────┬────────────┬────────────┐ +│ │ adjclose │ adjclose_1 │ adjclose_2 │ +├─────────────────────┼──────────┼────────────┼────────────┤ +│ 2024-08-01T13:30:00 │ 218.36 │ 216.86 │ 10.526 │ +│ 2024-08-02T13:30:00 │ 219.86 │ 207.67 │ 9.87617 │ +│ 2024-08-05T13:30:00 │ 209.27 │ 198.88 │ 9.56107 │ +│ 2024-08-06T13:30:00 │ 207.23 │ 200.64 │ 9.63 │ +│ 2024-08-07T13:30:00 │ 209.82 │ 191.76 │ 9.77 │ +└─────────────────────┴──────────┴────────────┴────────────┘ +``` + +Rename them back to the tickers: +```julia +TimeSeries.rename!(prices,Symbol.(tickers)) +``` + +```julia +5×3 TimeArray{Float64, 2, DateTime, Matrix{Float64}} 2024-08-01T13:30:00 to 2024-08-07T13:30:00 +┌─────────────────────┬────────┬────────┬─────────┐ +│ │ AAPL │ TSLA │ F │ +├─────────────────────┼────────┼────────┼─────────┤ +│ 2024-08-01T13:30:00 │ 218.36 │ 216.86 │ 10.526 │ +│ 2024-08-02T13:30:00 │ 219.86 │ 207.67 │ 9.87617 │ +│ 2024-08-05T13:30:00 │ 209.27 │ 198.88 │ 9.56107 │ +│ 2024-08-06T13:30:00 │ 207.23 │ 200.64 │ 9.63 │ +│ 2024-08-07T13:30:00 │ 209.82 │ 191.76 │ 9.77 │ +└─────────────────────┴────────┴────────┴─────────┘ +``` + +Or in one function: +```julia +function get_adj_close_TA(tickers,startdt,enddt,interval) + prices = get_prices.((TimeArray,),tickers,startdt=startdt,enddt=enddt,interval=interval) |> (x->hcat(x...)) + prices = prices[colnames(prices)[occursin.(r"adj",string.(colnames(prices)))]] + TimeSeries.rename!(prices,Symbol.(tickers)) + return prices +end; + +get_adj_close_TA(["AAPL","TSLA","F","AMD","NFLX","WBA"],Date(2023-01-01),Date(2024-01-01),"1d") +``` + +```julia +252×6 TimeArray{Float64, 2, DateTime, Matrix{Float64}} 2021-01-04T14:30:00 to 2021-12-31T14:30:00 +┌─────────────────────┬─────────┬─────────┬─────────┬────────┬────────┬─────────┐ +│ │ AAPL │ TSLA │ F │ AMD │ NFLX │ WBA │ +├─────────────────────┼─────────┼─────────┼─────────┼────────┼────────┼─────────┤ +│ 2021-01-04T14:30:00 │ 126.83 │ 243.257 │ 7.03792 │ 92.3 │ 522.86 │ 34.6737 │ +│ 2021-01-05T14:30:00 │ 128.398 │ 245.037 │ 7.1453 │ 92.77 │ 520.8 │ 34.4727 │ +│ 2021-01-06T14:30:00 │ 124.076 │ 251.993 │ 7.30225 │ 90.33 │ 500.49 │ 36.0389 │ +│ 2021-01-07T14:30:00 │ 128.31 │ 272.013 │ 7.48398 │ 95.16 │ 508.89 │ 37.9066 │ +│ ⋮ │ ⋮ │ ⋮ │ ⋮ │ ⋮ │ ⋮ │ ⋮ │ +│ 2021-12-29T14:30:00 │ 176.888 │ 362.063 │ 17.069 │ 148.26 │ 610.54 │ 45.4322 │ +│ 2021-12-30T14:30:00 │ 175.724 │ 356.78 │ 16.9943 │ 145.15 │ 612.09 │ 45.2061 │ +│ 2021-12-31T14:30:00 │ 175.103 │ 352.26 │ 17.2434 │ 143.9 │ 602.44 │ 45.3539 │ +└─────────────────────┴─────────┴─────────┴─────────┴────────┴────────┴─────────┘ + 245 rows omitted +``` + ## TSFrame from TSFrames.jl If you use Julia 1.9 or newer you can just use a sink argument in `get_prices` instead. @@ -83,4 +217,74 @@ function stock_price_to_TSFrames(x) end stock_price_to_TSFrames(prices) +``` + +### Broadcast and create one TSFrame for the adjclose prices +```julia +tickers = ["AAPL","TSLA","F"] +prices = get_prices.((TSFrame,),tickers); +``` + +We now want to combine them by taking the adjclose of each tsframe. + +```julia +prices = join(getindex.(prices,:,([:Index,:adjclose],))...) +``` + +```julia +5×3 TSFrame with DateTime Index + Index adjclose adjclose_1 adjclose_2 + DateTime Float64? Float64? Float64? +─────────────────────────────────────────────────────── + 2024-08-01T13:30:00 218.36 216.86 10.526 + 2024-08-02T13:30:00 219.86 207.67 9.87617 + 2024-08-05T13:30:00 209.27 198.88 9.56107 + 2024-08-06T13:30:00 207.23 200.64 9.63 + 2024-08-07T13:30:00 209.82 191.76 9.77 +``` + +Rename: +```julia +TSFrames.rename!(prices, tickers) +``` + +```julia +5×3 TSFrame with DateTime Index + Index AAPL TSLA F + DateTime Float64? Float64? Float64? +─────────────────────────────────────────────────── + 2024-08-01T13:30:00 218.36 216.86 10.526 + 2024-08-02T13:30:00 219.86 207.67 9.87617 + 2024-08-05T13:30:00 209.27 198.88 9.56107 + 2024-08-06T13:30:00 207.23 200.64 9.63 + 2024-08-07T13:30:00 209.82 191.76 9.77 +``` + +Or in one function: + +```julia + +function get_adj_close_TSF(tickers,startdt,enddt,interval) + prices = get_prices.((TSFrame,),tickers,startdt=startdt,enddt=enddt,interval=interval) + prices = join(getindex.(prices,:,([:Index,:adjclose],))...) + TSFrames.rename!(prices, tickers) + return prices +end; +get_adj_close_TSF(["AAPL","TSLA","F","AMD","NFLX","WBA"],Date(2023-01-01),Date(2024-01-01),"1d") +``` + +```julia +252×6 TSFrame with DateTime Index + Index AAPL TSLA F AMD NFLX WBA + DateTime Float64? Float64? Float64? Float64? Float64? Float64? +───────────────────────────────────────────────────────────────────────────────── + 2021-01-04T14:30:00 126.83 243.257 7.03792 92.3 522.86 34.6737 + 2021-01-05T14:30:00 128.398 245.037 7.1453 92.77 520.8 34.4727 + 2021-01-06T14:30:00 124.076 251.993 7.30225 90.33 500.49 36.0389 + 2021-01-07T14:30:00 128.31 272.013 7.48398 95.16 508.89 37.9066 + ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ + 2021-12-29T14:30:00 176.888 362.063 17.069 148.26 610.54 45.4322 + 2021-12-30T14:30:00 175.724 356.78 16.9943 145.15 612.09 45.2061 + 2021-12-31T14:30:00 175.103 352.26 17.2434 143.9 602.44 45.3539 + 245 rows omitted ``` \ No newline at end of file diff --git a/docs/src/Plotting_Example.md b/docs/src/Plotting_Example.md index 193d311..be85b00 100644 --- a/docs/src/Plotting_Example.md +++ b/docs/src/Plotting_Example.md @@ -5,16 +5,18 @@ This section gives some examples on how to create plots for a few data items - q ## Packages Used - *DataFrames.jl* for easier data handling - - *Dates.jl* because we need dates ;) - - *PlotlyJS.jl* for our plots + - *TimeSeries.jl* To show interoperability with TimeArray + - *TSFrames.jl* To show interoperability with TSFrame + - *Dates.jl* because we need dates + - *Plots.jl* + - *StatsPlots.jl* + ## Load the packages: ```julia using YFinance -using DataFrames -using Dates -using PlotlyJS +using DataFrames, Dates, Plots, StatsPlots ``` @@ -26,77 +28,16 @@ AAPL = get_prices("AAPL",interval = "1m",range="1d") # OHLC Plot (Intraday) - -## Plot Layout -This is not really needed just styles the plot and adds a rangeslider and rangeselector. -```julia -# Creates the Layout for our plots (not really needed unless you want to style the plots) -function plot_layout_minute(title="") - l = Layout( - title_text = "$(title)", - paper_bgcolor =:white, - plot_bgcolor =:white, - yaxis = attr( - gridcolor=:lightgrey, - griddash="dot", - zerolinecolor=:lightgrey), - xaxis=attr( - gridcolor=:lightgrey, - griddash="dot", - zerolinecolor=:lightgrey, - rangeslider_visible=true, - rangeselector=attr( - buttons=[ - attr(count=5, label="5m", step="minute", stepmode="backward"), - attr(count=10, label="10m", step="minute", stepmode="backward"), - attr(count=15, label="15m", step="minute", stepmode="backward"), - attr(count=30, label="30m", step="minute", stepmode="backward"), - attr(count=1, label="1h", step="hour", stepmode="backward"), - attr(count=2, label="2h", step="hour", stepmode="backward"), - attr(count=5, label="5h", step="hour", stepmode="backward"), - attr(step="all") - ]))) - return l -end; -#Dictionary to map column names to strings displayed on the plot (also not needed unless for styling of the plots) -labels=Dict( - :returns => "Return", - :log_ret => "Log Return", - :index => "Wealth Index", - :timestamp =>"Date", - :open => "Open", - :high => "High", - :low => "Low", - :close =>"Close", - :adjclose =>"Adjusted Close", - :vol =>"Volume", - :ticker => "Ticker"); -``` - - -## The Plot: -```julia +Here we can use the TimeSeries package. One can instead also just use the data from the dictionary, or sink into a DataFrame or a TSFrame -# Lets start with a OHLC Plot: -# creates a OHLC plot -function ohlc_plot(data::OrderedDict) - p = Plot(candlestick( - x=data["timestamp"], - open=data["open"], - high=data["high"], - low=data["low"], - close=data["close"], - increasing_line_color="turquoise", - decreasing_line_color="darkgray", - labels=labels #delete this argument for no styling of the plot - ), - plot_layout_minute(data["ticker"]) # delete this argument for no styling of the plot - ) - return p -end; +## The Plot: -ohlc_plot(AAPL) +Plotting the first 25 values. +```julia +plot( sink_prices_to(TimeArray,AAPL)[1:25] , seriestype = :candlestick) +# Alternative call: +plot(get_prices(TimeArray,"AAPL",interval = "1m",range="1d")[1:25] , seriestype = :candlestick) ``` ![OHCL Plot](assets/CandleMin.svg) @@ -107,84 +48,25 @@ For illustration I used Apple (AAPL), the S&P500 (^GSPC), and the NASDAQ (^IXIC) ## Download Data and convert to DataFrame ```julia -# Lets get multiple tickers and stack them into a dataframe! -# Downloads data and stacks it into a dataframe -function get_long_df(symbols::AbstractVector{<:AbstractString},interval,range) - p = get_prices.(symbols,interval=interval,range=range); - p = vcat([DataFrame(i) for i in values(p)]...); - p.timestamp = Date.(p.timestamp); - return p -end; - -#Download a Price -prices = get_long_df(["AAPL","^GSPC", "^IXIC"],"1d","2y") -``` - - -## OHLC Plot of a specific ticker - -### Plot Layout -This is not really needed just styles the plot and adds a rangeslider and rangeselector. -```julia -# Lets start with a OHLC Plot: -# creates a OHLC plot for a specific ticker - -function plot_layout(title="") - l = Layout( - title_text = "$(title)", - paper_bgcolor =:white, - plot_bgcolor =:white, - yaxis = attr( - gridcolor=:lightgrey, - griddash="dot", - zerolinecolor=:lightgrey), - xaxis=attr( - gridcolor=:lightgrey, - griddash="dot", - zerolinecolor=:lightgrey, - rangeslider_visible=true, - rangeselector=attr( - buttons=[ - attr(count=1, label="1m", step="month", stepmode="backward"), - attr(count=6, label="6m", step="month", stepmode="backward"), - attr(count=1, label="YTD", step="year", stepmode="todate"), - attr(count=1, label="1y", step="year", stepmode="backward"), - attr(step="all") - ]))) - return l -end; -``` - -### The Plot: -```julia -function ohlc_plot(data::DataFrame,symbol::AbstractString) - p = Plot(candlestick(data[isequal.(data.ticker,symbol),:], - x=:timestamp, - open=:open, - high=:high, - low=:low, - close=:close, - increasing_line_color="turquoise", - decreasing_line_color="darkgray",labels=labels), - plot_layout(symbol) ) - return p -end; - -ohlc_plot(prices,"AAPL") +# Lets use TSFrames now for this example. + +tickers = ["AAPL","^GSPC", "^IXIC"]; +# Broadcast and sink into a TSFrame +prices = get_prices.((TSFrame,),tickers,interval="1d",range="2y") +# get rid of the ^ in the tickers +tickers = replace.(tickers,"^"=>""); + +# Get only the adjusted close and time index and join the data into one TSFrame +prices = join(getindex.(prices,:,([:Index,:adjclose],))...) +# we want to rename the adjclose to the tickers +TSFrames.rename!(prices, tickers) ``` -![OHCL Plot](assets/CandleDaily.svg) - - ## Comparsion Plot - raw prices ```julia # Let's compare how the stocks have performed over time: # Creates a comparison plot of the price for all items -function comparison_plot(data::DataFrame,column::Symbol=:adjclose) - return Plot(data, x=:timestamp,y=column,group=:ticker,labels=labels, - plot_layout(labels[column])) -end; -comparison_plot(prices) +plot(prices) ``` ![Raw Comp](assets/CompRaw.svg) @@ -192,65 +74,54 @@ comparison_plot(prices) ## Comparison Plot - Wealth Index For better comparison we first calculate returns and afterwards a wealth index then plot that. ```julia +# First caluclate log returns. +prices = diff(log.(prices)) -# Calculate Return -function get_return(x::AbstractVector{<:Number}) - res = x[2:end]./x[1:(end-1)] - return vcat(missing,res.-1) -end; - -# Calculate Wealth Index -function wealthIndex(x::AbstractVector,base=100) - res = vcat(1,x[2:end]) - res = log.(res.+1) - res = exp.(cumsum(res)) .- 1 - return res.*base -end; +# next add a zero to the first missing value so the index starts at 1. +for t in tickers + getproperty(prices, Symbol(t*"_log"))[begin] = 0.0 +end -# groupby ticker and calculate returns and the wealth index -transform!(groupby(prices,:ticker), - :adjclose => get_return => :ret) -transform!(groupby(prices,:ticker), - :ret => wealthIndex => :index) +# we now need to cumulate these to get a wealth index. +for t in tickers + getproperty(prices, Symbol(t*"_log"))[begin:end] = cumsum(getproperty(prices, Symbol(t*"_log"))[begin:end]) +end -# Now lets plot the price index instead of the adjclose -comparison_plot(prices,:index) +# Take the exponent again to go back to "normal returns" +prices = exp.(prices) +TSFrames.rename!(prices,tickers) # rename back to the old names without "_log" attached. +plot(prices) ``` ![Wealth Index Comp](assets/CompWI.svg) - + +# Get Fundamental Data - Example Income Statement +```julia +# Download and store in a DataFrame +is_apple = get_Fundamental("AAPL","income_statement","annual","2020-01-01","2024-12-31") |> DataFrame +# Calculate Profit Margin etc at different levels +is_apple.ProfitM = is_apple.NetIncome./is_apple.TotalRevenue; +is_apple.OperIncM = is_apple.OperatingIncome./is_apple.TotalRevenue; +is_apple.GrossProfitM = is_apple.GrossProfit./is_apple.TotalRevenue; +select!(is_apple,:timestamp,:GrossProfitM,:OperIncM, :ProfitM) +plot(is_apple.timestamp, is_apple[:,2],label = names(is_apple)[2], seriestype = :bar, legend=true, size=(800,500)) +plot!(is_apple.timestamp, is_apple[:,3],label = names(is_apple)[3], seriestype = :bar) +plot!(is_apple.timestamp, is_apple[:,4],label = names(is_apple)[4], seriestype = :bar) +``` +![Profit Margin Over Time](assets/Income.svg) + # ESG Data Bar Chart Bar Chart comparing ESG scores between AAPL and its peers -## Download ESG Data + Download ESG data and convert to a DataFrame and reshape to long format for easier plotting ```julia esg = get_ESG("AAPL") esg = vcat([DataFrame(i) for i in values(esg)]...) #convert to DataFrame subset!(esg, :timestamp => x -> isequal.(x,maximum(x))) # take only the newest values esg = DataFrames.stack(esg,[:esgScore,:environmentScore,:governanceScore,:socialScore]) #reshape into long format -``` - -## Plotting: -```julia -function create_barplot() - esg[!,"colors"]= ifelse.(isequal.(esg.symbol,"AAPL"),"darkorange","steelblue") - - traces = bar(esg,x = :variable, y = :value,group=:symbol,names=:symbol,marker_color=:colors) - - layout = Layout(barmode="group", - legend=attr( - x=1, - y=1.02, - yanchor="bottom", - xanchor="right", - orientation="h"), - paper_bgcolor =:white, - plot_bgcolor =:white - ) - return Plot(traces, layout) -end -create_barplot() +using StatsPlots +groupedbar(esg.variable, esg.value, group = esg.symbol, ylabel = "Scores") ``` ![ESG Bar Chart](assets/ESGPlot.svg) @@ -260,21 +131,17 @@ create_barplot() ## Downloading the Data ```julia -major_holders = get_major_holders_breakdown("AAPL") +major_holders = get_major_holders_breakdown("AAPL") |> DataFrame ``` ## Creating the Pie Chart ```julia -function create_pie() - colors = ["darkorange","steelblue","teal"] # Set Colors - rest = (1-major_holders["insidersPercentHeld"] - major_holders["institutionsPercentHeld"]) - values = [major_holders["insidersPercentHeld"], major_holders["institutionsPercentHeld"],rest].*100 - plot( - pie(values = values, - labels = ["Insiders","Institutions","Rest"], - marker_colors = colors), - Layout(title_text = "Major Holders")) -end; -create_pie() +#select the relevant fields: +select!(major_holders, r"insiders|institutionsP"); +# Calculate the left over part +major_holders.Rest .= 1-sum(major_holders[1,1:2]) +# reshape to long +major_holders=stack(major_holders); +pie(major_holders.variable,major_holders.value) ``` ![Major Holders Pie Chart](assets/Holders.svg) \ No newline at end of file diff --git a/docs/src/assets/CandleMin.svg b/docs/src/assets/CandleMin.svg index 7e058e4..a9328ee 100644 --- a/docs/src/assets/CandleMin.svg +++ b/docs/src/assets/CandleMin.svg @@ -1 +1,158 @@ -15:00Dec 30, 202216:0017:0018:0019:0020:0021:00127.5128128.5129129.51305m10m15m30m1h2h5hallAAPL \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/src/assets/CompRaw.svg b/docs/src/assets/CompRaw.svg index c9ca59c..6ef8db6 100644 --- a/docs/src/assets/CompRaw.svg +++ b/docs/src/assets/CompRaw.svg @@ -1 +1,41 @@ -Jan 2021Apr 2021Jul 2021Oct 2021Jan 2022Apr 2022Jul 2022Oct 202202k4k6k8k10k12k14k16kAAPL^GSPC^IXIC1m6mYTD1yallAdjusted CloseAdjusted CloseDate \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/src/assets/CompWI.svg b/docs/src/assets/CompWI.svg index ef9339f..7d3e546 100644 --- a/docs/src/assets/CompWI.svg +++ b/docs/src/assets/CompWI.svg @@ -1 +1,47 @@ -Jan 2021Apr 2021Jul 2021Oct 2021Jan 2022Apr 2022Jul 2022Oct 20226080100120140160180AAPL^GSPC^IXIC1m6mYTD1yallWealth IndexWealth IndexDate \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/src/assets/ESGPlot.svg b/docs/src/assets/ESGPlot.svg index b74abcc..5e587a4 100644 --- a/docs/src/assets/ESGPlot.svg +++ b/docs/src/assets/ESGPlot.svg @@ -1 +1,67 @@ -esgScoreenvironmentScoregovernanceScoresocialScore0246810121416AAPLTechnology Hardware \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/src/assets/Holders.svg b/docs/src/assets/Holders.svg index 2a40bee..408ef8d 100644 --- a/docs/src/assets/Holders.svg +++ b/docs/src/assets/Holders.svg @@ -1 +1,33 @@ -60.9%39%0.072%InstitutionsRestInsidersMajor Holders \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/src/assets/Income.svg b/docs/src/assets/Income.svg new file mode 100644 index 0000000..a92703e --- /dev/null +++ b/docs/src/assets/Income.svg @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file