lazytrade
The goal of lazytrade is to keep all functions and scripts of the lazytrade educational project on UDEMY. Functions are providing an opportunity to learn Computer and Data Science using example of Algorithmic Trading
Installation
You can install the released version of lazytrade from CRAN with:
install.packages("lazytrade")
And the development version from GitHub with:
# install.packages("devtools")
devtools::install_github("vzhomeexperiments/lazytrade")
Example - prepare data for machine learning
This is a basic example which shows you how to solve a common problem:
library(lazytrade)
library(tidyverse, warn.conflicts = FALSE)
#> -- Attaching packages -------------------------------------------------------------------------------- tidyverse 1.3.0 --
#> <U+2713> ggplot2 3.2.1 <U+2713> purrr 0.3.3
#> <U+2713> tibble 2.1.3 <U+2713> dplyr 0.8.3
#> <U+2713> tidyr 1.0.0 <U+2713> stringr 1.4.0
#> <U+2713> readr 1.3.1 <U+2713> forcats 0.4.0
#> -- Conflicts ----------------------------------------------------------------------------------- tidyverse_conflicts() --
#> x dplyr::filter() masks stats::filter()
#> x dplyr::lag() masks stats::lag()
## basic example code
# Convert a time series vector to matrix with 64 columns
macd_m <- seq(1:1000) %>% as.data.frame() %>% to_m(20)
head(macd_m, 2)
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
#> [1,] 1 2 3 4 5 6 7 8 9 10 11 12 13 14
#> [2,] 21 22 23 24 25 26 27 28 29 30 31 32 33 34
#> [,15] [,16] [,17] [,18] [,19] [,20]
#> [1,] 15 16 17 18 19 20
#> [2,] 35 36 37 38 39 40
Example - aggregate multiple log files and visualize results
Multiple log files could be joined into one data object
library(lazytrade)
library(readr)
library(dplyr)
library(magrittr)
#>
#> Attaching package: 'magrittr'
#> The following object is masked from 'package:purrr':
#>
#> set_names
#> The following object is masked from 'package:tidyr':
#>
#> extract
library(lubridate)
#>
#> Attaching package: 'lubridate'
#> The following object is masked from 'package:base':
#>
#> date
# files are located in the sample folders
DFOLDER <- system.file("extdata/RES", package = "lazytrade")
DFR <- opt_aggregate_results(fold_path = DFOLDER)
This data object can be visualized
library(ggplot2)
opt_create_graphs(x = DFR, outp_path = dir,graph_type = 'bars')
Or just visualize results with time-series plot
opt_create_graphs(x = DFR, outp_path = dir,graph_type = 'ts')
Example - leverage Reinforcement Learning for Risk Management
Example below would generate RL policy based on the trade results achieved so far
library(dplyr)
library(ReinforcementLearning)
library(magrittr)
data(data_trades)
states <- c("tradewin", "tradeloss")
actions <- c("ON", "OFF")
control <- list(alpha = 0.7, gamma = 0.3, epsilon = 0.1)
generate_RL_policy(data_trades, states, actions, control)
#> TradeState Policy
#> 1 tradeloss ON
#> 2 tradewin OFF
Example - generating passwords for trading platforms login
Multiple trading accounts require passwords, package contains function that may easily generate random passwords:
library(lazytrade)
library(stringr)
library(magrittr)
library(openssl)
library(readr)
#generate 8digit password for trading platform
util_generate_password(salt = 'random text')
#> .
#> 1 a6b0BEB1
Example - generate initialization files for MT4 platform
Facilitate generation of initialisation files:
library(lazytrade)
dir <- normalizePath(tempdir(),winslash = "/")
# test file to launch MT4 terminal with parameters
write_ini_file(mt4_Profile = "Default",
mt4_Login = "12345678",
mt4_Password = "password",
mt4_Server = "BrokerServerName",
dss_inifilepath = dir,
dss_inifilename = "prod_T1.ini",
dss_mode = "prod")
Notes to remind myself how to create R package
This readme file
What is special about using README.Rmd
instead of just README.md
?
You can include R chunks like so:
summary(cars)
#> speed dist
#> Min. : 4.0 Min. : 2.00
#> 1st Qu.:12.0 1st Qu.: 26.00
#> Median :15.0 Median : 36.00
#> Mean :15.4 Mean : 42.98
#> 3rd Qu.:19.0 3rd Qu.: 56.00
#> Max. :25.0 Max. :120.00
You’ll still need to render README.Rmd
regularly, to keep README.md
up-to-date.
taken from http://r-pkgs.had.co.nz and https://r-pkgs.org/intro.html
Generating Documentation
Title of the package
Create right title case for the title of the package By running this
command… tools::toTitleCase("Learn computer and data science using
algorithmic trading")
the Title will become: “Learn Computer and Data
Science using Algorithmic Trading”
Re-generating documentation
Run this code to re-generate documentation devtools::document()
Fixing License
Run this code to fix license: usethis::use_mit_license(name = "Vladimir
Zhbanko")
Adding data to the package for internal tests
Run this code to add data to the folder data/
x <- sample(1000)
usethis::use_data(x)
To update this data: x <- sample(2000)
usethis::use_data(x, overwrite
= T)
Note: use option ’LazyLoad` to make data available only when user wants it always include LazyData: true in your DESCRIPTION. Note: to document dataset see https://stackoverflow.com/questions/2310409/how-can-i-document-data-sets-with-roxygen
Document dataset using the R script R/datasets.R
Adding examples to test package function
Tests setup first time
Run this command to setup tests ‘usethis::use_testthat()’
This will create a folder with the name tests
Inside this folder there will be another folder testthat
.
Examples in Roxygen code
@examples …
code to execute during package checks
@examples
/donttest{
code to NOT execute during package checks
}
Testing a package
Create a test script
Run this command to create a new script with the test skeleton:
usethis::use_test("profit_factor.R")
Enrich the test script
Details:
- add libraries used for test
- add function
context("profit_factor")
- add function test_that(“test description”, {test process})
- load data using function
data(named_data_object)
Example:
library(testthat)
#>
#> Attaching package: 'testthat'
#> The following objects are masked from 'package:magrittr':
#>
#> equals, is_less_than, not
#> The following object is masked from 'package:dplyr':
#>
#> matches
#> The following object is masked from 'package:purrr':
#>
#> is_null
#> The following object is masked from 'package:tidyr':
#>
#> matches
library(dplyr)
library(magrittr)
context("profit_factor")
test_that("test value of the calculation", {
data(profit_factor_data)
DF_Stats <- profit_factor_data %>%
group_by(X1) %>%
summarise(PnL = sum(X5),
NumTrades = n(),
PrFact = profit_factor(X5)) %>%
select(PrFact) %>%
head(1) %>%
as.vector() %>%
round(3)
expect_equal(DF_Stats$PrFact, 0.68)
})
Test of the coverage for the script
Test coverage shows you what you’ve tested devtools::test_coverage_file()
devtools::test_coverage_file()
Automated checks
This will add automatic test coverage badge to the readme file on github
usethis::use_coverage()
Checking package
Step 1. devtools::document()
Step 2. devtools::run_examples()
Step
3. Menu ‘Build’ Clean and Rebuild
Step 4. ‘Check’
devtools::check()
Handling functions that write files
In case functions are writing files there are few considerations to take into account:
- examples section must contain working example of code that writes files
- example code must write to the temporary directory defined by
tempdir()
function - after package check performed with
devtools::check()
there should nothing remain in the ‘tmp/’ directory
Considerations
File names defined by function tempdir()
would look like this:
# > tempdir()
# [1] "/tmp/RtmpkaFStZ"
File names defined by function tempfile()
would look like this:
# > tempfile()
# [1] "/tmp/RtmpkaFStZ/file7a33be992b4"
This is example of how function write_csv
example works:
tmp <- tempfile()
write_csv(mtcars, tmp)
results of this code are correctly stored to the temporary file
however this example from readr
package function write_csv
is
showing that file will be written to the ‘/tmp/’ directory
dir <- tempdir()
write_tsv(mtcars, file.path(dir, "mtcars.tsv.gz"))
Deleting files after running examples:
We use function unlink()
to do this:
unlink("/tmp/*.csv", recursive = TRUE, force = TRUE)
and we check that there is nothing more remained:
dir("/tmp/*.csv")
CRAN Submission Tips and Tricks
Many notes while using global variables:
see https://stackoverflow.com/questions/9439256/how-can-i-handle-r-cmd-check-no-visible-binding-for-global-variable-notes-when see https://github.com/HughParsonage/grattan/blob/master/R/zzz.R
Unfortunate note on specific flavors
After first submission there are some notes on specific R flavors
This question was addressed here but yet it’s not answered: https://stackoverflow.com/questions/48487541/r-cmd-check-note-namespace-in-imports-field-not-imported
Define min R version
When functions are writing to the file
It’s important to avoid that function write to the directory other then
tempdir()
Construct file name must be done using file.name()
function as follow:
dir_name <- normalizePath(tempdir(),winslash = "/")
file_name <- paste0('my_file', 1, '.csv')
# this needs to be used in the function
full_path <- file.path(dir_name, file_name)
Versioning of the package
http://r-pkgs.had.co.nz/description.html#version
..
Test Environments
Clone package from GitHub and test check it in Docker Container
- started docker container vladdsm/docker-r-studio
- new project package
- clone from vzhomeexperiments/lazytrade.git
- use check button to pass the test
Build package
devtools::build()
Adding Readme Rmd
usethis::use_readme_rmd()
Automatic check with Travis
usethis::use_travis()
Upload package to CRAN
Setup the new version of the package:
usethis::use_release_issue()
Follow checklist before upload to CRAN:
devtools::release_checks()
then:
devtools::release()
before release checks
spelling devtools::spell_check()
checking on R hub devtools::check_rhub(interactive = F)
checking win devel devtools::check_win_devel()
checking win old devel devtools::check_win_oldrelease()
check with rocker R in container - use docker image with R Studio, - clone repo, build, check package…
Update news.md file