2014-03-12 3 views
2

Я использую пакет blotter для запуска backtest и используя foreach для ускорения работы. Я сталкиваюсь с ошибкой, когда пятновыделение находит портфолио с тем же именем, хотя предполагается, что оно должно быть удалено в начале функции. Вот пример кода для воспроизведения ошибкиR: Использование foreach с blotter, портфолио уже существует ошибка

require('foreach') 
require('doSNOW') 
require('xts') 
require('blotter') 

backtestFunction <- function() { 

    currency("USD") 
    stock("AAPL", currency="USD", multiplier=1) 
    Sys.setenv(TZ="US/Eastern") 
    verbose = FALSE 

    try(rm("account.Snazzy","portfolio.Snazzy",pos=.blotter),silent=TRUE) 
    initPortf("Snazzy", "AAPL", initDate="2014-01-01", currency="USD") 
    initAcct("Snazzy", portfolios="Snazzy", initDate="2014-01-01", initEq=1000, currency="USD") 

    return (TRUE) 
} 

cl <- snow::makeCluster(8, type = "SOCK") 
registerDoSNOW(cl) 

results <- foreach(i=1:100, .combine=rbind, .packages=c('xts','blotter')) %dopar% { 
    return (backtestFunction()) 
} 
snow::stopCluster(cl) 

Вот ошибка

Error in { : 
    task 9 failed - "Portfolio Snazzy already exists, use updatePortf() or addPortfInstr() to update it." 

Я понимаю, что портфель и счета объекты хранятся в среде .blotter, однако

  1. Wouldn» t foreach порождает каждого работника в новой R-сессии, чтобы не возникало конфликтов?
  2. Почему не работали try(rm("account.Snazzy","portfolio.Snazzy",pos=.blotter),silent=TRUE)?
  3. Как я могу получить foreach для работы с blotter здесь?

Если это имеет значение, я использую R 3.0.2, запустив RStudio в Windows. Я включаю квант в тег, потому что они обычно используются вместе, поэтому, вероятно, опытный пользователь квантры будет знать исправление. Спасибо

ответ

2

Проблема заключается в том, что «.blotter» автоматически экспортируется в рабочих, но в среду экспорта doSNOW, , а не в глобальную среду. Это не путает пакет blotter, но это не позволяет вашей команде «rm» удалять «account.Snazzy» и «portfolio.Snazzy» из реальной среды «.blotter».

Одним из решений является добавление .noexport=".blotter" к foreach. Другим решением является указать среду более явно при выполнении «гт»:

try(rm("account.Snazzy","portfolio.Snazzy",pos=.GlobalEnv$.blotter), 
    silent=TRUE) 

doSNOW не порождает работника для каждой задачи, так как это может быть довольно медленным. Даже для местных работников время запуска сеанса R может быть значительным по сравнению с временем выполнения задачи, особенно в кластере с использованием ssh. И что еще более важно, если работники выполняют несколько задач, вы можете отправлять им большие массивы данных и повторно использовать эти данные для многих задач, таким образом амортизируя затраты на связь.

+0

Спасибо Стив за разъяснения! Я вырыл дальше и просто для того, чтобы предоставить более подробную информацию для других, среда оценки функции была окружена временной средой, созданной foreach/doSNOW, которая, в свою очередь, была окружена глобальной средой. Поэтому, когда «.blotter» был экспортирован во временную среду, был «.blotter» как во временной среде, так и в глобальной среде. Команда «rm» заперта на той, что была во временной среде, в то время как пакет blotter использовал его в глобальной среде. – wintermelon

+0

Это совершенно верно. Тот же метод используется doMPI, doRedis, и когда объект кластера зарегистрирован в doParallel. Эта временная среда - это то, что я называю «экспортной» средой. –