Machine learning in trading: theory, models, practice and algo-trading - page 2103

 
Vladimir Perervenko:

Do you happen to have a function that calculates both the net worth and the commission?

 
mytarmailS:

And you do not have by any chance a function which counts and equities and commission?

Language, exchange, forex? I don't know what you mean.

 
Vladimir Perervenko:

Language, Stock Exchange, Forex? I don't know what that means.

R-ka, forex.

Well a function that would calculate the balance chart for trades + commission\spread (costs)

I wrote this, I don't know if it's correct

calc.balance <- function(sig,x, comision=0){
sig <- ifelse(sig>0, 1, -1)

trades.count <- length(rle(c(sig))$values) # сколько было сделок
comis <- comision*trades.count


sig <- na.omit(  dplyr::lag(sig)  )
dC <- c(NA, diff(x))
bal <- cumsum(sig * tail(dC, length(sig) )   )

bal <- bal-comis
return(bal)}

 

Example of R script that uses "MetaTrader5" (Python) package to load quotes. The "reticulate" library must be installed in R. This library provides interaction with Python. Read carefully here and here. The first time you run the reticulate library you will be offered to install miniconda. I recommend that you do not refuse. This will create the conda environment r-reticulate with python(3.6.xx) and an initial set of packages installed. If you have already installed Pyhon (or several versions) at the beginning of the script you should activate required environment. All commands of MetaTrader5 package are here.

Initialization script

#---необходимые константы------------------
sym <- "Si-12.20"
#TERMINAL_PATH <- "C:/Program Files/.../terminal64.exe"
# server <- "Open-Broker"
# login <- xxxxxx
bar <- 6000 L
tf <- 3 L
ch <- 15 L
# TP <-5
# SL <-
# lot <- 1.0
# magik <-
#----------------------------------
require(reticulate)
#----Connect terminal(Python)-------------------
mt5 <- import('MetaTrader5')

if(!mt5$initialize())
    print("initialize() failed, error code =", mt5$last_error())


termInfo <- mt5$terminal_info()
termInfo$data_path -> dataPath
termInfo$name -> broker

#termInfo$trade_allowed
#termInfo$connected

AccInfo <- mt5$account_info()
AccInfo$login -> login
AccInfo$server -> server
AccInfo$balance -> start_balance
AccInfo$equity -> start_equity
AccInfo$profit -> profit

selected = mt5$symbol_select(sym,TRUE)
if(!selected){
    print("Failed to select ", sym, ", error code =", mt5$last_error())
    mt5$shutdown()
    quit()
}

SymInfo = mt5$symbol_info(sym)
SymInfo$digits -> Dig


To download quotes we will write the function

#---Function-------------------------------
GetCotirPy <- function(sym){
    selected = mt5$symbol_select(sym,TRUE)
    if (selected)
        py_run_string("
import pandas as pd
import MetaTrader5 as mt5
rates = pd.DataFrame(mt5.copy_rates_from_pos(r.sym, r.tf, 1, r.bar))"
        )
    return(py$rates)
}

Let's see the structure of obtained data.

rates <- GetCotirPy(sym = sym)
str(rates)
'data.frame':   6000 obs. of  8 variables:
 $ time       : num  1.6e+09 1.6e+09 1.6e+09 1.6e+09 1.6e+09 ...
 $ open       : num  77498 77504 77511 77528 77553 ...
 $ high       : num  77520 77561 77555 77560 77578 ...
 $ low        : num  77472 77504 77500 77521 77537 ...
 $ close      : num  77502 77511 77528 77553 77564 ...
 $ tick_volume: num  2748 3934 1984 1459 2452 ...
 $ spread     : int  1 1 1 1 1 1 1 1 1 1 ...
 $ real_volume: num  11540 21547 8953 6521 14932 ...
 - attr(*, "pandas.index")=RangeIndex(start=0, stop=6000, step=1)

Next, the necessary calculations.

reticulate 1.14
  • blog.rstudio.com
