R/aml_test_model.R

Defines functions aml_test_model

Documented in aml_test_model

#' Function to test the model and conditionally decide to update existing model for a single currency pair
#'
#' @description Function is designed to test the trading decision generated by the Deep learning regression model.
#' It is doing so by simulating trading strategy outcome.
#' The outcome of this function will be also used to define best trigger to join into the
#' trading opportunity
#'
#' `r lifecycle::badge('experimental')`
#'
#' @details  Function is reading price data and corresponding indicator.
#' Starting from the trained model function will test the trading strategy using simplified trading approach.
#' Trading approach will entail using the last available indicator data, predict the price change for every row,
#' trade will be simulating by holding the asset for 3, 5, 10 and 34 hours.
#' Several trigger points will be evaluated selecting the most optimal trading trigger.
#' Function is writing most optimal decision into *.csv file
#' Such file will be used by the function aml_make_model.R to decide whether model must be updated...
#'
#' @author (C) 2020, 2021 Vladimir Zhbanko
#'
#' @param symbol              Character symbol of the asset for which to train the model
#' @param num_bars            Integer, Number of (rows) bars used to test the model
#' @param timeframe           Integer, Data timeframe e.g. 60 min. This will be equal to 1 bar
#' @param path_model          String, User path where the models are be stored
#' @param path_data           String, User path where the aggregated historical data is stored, if exists in rds format
#' @param path_sbxm           String, User path to the sandbox where file with strategy test results should be written (master terminal)
#' @param path_sbxs           String, User path to the sandbox where file with strategy test results should be written (slave terminal)
#'
#' @return Function is writing file into Decision Support System folders
#' @export
#'
#' @examples
#'
#' \donttest{
#'
#' library(dplyr)
#' library(magrittr)
#' library(readr)
#' library(h2o)
#' library(lazytrade)
#' library(lubridate)
#'
#' path_model <- normalizePath(tempdir(),winslash = "/")
#' path_data <- normalizePath(tempdir(),winslash = "/")
#'
#' ind = system.file("extdata", "AI_RSIADXUSDJPY60.csv",
#'                   package = "lazytrade") %>% read_csv(col_names = FALSE)
#'
#' ind$X1 <- ymd_hms(ind$X1)
#'
#' tick = system.file("extdata", "TickSize_AI_RSIADX.csv",
#'                   package = "lazytrade") %>% read_csv(col_names = FALSE)
#'
#' write_csv(ind, file.path(path_data, "AI_RSIADXUSDJPY60.csv"), col_names = FALSE)
#'
#' write_csv(tick, file.path(path_data, "TickSize_AI_RSIADX.csv"), col_names = FALSE)
#'
#' # data transformation using the custom function for one symbol
#' aml_collect_data(indicator_dataset = ind,
#'                  symbol = 'USDJPY',
#'                  timeframe = 60,
#'                  path_data = path_data)
#'
#'
#' # start h2o engine
#' h2o.init(nthreads = 2)
#'
#'
#' # performing Deep Learning Regression using the custom function
#' aml_make_model(symbol = 'USDJPY',
#'                timeframe = 60,
#'                path_model = path_model,
#'                path_data = path_data,
#'                force_update=FALSE,
#'                num_nn_options = 3)
#'
#' path_sbxm <- normalizePath(tempdir(),winslash = "/")
#' path_sbxs <- normalizePath(tempdir(),winslash = "/")
#'
#' # score the latest data to generate predictions for one currency pair
#' aml_score_data(symbol = 'USDJPY',
#'                timeframe = 60,
#'                path_model = path_model,
#'                path_data = path_data,
#'                path_sbxm = path_sbxm,
#'                path_sbxs = path_sbxs)
#'
#' # test the results of predictions
#' aml_test_model(symbol = 'USDJPY',
#'                num_bars = 600,
#'                timeframe = 60,
#'                path_model = path_model,
#'                path_data = path_data,
#'                path_sbxm = path_sbxm,
#'                path_sbxs = path_sbxs)
#'
#' # stop h2o engine
#' h2o.shutdown(prompt = FALSE)
#'
#' #set delay to insure h2o unit closes properly before the next test
#' Sys.sleep(5)
#'
#' }
#'
#'
#'
aml_test_model <- function(symbol, num_bars, timeframe, path_model, path_data,
                           path_sbxm = path_sbxm,
                           path_sbxs = path_sbxs){

  requireNamespace("dplyr", quietly = TRUE)
  requireNamespace("readr", quietly = TRUE)
  requireNamespace("h2o", quietly = TRUE)

  #construct the path to the data object see function aml_collect_data.R
  # generate a file name to be able to read the right dataset
  f_name <- paste0("AI_RSIADX", symbol,timeframe, ".rds")
  full_path <- file.path(path_data,  f_name)
  # file name with the tick data
  path_tick <- file.path(path_data, "TickSize_AI_RSIADX.csv")

  #dataset with date column X1
  y <- readr::read_rds(full_path) %>%
    # remove empty rows
    na.omit() %>% dplyr::filter_all(any_vars(. != 0))


  #dataset without X1 column (for predictions)
  x <- y  %>%
    dplyr::select(-X1, -X2, -X3, -LABEL) %>%
    # only keep last month for simulation
    utils::head(num_bars)

  #dataset with tick data
  z <- readr::read_csv(path_tick, col_names = FALSE, col_types = readr::cols()) %>%
    #filter line with a symbol we need
    dplyr::filter(X1 == symbol) %$%
    #value z will contain tick value for this symbol
    X2

  #TDL add fail safe mechanism for 'z'

  # generate a file name for model
  m_name <- paste0("DL_Regression", "-", symbol,"-", timeframe)
  m_path <- file.path(path_model, m_name)
  #load model
  ModelR <- h2o::h2o.loadModel(path = m_path)

  # uploading data to h2o
  recent_ML  <- h2o::as.h2o(x = x, destination_frame = "recent_ML")
  # PREDICT the next period...
  result_R1 <- h2o::h2o.predict(ModelR, recent_ML) %>% as.data.frame()

  ## Checking the trading strategy assuming we open and hold position for 2 - 50 bars!

  NBars <- c(2:50)
  # trying different N of bars
  for (NB in NBars) {
    #NB <- 3


  # To DO: Add ATR multiplier to simulate TP/SL
  # add for loop for ATR Multiplier



  # Note: Position will only be opened if predicted price is higher than a Trigger
  Trigger <- c(20, 30, 40, 50, 60, 70)
  # trying different levels
  for (TR in Trigger) {
    #TR <- 20


  dat31 <- y %>%
    # using last 600 observations
    utils::head(num_bars) %>%
    ## select columns:
    # X1 time index
    # X2 price at the time index
    # X3 price 34 bars ago
    # LABEL is a price difference X3-X2
    dplyr::select(X1, X2) %>%
    # add column with predicted price change
    dplyr::bind_cols(result_R1) %>%
    ## create columns:
    # dP_34 - price difference now vs 34 bars (only for check)
    # dplyr::mutate(dP_34 = X3-X2) %>%
    ## setup condition to enter the trade
    # create a risk column, use 20 pips as a trigger
    dplyr::mutate(Risk = if_else(predict > TR, 1/z, if_else(predict < -TR, -1/z, 0))) %>%
    ## create a columns with shifted X2 price down:
    # value BR will indicate number of bars we will hold this position
    dplyr::mutate(X2_NB = lag(X2, NB)) %>%
    # clean up this dataset
    na.omit() %>%
    # now calculate the scenario
    dplyr::mutate(Hold_NB = Risk*(X2_NB - X2)) %>%
    # remove zero values to calculate presumed number of trades
    dplyr::filter(Risk != 0) %>%
    # get the sum of columns
    # Column Expected PNL would be the result in case all trades would be successful
    # Column Achieved PNL is the results achieved in reality
    dplyr::summarise(PnL_NB = sum(Hold_NB),
                     TotalTrades = n(),
                     TR_Level = TR,
                     NB_hold = NB,
                     Symbol = symbol) %>%

  # interpret the results
  dplyr::mutate(FinalOutcome = if_else(PnL_NB > 0, "Good", "Bad"))

  # record results of testing
  if(!exists("df_res")){
    df_res <- dat31
  } else {
    df_res <- df_res %>% dplyr::bind_rows(dat31)
  }




  } #end of the for loop Trigger


  } #end of the for loops NBars

  #write this structure to the model folder as it can be useful to analyse:
  # generate a file name for the strategy test file
  s_name <- paste0("StrTestFull-", "-", symbol,"-", timeframe,".rds")
  s_path <- file.path(path_model, s_name)
  readr::write_rds(df_res, s_path)

  #library(ggplot2)
  #ggplot(df_res, aes(x = NB_hold, y = PnL_NB,
  #               size = TotalTrades, col = as.factor(TR_Level)))+geom_point()

  ## select the best trading option (Trigger and Max Hours option)
  # select amount of bars to hold the position and suggested Trigger


  df_tr <- df_res %>%
    dplyr::group_by(TR_Level, NB_hold, Symbol) %>%
    dplyr::summarise(MaxPerf = max(PnL_NB)) %>%
    dplyr::arrange(desc(MaxPerf)) %>%
    utils::head(1)




  ## write condition to the csv file
  dec_file_name <- paste0("StrTest-", symbol, "M",timeframe, ".csv")
  dec_file_path <- file.path(path_model,  dec_file_name)
  readr::write_csv(df_tr, dec_file_path)

  # also write these results for MT4 robot use
  readr::write_csv(df_tr, file.path(path_sbxm, dec_file_name))
  readr::write_csv(df_tr, file.path(path_sbxs, dec_file_name))

  #h2o.shutdown(prompt = FALSE)




}
vzhomeexperiments/lazytrade documentation built on Feb. 20, 2024, 6:09 p.m.