рдирд┐рд░рдкреЗрдХреНрд╖ рджрд░ рдкрд░рд┐рдХрд▓реНрдкрдирд╛ рдХреА рдореЗрд░реА рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рдкрд░реАрдХреНрд╖рд╛

рдирдорд╕реНрдХрд╛рд░, рд╣реЗрдмреНрд░!

рдпрд╣ рдкреНрд░рдХрд╛рд╢рди рдореЗрд░реЗ рд▓рд┐рдП рджрд┐рд▓рдЪрд╕реНрдк рд▓рдЧ рд░рд╣рд╛ рдерд╛: рд╣рдо рдпреБрдЧреНрдорд┐рдд рдХреНрд░реЙрд╕-рдХрд░реЗрдВрд╕реА рд╡рд┐рдирд┐рдордп рджрд░реЛрдВ рд╕реЗ рдкреВрд░реНрдг рд╡рд┐рдирд┐рдордп рджрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдореИрдВ рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рдореЙрдбрд▓рд┐рдВрдЧ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЗрд╕ рдЖрд╣рд╛рдмрд╕реЙрд▓реНрдм рд╡рд┐рдирд┐рдордп рджрд░ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рдЖрдорддреМрд░ рдкрд░ рд░реИрдЦрд┐рдХ рдмреАрдЬрдЧрдгрд┐рдд рдХреЛ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реВрдВред



рдкрд░рд┐рдгрд╛рдо рджрд┐рд▓рдЪрд╕реНрдк рдереЗред

рдкреНрд░рдпреЛрдЧ рдЫреЛрдЯрд╛ рд╣реЛрдЧрд╛: 4 рдореБрджреНрд░рд╛рдПрдБ, 6 рдореБрджреНрд░рд╛ рдЬреЛрдбрд╝реЗред рдкреНрд░рддреНрдпреЗрдХ рдЬреЛрдбрд╝реА рдХреЗ рд▓рд┐рдП, рдПрдХ рдкрд╛рдареНрдпрдХреНрд░рдо рдорд╛рдкред

рддреЛ рдЪрд▓рд┐рдП рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ


рдкрд░рд┐рдХрд▓реНрдкрдирд╛ рдпрд╣ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рднреА рдореБрджреНрд░рд╛ рдХреЗ рдореВрд▓реНрдп рдХреЛ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдореВрд▓реНрдп рдХреЗ рд╕рд╛рде рд╡реНрдпрдХреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдЕрдиреНрдп рдореБрджреНрд░рд╛рдУрдВ рдХреЗ рдореВрд▓реНрдп рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦреЗрдЧрд╛ рдЬрд┐рд╕рдореЗрдВ рдЗрд╕реЗ рдЙрджреНрдзреГрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрдмрдХрд┐ рдЕрдиреНрдп рдореБрджреНрд░рд╛рдУрдВ рдХреЛ рд╕реНрд╡рдпрдВ рдЕрдиреНрдп рд╕рднреА рдореБрджреНрд░рд╛рдУрдВ рдХреЗ рдореВрд▓реНрдп рдореЗрдВ рд╡реНрдпрдХреНрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдпрд╣ рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдкреБрдирд░рд╛рд╡рд░реНрддреА рдХрд╛рд░реНрдп рд╣реИред

4 рдореБрджреНрд░рд╛рдПрдБ рд╣реИрдВ:

  • рдЕрдорд░реАрдХреА рдбрд╛рд▓рд░
  • eur
  • CHF
  • gbp

рдЙрдирдХреЗ рд▓рд┐рдП, рдореБрджреНрд░рд╛ рдЬреЛрдбрд╝реЗ рдбрд╛рдпрд▓ рдХрд┐рдП рдЧрдП рдереЗ:

  • EURUSD
  • GBPUSD
  • EURCHF
  • EURGBP
  • gbpchf
  • USDCHF

рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрджрд┐ рдореБрджреНрд░рд╛рдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ n = 4 рд╣реИ, рддреЛ рдпреБрдЧреНрдореЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ k = (n ^ 2 - n) / 2 = 6. рд╣реИ рдпрджрд┐ рдпреВрд░реЗрд╢реНрдб рдХреЛ рдЙрджреНрдзреГрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рддреЛ usdeur рдХреЛ рджреЗрдЦрдиреЗ рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИ ...

рд╕рдордп рдЯреА, рдкреНрд░рджрд╛рддрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреА рд╡рд┐рдирд┐рдордп рджрд░ рдХреЛ рдорд╛рдкрд╛ рдЧрдпрд╛ рдерд╛:



рдЗрди рдореВрд▓реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЧрдгрдирд╛ рдХреА рдЬрд╛рдПрдЧреАред

рдЧрдгрд┐рдд


рдореИрдВ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╡рд┐рд╢реНрд▓реЗрд╖рдгрд╛рддреНрдордХ рд░реВрдк рд╕реЗ рдиреБрдХрд╕рд╛рди рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЧреНрд░реЗрдбрд┐рдПрдВрдЯ рд▓реЗрддреЗ рд╣реБрдП рд╣рд▓ рдХрд░рддрд╛ рд╣реВрдВ, рдЬреЛ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рд╕рдореАрдХрд░рдгреЛрдВ рдХреА рдПрдХ рдкреНрд░рдгрд╛рд▓реА рд╣реИред

рдкреНрд░рдпреЛрдЧ рдХреЛрдб R рдореЗрдВ рд╣реЛрдЧрд╛:

#set.seed(111) usd <- runif(1) eur <- runif(1) chf <- runif(1) gbp <- runif(1) # snapshot of values at time t eurusd <- 1.12012 gbpusd <- 1.30890 eurchf <- 1.14135 eurgbp <- 0.85570 gbpchf <- 1.33373 usdchf <- 1.01896 ## symbolic task ------------ express <- expression( (eurusd - eur / usd) ^ 2 + (gbpusd - gbp / usd) ^ 2 + (eurchf - eur / chf) ^ 2 + (eurgbp - eur / gbp) ^ 2 + (gbpchf - gbp / chf) ^ 2 + (usdchf - usd / chf) ^ 2 ) eval(express) x = 'usd' D(express, x) eval(D(express, x)) 

R рдХрд┐рд╕реА рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд╡реНрдпреБрддреНрдкрдиреНрди рд▓реЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдБрдХрдбрд╝реЗ :: D рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рд╣рдо USD рдореБрджреНрд░рд╛ рджреНрд╡рд╛рд░рд╛ рдЕрдВрддрд░ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдорд┐рд▓рддреА рд╣реИ:
2 * (eur / usd ^ 2 * (eurusd - eur / usd)) + 2 * (gbp / usd ^ 2 * (gbpusd -)
gbp / usd)) - 2 * (1 / chf * (usdchf - usd / chf))
рдПрдХреНрд╕рдкреНрд░реЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдореВрд▓реНрдп рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдврд╛рд▓ рдореВрд▓ рдкреНрд░рджрд░реНрд╢рди рдХрд░реЗрдВрдЧреЗ рдФрд░ рдпрд╣ рддреБрд░рдВрдд рд╕реНрдкрд╖реНрдЯ рд╣реИ (рд╣рдо рд╡рд░реНрдЧ рдЕрдВрддрд░ рджреЗрдЦрддреЗ рд╣реИрдВ) рдХрд┐ рдиреНрдпреВрдирддрдо рдореВрд▓реНрдп рд╢реВрдиреНрдп рд╣реЛрдЧрд╛, рдЬреЛ рдХрд┐ рд╣рдореЗрдВ рдЪрд╛рд╣рд┐рдПред

 -deriv_vals * lr 

рдЧреНрд░реЗрдбрд┐рдПрдВрдЯ рдбрд┐рд╕реЗрдВрдЯ рд╕реНрдЯреЗрдк рдХреЛ рдкреИрд░рд╛рдореАрдЯрд░ lr рджреНрд╡рд╛рд░рд╛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдпрд╣ рд╕рдм рдПрдХ рдирдХрд╛рд░рд╛рддреНрдордХ рд╕рдВрдХреЗрдд рдХреЗ рд╕рд╛рде рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

