1

パッケージのdrawdown関数を使用するカスタム関数を作成しようとしています。tseriesこの関数を関数の正しい範囲の値に適用したいのですが、これはかなり初心者の質問ですが、考えられる解決策がわかりません。

私のデータフレームは次のようになります。

> 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'))
}

このカスタム関数の手順を手動でたどると、'<code>from' および '<code>to' 行番号の計算に問題があることがわかります (つまり、R は楽器の長さに合わせて KFT の値を調整する必要があります。この場合は JPM)。考えられる解決策として、R は次のようなことを行う必要があります。

maxdrawdownこのインストゥルメントが最初 (リストの一番上) の場合、関数の「from」値を取得します。ただし、現在の楽器が 2 番目 (または 3 番目など) の場合は、前の楽器の長さを考慮してください。したがって、ツール JPM の長さが 10 の場合、KFT の値の検索は +10 から開始する必要があります。fromまた、楽器 3 のとの値の検索は、to楽器 1 の長さ + 楽器 2 の長さから開始する必要があります。

nrownrowが正しく使用されていても(つまり、関数外の同じステートメントが機能した)、「長さ0の引数」に関するエラーが発生しました。また、関数内のデータをサブセット化しようとしましたが、これもうまくいきませんでした。どんなアイデアでも大歓迎です。:)

4

1 に答える 1

2

splitここにあなたの友達です。次のように、対象の3つの変数(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

データセットのデータフレーム/サブセットを受け入れて操作する関数がある限り、splitサブセットを形成したり、それらのサブセットに関数を適用しlapplyたりするために使用できます。sapply

これを関数に組み込みたいと思うかもしれません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)
}

新しい(R 2.12.xの)関数droplevelsx[, "Instrument"])使用して、単一レベルのデータがある場合やデータのサブセットを操作している場合でも関数が機能できるようにする場合:

> MDD_Duration2(subSetTrades)
JPM KFT 
106  67 
> MDD_Duration2(subSetTrades[1:10,])
JPM 
106
于 2011-01-10T08:12:33.127 に答える