Làm cách nào để thay thế Quantstrat 'for loop' bằng mclapply [được song song hóa]?
Tôi muốn song song hóa lượng tử. Mã của tôi không chính xác như thế này, nhưng điều này cho thấy vấn đề. Vấn đề mà tôi tin là .blotter env được khởi tạo thành địa chỉ bộ nhớ con trỏ và tôi không thể khởi tạo mảng / ma trận new.env ().
Những gì tôi muốn làm là thay thế vòng lặp for bằng một mclapply để tôi có thể chạy nhiều applyStrategies với các ngày / ký hiệu khác nhau (chỉ các ký hiệu khác nhau được hiển thị ở đây). Mục tiêu cuối cùng của tôi là một cụm beowulf (makeCluster) và dự định chạy chúng song song trong tối đa 252 ngày giao dịch (cửa sổ luân phiên) với các ký hiệu khác nhau cho mỗi lần lặp (nhưng tôi không cần tất cả những điều đó. Tôi chỉ đơn giản hỏi nếu có cách làm việc với việc gán danh mục đầu tư và đối tượng bộ nhớ .blotter tiếp theo theo cách mà tôi có thể sử dụng mclapply)
#Load quantstrat in your R environment.
rm(list = ls())
local()
library(quantstrat)
library(parallel)
# The search command lists all attached packages.
search()
symbolstring1 <- c('QQQ','GOOG')
#symbolstring <- c('QQQ','GOOG')
#for(i in 1:length(symbolstring1))
mlapply(symbolstring1, function(symbolstring)
{
#local()
#i=2
#symbolstring=as.character(symbolstring1[i])
.blotter <- new.env()
.strategy <- new.env()
try(rm.strat(strategyName),silent=TRUE)
try(rm(envir=FinancialInstrument:::.instrument),silent=TRUE)
for (name in ls(FinancialInstrument:::.instrument)){rm_instruments(name,keep.currencies = FALSE)}
print(symbolstring)
currency('USD')
stock(symbolstring,currency='USD',multiplier=1)
# Currency and trading instrument objects stored in the
# .instrument environment
print("FI")
ls(envir=FinancialInstrument:::.instrument)
# blotter functions used for instrument initialization
# quantstrat creates a private storage area called .strategy
ls(all=T)
# The initDate should be lower than the startDate. The initDate will be used later while initializing the strategy.
initDate <- '2010-01-01'
startDate <- '2011-01-01'
endDate <- '2019-08-10'
init_equity <- 50000
# Set UTC TIME
Sys.setenv(TZ="UTC")
getSymbols(symbolstring,from=startDate,to=endDate,adjust=TRUE,src='yahoo')
# Define names for portfolio, account and strategy.
#portfolioName <- accountName <- strategyName <- "FirstPortfolio"
portfolioName <- accountName <- strategyName <- paste0("FirstPortfolio",symbolstring)
print(portfolioName)
# The function rm.strat removes any strategy, portfolio, account, or order book object with the given name. This is important
#rm.strat(strategyName)
print("port")
initPortf(name = portfolioName,
symbols = symbolstring,
initDate = initDate)
initAcct(name = accountName,
portfolios = portfolioName,
initDate = initDate,
initEq = init_equity)
initOrders(portfolio = portfolioName,
symbols = symbolstring,
initDate = initDate)
# name: the string name of the strategy
# assets: optional list of assets to apply the strategy to.
# Normally these are defined in the portfolio object
# contstrains: optional portfolio constraints
# store: can be True or False. If True store the strategy in the environment. Default is False
print("strat")
strategy(strategyName, store = TRUE)
ls(all=T)
# .blotter holds the portfolio and account object
ls(.blotter)
# .strategy holds the orderbook and strategy object
print(ls(.strategy))
print("ind")
add.indicator(strategy = strategyName,
name = "EMA",
arguments = list(x = quote(Cl(mktdata)),
n = 10), label = "nFast")
add.indicator(strategy = strategyName,
name = "EMA",
arguments = list(x = quote(Cl(mktdata)),
n = 30),
label = "nSlow")
# Add long signal when the fast EMA crosses over slow EMA.
print("sig")
add.signal(strategy = strategyName,
name="sigCrossover",
arguments = list(columns = c("nFast", "nSlow"),
relationship = "gte"),
label = "longSignal")
# Add short signal when the fast EMA goes below slow EMA.
add.signal(strategy = strategyName,
name = "sigCrossover",
arguments = list(columns = c("nFast", "nSlow"),
relationship = "lt"),
label = "shortSignal")
# go long when 10-period EMA (nFast) >= 30-period EMA (nSlow)
print("rul")
add.rule(strategyName,
name= "ruleSignal",
arguments=list(sigcol="longSignal",
sigval=TRUE,
orderqty=100,
ordertype="market",
orderside="long",
replace = TRUE,
TxnFees = -10),
type="enter",
label="EnterLong")
# go short when 10-period EMA (nFast) < 30-period EMA (nSlow)
add.rule(strategyName,
name = "ruleSignal",
arguments = list(sigcol = "shortSignal",
sigval = TRUE,
orderside = "short",
ordertype = "market",
orderqty = -100,
TxnFees = -10,
replace = TRUE),
type = "enter",
label = "EnterShort")
# Close long positions when the shortSignal column is True
add.rule(strategyName,
name = "ruleSignal",
arguments = list(sigcol = "shortSignal",
sigval = TRUE,
orderside = "long",
ordertype = "market",
orderqty = "all",
TxnFees = -10,
replace = TRUE),
type = "exit",
label = "ExitLong")
# Close Short positions when the longSignal column is True
add.rule(strategyName,
name = "ruleSignal",
arguments = list(sigcol = "longSignal",
sigval = TRUE,
orderside = "short",
ordertype = "market",
orderqty = "all",
TxnFees = -10,
replace = TRUE),
type = "exit",
label = "ExitShort")
print("summary")
summary(getStrategy(strategyName))
# Summary results are produced below
print("results")
results <- applyStrategy(strategy= strategyName, portfolios = portfolioName,symbols=symbolstring)
# The applyStrategy() outputs all transactions(from the oldest to recent transactions)that the strategy sends. The first few rows of the applyStrategy() output are shown below
getTxns(Portfolio=portfolioName, Symbol=symbolstring)
mktdata
updatePortf(portfolioName)
dateRange <- time(getPortfolio(portfolioName)$summary)[-1] updateAcct(portfolioName,dateRange) updateEndEq(accountName) print(plot(tail(getAccount(portfolioName)$summary$End.Eq,-1), main = "Portfolio Equity"))
#cleanup
for (name in symbolstring) rm(list = name)
#rm(.blotter)
rm(.stoploss)
rm(.txnfees)
#rm(.strategy)
rm(symbols)
}
)
Nhưng một lỗi được đưa ra Lỗi trong get (biểu tượng, envir = envir): không tìm thấy đối tượng 'QQQ'
Cụ thể, vấn đề là công cụ FinancialInticment :::. Đang trỏ đến một địa chỉ bộ nhớ không được cập nhật với các lệnh gọi biến đóng gói của tôi (chuỗi biểu tượng)
Trả lời
apply.paramset
trong quantstrat
đã sử dụng một foreach
cấu trúc để song song hóa việc thực thi applyStrategy
.
apply.paramset
cần phải thực hiện một lượng công việc hợp lý để đảm bảo rằng các môi trường có sẵn cho người lao động để thực hiện công việc và thu thập các kết quả thích hợp để gửi họ trở lại quy trình kêu gọi.
Điều đơn giản nhất để bạn có thể làm là sử dụng apply.paramset
. Tạo các thông số ngày tháng và ký hiệu của bạn và để chức năng chạy bình thường.
Ngoài ra, tôi khuyên bạn nên xem các bước cần thiết để sử dụng foreach
cấu trúc song song apply.paramset
để sửa đổi nó cho phù hợp với trường hợp bạn đề xuất.
Cũng lưu ý rằng câu hỏi của bạn hỏi về việc sử dụng cụm Beowulf và mclapply
. Điều này sẽ không hoạt động. mclapply
chỉ hoạt động trong một không gian bộ nhớ duy nhất. Các cụm Beowulf thường không chia sẻ một bộ nhớ và không gian xử lý. Họ thường phân phối công việc thông qua các thư viện song song như MPI. apply.paramset
đã có thể phân phối trên một cụm Beowulf bằng cách sử dụng chương trình doMPI
phụ trợ cho foreach
. Đó là một trong những lý do chúng tôi sử dụng foreach
: vô số các phụ trợ song song khác nhau có sẵn. Phần doMC
phụ trợ foreach
thực sự sử dụng mclapply
đằng sau hậu trường.
Tôi tin rằng điều này song song với mã. Tôi đã hoán đổi các chỉ báo cũng như các ký hiệu, nhưng logic của việc sử dụng các ký hiệu và ngày tháng khác nhau là ở đó
Về cơ bản tôi đã thêm
Dates=paste0(startDate,"::",endDate)
rm(list = ls())
library(lubridate)
library(parallel)
autoregressor1 = function(x){
if(NROW(x)<12){ result = NA} else{
y = Vo(x)*Ad(x)
#y = ROC(Ad(x))
y = ROC(y)
y = na.omit(y)
step1 = ar.yw(y)
step2 = predict(step1,newdata=y,n.ahead=1)
step3 = step2$pred[1]+1 step4 = (step3*last(Ad(x))) - last(Ad(x)) result = step4 } return(result) } autoregressor = function(x){ ans = rollapply(x,26,FUN = autoregressor1,by.column=FALSE) return (ans)} ########################indicators############################# library(quantstrat) library(future.apply) library(scorecard) reset_quantstrat <- function() { if (! exists(".strategy")) .strategy <<- new.env(parent = .GlobalEnv) if (! exists(".blotter")) .blotter <<- new.env(parent = .GlobalEnv) if (! exists(".audit")) .audit <<- new.env(parent = .GlobalEnv) suppressWarnings(rm(list = ls(.strategy), pos = .strategy)) suppressWarnings(rm(list = ls(.blotter), pos = .blotter)) suppressWarnings(rm(list = ls(.audit), pos = .audit)) FinancialInstrument::currency("USD") } reset_quantstrat() initDate <- '2010-01-01' endDate <- as.Date(Sys.Date()) startDate <- endDate %m-% years(3) symbolstring1 <- c('SSO','GOLD') getSymbols(symbolstring1,from=startDate,to=endDate,adjust=TRUE,src='yahoo') #symbolstring1 <- c('SP500TR','GOOG') .orderqty <- 1 .txnfees <- 0 #random <- sample(1:2, 2, replace=FALSE) random <- (1:2) equity <- lapply(random, function(x) {#x=1 try(rm("account.Snazzy","portfolio.Snazzy",pos=.GlobalEnv$.blotter),silent=TRUE)
rm(.blotter)
rm(.strategy)
portfolioName <- accountName <- strategyName <- paste0("FirstPortfolio",x+2)
#endDate <- as.Date(Sys.Date())
startDate <- endDate %m-% years(1+x)
#Load quantstrat in your R environment.
reset_quantstrat()
# The search command lists all attached packages.
search()
symbolstring=as.character(symbolstring1[x])
print(symbolstring)
try(rm.strat(strategyName),silent=TRUE)
try(rm(envir=FinancialInstrument:::.instrument),silent=TRUE)
for (name in ls(FinancialInstrument:::.instrument)){rm_instruments(name,keep.currencies = FALSE)}
print(symbolstring)
currency('USD')
stock(symbolstring,currency='USD',multiplier=1)
# Currency and trading instrument objects stored in the
# .instrument environment
print("FI")
ls(envir=FinancialInstrument:::.instrument)
# blotter functions used for instrument initialization
# quantstrat creates a private storage area called .strategy
ls(all=T)
init_equity <- 10000
Sys.setenv(TZ="UTC")
print(portfolioName)
print("port")
try(initPortf(name = portfolioName,
symbols = symbolstring,
initDate = initDate))
try(initAcct(name = accountName,
portfolios = portfolioName,
initDate = initDate,
initEq = init_equity))
try(initOrders(portfolio = portfolioName,
symbols = symbolstring,
initDate = initDate))
# name: the string name of the strategy
# assets: optional list of assets to apply the strategy to.
# Normally these are defined in the portfolio object
# contstrains: optional portfolio constraints
# store: can be True or False. If True store the strategy in the environment. Default is False
print("strat")
strategy(strategyName, store = TRUE)
ls(all=T)
# .blotter holds the portfolio and account object
ls(.blotter)
# .strategy holds the orderbook and strategy object
print(ls(.strategy))
print("ind")
#ARIMA
add.indicator(
strategy = strategyName,
name = "autoregressor",
arguments = list(
x = quote(mktdata)),
label = "arspread")
################################################ Signals #############################
add.signal(
strategy = strategyName,
name = "sigThreshold",
arguments = list(
threshold = 0.25,
column = "arspread",
relationship = "gte",
cross = TRUE),
label = "Selltime")
add.signal(
strategy = strategyName,
name = "sigThreshold",
arguments = list(
threshold = 0.1,
column = "arspread",
relationship = "lt",
cross = TRUE),
label = "cashtime")
add.signal(
strategy = strategyName,
name = "sigThreshold",
arguments = list(
threshold = -0.1,
column = "arspread",
relationship = "gt",
cross = TRUE),
label = "cashtime")
add.signal(
strategy = strategyName,
name = "sigThreshold",
arguments = list(
threshold = -0.25,
column = "arspread",
relationship = "lte",
cross = TRUE),
label = "Buytime")
######################################## Rules #################################################
#Entry Rule Long
add.rule(strategyName,
name = "ruleSignal",
arguments = list(
sigcol = "Buytime",
sigval = TRUE,
orderqty = .orderqty,
ordertype = "market",
orderside = "long",
pricemethod = "market",
replace = TRUE,
TxnFees = -.txnfees
#,
#osFUN = osMaxPos
),
type = "enter",
path.dep = TRUE,
label = "Entry")
#Entry Rule Short
add.rule(strategyName,
name = "ruleSignal",
arguments = list(
sigcol = "Selltime",
sigval = TRUE,
orderqty = .orderqty,
ordertype = "market",
orderside = "short",
pricemethod = "market",
replace = TRUE,
TxnFees = -.txnfees
#,
#osFUN = osMaxPos
),
type = "enter",
path.dep = TRUE,
label = "Entry")
#Exit Rules
print("summary")
summary(getStrategy(strategyName))
# Summary results are produced below
print("results")
results <- applyStrategy(strategy= strategyName, portfolios = portfolioName)
# The applyStrategy() outputs all transactions(from the oldest to recent transactions)that the strategy sends. The first few rows of the applyStrategy() output are shown below
getTxns(Portfolio=portfolioName, Symbol=symbolstring)
mktdata
updatePortf(portfolioName,Dates=paste0(startDate,"::",endDate))
dateRange <- time(getPortfolio(portfolioName)$summary) updateAcct(portfolioName,dateRange[which(dateRange >= startDate & dateRange <= endDate)]) updateEndEq(accountName, Dates=paste0(startDate,"::",endDate)) print(plot(tail(getAccount(portfolioName)$summary$End.Eq,-1), main = symbolstring)) tStats <- tradeStats(Portfolios = portfolioName, use="trades", inclZeroDays=FALSE,Dates=paste0(startDate,"::",endDate)) final_acct <- getAccount(portfolioName) #final_acct #View(final_acct) options(width=70) print(plot(tail(final_acct$summary$End.Eq,-1), main = symbolstring)) #dev.off() tail(final_acct$summary$End.Eq) rets <- PortfReturns(Account = accountName) #rownames(rets) <- NULL tab.perf <- table.Arbitrary(rets, metrics=c( "Return.cumulative", "Return.annualized", "SharpeRatio.annualized", "CalmarRatio"), metricsNames=c( "Cumulative Return", "Annualized Return", "Annualized Sharpe Ratio", "Calmar Ratio")) tab.perf tab.risk <- table.Arbitrary(rets, metrics=c( "StdDev.annualized", "maxDrawdown" ), metricsNames=c( "Annualized StdDev", "Max DrawDown")) tab.risk return (as.numeric(tail(final_acct$summary$End.Eq,1))-init_equity)
#reset_quantstrat()
}
)
nó dường như được song song nhưng nó không cập nhật init_equity một cách chính xác