If you want to try OnlineTechnicalIndicators with Lucky, (… explanation omitted …)
Thanks for explaining how you might go about incorporating OnlineTechnicalIndicators into the Lucky indicator system. If I have some down time later, I may explore this. The thing that may slow me down the most at this point is my lack of understanding when it comes to Rocket.jl operators. I have yet to make one or even use one.
Are SMA{Float64}(period=5) also dispatchable at the period level?
I don’t think the period of an indicator is something you can dispatch on with OnlineTechnicalIndicators.jl. (@femtotrader - please correct me if I’m wrong.)
julia> using OnlineTechnicalIndicators
julia> sma50 = SMA{Float64}(period=50)
SMA: n=0 | value=missing
julia> sma200 = SMA{Float64}(period=200)
SMA: n=0 | value=missing
julia> typeof(sma50) == typeof(sma200) # They're the same type.
true
Personally, I’m fine with that.
I’m not sure what should subscribe to ChartSubject. It seems like some kind of Blotter to render charts.
The ChartSubject is a thin wrapper around the Chart struct from my library, TechnicalIndicatorCharts.jl. It’s designed to consume candles and incrementally build a DataFrame that contains OHLCV values + indicator values calculated by OnlineTechnicalIndicators.jl. In my own trading system, I have a StrategySubject that subscribes to the ChartSubject, and it uses the data inside the chart_subject
instance to make trading decisions.
Whereas you have an on_next!
for each indicator:
Rocket.on_next!(strat::GoldenCross, data::SlowIndicatorType)
Rocket.on_next!(strat::GoldenCross, data::FastIndicatorType)
I have one comparable on_next!
that looks like:
Rocket.on_next!(subject::StrategySubject, t::Tuple{Symbol, Candle})
That fires when ChartSubject has formed a complete candle for a Chart. Every complete candle implies all indicators in a Chart had new values calculated for them, so the ChartSubject notifies the StrategySubject with that tuple. Then, the StrategySubject uses the chart data that it already has access to to make trading decisions.
I really don’t want to confuse you further, but if you’re really curious, you can take a peek over at my very experimental code in g-gundam/TradingPipeline.jl.
not sure i understand that comment: yield() # INFO: This allows ExchangeFillSubject to have a chance to work.
I have my own simulation pipeline, and it uses Channels to report back that an order was filled or if a stop loss was hit. The problem was that the Rocket loop was so tight that an order was put in and filled, but the fill response didn’t get reported back until months later in simulated time. The async task that I had monitoring the Channel didn’t get a chance to work until I put that yield there. Then the order fill responses came back in a timely manner.
In realtime situations, the yield wouldn’t have been needed, but in simulation, I needed it. Rocket was too fast.
multicast
Thanks for the tip. I still have a lot to learn about Rocket.