We’re excited to announce that 1.14 is now available on CRAN! You can install it with: With this release, we are introducing a major new feature: can now automatically configure a Python environment for the user, in coordination with any loaded R packages that depend on . This means that: Ultimately, the goal is for R packages using to be able...
 
mytarmailS:

R-card, forex.

Well, a function that would calculate the balance chart for trades + commission/spread (costs)

wrote this, I do not know if this is right


I do not understand here

trades.count <- length(rle(c(sig))$values) #  сколько было сделок
 
mytarmailS:

R-card, forex.

Well, a function that would calculate the balance chart for trades + commission/spread (costs)

wrote this, I do not know if it is correct


I think that the number of deals should not be counted here. And just subtract spread with commission from each deal. That's how it is:

calc.balance <- function(sig,x, comision=0){
sig <- ifelse(sig>0, 1, -1)


sig <- na.omit(  dplyr::lag(sig)  )
dC <- c(NA, diff(x))
bal <- cumsum(sig * tail(dC, length(sig) )   )

bal <- bal-comision
return(bal)}
 
elibrarius:

I think that the number of deals does not need to be counted here. And just subtract the spread with the commission from each deal. That's the way it is:

Not like that. For example

sig<- rep(c(1,1,1,1,1,-1,-1,-1,-1), 100)
length(sig)
[1] 900

The commission will not be charged for each signal, but only when the signal is reversed. I use the function

cnt<-function(x){
    n <- 1:(length(x)-1)
    cnt <- 0
    for(i in n) {if(x[i]!=x[i+1]) {cnt<-cnt+1}}
    return(cnt)
}

For the signal vector above

cnt(sig)
[1] 199
length(rle(c(sig))$values)
[1] 200

The difference is not clear.

And for calculating the balance the function

test_bal <- function(sig, CO){
    import::here(poorman, Lag = lag)
    import::here(.from = fTrading, maxDrawDown)
    sig %>%  Lag() %>% na.omit()->sig
    CO %>% tail(length(sig))-> CO
    bal <- cumsum(CO * sig)
    K <- (last(bal)/length(bal) * 10^Dig)%>% round()
    Kmax <- max(bal)/which.max(bal) * 10^Dig %>% round()
    dd <- maxDrawDown(bal)[[1]] %>% round()
    op <-cnt(sig)
    tst<-list(bal = bal, k = K, k.max = Kmax, op = op, dd = dd)
    return(tst)
}

Good luck

 
Vladimir Perervenko:

I don't get it here.

c "rle" you can count the number of signal changes, those number of deals

 sig <- c(1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1)
> sig
 [1] 1 1 1 1 1 0 0 0 0 1 1 1 0 0 0 0 1 1 1
> rle(sig)
Run Length Encoding
  lengths: int [1:5] 5 4 3 4 3
  values : num [1:5] 1 0 1 0 1

You can see by "values" that the signal changed 5 times, it means that there were 5 deals.

Vladimir Perervenko:

I do not understand the difference.

I think my implementation takes into account commission as if "of the first trade, the opening of which we don't have, there is only the closing"

 sig <- c(1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1)

 [1] 1 1 1 1 1 0 0 0 0 1 1 1 0 0 0 0 1 1 1

Like for this deal, my variant takes a commission

and your version starts charging this one, your version is more correct, but it's easy to correct, just subtract "1"

 sig <- c(1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1)
> sig
 [1] 1 1 1 1 1 0 0 0 0 1 1 1 0 0 0 0 1 1 1
 
Vladimir Perervenko:

Example script in R using ...

Thanks, I will look into it

 
mytarmailS:

With "rle" you can calculate the number of signal changes, i.e. number of deals

It is clear from "values" that the signal changed 5 times, so there were 5 trades.

I think my implementation also takes into account the commission and as "the first trade, the opening of which we do not have, there is only the closing"

like for this deal, my variant takes a commission

and your version starts to take this one, your version is more correct, but it's easy to correct, just do, just subtract "1"

Yes, your version is more correct.

Reason: