2011-01-10 58 views
1

我試圖創建一個使用tseries包中的drawdown函數的自定義函數。我想將這個函數應用到函數中正確的值範圍,但即使這是一個相當新手的問題,我看不到一個可能的解決方案。在函數內選擇正確的值範圍

這裏是我的數據幀是什麼樣子:

> subSetTrades 
    Instrument EntryTime ExitTime AccountValue 
1   JPM 2007-03-01 2007-04-10   6997 
2   JPM 2007-04-10 2007-05-29   7261 
3   JPM 2007-05-29 2007-07-18   7545 
4   JPM 2007-07-18 2007-07-19   7614 
5   JPM 2007-07-19 2007-08-22   7897 
6   JPM 2007-08-22 2007-08-28   7678 
7   JPM 2007-08-28 2007-09-17   7587 
8   JPM 2007-09-17 2007-10-17   7752 
9   JPM 2007-10-17 2007-10-29   7717 
10  JPM 2007-10-29 2007-11-02   7423 
11  KFT 2007-04-13 2007-05-14   6992 
12  KFT 2007-05-14 2007-05-21   6944 
13  KFT 2007-05-21 2007-07-09   7069 
14  KFT 2007-07-09 2007-07-16   6919 
15  KFT 2007-07-16 2007-07-27   6713 
16  KFT 2007-07-27 2007-09-07   6820 
17  KFT 2007-09-07 2007-10-12   6927 
18  KFT 2007-10-12 2007-11-28   6983 
19  KFT 2007-11-28 2007-12-18   6957 
20  KFT 2007-12-18 2008-02-20   7146 

如果我手動計算我想我的函數輸出值,結果是正確的:

# Apply the function to the dataframe 
with(subSetTrades, tapply(AccountValue, Instrument, MDD_Duration)) 
JPM KFT 
106 85 
> # Check the function for JPM 
> maxdrawdown(subSetTrades[1:10,4])$from 
[1] 5 
> maxdrawdown(subSetTrades[1:10,4])$to 
[1] 10 
> # Get the entry time for JPM on row 5 
> # Get the exit time for JPM on row 10 
> # Calculate the time difference 
> difftime(subSetTrades[10,3], subSetTrades[5,2], units='days') 
Time difference of 106 days 
# Check the calculations for the other Instrument 
> maxdrawdown(subSetTrades[11:20,4])$from 
[1] 3 
> maxdrawdown(subSetTrades[11:20,4])$to 
[1] 5 
> # Get the exittime on row 5 for KFT, get the entrytime for KFT on row 3, 
# and calculate the time difference 
> difftime(subSetTrades[15,3], subSetTrades[13,2]) 
Time difference of 67 days 

正如你可以在上面看到例如,我的自定義函數(MDD_Duration)爲JPM提供了正確的值,但給出了KFT的錯誤值:而不是85,結果應該是67.函數MDD_Duration如下:

MDD_Duration <- function(x){ 
    require(tseries) 
    # Get starting point 
    mdd_Start <- maxdrawdown(x)$from 
    mdd_StartDate <- subSetTrades$EntryTime[mdd_Start] 
    # Get the endpoint 
    mdd_End <- maxdrawdown(x)$to 
    mdd_EndDate <- subSetTrades$ExitTime[mdd_End] 
    return(difftime(mdd_EndDate, mdd_StartDate, units='days')) 
} 

手動折回此自定義函數的步驟,示出了存在具有與「from」和「to」行數的計算的問題(即R需要根據其之前的樂器長度調整KFT的值,在這種情況下是JPM)。對於可能的解決方案,R需要執行以下操作:

如果此工具是第一個(即列表頂部),則獲取maxdrawdown函數的'from'值。但是,如果當前儀器是第二個(或第三個等),則應考慮先前儀器的長度。因此,如果儀器JPM的長度爲10,則搜索KFT的值應該從+10開始。而對於儀表3 fromto值搜索應在儀器1的lenght +儀器2.