рдпрд╣реА рд╣реИ, рдорд╛рдирд╡ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рд╣рдо 4 рдореБрджреНрд░рд╛рдУрдВ рдХреА рджрд░реЛрдВ рдХрд╛ рдЪрдпрди рдХрд░рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдкреНрд░рдпреЛрдЧ рдореЗрдВ рд╕рднреА рдореБрджреНрд░рд╛ рдЬреЛрдбрд╝реЗ рдЗрди рдЬреЛрдбрд╝реЛрдВ рдХреЗ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдореВрд▓реНрдпреЛрдВ рдХреЗ рдмрд░рд╛рдмрд░ рдореВрд▓реНрдп рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред рдордореНрдо, рдЪрд▓реЛ рдкрд╣реЗрд▓реА рдХреЛ рд╣рд▓ рдХрд░реЗрдВ - рдорд╛рдереЗ рдореЗрдВ!

рдкрд░рд┐рдгрд╛рдо


рдЦрд┐рдВрдЪрд╛рд╡ рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ рддреБрд░рдВрдд рдЖрдкрдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЬрд╛рдирдХрд╛рд░реА рджреВрдВрдЧрд╛: рдПрдХ рдкреВрд░реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рдпреЛрдЧ рд╕рдлрд▓ рд░рд╣рд╛, рдХреЛрдб рдиреЗ рдХрд╛рдо рдХрд┐рдпрд╛, рддреНрд░реБрдЯрд┐ рдХрд░реАрдм рдЧрдИ, рд╢реВрдиреНрдп рдХреЗ рдХрд░реАрдмред рд▓реЗрдХрд┐рди рдлрд┐рд░ рдореИрдВрдиреЗ рджреЗрдЦрд╛ рдХрд┐ рдкрд░рд┐рдгрд╛рдо рд╣рдореЗрд╢рд╛ рдЕрд▓рдЧ рд╣реЛрддреЗ рд╣реИрдВред

рдкрд╛рд░рдЦреА рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╡рд╛рд▓: рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдХрд╛рд░реНрдп рдореЗрдВ рдЕрд╕реАрдорд┐рдд рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╕рдорд╛рдзрд╛рди рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕рдореЗрдВ рдореИрдВ рдПрдХ рдкреВрд░реНрдг рд╢реВрдиреНрдп рд╣реВрдВ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╡реЗ рдореБрдЭреЗ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдмрддрд╛рдПрдВрдЧреЗред

рд╕рдорд╛рдзрд╛рди рдХреА (рдЕрди) рд╕реНрдерд┐рд░рддрд╛ рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдореБрджреНрд░рд╛ рдореВрд▓реНрдпреЛрдВ рдХреЗ рд╢реБрд░реБрдЖрддреА рдореВрд▓реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП PRNG рдмреАрдЬ рдХреЛ рдареАрдХ рдХрд┐рдП рдмрд┐рдирд╛ 1000 рдмрд╛рд░ рдЕрдиреБрдХрд░рдг рдХрд┐рдпрд╛ред

рдФрд░ рдпрд╣рд╛рдВ рдХрд╛рдЯрд╛ рд╕реЗ рдЪрд┐рддреНрд░ рдЖрддрд╛ рд╣реИ: рддреНрд░реБрдЯрд┐ 0.00001 рддрдХ рдкрд╣реБрдВрдЪрддреА рд╣реИ рдФрд░ рдХрдо (рдЕрдиреБрдХреВрд▓рди рдЗрд╕ рддрд░рд╣ рд╕реЗ рд╕реЗрдЯ рд╣реЛрддрд╛ рд╣реИ) рд╣рдореЗрд╢рд╛, рдЬрдмрдХрд┐ рдореБрджреНрд░рд╛рдУрдВ рдХреЗ рдореВрд▓реНрдп рд╢реИрддрд╛рди рдХреЛ рддреИрд░рддреЗ рд╣реИрдВ, рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдХрд╣рд╛рдВред рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рд╣рдореЗрд╢рд╛ рдПрдХ рдЕрд▓рдЧ рдирд┐рд░реНрдгрдп рд╣реЛрддрд╛ рд╣реИ, рд╕рдЬреНрдЬрдиреЛрдВ!

