Hi there
julia noob here. Starting to use Stipple.jl and hit a stumbling block caused by my ignorance. I am using zmq to pass an ipm who’s payload can insert a row or update an existing row in a dataframe. I have the concept working in Dash but want to look into using Stipple.jl. I am using dataframes for a specific reason and don’t want to use Dict or Arrays right now. I cannot figure out how to set up the notify function to “refresh” the Stipple model. The Stipple.jl code below generates
Received request: STK~MA~OPTION_IMPLIED_VOL~900.0
message to add : STK MA iv 900.0
ERROR: LoadError: type Ptr has no field DataTable
I am defining the DataTable like this.
@reactive mutable struct TontineModel <: ReactiveModel
tontine_data::R{DataTable} = DataTable(df_table)
end
So I have a script to generate test data that should feed the Stipple code
using ZMQ
using CSV
using DataFrames
context = Context()
socket = Socket(context, PUSH)
ZMQ.connect(socket, "tcp://localhost:5555")
fields = ["LAST","OPTION_IMPLIED_VOL","VOLUME","IV"]
function generate_TWS_messages()
for test in 1:1000
source = "STK"
value = round((rand( (2, 9))* 100);digits = 2)
symbol = rand(symbols.Sym)
field = rand(fields)
send_message = (source * "~" * symbol * "~" * field * "~"* string(value) )
# send_message = test_new_message(symbols)
println(send_message)
ZMQ.send(socket, send_message) #"Hello" )
end
end
generate_TWS_messages()
ZMQ.send(socket,"END")
# Making a clean exit.
ZMQ.close(socket)
ZMQ.close(context)
and the Stipple.jl code. So a zmq message comes in and either inserts or updates a row in the dataframe. When this happens I want to update the UI dataframe.
using Stipple
using StippleUI
using StipplePlotly
using CSV, DataFrames, Dates
using ZMQ
dash_columns = ["sym","price","sdmove","hv20","hv10","hv5","iv","iv%ile","prc%ile","volume"]
df_table = DataFrame([col => (col == "sym" ? String : Float64)[] for col in dash_columns ])
zmq_dash = Dict("LAST" => "price","CLOSE" => "price","OPTION_IMPLIED_VOL" => "iv",
"VOLUME" => "volume","IV" => "iv","IV_PERCENTILE" => "iv%ile" ,"HV20" => "hv20",
"HV10" => "hv10","HV5" => "hv5" ,"PRICE_PERCENTILE" => "prc%ile")
@reactive mutable struct TontineModel <: ReactiveModel
tontine_data::R{DataTable} = DataTable(df_table)
end
function ui(model::TontineModel)
page(
model, class="container", title="title TONTINE2 ", head_content=Genie.Assets.favicon_support(),
prepend = style(
),
[
heading("heading Tontine2 7/18/22")
row([
cell(class="st-module", [
h5("h5 tontine data")
table(:tontine_data)
])
])
]
)
end
route("/") do
TontineModel |> init |> ui |> html
end
up(9000; async = true, server = Stipple.bootstrap())
context = Context()
socket = Socket(context, PULL)
ZMQ.bind(socket, "tcp://*:5555")
println("starting IN Socket 5555")
println("entering main, waiting for message")
while true
message = String(ZMQ.recv(socket))
println("Received request: $message")
if message == "END"
println("dying")
ZMQ.close(socket)
ZMQ.close(context)
break
end
global in_source,sym_in,field_in ,value_in = split( message , "~")
global value_fl = parse(Float64, value_in) # convert to Float64
try
global field_out = zmq_dash[ field_in] # ie field_in "OPTION_IMPLIED_VOL" => field_out "iv"
println("message to add : ", in_source," ",sym_in," ",field_out," " ,value_in)
catch e
println("field_in : ", field_in, " not in cols" )
end
if sym_in in df_table[!,:sym]
df_table[findfirst(==(sym_in),df_table.sym),findfirst(==(field_out),names(df_table))] = value_fl
else
push!(df_table, (sym_in, 0.0, 0.0, 0.0 , 0.0, 0.0 , 0.0 , 0.0 , 0.0 , 0.0 ) )
df_table[findfirst(==(sym_in),df_table.sym),findfirst(==(field_out),names(df_table))] = value_fl
end
#notify(TontineModel.tontine_data )
# try TontineModel.layout.DataTable FOUND IN REPL TAB EXPANSION OF TontineModel
notify(TontineModel.layout.DataTable)
end