我使用nrow到函數嘗試的長度開始(這似乎明顯地解決了這個答案)即使正確使用了nrow(即函數外部的相同語句無效),也會導致「長度爲0的參數」的錯誤。我也嘗試在函數內部對數據進行子集化,這也沒有奏效。任何想法都非常受歡迎。 :)

回答

2

split是你的朋友在這裏。如果我修改您的函數,這樣,預計與感興趣的三個變量(AccountValue,EntryTime,EXITTIME)這樣的數據幀:

MDD_Duration <- function(x){ 
    # require(tseries) 
    # Get starting point 
    mdd_Start <- maxdrawdown(x$AccountValue)$from 
    mdd_StartDate <- x$EntryTime[mdd_Start] 
    # Get the endpoint 
    mdd_End <- maxdrawdown(x$AccountValue)$to 
    mdd_EndDate <- x$ExitTime[mdd_End] 
    return(difftime(mdd_EndDate, mdd_StartDate, units='days')) 
} 

的,我們可以把它應用到您的數據的分裂版本:

> sapply(split(subSetTrades[,-1], subSetTrades[,1]), MDD_Duration) 
JPM KFT 
106 67 

這可能是有益的,看看有什麼split是做給你的數據:

> split(subSetTrades[,-1], subSetTrades[,1]) 
$JPM 
    EntryTime ExitTime AccountValue 
1 2007-03-01 2007-04-10   6997 
2 2007-04-10 2007-05-29   7261 
3 2007-05-29 2007-07-18   7545 
4 2007-07-18 2007-07-19   7614 
5 2007-07-19 2007-08-22   7897 
6 2007-08-22 2007-08-28   7678 
7 2007-08-28 2007-09-17   7587 
8 2007-09-17 2007-10-17   7752 
9 2007-10-17 2007-10-29   7717 
10 2007-10-29 2007-11-02   7423 

$KFT 
    EntryTime ExitTime AccountValue 
11 2007-04-13 2007-05-14   6992 
12 2007-05-14 2007-05-21   6944 
13 2007-05-21 2007-07-09   7069 
14 2007-07-09 2007-07-16   6919 
15 2007-07-16 2007-07-27   6713 
16 2007-07-27 2007-09-07   6820 
17 2007-09-07 2007-10-12   6927 
18 2007-10-12 2007-11-28   6983 
19 2007-11-28 2007-12-18   6957 
20 2007-12-18 2008-02-20   7146 

所以只要你有會接受,並用數據FRA工作的功能我/您的數據集的子集,我們可以使用split組成子集,lapplysapply將我們的功能應用於這些子集。

你可能想融入你的函數MDD_Duration()這一點:

MDD_Duration2 <- function(x){ 
    FUN <- function(x) { 
     # Get starting point 
     mdd_Start <- maxdrawdown(x$AccountValue)$from 
     mdd_StartDate <- x$EntryTime[mdd_Start] 
     # Get the endpoint 
     mdd_End <- maxdrawdown(x$AccountValue)$to 
     mdd_EndDate <- x$ExitTime[mdd_End] 
     return(difftime(mdd_EndDate, mdd_StartDate, units='days')) 
    } 
    sapply(split(x, droplevels(x[, "Instrument"])), FUN) 
} 

當我們使用新的(在讀2.12。X)上x[, "Instrument"])功能droplevels,讓即使我們有數據的單級函數工作或對數據的子集進行操作:

> MDD_Duration2(subSetTrades) 
JPM KFT 
106 67 
> MDD_Duration2(subSetTrades[1:10,]) 
JPM 
106 
+1

我原來的結果和@ Jura25之間的差異是由於當從帖子中讀取數據時,我忘記將`EntryTime`和`ExitTime`轉換爲``Date'`類的對象。我已經對修正後的數據重新運行了我的答案,現在它複製了@ Jura25的結果。 – 2011-01-10 08:50:51