jofaichow commited on
Commit
7d44ee0
1 Parent(s): 08ad3ee

0.2.1 added KPI (All) (WIP)

Browse files
Files changed (1) hide show
  1. app/app.R +227 -42
app/app.R CHANGED
@@ -213,8 +213,8 @@ ui <- shinydashboardPlus::dashboardPage(
213
  # "joe_the_hedgehog_03",
214
  # "joe_the_hedgehog_04",
215
  # "joe_the_hedgehog_05"
216
- )
217
- ),
218
  multiple = TRUE,
219
  width = "100%",
220
  options = list(
@@ -320,7 +320,7 @@ ui <- shinydashboardPlus::dashboardPage(
320
  tabsetPanel(type = "tabs",
321
 
322
 
323
- tabPanel("KPI (CORR+TC)",
324
 
325
  br(),
326
 
@@ -359,22 +359,96 @@ ui <- shinydashboardPlus::dashboardPage(
359
  br()
360
  ),
361
 
362
-
363
  br()
364
-
365
  ),
366
 
367
  # Coming soon
368
- # tabPanel("KPI (All)",
369
- #
370
- # br(),
371
- #
372
- # markdown("xxx"),
373
- #
374
- # br()
375
- # ),
376
-
377
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
378
 
379
  tabPanel("Payout (Overview)",
380
 
@@ -511,7 +585,7 @@ ui <- shinydashboardPlus::dashboardPage(
511
 
512
  br()
513
  )
514
-
515
  ) # end of tabsetPanel
516
 
517
  ) # end of fluidPage
@@ -584,6 +658,7 @@ ui <- shinydashboardPlus::dashboardPage(
584
  - #### **0.1.8** — Various improvements in `Payout Summary`
585
  - #### **0.1.9** — Added `Payout Sim` based on new Corr and TC multipier settings
586
  - #### **0.2.0** — Replaced `Payout Summary` with `Performance Summary`. Added KPIs summary.
 
587
  "),
588
 
589
  br(),
@@ -602,7 +677,7 @@ ui <- shinydashboardPlus::dashboardPage(
602
 
603
  footer = shinydashboardPlus::dashboardFooter(
604
  left = "Powered by ❤️, ☕, Shiny, and 🤗 Spaces",
605
- right = paste0("Version 0.2.0"))
606
 
607
  )
608
 
@@ -663,7 +738,7 @@ server <- function(input, output) {
663
  }
664
  )
665
 
666
-
667
 
668
  # ============================================================================
669
  # Reactive: DataTable
@@ -805,7 +880,7 @@ server <- function(input, output) {
805
  d_smry
806
 
807
  })
808
-
809
 
810
  react_d_payout_sim_model <- eventReactive(
811
  input$button_filter,
@@ -819,7 +894,7 @@ server <- function(input, output) {
819
  filter(pay_ftr > 0) |>
820
  filter(stake > 0) |>
821
  as.data.table()
822
-
823
  # Apply clip to corrV2
824
  d_payout[, corrV2_final := corrV2]
825
  d_payout[corrV2 > 0.25, corrV2_final := 0.25]
@@ -856,7 +931,7 @@ server <- function(input, output) {
856
 
857
  ) |>
858
  as.data.table()
859
-
860
  # Return
861
  d_payout_smry
862
 
@@ -954,6 +1029,69 @@ server <- function(input, output) {
954
  })
955
 
956
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
957
  # ============================================================================
958
  # Reactive: Payout Value Boxes
959
  # ============================================================================
@@ -981,9 +1119,9 @@ server <- function(input, output) {
981
  output$text_payout_sim <- renderText({
982
  if (nrow(react_d_filter()) >= 1) "New Payout Simulation (NOTE: Experimental!)" else " "
983
  })
984
-
985
  output$text_performance_models <- renderText({
986
- if (nrow(react_d_filter()) >= 1) "KPI Analysis (CORR and TC)" else " "
987
  })
988
 
989
  output$text_performance_models_note <- renderText({
@@ -991,15 +1129,27 @@ server <- function(input, output) {
991
  })
992
 
993
  output$text_performance_chart <- renderText({
994
- if (nrow(react_d_filter()) >= 1) "KPI Charts" else " "
995
  })
996
 
 
 
 
 
 
 
 
 
 
 
 
997
 
998
 
999
  # ============================================================================
1000
  # Reactive valueBox outputs: Rounds
1001
  # ============================================================================
1002
 
 
1003
  output$payout_n_round_resolved <- renderValueBox({
1004
  # Use rounds with stake > 0 only
1005
  valueBox(value = nrow(react_d_payout_summary()[resolved == TRUE & total_stake > 0, ]),
@@ -1028,18 +1178,21 @@ server <- function(input, output) {
1028
  # Reactive valueBox outputs: Payouts
1029
  # ============================================================================
1030
 
 
1031
  output$payout_resolved <- renderValueBox({
1032
  valueBox(value = paste(as.character(format(round(sum(react_d_filter()[resolved == T, ]$payout, na.rm = T), 2), nsmall = 2)), "NMR"),
1033
  subtitle = "Total Payout (Resolved)",
1034
  color = "olive")
1035
  })
1036
 
 
1037
  output$payout_pending <- renderValueBox({
1038
  valueBox(value = paste(as.character(format(round(sum(react_d_filter()[resolved == F, ]$payout, na.rm = T), 2), nsmall = 2)), "NMR"),
1039
  subtitle = "Total Payout (Pending)",
1040
  color = "yellow")
1041
  })
1042
 
 
1043
  output$payout_total <- renderValueBox({
1044
  valueBox(value = paste(as.character(format(round(sum(react_d_filter()$payout, na.rm = T), 2), nsmall = 2)), "NMR"),
1045
  subtitle = "Total Payout (All)",
@@ -1051,6 +1204,7 @@ server <- function(input, output) {
1051
  # Reactive valueBox outputs: Average Round Payouts
1052
  # ============================================================================
1053
 
 
1054
  output$payout_average_resolved <- renderValueBox({
1055
  # Use rounds with stake > 0 only
1056
  valueBox(value = paste(as.character(format(round(mean(react_d_payout_summary()[resolved == T & total_stake > 0, ]$net_payout, na.rm = T), 2), nsmall = 2)), "NMR"),
@@ -1058,6 +1212,7 @@ server <- function(input, output) {
1058
  color = "olive")
1059
  })
1060
 
 
1061
  output$payout_average_pending <- renderValueBox({
1062
  # Use rounds with stake > 0 only
1063
  valueBox(value = paste(as.character(format(round(mean(react_d_payout_summary()[resolved == F & total_stake > 0, ]$net_payout, na.rm = T), 2), nsmall = 2)), "NMR"),
@@ -1065,6 +1220,7 @@ server <- function(input, output) {
1065
  color = "yellow")
1066
  })
1067
 
 
1068
  output$payout_average <- renderValueBox({
1069
  # Use rounds with stake > 0 only
1070
  valueBox(value = paste(as.character(format(round(mean(react_d_payout_summary()[total_stake > 0, ]$net_payout, na.rm = T), 2), nsmall = 2)), "NMR"),
@@ -1072,10 +1228,12 @@ server <- function(input, output) {
1072
  color = "light-blue")
1073
  })
1074
 
 
1075
  # ============================================================================
1076
  # Reactive valueBox outputs: Average Rate of Return
1077
  # ============================================================================
1078
 
 
1079
  output$payout_avg_ror_resolved <- renderValueBox({
1080
  # Use rounds with stake > 0 only
1081
  valueBox(value = paste(as.character(format(round(mean(react_d_payout_summary()[resolved == T & total_stake > 0, ]$rate_of_return), 2), nsmall = 2)), "%"),
@@ -1083,6 +1241,7 @@ server <- function(input, output) {
1083
  color = "olive")
1084
  })
1085
 
 
1086
  output$payout_avg_ror_pending <- renderValueBox({
1087
  # Use rounds with stake > 0 only
1088
  valueBox(value = paste(as.character(format(round(mean(react_d_payout_summary()[resolved == F & total_stake > 0, ]$rate_of_return), 2), nsmall = 2)), "%"),
@@ -1090,6 +1249,7 @@ server <- function(input, output) {
1090
  color = "yellow")
1091
  })
1092
 
 
1093
  output$payout_avg_ror <- renderValueBox({
1094
  # Use rounds with stake > 0 only
1095
  valueBox(value = paste(as.character(format(round(mean(react_d_payout_summary()[total_stake > 0, ]$rate_of_return), 2), nsmall = 2)), "%"),
@@ -1279,7 +1439,7 @@ server <- function(input, output) {
1279
 
1280
  })
1281
 
1282
-
1283
  # KPI Chart: Avg Corr vs. Avg TC
1284
  output$plot_performance_avg <- renderPlotly({
1285
 
@@ -1315,7 +1475,7 @@ server <- function(input, output) {
1315
  # Add vline and hline if needed
1316
  if (min(d_pref$avg_corrV2) <0) p_avg <- p_avg + geom_hline(aes(yintercept = 0), linewidth = 0.25, color = "grey", linetype = "dashed")
1317
  if (min(d_pref$avg_tc) <0) p_avg <- p_avg + geom_vline(aes(xintercept = 0), linewidth = 0.25, color = "grey", linetype = "dashed")
1318
-
1319
  # Convert to Plotly
1320
  ggplotly(p_avg, tooltip = "text")
1321
 
@@ -1330,11 +1490,11 @@ server <- function(input, output) {
1330
 
1331
  # Plot
1332
  p_sharpe <- ggplot(d_pref,
1333
- aes(x = sharpe_tc, y = sharpe_corrV2,
1334
- text = paste("Model:", model,
1335
- "\nSharpe Ratio of CORRv2:", round(sharpe_corrV2, 4),
1336
- "\nSharpe Ratio of TC:", round(sharpe_tc, 4))
1337
- )) +
1338
  geom_point() +
1339
  theme(
1340
  panel.border = element_rect(fill = 'transparent', color = "grey", linewidth = 0.25),
@@ -1483,7 +1643,7 @@ server <- function(input, output) {
1483
  formatRound(columns = c("sum_pay_1C0T", "sum_pay_2C0T", "sum_pay_2C1T", "sum_pay_1C3T",
1484
  "shp_pay_1C0T", "shp_pay_2C0T", "shp_pay_2C1T", "shp_pay_1C3T"),
1485
  digits = 2) |>
1486
-
1487
  formatStyle(columns = c("sum_pay_1C0T", "sum_pay_2C0T", "sum_pay_2C1T", "sum_pay_1C3T",
1488
  "shp_pay_1C0T", "shp_pay_2C0T", "shp_pay_2C1T", "shp_pay_1C3T"),
1489
  color = styleInterval(cuts = c(-1e-15, 1e-15),
@@ -1562,24 +1722,49 @@ server <- function(input, output) {
1562
  formatRound(columns = c("avg_corrV2", "sharpe_corrV2",
1563
  "avg_tc", "sharpe_tc",
1564
  "avg_2C1T", "sharpe_2C1T"
1565
- ),
1566
- digits = 4) |>
1567
 
1568
  formatStyle(columns = c("avg_corrV2", "sharpe_corrV2",
1569
  "avg_tc", "sharpe_tc",
1570
  "avg_2C1T", "sharpe_2C1T"
1571
- ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1572
  color = styleInterval(cuts = c(-1e-15, 1e-15),
1573
  values = c("#D24141", "#D1D1D1", "#00A800")))
1574
-
1575
- # formatStyle(columns = c("model",
1576
- # "sum_pay_2C1T", "sum_pay_1C3T",
1577
- # "shp_pay_2C1T", "shp_pay_1C3T"
1578
- # ), fontWeight = "bold")
1579
 
1580
  })
1581
-
1582
-
1583
 
1584
  # ============================================================================
1585
  # Reactive: Model Performance Charts
 
213
  # "joe_the_hedgehog_03",
214
  # "joe_the_hedgehog_04",
215
  # "joe_the_hedgehog_05"
216
+ )
217
+ ),
218
  multiple = TRUE,
219
  width = "100%",
220
  options = list(
 
320
  tabsetPanel(type = "tabs",
321
 
322
 
323
+ tabPanel("KPI (CT)",
324
 
325
  br(),
326
 
 
359
  br()
360
  ),
361
 
362
+
363
  br()
364
+
365
  ),
366
 
367
  # Coming soon
368
+ tabPanel("KPI (All)",
369
+
370
+ br(),
371
+
372
+ h3(strong(textOutput(outputId = "text_performance_chart"))),
373
+
374
+ h4(textOutput(outputId = "text_performance_chart_note")),
375
+
376
+ br(),
377
+
378
+ # Controls
379
+
380
+ fluidRow(
381
+
382
+ column(6,
383
+ markdown("#### **Pick ONE of the KPIs:**"),
384
+ pickerInput(
385
+ inputId = "kpi_choice",
386
+ choices = c("CORRv2: CORRelation with target cyrus_v4_20",
387
+ "TC: True Contribtuion to the hedge fund's returns",
388
+ "FNCv3: Feature Neutral Correlation with respect to the FNCv3 features",
389
+ # "CORJ60: CORRelation with target Jerome_v4_60", # add this later
390
+
391
+ "CWMM: Correlation With the Meta Model",
392
+ "MCWNM: Maximum Correlation With Numerai Models staked at least 10 NMR",
393
+ "APCWNM: Average Pairwise Correlation With Numerai Models staked at least 10 NMR",
394
+
395
+ "Score Multipliers: 0.5 x CORRv2",
396
+ "Score Multipliers: 1.5 x CORRv2",
397
+ "Score Multipliers: 2.0 x CORRv2",
398
+ "Score Multipliers: 2.0 x CORRv2 + 0.5 x TC",
399
+ "Score Multipliers: 2.0 x CORRv2 + 1.0 x TC",
400
+
401
+ "Percentile: CORRv2",
402
+ "Percentile: TC",
403
+ "Percentile: FNCv3",
404
+
405
+ "Payout",
406
+ "Rate of Return (%): Payout / Stake x 100"),
407
+ multiple = FALSE,
408
+ width = "95%")
409
+ ),
410
+
411
+
412
+ column(3,
413
+ markdown("#### **Hide Pending Rounds?**"),
414
+ switchInput(
415
+ inputId = "kpi_hide_pending",
416
+ onLabel = "Yes",
417
+ offLabel = "No",
418
+ value = FALSE)
419
+ ),
420
+
421
+ column(2,
422
+ markdown("#### **Cumulative?**"),
423
+ switchInput(
424
+ inputId = "kpi_culmulative",
425
+ onLabel = "Yes",
426
+ offLabel = "No",
427
+ value = FALSE)
428
+ )
429
+
430
+
431
+ ),
432
+
433
+ br(),
434
+
435
+ h4(strong(textOutput(outputId = "text_performance_chart_title"))),
436
+
437
+ markdown("![image](https://media.giphy.com/media/cftSzNoCTfSyAWctcl/giphy.gif)"),
438
+
439
+ br(),
440
+
441
+ h4(strong(textOutput(outputId = "text_performance_chart_data"))),
442
+
443
+ br(),
444
+
445
+ DTOutput("dt_kpi"),
446
+
447
+ br()
448
+
449
+ ),
450
+
451
+
452
 
453
  tabPanel("Payout (Overview)",
454
 
 
585
 
586
  br()
587
  )
588
+
589
  ) # end of tabsetPanel
590
 
591
  ) # end of fluidPage
 
658
  - #### **0.1.8** — Various improvements in `Payout Summary`
659
  - #### **0.1.9** — Added `Payout Sim` based on new Corr and TC multipier settings
660
  - #### **0.2.0** — Replaced `Payout Summary` with `Performance Summary`. Added KPIs summary.
661
+ - #### **0.2.1** — Added `KPI (All)` (work in progress).
662
  "),
663
 
664
  br(),
 
677
 
678
  footer = shinydashboardPlus::dashboardFooter(
679
  left = "Powered by ❤️, ☕, Shiny, and 🤗 Spaces",
680
+ right = paste0("Version 0.2.1"))
681
 
682
  )
683
 
 
738
  }
739
  )
740
 
741
+
742
 
743
  # ============================================================================
744
  # Reactive: DataTable
 
880
  d_smry
881
 
882
  })
883
+
884
 
885
  react_d_payout_sim_model <- eventReactive(
886
  input$button_filter,
 
894
  filter(pay_ftr > 0) |>
895
  filter(stake > 0) |>
896
  as.data.table()
897
+
898
  # Apply clip to corrV2
899
  d_payout[, corrV2_final := corrV2]
900
  d_payout[corrV2 > 0.25, corrV2_final := 0.25]
 
931
 
932
  ) |>
933
  as.data.table()
934
+
935
  # Return
936
  d_payout_smry
937
 
 
1029
  })
1030
 
1031
 
1032
+ react_d_kpi <- eventReactive(
1033
+ input$button_filter,
1034
+ {
1035
+
1036
+ # Get filtered data
1037
+ d_pref <- as.data.table(react_d_filter())
1038
+
1039
+ # Hide Pending?
1040
+ if (input$kpi_hide_pending) d_pref <- d_pref[resolved == TRUE]
1041
+
1042
+ # Add Rate of Return
1043
+ d_pref[stake >0, rate_of_return := payout / stake * 100]
1044
+
1045
+ # Extract Raw KPI
1046
+ if (input$kpi_choice == "CORRv2: CORRelation with target cyrus_v4_20") d_pref[, KPI := corrV2]
1047
+ if (input$kpi_choice == "TC: True Contribtuion to the hedge fund's returns") d_pref[, KPI := tc]
1048
+ if (input$kpi_choice == "FNCv3: Feature Neutral Correlation with respect to the FNCv3 features") d_pref[, KPI := fncV3]
1049
+ if (input$kpi_choice == "CWMM: Correlation With the Meta Model") d_pref[, KPI := corr_meta]
1050
+ if (input$kpi_choice == "MCWNM: Maximum Correlation With Numerai Models staked at least 10 NMR") d_pref[, KPI := mcwnm]
1051
+ if (input$kpi_choice == "APCWNM: Average Pairwise Correlation With Numerai Models staked at least 10 NMR") d_pref[, KPI := apcwnm]
1052
+
1053
+ # Calculate Score Multiplies
1054
+ if (input$kpi_choice == "Score Multipliers: 0.5 x CORRv2") d_pref[, KPI := 0.5 * corrV2]
1055
+ if (input$kpi_choice == "Score Multipliers: 1.5 x CORRv2") d_pref[, KPI := 1.5 * corrV2]
1056
+ if (input$kpi_choice == "Score Multipliers: 2.0 x CORRv2") d_pref[, KPI := 2.0 * corrV2]
1057
+ if (input$kpi_choice == "Score Multipliers: 2.0 x CORRv2 + 0.5 x TC") d_pref[, KPI := 2.0 * corrV2 + 0.5 * tc]
1058
+ if (input$kpi_choice == "Score Multipliers: 2.0 x CORRv2 + 1.0 x TC") d_pref[, KPI := 2.0 * corrV2 + 1.0 * tc]
1059
+
1060
+ # Extract Percentile
1061
+ if (input$kpi_choice == "Percentile: CORRv2") d_pref[, KPI := corrV2_pct]
1062
+ if (input$kpi_choice == "Percentile: TC") d_pref[, KPI := tc_pct]
1063
+ if (input$kpi_choice == "Percentile: FNCv3") d_pref[, KPI := fncV3_pct]
1064
+
1065
+ # Extract Payout info
1066
+ if (input$kpi_choice == "Payout") d_pref[, KPI := payout]
1067
+ if (input$kpi_choice == "Rate of Return (%): Payout / Stake x 100") d_pref[, KPI := rate_of_return]
1068
+
1069
+ # Remove rows with NA (quick hack for now)
1070
+ d_pref <- d_pref[!is.na(KPI)]
1071
+
1072
+ # Calculate Cumulative KPI (if needed)
1073
+ if (input$kpi_culmulative) {
1074
+
1075
+ # Sort before doing cumsum
1076
+ setorderv(d_pref, c("model", "round"))
1077
+
1078
+ # The data.table way
1079
+ d_pref[, KPI := cumsum(KPI), "model"]
1080
+
1081
+ }
1082
+
1083
+ # Trim and sort
1084
+ d_trim <- d_pref[, c("model", "round", "date_resolved", "resolved", "KPI")]
1085
+ setorderv(d_trim, c("model", "round"))
1086
+
1087
+ # Return
1088
+ d_trim
1089
+
1090
+ })
1091
+
1092
+
1093
+
1094
+
1095
  # ============================================================================
1096
  # Reactive: Payout Value Boxes
1097
  # ============================================================================
 
1119
  output$text_payout_sim <- renderText({
1120
  if (nrow(react_d_filter()) >= 1) "New Payout Simulation (NOTE: Experimental!)" else " "
1121
  })
1122
+
1123
  output$text_performance_models <- renderText({
1124
+ if (nrow(react_d_filter()) >= 1) "KPI Analysis (CORRv2 and TC)" else " "
1125
  })
1126
 
1127
  output$text_performance_models_note <- renderText({
 
1129
  })
1130
 
1131
  output$text_performance_chart <- renderText({
1132
+ if (nrow(react_d_filter()) >= 1) "KPI Analysis (Model Comparison)" else " "
1133
  })
1134
 
1135
+ output$text_performance_chart_note <- renderText({
1136
+ if (nrow(react_d_filter()) >= 1) "NOTE: Remember to refresh the chart (Step 5 ↑) after making any changes." else " "
1137
+ })
1138
+
1139
+ output$text_performance_chart_title <- renderText({
1140
+ if (nrow(react_d_filter()) >= 1) "One Big Chart (Coming Soon!)" else " "
1141
+ })
1142
+
1143
+ output$text_performance_chart_data <- renderText({
1144
+ if (nrow(react_d_filter()) >= 1) "KPI Data" else " "
1145
+ })
1146
 
1147
 
1148
  # ============================================================================
1149
  # Reactive valueBox outputs: Rounds
1150
  # ============================================================================
1151
 
1152
+
1153
  output$payout_n_round_resolved <- renderValueBox({
1154
  # Use rounds with stake > 0 only
1155
  valueBox(value = nrow(react_d_payout_summary()[resolved == TRUE & total_stake > 0, ]),
 
1178
  # Reactive valueBox outputs: Payouts
1179
  # ============================================================================
1180
 
1181
+
1182
  output$payout_resolved <- renderValueBox({
1183
  valueBox(value = paste(as.character(format(round(sum(react_d_filter()[resolved == T, ]$payout, na.rm = T), 2), nsmall = 2)), "NMR"),
1184
  subtitle = "Total Payout (Resolved)",
1185
  color = "olive")
1186
  })
1187
 
1188
+
1189
  output$payout_pending <- renderValueBox({
1190
  valueBox(value = paste(as.character(format(round(sum(react_d_filter()[resolved == F, ]$payout, na.rm = T), 2), nsmall = 2)), "NMR"),
1191
  subtitle = "Total Payout (Pending)",
1192
  color = "yellow")
1193
  })
1194
 
1195
+
1196
  output$payout_total <- renderValueBox({
1197
  valueBox(value = paste(as.character(format(round(sum(react_d_filter()$payout, na.rm = T), 2), nsmall = 2)), "NMR"),
1198
  subtitle = "Total Payout (All)",
 
1204
  # Reactive valueBox outputs: Average Round Payouts
1205
  # ============================================================================
1206
 
1207
+
1208
  output$payout_average_resolved <- renderValueBox({
1209
  # Use rounds with stake > 0 only
1210
  valueBox(value = paste(as.character(format(round(mean(react_d_payout_summary()[resolved == T & total_stake > 0, ]$net_payout, na.rm = T), 2), nsmall = 2)), "NMR"),
 
1212
  color = "olive")
1213
  })
1214
 
1215
+
1216
  output$payout_average_pending <- renderValueBox({
1217
  # Use rounds with stake > 0 only
1218
  valueBox(value = paste(as.character(format(round(mean(react_d_payout_summary()[resolved == F & total_stake > 0, ]$net_payout, na.rm = T), 2), nsmall = 2)), "NMR"),
 
1220
  color = "yellow")
1221
  })
1222
 
1223
+
1224
  output$payout_average <- renderValueBox({
1225
  # Use rounds with stake > 0 only
1226
  valueBox(value = paste(as.character(format(round(mean(react_d_payout_summary()[total_stake > 0, ]$net_payout, na.rm = T), 2), nsmall = 2)), "NMR"),
 
1228
  color = "light-blue")
1229
  })
1230
 
1231
+
1232
  # ============================================================================
1233
  # Reactive valueBox outputs: Average Rate of Return
1234
  # ============================================================================
1235
 
1236
+
1237
  output$payout_avg_ror_resolved <- renderValueBox({
1238
  # Use rounds with stake > 0 only
1239
  valueBox(value = paste(as.character(format(round(mean(react_d_payout_summary()[resolved == T & total_stake > 0, ]$rate_of_return), 2), nsmall = 2)), "%"),
 
1241
  color = "olive")
1242
  })
1243
 
1244
+
1245
  output$payout_avg_ror_pending <- renderValueBox({
1246
  # Use rounds with stake > 0 only
1247
  valueBox(value = paste(as.character(format(round(mean(react_d_payout_summary()[resolved == F & total_stake > 0, ]$rate_of_return), 2), nsmall = 2)), "%"),
 
1249
  color = "yellow")
1250
  })
1251
 
1252
+
1253
  output$payout_avg_ror <- renderValueBox({
1254
  # Use rounds with stake > 0 only
1255
  valueBox(value = paste(as.character(format(round(mean(react_d_payout_summary()[total_stake > 0, ]$rate_of_return), 2), nsmall = 2)), "%"),
 
1439
 
1440
  })
1441
 
1442
+
1443
  # KPI Chart: Avg Corr vs. Avg TC
1444
  output$plot_performance_avg <- renderPlotly({
1445
 
 
1475
  # Add vline and hline if needed
1476
  if (min(d_pref$avg_corrV2) <0) p_avg <- p_avg + geom_hline(aes(yintercept = 0), linewidth = 0.25, color = "grey", linetype = "dashed")
1477
  if (min(d_pref$avg_tc) <0) p_avg <- p_avg + geom_vline(aes(xintercept = 0), linewidth = 0.25, color = "grey", linetype = "dashed")
1478
+
1479
  # Convert to Plotly
1480
  ggplotly(p_avg, tooltip = "text")
1481
 
 
1490
 
1491
  # Plot
1492
  p_sharpe <- ggplot(d_pref,
1493
+ aes(x = sharpe_tc, y = sharpe_corrV2,
1494
+ text = paste("Model:", model,
1495
+ "\nSharpe Ratio of CORRv2:", round(sharpe_corrV2, 4),
1496
+ "\nSharpe Ratio of TC:", round(sharpe_tc, 4))
1497
+ )) +
1498
  geom_point() +
1499
  theme(
1500
  panel.border = element_rect(fill = 'transparent', color = "grey", linewidth = 0.25),
 
1643
  formatRound(columns = c("sum_pay_1C0T", "sum_pay_2C0T", "sum_pay_2C1T", "sum_pay_1C3T",
1644
  "shp_pay_1C0T", "shp_pay_2C0T", "shp_pay_2C1T", "shp_pay_1C3T"),
1645
  digits = 2) |>
1646
+
1647
  formatStyle(columns = c("sum_pay_1C0T", "sum_pay_2C0T", "sum_pay_2C1T", "sum_pay_1C3T",
1648
  "shp_pay_1C0T", "shp_pay_2C0T", "shp_pay_2C1T", "shp_pay_1C3T"),
1649
  color = styleInterval(cuts = c(-1e-15, 1e-15),
 
1722
  formatRound(columns = c("avg_corrV2", "sharpe_corrV2",
1723
  "avg_tc", "sharpe_tc",
1724
  "avg_2C1T", "sharpe_2C1T"
1725
+ ),
1726
+ digits = 4) |>
1727
 
1728
  formatStyle(columns = c("avg_corrV2", "sharpe_corrV2",
1729
  "avg_tc", "sharpe_tc",
1730
  "avg_2C1T", "sharpe_2C1T"
1731
+ ),
1732
+ color = styleInterval(cuts = c(-1e-15, 1e-15),
1733
+ values = c("#D24141", "#D1D1D1", "#00A800")))
1734
+
1735
+ })
1736
+
1737
+
1738
+ # KPI Filter
1739
+ output$dt_kpi <- DT::renderDT({
1740
+
1741
+ # Generate a new DT
1742
+ DT::datatable(
1743
+
1744
+ # Data
1745
+ react_d_kpi(),
1746
+
1747
+ # Other Options
1748
+ rownames = FALSE,
1749
+ extensions = "Buttons",
1750
+ options =
1751
+ list(
1752
+ dom = 'Bflrtip', # https://datatables.net/reference/option/dom
1753
+ buttons = list('csv', 'excel', 'copy', 'print'), # https://rstudio.github.io/DT/003-tabletools-buttons.html
1754
+ order = list(list(0, 'asc'), list(1, 'asc')),
1755
+ pageLength = 10,
1756
+ lengthMenu = c(10, 50, 100, 500, 1000),
1757
+ columnDefs = list(list(className = 'dt-center', targets = "_all")))
1758
+ ) |>
1759
+
1760
+ # Reformat individual columns
1761
+ formatRound(columns = c("KPI"), digits = 4) |>
1762
+
1763
+ formatStyle(columns = c("KPI"),
1764
  color = styleInterval(cuts = c(-1e-15, 1e-15),
1765
  values = c("#D24141", "#D1D1D1", "#00A800")))
 
 
 
 
 
1766
 
1767
  })
 
 
1768
 
1769
  # ============================================================================
1770
  # Reactive: Model Performance Charts