Welcome to the final installment of my three-part series on the Sortino ratio, a metric for measuring the return you are likely to get from a given level of risk

Welcome to the final installment of my three-part series on the Sortino ratio, a metric for measuring the return you are likely to get from a given level of risk. In case you missed them, my first post focused on calculating the Sortino ratio and my second post focused on visualizing it. Both are necessary components of building the final Shiny application featured in this post, which allows users to build custom portfolios and visualize the Sortino ratio interactively. 

I am going to lean heavily on my previous work, so I recommend at least skimming the previous posts before diving in here. Not only will they provide background on the substance and functions of this application, but they will explain why a Shiny app like this one can be a valuable tool for sharing work with a broader audience beyond other R coders. If you’re entirely new to Shiny, there are plenty of tutorials, introductory information, and examples on the Shiny homepage. 

This app could have been built using the classical app.r file format, but I prefer to use a flexdashboard because it keeps the entire workflow in the R Markdown world. In my previous posts, I used R Markdown and code chunks to enforce logic on my data import, calculations, and visualizations. This Shiny app follows the same code chunk structure, and I find that the logic and functions translate well.

I will review the substantive code in detail, but we won’t cover formatting features like how to create a new row or how to tab-set a row. If you'd like that information, the source code includes all of the formatting code.

On to the substance: Our first task is to build an input sidebar and enable users to choose five stocks and weights. We will use textInput("stock1",...)) to create a space where the user can type a stock symbol and the numericInput("w1",...) to create a space where the user can enter a numeric weight. Since we have five stocks and weights, we repeat this five times. Notice that the stock symbol field uses textInput() because the user needs to enter text and the weight field uses numericInput() because the user needs to enter a number.

library(tidyverse)
library(highcharter)
library(tidyquant)
library(timetk)

fluidRow(
column(7,
textInput("stock1", "Stock 1", "SPY")),
column(5,
numericInput("w1", "Portf. %", 25, min = 1, max = 100))
)

fluidRow(
column(7,
textInput("stock2", "Stock 2", "EFA")),
column(5,
numericInput("w2", "Portf. %", 25, min = 1, max = 100))
)

fluidRow(
column(7,
textInput("stock3", "Stock 3", "IJS")),
column(5,
numericInput("w3", "Portf. %", 20, min = 1, max = 100))
)

fluidRow(
column(7,
textInput("stock4", "Stock 4", "EEM")),
column(5,
numericInput("w4", "Portf. %", 20, min = 1, max = 100))
)

fluidRow(
column(7,
textInput("stock5", "Stock 5", "AGG")),
column(5,
numericInput("w5", "Portf. %", 10, min = 1, max = 100))
)

Next, we give the end user the ability to choose a start date with dateInput("date",...).

fluidRow(
  column(7,
  dateInput("date", "Starting Date", "2010-01-01", format = "yyyy-mm-dd"))
)

And for the final inputs, let’s have a row where the user can choose a Minimum Acceptable Rate (MAR) and the length of the rolling window. These are both numbers, so I used numericInput("mar",...) and numericInput("window",...).

fluidRow(
  column(5,
  numericInput("mar", "MAR%", .8, min = 0, max = 3, step = .01)),
  column(5,
  numericInput("window", "Window", 6, min = 2, max = 24, step = 2))
)

Finally, let's include a submit button for our end user. This button is what takes all those inputs and passes them on to your reactive functions so the Shiny engine can start doing its work. The app won’t fire until the user clicks submit.

actionButton("go", "Submit")

This is a hugely important button because it enables the use of eventReactives() to control your computation. Let’s have a look at that first eventReaactive() wherein we take the user-chosen stocks and grab their daily prices.

 to read the full article : https://www.datascience.com