簡體   English   中英

在R量子代碼中循環 - 如何使其更快?

[英]While loop in R quantstrat code - how to make it faster?

在quantstrat包中,我找到了applyRule函數緩慢的主要罪魁禍首之一,並想知道是否有更高效的寫入while循環。 任何反饋都會有所幫助。 任何人都可以將這部分包裝成並行R.

作為一種選擇,申請會有效嗎? 或者我應該將此部分重新編寫為新函數,例如ruleProc和nextIndex? 我也在沉迷於Rcpp,但這可能是一個特殊的問題。 非常感謝任何幫助和建設性的建議?

   while (curIndex) {
    timestamp = Dates[curIndex]
    if (isTRUE(hold) & holdtill < timestamp) {
        hold = FALSE
        holdtill = NULL
    }
    types <- sort(factor(names(strategy$rules), levels = c("pre",
        "risk", "order", "rebalance", "exit", "enter", "entry",
        "post")))
    for (type in types) {
        switch(type, pre = {
            if (length(strategy$rules[[type]]) >= 1) {
              ruleProc(strategy$rules$pre, timestamp = timestamp,
                path.dep = path.dep, mktdata = mktdata, portfolio = portfolio,
                symbol = symbol, ruletype = type, mktinstr = mktinstr)
            }
        }, risk = {
            if (length(strategy$rules$risk) >= 1) {
              ruleProc(strategy$rules$risk, timestamp = timestamp,
                path.dep = path.dep, mktdata = mktdata, portfolio = portfolio,
                symbol = symbol, ruletype = type, mktinstr = mktinstr)
            }
        }, order = {
            if (length(strategy$rules[[type]]) >= 1) {
              ruleProc(strategy$rules[[type]], timestamp = timestamp,
                path.dep = path.dep, mktdata = mktdata, portfolio = portfolio,
                symbol = symbol, ruletype = type, mktinstr = mktinstr,)
            } else {
              if (isTRUE(path.dep)) {
                timespan <- paste("::", timestamp, sep = "")
              } else timespan = NULL
              ruleOrderProc(portfolio = portfolio, symbol = symbol,
                mktdata = mktdata, timespan = timespan)
            }
        }, rebalance = , exit = , enter = , entry = {
            if (isTRUE(hold)) next()
            if (type == "exit") {
              if (getPosQty(Portfolio = portfolio, Symbol = symbol,
                Date = timestamp) == 0) next()
            }
            if (length(strategy$rules[[type]]) >= 1) {
              ruleProc(strategy$rules[[type]], timestamp = timestamp,
                path.dep = path.dep, mktdata = mktdata, portfolio = portfolio,
                symbol = symbol, ruletype = type, mktinstr = mktinstr)
            }
            if (isTRUE(path.dep) && length(getOrders(portfolio = portfolio,
              symbol = symbol, status = "open", timespan = timestamp,
              which.i = TRUE))) {
            }
        }, post = {
            if (length(strategy$rules$post) >= 1) {
              ruleProc(strategy$rules$post, timestamp = timestamp,
                path.dep = path.dep, mktdata = mktdata, portfolio = portfolio,
                symbol = symbol, ruletype = type, mktinstr = mktinstr)
            }
        })
    }
    if (isTRUE(path.dep))
        curIndex <- nextIndex(curIndex)
    else curIndex = FALSE
}

加勒特的回答確實指出了關於R-SIG財務清單的最后一次重要討論,其中討論了相關問題。

quantstrat中的applyRules函數絕對是花費大部分時間的地方。

在這個問題中復制的while循環代碼是applyRules執行的路徑依賴部分。 我相信所有這些都在文檔中有所涉及,但我將簡要回顧一下后代。

我們在applyRules中構建一個降維索引,這樣我們就不必觀察每個時間戳並檢查它。 我們只注意到可以合理地預期策略可以在訂單簿上執行的特定時間點,或者可以合理地預期訂單被填補的特定時間點。

這是依賴於狀態路徑的代碼。 在這種背景下,對“矢量化”的閑談沒有任何意義。 如果我需要知道市場的當前狀態,訂單和我的位置,如果我的訂單可能會被其他規則以時間依賴的方式修改,我看不出這個代碼是如何被矢量化的。

從計算機科學的角度來看,這是一台狀態機。 我能想到的幾乎所有語言的狀態機通常都是以while循環編寫的。 這不是真正可以談判或改變的。

問題是否使用申請會有所幫助。 R中的apply語句實現為循環,所以不,它沒有幫助。 即使是mclapplyforeach等並行應用也無濟於事,因為這是代碼中依賴於狀態的部分。 在不考慮狀態的情況下評估不同的時間點沒有任何意義。 您將注意到,quantstrat的非狀態相關部分盡可能地進行矢量化,並且占用的運行時間非常少。

John的評論建議刪除ruleProc中的for循環。 for循環所做的就是檢查此時與策略關聯的每個規則。 該循環中唯一的計算密集型部分是do.call來調用規則函數。 for循環的其余部分只是為這些函數定位和匹配參數,而從代碼分析中,根本不需要花費太多時間。 在這里使用並行應用也沒有多大意義,因為規則函數以類型順序應用,因此可以在新的條目指令之前應用取消或風險指令。 就像數學有一個操作順序,或者銀行有存款/取款處理訂單一樣,quantstrat有一個規則類型評估訂單,如文檔中所述。

為了加快執行速度,可以做四件事:

  1. 編寫非路徑依賴策略 :代碼支持這一點,簡單策略可以這種方式建模。 在這個模型中,您將編寫一個自定義規則函數,當您認為應該填充時, 它會直接調用addTxn 它可能是一個操作指標/信號的矢量化函數,應該非常快。
  2. 預處理您的信號 :如果狀態機需要評估訂單簿/規則/組合的狀態以查看是否需要執行某些操作,則速度增加幾乎與信號減少呈線性關系。 這是大多數用戶忽略的區域,寫入信號功能並不真正評估何時可能需要修改位置或訂單簿的操作。
  3. 顯式並行化部分分析問題 :我通常明確地編寫並行包裝器以分離出不同的參數評估或符號評估,請參閱applyParameter以獲取使用foreach的示例
  4. 在C / C ++中重寫applyRules中的狀態機 :歡迎補丁,但請看Garrett發布的鏈接以獲取更多詳細信息。

我可以向您保證,如果對信號生成功能稍加注意,大多數策略可以在每個符號每個核心每分鍾的核心分鍾上運行。 不建議在筆記本電腦上運行大型背景測試。

參考: quantstrat - applyRules

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM