# Seeking API Design Advice for Setting Defaults

**URL:** <https://discourse.julialang.org/t/seeking-api-design-advice-for-setting-defaults/123845>\
**Category:** New to Julia\
**Tags:** question, finance\
**Created:** [December 14, 2024, 7:35pm UTC](https://discourse.julialang.org/t/seeking-api-design-advice-for-setting-defaults/123845 "2024-12-14T19:35:43Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![g-gundam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/g-gundam/32/47593_2.png) [@g-gundam](https://discourse.julialang.org/u/g-gundam)\
**Post date:** [December 14, 2024, 7:35pm UTC](https://discourse.julialang.org/t/seeking-api-design-advice-for-setting-defaults/123845/1 "2024-12-14T19:35:43Z")

</div>

I have a constructor for a mutable `Chart` struct that is used like this.

```julia
using OnlineTechnicalIndicators
using TechnicalIndicatorCharts

golden_cross_chart = Chart(
    "AAPL", Week(1);
    indicators = [
        SMA{Float64}(;period=50), # Setup indicators
        SMA{Float64}(;period=200)
    ],
    visuals = [
        Dict(
            :label_name => "SMA 50", # Describe how to draw indicators
            :line_color => "#E072A4",
            :line_width => 2
        ),
        Dict(
            :label_name => "SMA 200",
            :line_color => "#3D3B8E",
            :line_width => 5
        )
    ]
)

```

There’s a 1-to-1 correspondence between the values in `indicators` and the values in `visuals`. This is for my unreleased library [TechnicalIndicatorCharts.jl](https://github.com/g-gundam/TechnicalIndicatorCharts.jl).

## What if I don’t care about colors?

If I don’t care how it looks, and I just want to use the defaults, this is what I currently have to do.

```julia
golden_cross_chart = Chart(
    "AAPL", Week(1);
    indicators = [
        SMA{Float64}(;period=50), # Setup indicators
        SMA{Float64}(;period=200)
    ],
    visuals = [
        Dict(), # Not the prettiest, but tolerable.
        Dict()
    ]
)

```

## It can get worse.

That might not be so bad, but what if I added Bollinger Bands which is drawn with 3 lines instead of just one like SMA.

```julia
golden_cross_chart = Chart(
    "AAPL", Week(1);
    indicators = [
        SMA{Float64}(;period=50), # Setup indicators
        SMA{Float64}(;period=200),
        BB{Float64}(;period=20)
    ],
    visuals = [
        Dict(), # Not the prettiest
        Dict(),
        Dict(
            :upper => Dict(), # Now it's getting ugly.
            :central => Dict(),
            :lower => Dict() # All this typing just for defaults?!
        )
    ]
)

```

## How should I do this?

I want to be able to declare defaults in the `visuals` vector with way less typing. How could this be accomplished?

---

<div class="post-metadata">

**Author:** ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)\
**Post date:** [December 15, 2024, 6:54pm UTC](https://discourse.julialang.org/t/seeking-api-design-advice-for-setting-defaults/123845/2 "2024-12-15T18:54:11Z")

</div>

just a side note: in the post or in the package readme, specify you are dealing with _financial_ technical indicators, that’s not super obvious from people not in the domain 😉

---

<div class="post-metadata">

**Author:** ![g-gundam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/g-gundam/32/47593_2.png) [@g-gundam](https://discourse.julialang.org/u/g-gundam)\
**Post date:** [December 15, 2024, 10:16pm UTC](https://discourse.julialang.org/t/seeking-api-design-advice-for-setting-defaults/123845/3 "2024-12-15T22:16:34Z")

</div>

I’m kinda curious what the non-financial kind of technical indicators might be. (The financial kind are the only ones I know.) To provide a hint to the reader, I added the **[finance](https://discourse.julialang.org/tag/finance)** tag to this thread.

In other news, I got a **[little bit of advice](https://julialang.zulipchat.com/#narrow/channel/274208-helpdesk-.28published.29/topic/Seeking.20API.20Design.20Advice.20for.20Setting.20Defaults/near/489094516)** from someone over on Zulip. I was kinda losing hope on getting a response on this, but he had a nice idea that I’m working on implementing today.

---

<div class="post-metadata">

**Author:** ![cdawg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cdawg/32/9811_2.png) [@cdawg](https://discourse.julialang.org/u/cdawg)\
**Post date:** [December 17, 2024, 2:21pm UTC](https://discourse.julialang.org/t/seeking-api-design-advice-for-setting-defaults/123845/4 "2024-12-17T14:21:30Z")

</div>

Perhaps Im wrong, but I think you could just use (maybe typed) global variables in the module where you define chart and have keywords in the inner constructor.

```julia
module ChartVisuals
    
    bollinger_default = Dict(1 => "red")
    
    struct Chart{S,T}
        symbol::S
        visuals::T
        function Chart(s::S; visuals::T = bollinger_default) where {S,T}
            new{S,T}(s,visuals)
        end
    end

end

```

You can even update the global values in the module just like any other variable ChartVisuals.bollinger\_default = Dict\_of\_new\_colors, have a different global, ChartVisuals.sma\_default.

Sometimes the “dont use globals” thinking gets a little too dogmatic. I think they have a nice place outside “hot code” like for package related preferences. Not sure if this is exactly what you want.

---

<div class="post-metadata">

**Author:** ![g-gundam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/g-gundam/32/47593_2.png) [@g-gundam](https://discourse.julialang.org/u/g-gundam)\
**Post date:** [December 17, 2024, 2:39pm UTC](https://discourse.julialang.org/t/seeking-api-design-advice-for-setting-defaults/123845/5 "2024-12-17T14:39:24Z")

</div>

I have to be honest. My Julia skill level is currently at the point where I don’t really know how to use `where`. Maybe I’ll learn today to fully understand your reply, but my understanding is not there yet.

Also, I need Chart to potentially contain multiple indicators so that they can be drawn together. It seems like you restructured Chart to only have one. That’s not enough for me.

Regarding globals, I’m not opposed to them if they’re essentially constants.

---

<div class="post-metadata">

**Author:** ![cdawg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cdawg/32/9811_2.png) [@cdawg](https://discourse.julialang.org/u/cdawg)\
**Post date:** [December 17, 2024, 3:02pm UTC](https://discourse.julialang.org/t/seeking-api-design-advice-for-setting-defaults/123845/6 "2024-12-17T15:02:20Z")

</div>

I know it looks freaky, but this pattern brings the types of the variables into scope so that S and T can be used at compile time to build the new type. Basically, if I need to use type parameters as variables, for constructing new objects, I use “where” even if Im not enforcing fancy dispatch patterns (which is how where is usually discussed in the docs).

I didn’t want to learn it either, but I found ‘where’ to be super important, and found that it was neccesary in many cases to construct fully specified, fast, concrete types. You don’t need much more than the pattern you see above.

EDIT: yes I dropped the indicator field, I was just trying to concisely express the pattern sorry!
