Spaces:
Running
Running
added date info and tweaked charts
Browse files- Dockerfile +1 -1
- app/app.R +86 -59
Dockerfile
CHANGED
@@ -8,7 +8,7 @@ RUN R -q -e "install.packages(c('shinydashboard', 'shinydashboardPlus'))"
|
|
8 |
RUN R -q -e "install.packages(c('shinyWidgets', 'shinycssloaders'))"
|
9 |
|
10 |
# other R packages
|
11 |
-
RUN R -q -e "install.packages(c('DT', 'plotly', 'scico', 'ggthemes'))"
|
12 |
RUN R -q -e "install.packages(c('data.table', 'dtplyr', 'parallel', 'Rnumerai'))"
|
13 |
|
14 |
# copy the app to the image
|
|
|
8 |
RUN R -q -e "install.packages(c('shinyWidgets', 'shinycssloaders'))"
|
9 |
|
10 |
# other R packages
|
11 |
+
RUN R -q -e "install.packages(c('DT', 'plotly', 'scico', 'ggthemes', 'scales'))"
|
12 |
RUN R -q -e "install.packages(c('data.table', 'dtplyr', 'parallel', 'Rnumerai'))"
|
13 |
|
14 |
# copy the app to the image
|
app/app.R
CHANGED
@@ -3,12 +3,16 @@ library(shinydashboard)
|
|
3 |
library(shinydashboardPlus)
|
4 |
library(shinyWidgets)
|
5 |
library(shinycssloaders)
|
|
|
6 |
library(DT)
|
7 |
library(plotly)
|
8 |
library(scico)
|
9 |
library(ggthemes)
|
|
|
|
|
10 |
library(data.table)
|
11 |
library(dtplyr)
|
|
|
12 |
library(parallel)
|
13 |
library(Rnumerai)
|
14 |
|
@@ -30,7 +34,7 @@ download_raw_data <- function(model_name) {
|
|
30 |
d_raw$model <- model_name
|
31 |
|
32 |
# Return
|
33 |
-
return(d_raw)
|
34 |
|
35 |
}
|
36 |
|
@@ -38,34 +42,34 @@ download_raw_data <- function(model_name) {
|
|
38 |
reformat_data <- function(d_raw) {
|
39 |
|
40 |
# Keep some columns only
|
41 |
-
col_keep <- c("model", "
|
42 |
-
"
|
43 |
-
"
|
44 |
-
"
|
|
|
|
|
|
|
|
|
45 |
d_munged <- d_raw[, col_keep, with = FALSE]
|
46 |
|
|
|
|
|
|
|
|
|
47 |
# Reformat percentile
|
48 |
d_munged[, corrPercentile := round(corrPercentile * 100, 6)]
|
49 |
d_munged[, fncV3Percentile := round(fncV3Percentile * 100, 6)]
|
50 |
d_munged[, tcPercentile := round(tcPercentile * 100, 6)]
|
51 |
|
52 |
-
# Reorder columns
|
53 |
-
setcolorder(d_munged, c("model", "roundNumber", "roundResolved",
|
54 |
-
"selectedStakeValue",
|
55 |
-
"corr", "corrPercentile",
|
56 |
-
"fncV3", "fncV3Percentile",
|
57 |
-
"tc", "tcPercentile",
|
58 |
-
"corrWMetamodel",
|
59 |
-
"roundPayoutFactor", "payout"))
|
60 |
-
|
61 |
# Rename columns
|
62 |
-
colnames(d_munged) <- c("model", "round",
|
63 |
-
"
|
|
|
64 |
"corr", "corr_pct",
|
65 |
"fncv3", "fncv3_pct",
|
66 |
"tc", "tc_pct",
|
67 |
"corr_meta",
|
68 |
-
"pay_ftr", "payout")
|
69 |
|
70 |
# Return
|
71 |
return(d_munged)
|
@@ -227,6 +231,7 @@ ui <- shinydashboardPlus::dashboardPage(
|
|
227 |
# ========================================================================
|
228 |
|
229 |
tabItem(tabName = "payout",
|
|
|
230 |
fluidPage(
|
231 |
|
232 |
markdown("# **Payout Summary**"),
|
@@ -260,7 +265,7 @@ ui <- shinydashboardPlus::dashboardPage(
|
|
260 |
style = "gradient",
|
261 |
block = TRUE)
|
262 |
)
|
263 |
-
),
|
264 |
|
265 |
br(),
|
266 |
|
@@ -286,7 +291,6 @@ ui <- shinydashboardPlus::dashboardPage(
|
|
286 |
|
287 |
shinycssloaders::withSpinner(plotlyOutput("plot_payout_stacked")),
|
288 |
|
289 |
-
br(),
|
290 |
br(),
|
291 |
br(),
|
292 |
|
@@ -296,12 +300,12 @@ ui <- shinydashboardPlus::dashboardPage(
|
|
296 |
|
297 |
tabPanel("Individual Models",
|
298 |
br(),
|
299 |
-
shinycssloaders::withSpinner(plotlyOutput("plot_payout_individual"))
|
|
|
300 |
|
301 |
-
|
302 |
-
)
|
303 |
|
304 |
-
)
|
305 |
|
306 |
),
|
307 |
|
@@ -400,7 +404,7 @@ server <- function(input, output) {
|
|
400 |
if (length(react_ls_model()) >= 1) "⬅ [COMING SOON] Model Performance 📈🔥" else " "
|
401 |
})
|
402 |
|
403 |
-
|
404 |
input$button_download,
|
405 |
{
|
406 |
|
@@ -409,25 +413,30 @@ server <- function(input, output) {
|
|
409 |
FUN = download_raw_data,
|
410 |
mc.cores = detectCores()))
|
411 |
|
412 |
-
#
|
413 |
-
|
414 |
-
|
415 |
-
# Return final result
|
416 |
-
d_munged
|
417 |
|
418 |
}
|
419 |
)
|
420 |
|
|
|
421 |
# ============================================================================
|
422 |
# Reactive: DataTable
|
423 |
# ============================================================================
|
424 |
|
425 |
output$dt_model <- DT::renderDT({
|
426 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
427 |
DT::datatable(
|
428 |
|
429 |
# Data
|
430 |
-
|
431 |
|
432 |
# Other Options
|
433 |
rownames = FALSE,
|
@@ -482,10 +491,8 @@ server <- function(input, output) {
|
|
482 |
input$button_filter,
|
483 |
{
|
484 |
|
485 |
-
#
|
486 |
-
d_filter <-
|
487 |
-
|
488 |
-
# Filtering
|
489 |
d_filter <- d_filter[pay_ftr > 0, ] # ignoring the new daily rounds for now
|
490 |
d_filter <- d_filter[round >= input$range_round[1], ]
|
491 |
d_filter <- d_filter[round <= input$range_round[2], ]
|
@@ -502,16 +509,14 @@ server <- function(input, output) {
|
|
502 |
|
503 |
# Summarise payout
|
504 |
d_smry <-
|
505 |
-
react_d_filter() |>
|
506 |
-
|
507 |
-
|
508 |
-
|
|
|
|
|
509 |
as.data.table()
|
510 |
-
d_smry$rate_of_return <- (d_smry$
|
511 |
-
|
512 |
-
# Rename
|
513 |
-
colnames(d_smry) <- c("round", "resolved", "total_stake",
|
514 |
-
"total_payout", "rate_of_return")
|
515 |
|
516 |
# Return
|
517 |
d_smry
|
@@ -554,11 +559,11 @@ server <- function(input, output) {
|
|
554 |
|
555 |
output$payout_average <- renderValueBox({
|
556 |
# Use rounds with stake > 0 only
|
557 |
-
valueBox(value = round(mean(react_d_payout_summary()[total_stake > 0, ]$
|
558 |
subtitle = "Avg. Round Payout",
|
559 |
color = "light-blue")
|
560 |
})
|
561 |
-
|
562 |
output$payout_avg_ror <- renderValueBox({
|
563 |
# Use rounds with stake > 0 only
|
564 |
valueBox(value = paste(round(mean(react_d_payout_summary()[total_stake > 0, ]$rate_of_return), 2), "%"),
|
@@ -573,12 +578,17 @@ server <- function(input, output) {
|
|
573 |
# Stacked Bar Chart
|
574 |
output$plot_payout_stacked <- renderPlotly({
|
575 |
|
|
|
|
|
|
|
576 |
# ggplot
|
577 |
-
p <- ggplot(
|
578 |
-
aes(x =
|
579 |
text = paste("Model:", model,
|
580 |
"\nRound:", round,
|
581 |
-
"\
|
|
|
|
|
582 |
"\nPayout:", round(payout,2), "NMR"))) +
|
583 |
geom_bar(position = "stack", stat = "identity") +
|
584 |
theme(
|
@@ -596,9 +606,12 @@ server <- function(input, output) {
|
|
596 |
) +
|
597 |
geom_hline(aes(yintercept = 0), linewidth = 0.25, color = "grey") +
|
598 |
scale_fill_scico(palette = "vikO", direction = -1, midpoint = 0) +
|
599 |
-
|
|
|
|
|
|
|
600 |
ylab("Payout (NMR)")
|
601 |
-
|
602 |
# Generate plotly
|
603 |
ggplotly(p, tooltip = "text")
|
604 |
|
@@ -608,14 +621,21 @@ server <- function(input, output) {
|
|
608 |
# Individual
|
609 |
output$plot_payout_individual <- renderPlotly({
|
610 |
|
|
|
|
|
|
|
611 |
# Get the number of unique models
|
612 |
-
n_model <- length(unique(
|
613 |
|
614 |
# Base plot
|
615 |
-
p <- ggplot(
|
616 |
-
|
617 |
-
|
618 |
-
|
|
|
|
|
|
|
|
|
619 |
geom_bar(stat = "identity") +
|
620 |
theme(
|
621 |
panel.border = element_rect(fill = 'transparent',
|
@@ -628,11 +648,13 @@ server <- function(input, output) {
|
|
628 |
strip.text = element_text(),
|
629 |
strip.clip = "on",
|
630 |
legend.background = element_rect(fill = 'transparent'),
|
631 |
-
legend.box.background = element_rect(fill = 'transparent')
|
|
|
632 |
) +
|
633 |
geom_hline(aes(yintercept = 0), linewidth = 0.25, color = "grey") +
|
634 |
scale_fill_scico(palette = "vikO", direction = -1, midpoint = 0) +
|
635 |
-
|
|
|
636 |
ylab("Confirmed / Pending Payout (NMR)")
|
637 |
|
638 |
# Facet setting
|
@@ -686,15 +708,20 @@ server <- function(input, output) {
|
|
686 |
) |>
|
687 |
|
688 |
# Reformat individual columns
|
689 |
-
formatRound(columns = c("total_stake", "
|
690 |
|
691 |
formatStyle(columns = c("round"), fontWeight = "bold") |>
|
|
|
|
|
|
|
|
|
|
|
692 |
|
693 |
formatStyle(columns = c("total_stake"),
|
694 |
fontWeight = "bold",
|
695 |
color = styleInterval(cuts = -1e-15, values = c("#D24141", "#2196F3"))) |>
|
696 |
|
697 |
-
formatStyle(columns = c("
|
698 |
fontWeight = "bold",
|
699 |
color = styleInterval(cuts = c(-1e-15, 1e-15),
|
700 |
values = c("#D24141", "#D1D1D1", "#00A800"))) |>
|
|
|
3 |
library(shinydashboardPlus)
|
4 |
library(shinyWidgets)
|
5 |
library(shinycssloaders)
|
6 |
+
|
7 |
library(DT)
|
8 |
library(plotly)
|
9 |
library(scico)
|
10 |
library(ggthemes)
|
11 |
+
library(scales)
|
12 |
+
|
13 |
library(data.table)
|
14 |
library(dtplyr)
|
15 |
+
|
16 |
library(parallel)
|
17 |
library(Rnumerai)
|
18 |
|
|
|
34 |
d_raw$model <- model_name
|
35 |
|
36 |
# Return
|
37 |
+
return(as.data.table(d_raw))
|
38 |
|
39 |
}
|
40 |
|
|
|
42 |
reformat_data <- function(d_raw) {
|
43 |
|
44 |
# Keep some columns only
|
45 |
+
col_keep <- c("model", "roundNumber",
|
46 |
+
"roundOpenTime", "roundResolveTime",
|
47 |
+
"roundResolved", "selectedStakeValue",
|
48 |
+
"corr", "corrPercentile",
|
49 |
+
"fncV3", "fncV3Percentile",
|
50 |
+
"tc", "tcPercentile",
|
51 |
+
"corrWMetamodel",
|
52 |
+
"roundPayoutFactor", "payout")
|
53 |
d_munged <- d_raw[, col_keep, with = FALSE]
|
54 |
|
55 |
+
# Date
|
56 |
+
d_munged[, roundOpenTime := as.Date(roundOpenTime)]
|
57 |
+
d_munged[, roundResolveTime := as.Date(roundResolveTime)]
|
58 |
+
|
59 |
# Reformat percentile
|
60 |
d_munged[, corrPercentile := round(corrPercentile * 100, 6)]
|
61 |
d_munged[, fncV3Percentile := round(fncV3Percentile * 100, 6)]
|
62 |
d_munged[, tcPercentile := round(tcPercentile * 100, 6)]
|
63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
# Rename columns
|
65 |
+
colnames(d_munged) <- c("model", "round",
|
66 |
+
"date_open", "date_resolved",
|
67 |
+
"resolved", "stake",
|
68 |
"corr", "corr_pct",
|
69 |
"fncv3", "fncv3_pct",
|
70 |
"tc", "tc_pct",
|
71 |
"corr_meta",
|
72 |
+
"pay_ftr", "payout")
|
73 |
|
74 |
# Return
|
75 |
return(d_munged)
|
|
|
231 |
# ========================================================================
|
232 |
|
233 |
tabItem(tabName = "payout",
|
234 |
+
|
235 |
fluidPage(
|
236 |
|
237 |
markdown("# **Payout Summary**"),
|
|
|
265 |
style = "gradient",
|
266 |
block = TRUE)
|
267 |
)
|
268 |
+
), # end of fluidRow
|
269 |
|
270 |
br(),
|
271 |
|
|
|
291 |
|
292 |
shinycssloaders::withSpinner(plotlyOutput("plot_payout_stacked")),
|
293 |
|
|
|
294 |
br(),
|
295 |
br(),
|
296 |
|
|
|
300 |
|
301 |
tabPanel("Individual Models",
|
302 |
br(),
|
303 |
+
shinycssloaders::withSpinner(plotlyOutput("plot_payout_individual"))
|
304 |
+
)
|
305 |
|
306 |
+
) # end of tabsetPanel
|
|
|
307 |
|
308 |
+
) # end of fluidPage
|
309 |
|
310 |
),
|
311 |
|
|
|
404 |
if (length(react_ls_model()) >= 1) "⬅ [COMING SOON] Model Performance 📈🔥" else " "
|
405 |
})
|
406 |
|
407 |
+
react_d_raw <- eventReactive(
|
408 |
input$button_download,
|
409 |
{
|
410 |
|
|
|
413 |
FUN = download_raw_data,
|
414 |
mc.cores = detectCores()))
|
415 |
|
416 |
+
# Return
|
417 |
+
d_raw
|
|
|
|
|
|
|
418 |
|
419 |
}
|
420 |
)
|
421 |
|
422 |
+
|
423 |
# ============================================================================
|
424 |
# Reactive: DataTable
|
425 |
# ============================================================================
|
426 |
|
427 |
output$dt_model <- DT::renderDT({
|
428 |
|
429 |
+
# Raw Data
|
430 |
+
d_raw <- react_d_raw()
|
431 |
+
|
432 |
+
# Reformat
|
433 |
+
d_munged <- reformat_data(d_raw)
|
434 |
+
|
435 |
+
# Main DT
|
436 |
DT::datatable(
|
437 |
|
438 |
# Data
|
439 |
+
d_munged,
|
440 |
|
441 |
# Other Options
|
442 |
rownames = FALSE,
|
|
|
491 |
input$button_filter,
|
492 |
{
|
493 |
|
494 |
+
# Reformat and Filter
|
495 |
+
d_filter <- reformat_data(react_d_raw())
|
|
|
|
|
496 |
d_filter <- d_filter[pay_ftr > 0, ] # ignoring the new daily rounds for now
|
497 |
d_filter <- d_filter[round >= input$range_round[1], ]
|
498 |
d_filter <- d_filter[round <= input$range_round[2], ]
|
|
|
509 |
|
510 |
# Summarise payout
|
511 |
d_smry <-
|
512 |
+
react_d_filter() |>
|
513 |
+
lazy_dt() |>
|
514 |
+
group_by(round, date_open, date_resolved, resolved) |>
|
515 |
+
summarise(staked_models = n(),
|
516 |
+
total_stake = sum(stake, na.rm = T),
|
517 |
+
net_payout = sum(payout, na.rm = T)) |>
|
518 |
as.data.table()
|
519 |
+
d_smry$rate_of_return <- (d_smry$net_payout / d_smry$total_stake) * 100
|
|
|
|
|
|
|
|
|
520 |
|
521 |
# Return
|
522 |
d_smry
|
|
|
559 |
|
560 |
output$payout_average <- renderValueBox({
|
561 |
# Use rounds with stake > 0 only
|
562 |
+
valueBox(value = round(mean(react_d_payout_summary()[total_stake > 0, ]$net_payout, na.rm = T), 2),
|
563 |
subtitle = "Avg. Round Payout",
|
564 |
color = "light-blue")
|
565 |
})
|
566 |
+
|
567 |
output$payout_avg_ror <- renderValueBox({
|
568 |
# Use rounds with stake > 0 only
|
569 |
valueBox(value = paste(round(mean(react_d_payout_summary()[total_stake > 0, ]$rate_of_return), 2), "%"),
|
|
|
578 |
# Stacked Bar Chart
|
579 |
output$plot_payout_stacked <- renderPlotly({
|
580 |
|
581 |
+
# Data
|
582 |
+
d_filter <- react_d_filter()
|
583 |
+
|
584 |
# ggplot
|
585 |
+
p <- ggplot(d_filter,
|
586 |
+
aes(x = date_resolved, y = payout, fill = payout,
|
587 |
text = paste("Model:", model,
|
588 |
"\nRound:", round,
|
589 |
+
"\nRound Open Date:", date_open,
|
590 |
+
"\nRound Resolved Date:", date_resolved,
|
591 |
+
"\nRound Status:", resolved,
|
592 |
"\nPayout:", round(payout,2), "NMR"))) +
|
593 |
geom_bar(position = "stack", stat = "identity") +
|
594 |
theme(
|
|
|
606 |
) +
|
607 |
geom_hline(aes(yintercept = 0), linewidth = 0.25, color = "grey") +
|
608 |
scale_fill_scico(palette = "vikO", direction = -1, midpoint = 0) +
|
609 |
+
scale_x_date(breaks = breaks_pretty(10),
|
610 |
+
labels = label_date_short(format = c("%Y", "%b", "%d"), sep = "\n")
|
611 |
+
) +
|
612 |
+
xlab(" \nDate (Round Resolved / Resolving)") +
|
613 |
ylab("Payout (NMR)")
|
614 |
+
|
615 |
# Generate plotly
|
616 |
ggplotly(p, tooltip = "text")
|
617 |
|
|
|
621 |
# Individual
|
622 |
output$plot_payout_individual <- renderPlotly({
|
623 |
|
624 |
+
# Data
|
625 |
+
d_filter <- react_d_filter()
|
626 |
+
|
627 |
# Get the number of unique models
|
628 |
+
n_model <- length(unique(d_filter$model))
|
629 |
|
630 |
# Base plot
|
631 |
+
p <- ggplot(d_filter,
|
632 |
+
aes(x = round, y = payout, fill = payout,
|
633 |
+
text = paste("Model:", model,
|
634 |
+
"\nRound:", round,
|
635 |
+
"\nRound Open Date:", date_open,
|
636 |
+
"\nRound Resolved Date:", date_resolved,
|
637 |
+
"\nRound Status:", resolved,
|
638 |
+
"\nPayout:", round(payout,2), "NMR"))) +
|
639 |
geom_bar(stat = "identity") +
|
640 |
theme(
|
641 |
panel.border = element_rect(fill = 'transparent',
|
|
|
648 |
strip.text = element_text(),
|
649 |
strip.clip = "on",
|
650 |
legend.background = element_rect(fill = 'transparent'),
|
651 |
+
legend.box.background = element_rect(fill = 'transparent'),
|
652 |
+
axis.text.x = element_text(angle = 45, hjust = 1)
|
653 |
) +
|
654 |
geom_hline(aes(yintercept = 0), linewidth = 0.25, color = "grey") +
|
655 |
scale_fill_scico(palette = "vikO", direction = -1, midpoint = 0) +
|
656 |
+
scale_x_continuous(breaks = breaks_pretty(5)) +
|
657 |
+
xlab(" \nTournament Round") +
|
658 |
ylab("Confirmed / Pending Payout (NMR)")
|
659 |
|
660 |
# Facet setting
|
|
|
708 |
) |>
|
709 |
|
710 |
# Reformat individual columns
|
711 |
+
formatRound(columns = c("total_stake", "net_payout", "rate_of_return"), digits = 2) |>
|
712 |
|
713 |
formatStyle(columns = c("round"), fontWeight = "bold") |>
|
714 |
+
|
715 |
+
formatStyle(columns = c("resolved"),
|
716 |
+
target = "row",
|
717 |
+
backgroundColor = styleEqual(c(1,0), c("transparent", "#FFF8E1"))) |>
|
718 |
+
|
719 |
|
720 |
formatStyle(columns = c("total_stake"),
|
721 |
fontWeight = "bold",
|
722 |
color = styleInterval(cuts = -1e-15, values = c("#D24141", "#2196F3"))) |>
|
723 |
|
724 |
+
formatStyle(columns = c("net_payout"),
|
725 |
fontWeight = "bold",
|
726 |
color = styleInterval(cuts = c(-1e-15, 1e-15),
|
727 |
values = c("#D24141", "#D1D1D1", "#00A800"))) |>
|