R Shiny Application

This project was done using R programming languages and shiny server. A historical price and indicators plot based on stock symbols. The app take the price from specific date that is set by the user to end user specified date.

The app will do back testing 3 trading strategies and show the earning based on each strategy. it is based on a simple strategy, indicator user specified strategy and custom trading strategy that will be uploaded by the user as an R script and will be ran in the app and the results will be shown.

The app include reports based on each trading strategy that will be saved in the user app location in the pc as text file.

The app include real-time price which shows the last quote of the stock price. User can buy and sell based on his own strategy in the game mode of the app. This app include game mode which allows the user to play with the stock prices and do his/her own trading. after completion of the game user can see earning and the summary report based on his/her trade.  This app main window as as below:

Looking at the above figure we can see the plot of the date range. The plot could be based on year, 3 month, 1 month, 1 week and daily.

Back testing result show 41682$ as earning while still 662 shares are unrealized.

libraries used in this app could be seen in the initial line of UI and Server code.

ui.R

# ui.R
library(shiny)
library(shinyWidgets)
library(shinyjs)
library(dygraphs)
library(shinythemes)
shinyUI(fluidPage(
 useShinyjs(),
 theme = shinytheme("slate"),
 #shinyWidgets::shinyWidgetsGallery(),
 titlePanel("Stock Price"),
 sidebarLayout(
 sidebarPanel(
 hidden( dateRangeInput("dateG",'Date input: yyyy-mm-dd', 
 start = as.character(Sys.Date()-90),
 end = as.character(Sys.Date()-1),
 min = "2001-01-01",
 max = as.character(Sys.Date()),
 format = "mm/dd/yy",
 separator = " - ")),
 hidden(selectInput("indicatorG", 
 label = "Indicator",
 choices = list("RSI","CCI","Bbands","SMA", "SMI","SAR"),
 selected = "SMA")),
 hidden( switchInput(inputId = "checkG",value = TRUE, onLabel = "Smaller",
 offLabel = "Greater",offStatus="primary")),
 #helpText("Stock price"),
 # submitButton("Submit"),
 #textInput("symb", "Symbol", "AAPL"),
 selectInput("symb", 
 label = "Choose a Stock",
 choices = list("AAPL", "CELG",
 "JPM", "XOM","ABX"),
 selected = "AAPL"), 
 hidden(selectInput("strategyG", label = "Strategy",
 choices = list("Simple", "Trading Indicators","Rscript"),selected = "Trading Indicators")), 
 selectInput("trade", 
 label = "Trading Strategy",
 choices = list("Simple", "Trading Indicators",
 "Rscript"),
 selected = "Simple"),
 dateRangeInput("dates", "Date range for backtesting:",
 start = "2016-01-01",
 end = as.character(Sys.Date()-1),
 min = "2001-01-01",
 max = as.character(Sys.Date()),
 format = "mm/dd/yy",
 separator = " - "),

Server.R

# server.R
library(quantmod)
library(dygraphs)
library(magrittr)
library(pracma)
#library(qmao)
source("tradingstrategy.R")
require(xts)
require(jsonlite)
library(TTR)
library(zoo)
source("tradedynamic.R")

getQuote_ <- function(ticks) {
qRoot <- "https://query1.finance.yahoo.com/v7/finance/quote?fields=symbol,longName,regularMarketTime,regularMarketPreviousClose,regularMarketChange,regularMarketOpen,regularMarketDayHigh,regularMarketDayLow,regularMarketVolume&formatted=false&symbols="
z <- fromJSON(paste(qRoot, paste(ticks, collapse=","), sep=""))
z <- z$quoteResponse$result[,c("symbol", "regularMarketTime", "regularMarketPreviousClose", "regularMarketChange", "regularMarketOpen", "regularMarketDayHigh", "regularMarketDayLow", "regularMarketVolume")]
row.names(z) <- z$symbol
z$symbol <- NULL
names(z) <- c("Time", "Last", "Change", "Open", "High", "Low", "Volume")
z$Time <- as.POSIXct(z$Time, origin = '1970-01-01 00:00:00')
return(z)
}

User is capable of changing the trading strategy, he can also use his own trading strategy that is already written as an R script, below is an example of custom trading strategy that user can upload in this app:

calc <- function(datai,v){
# This function is the typical function that is used for testing the upload script window in the Trading Strategy.
# in this function the name of the function (calc) should not be changed.
# user could write his/her own R script for thier trading strategy and use it in the upload script window and the application will show the
# back testing results for that R script.
#
# input:
# ...... datai: The historical data of a specific stock. that contains Open, close, volume and so on.. datai is the historical stock prices.
# ...... v: v is 1 or 2. when v = 1 in conditional statement in the end of the script, ret should be for Buy prices.
# ...... when v = 2. the conditional statement in the end of the script, ret should be for sell prices.
#
#
# Output: ret: return of this function should be a data frame that contain two columns. if v = 1 then ret = ret1. if v = 2 then ret = ret2.
# and ret1 includes the buy dates and buy prices. ret2 includes the sell dates and sell prices. like below:
# ret1 <- data.frame(format(time(pob),'%Y-%m-%d'),pcb)
# colnames(ret1) <- c("buy-date","buy price")
# ret2 <- data.frame(format(time(pos),'%Y-%m-%d'),pcs)
# colnames(ret2) <- c("sell-date","sell price")
#
# 
# note: other parts of the code, all could be changed according to the user trading strategy.
# note: ret3 at the end of the script is for total trades. including all the interval date. even if it has trade or not, ret3 did not used in the 
# report of the Rscript upload window. so it could be neglected.
Po <- datai[,1]
Pc <- datai[,4] 
G = matrix(0,nrow=length(Pc),ncol=1)
stradeopen = 0
 for (i in 1:length(Pc)){
 if (Pc[i] < Po[i]){
 G[i,1] = 1
 stradeopen = stradeopen + 1
 }else{
 G[i,1] = 0
 }
 if ((Pc[i] > Po[i]) & (stradeopen >= 1)){
 G[i,1] = 2
 stradeopen = stradeopen - 1
 }
 }
ind1 <- G == 1
ind2 <- G == 2
diff1 <- c(0,diff(ind1))
diff2 <- c(0,diff(ind2))
index1 <- ind1
index2 <- ind2
 for (i in c(1:length(ind1))){
 if (i == 1){
 index1[i] = 0
 }else{
 if (diff1[i] == -1){
 index1[i] = 1
 }else if(diff1[i] == 0 & ind1[i - 1] == 1){
 index1[i] = 1
 }else{
 index1[i] = 0
 }}
 }
 for (i in c(1:length(ind2))){
 if (i == 1){
 index2[i] = 0
 }else{
 if (diff2[i] == -1){
 index2[i] = 1
 }else if(diff2[i] == 0 & ind2[i - 1] == 1){
 index2[i] = 1
 }else{
 index2[i] = 0
 }}
 }
atrade <- 0
pob <- Po[ind1]
pcb <- Pc[ind1]
pcbt <- Pc[index1]
pos <- Po[ind2]
pcs <- Pc[ind2]
pcst <- Pc[index2]
buyc <- sum(pcb)
sellc <- sum(pcs)
buyct <- sum(pcbt)
sellct <- sum(pcst)
earnc <- sellc - buyc
earnt <- sellct - buyct
StrG = matrix(0,nrow=length(G),ncol=1)
for (i in 1:length(G)){
 if (G[i] == 1){
 StrG[i] = "B"
 }else if (G[i] == 2){
 StrG[i] = "S"
 }else if (G[i] == 0){
 StrG[i] = "N"
 }
}
ret1 <- data.frame(format(time(pob),'%Y-%m-%d'),pcb)
colnames(ret1) <- c("buy-date","buy price")
ret2 <- data.frame(format(time(pos),'%Y-%m-%d'),pcs)
colnames(ret2) <- c("sell-date","sell price")
ret3 <- data.frame(format(time(Pc),'%Y-%m-%d'),StrG,Pc)
colnames(ret3) <- c("date","all-trades","price")
if (v == 1){
ret <- ret1
}else if(v == 2){
ret <- ret2
}else if(v == 3){
ret <- ret3
}
return(ret)
}

 

Leave a Reply

Your email address will not be published. Required fields are marked *