рдПрдХ рдмрд╛рд░ рдлрд┐рд░, рдпрд╣ рдЪрд┐рддреНрд░, рдореВрд▓ рдЗрдХрд╛рдЗрдпреЛрдВ рдореЗрдВ y- рдЕрдХреНрд╖ (рд▓реЙрдЧ рдирд╣реАрдВ рд╣реИред):



рддрд╛рдХрд┐ рдЖрдк рдЗрд╕реЗ рджреЛрд╣рд░рд╛ рд╕рдХреЗрдВ, рдиреАрдЪреЗ рдореИрдВ рдкреВрд░реНрдг рдХреЛрдб рд╕рдВрд▓рдЧреНрди рдХрд░ рд░рд╣рд╛ рд╣реВрдВред

рдХреЛрдб
 # clear environment rm(list = ls()); gc() ## load libs library(data.table) library(ggplot2) library(magrittr) ## set WD -------------------------------- # your dir here ... ## set vars ------------- currs <- c( 'usd', 'eur', 'chf', 'gbp' ) ############ ## RUN SIMULATION LOOP ------------------------------- simuls <- 1000L simul_dt <- data.table() for( s in seq_len(simuls) ) { #set.seed(111) usd <- runif(1) eur <- runif(1) chf <- runif(1) gbp <- runif(1) # snapshot of values at time t eurusd <- 1.12012 gbpusd <- 1.30890 eurchf <- 1.14135 eurgbp <- 0.85570 gbpchf <- 1.33373 usdchf <- 1.01896 ## symbolic task ------------ express <- expression( (eurusd - eur / usd) ^ 2 + (gbpusd - gbp / usd) ^ 2 + (eurchf - eur / chf) ^ 2 + (eurgbp - eur / gbp) ^ 2 + (gbpchf - gbp / chf) ^ 2 + (usdchf - usd / chf) ^ 2 ) ## define gradient and iterate to make descent to zero -------------- iter_max <- 1e+3 lr <- 1e-3 min_tolerance <- 0.00001 rm(grad_desc_func) grad_desc_func <- function( lr, curr_list ) { derivs <- character(length(curr_list)) deriv_vals <- numeric(length(curr_list)) grads <- numeric(length(curr_list)) # symbolic derivatives derivs <- sapply( curr_list, function(x){ D(express, x) } ) # derivative values deriv_vals <- sapply( derivs, function(x){ eval(x) } ) # gradient change values -deriv_vals * lr } ## get gradient values ---------- progress_list <- list() for( i in seq_len(iter_max) ) { grad_deltas <- grad_desc_func(lr, curr_list = currs) currency_vals <- sapply( currs , function(x) { # update currency values current_val <- get(x, envir = .GlobalEnv) new_delta <- grad_deltas[x] if(new_delta > -1 & new_delta < 1) { new_delta = new_delta } else { new_delta = sign(new_delta) } new_val <- current_val + new_delta if(new_val > 0 & new_val < 2) { new_val = new_val } else { new_val = current_val } names(new_val) <- NULL # change values of currencies by gradient descent step in global env assign(x, new_val , envir = .GlobalEnv) # save history of values for later plotting new_val } ) progress_list[[i]] <- c( currency_vals, eval(express) ) if( eval(express) < min_tolerance ) { break('solution was found') } } ## check results ---------- # print( # paste0( # 'Final error: ' # , round(eval(express), 5) # ) # ) # # print( # round(unlist(mget(currs)), 5) # ) progress_dt <- rbindlist( lapply( progress_list , function(x) { as.data.frame(t(x)) } ) ) colnames(progress_dt)[length(colnames(progress_dt))] <- 'error' progress_dt[, steps := 1:nrow(progress_dt)] progress_dt_melt <- melt( progress_dt , id.vars = 'steps' , measure.vars = colnames(progress_dt)[colnames(progress_dt) != 'steps'] ) progress_dt_melt[, simul := s] simul_dt <- rbind( simul_dt , progress_dt_melt ) } ggplot(data = simul_dt) + facet_wrap(~ variable, scales = 'free') + geom_line( aes( x = steps , y = value , group = simul , color = simul ) ) + scale_y_log10() + theme_minimal() 


1000 рд╕рд┐рдореБрд▓реЗрд╢рди рдХреЗ рд▓рд┐рдП рдХреЛрдб рд▓рдЧрднрдЧ рдПрдХ рдорд┐рдирдЯ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рдирд┐рд╖реНрдХрд░реНрд╖


рдпрд╣рд╛рдБ рдореЗрд░реЗ рд▓рд┐рдП рдЕрд╕реНрдкрд╖реНрдЯ рд╣реИ:

  • рдХреНрдпрд╛ рдпрд╣ рдореБрд╢реНрдХрд┐рд▓ рдЧрдгрд┐рддреАрдп рддрд░реАрдХреЗ рд╕реЗ рд╕рдорд╛рдзрд╛рди рдХреЛ рд╕реНрдерд┐рд░ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ;
  • рдХреНрдпрд╛ рдЕрдзрд┐рдХ рдореБрджреНрд░рд╛рдУрдВ рдФрд░ рдореБрджреНрд░рд╛ рдЬреЛрдбрд╝реЗ рдХреЗ рд╕рд╛рде рдЕрднрд┐рд╕рд░рдг рд╣реЛрдЧрд╛;
  • рдпрджрд┐ рдХреЛрдИ рд╕реНрдерд┐рд░рддрд╛ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреА рд╣реИ, рддреЛ рдкреНрд░рддреНрдпреЗрдХ рдирдП рдбреЗрдЯрд╛ рд╕реНрдиреИрдкрд╢реЙрдЯ рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реА рдореБрджреНрд░рд╛рдПрдВ рдЪрд▓реЗрдВрдЧреА рдЬреИрд╕реЗ рд╡реЗ, рдпрджрд┐ рдЖрдк PRNG рдмреАрдЬ рдХреЛ рдареАрдХ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣ рдПрдХ рд╡рд┐рдлрд▓рддрд╛ рд╣реИред

рд╕рдВрдкреВрд░реНрдг рд╡рд┐рдЪрд╛рд░ рдХрд┐рд╕реА рднреА рдмреБрджреНрдзрд┐рдорд╛рди рдкреВрд░реНрд╡рд╛рдкреЗрдХреНрд╖рд╛ рдФрд░ рд╕реАрдорд╛рдУрдВ рдХреЗ рдЕрднрд╛рд╡ рдореЗрдВ рдмрд╣реБрдд рдЕрд╕реНрдкрд╖реНрдЯ рд▓рдЧрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдпрд╣ рджрд┐рд▓рдЪрд╕реНрдк рдерд╛!

рд╡реИрд╕реЗ, рдореИрдВ рдпрд╣ рднреА рдХрд╣рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдХрд┐ рдЬрдм рдбреЗрдЯрд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ, рддреЛ рдЖрдк рдУрдПрд▓рдПрд╕ рдХреЗ рдмрд┐рдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдореЗрдЯреНрд░рд┐рдХреНрд╕ рдПрдХрд╡рдЪрди рд╣реИрдВ, рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ, рдпрд╛ рдЬрдм рд╕рд┐рджреНрдзрд╛рдВрдд рдЦрд░рд╛рдм рдЬреНрдЮрд╛рдд рд╣реИ (рдПрд╣ ...)ред

рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕рдВрджреЗрд╢ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж eavprog ред

рдЕрд▓рд╡рд┐рджрд╛!

Source: https://habr.com/ru/post/hi450874/


All Articles