Попытка понять расчет блоттерной учетной записи Unrealized.PL и End.Eq

При программировании стратегии в блоттере я столкнулся с проблемой, что End.Eq после моих сделок не соответствовало моим ожидаемым результатам ручного расчета. Поэтому я написал простой код на R, чтобы лучше понять, как работает блоттер. Также здесь результаты отличаются от того, что я ожидал.

Может быть, кто-то с лучшим пониманием может помочь мне с объяснением.

# R version 3.2.1 (2015-06-18)
# Platform: x86_64-pc-linux-gnu (64-bit)
# blotter: 0.9.1666
require(blotter)
Sys.setenv(TZ="UTC")
rm(list =ls(envir=.blotter), envir=.blotter) 

initDate <- '2008-01-01'
initEq <- 1000

currency("USD")
stock("MDY", currency = "USD", multiplier = 1)

getSymbols("MDY", from='2008-01-01', to='2008-06-30', index.class="POSIXct", adjust=T)

b.strategy <- "b.test"
initPortf(name = b.strategy, symbols = "MDY", initDate = initDate)
initAcct(name = b.strategy, portfolios = b.strategy, initDate = initDate, initEq = initEq)

addTxn(b.strategy, Symbol = "MDY", TxnDate = "2008-04-30",
   TxnPrice = as.numeric(Cl(MDY["2008-04-30"])), TxnQty = 1, TxnFees = 0)
updatePortf(b.strategy, Dates = "2008-04-30")
updateAcct(b.strategy, Dates = "2008-04-30")
updateEndEq(b.strategy, Dates = "2008-04-30")

addTxn(b.strategy, Symbol = "MDY", TxnDate = "2008-05-30",
   TxnPrice = as.numeric(Cl(MDY["2008-05-30"])), TxnQty = -1, TxnFees = 0)
updatePortf(b.strategy, Dates = "2008-05-30")
updateAcct(b.strategy, Dates = "2008-05-30")
updateEndEq(b.strategy, Dates = "2008-05-30")

perTradeStats(b.strategy, "MDY")
tradeStats(b.strategy)
getAccount(b.strategy)$summary

Приведенный выше код инициализирует портфель наличными в размере 1000 долларов. Я покупаю 1 MDY по цене закрытия 30 апреля 2008 года. Затем я закрываю позицию через месяц по цене закрытия "2008-05-30".

[1] "2008-04-30 00:00:00 MDY 1 @ 151.920844224256"
[1] "2008-05-30 00:00:00 MDY -1 @ 160.178061444191"

Поскольку в портфеле больше нет открытых позиций, я ожидаю прирост End.Eq в размере 1000+8,257217 = 1008,257217, но я вижу гораздо более низкий результат из-за Unrealized.PL = -6.72.

Но откуда это? Все позиции закрыты, поэтому ожидаю Unrealized.PL = 0. Хотя транзакция по-прежнему дает мне ожидаемый результат Net.Trading.PL = 8.257217.

> perTradeStats(b.strategy, "MDY")
       Start        End Init.Pos Max.Pos Num.Txns Max.Notional.Cost Net.Trading.PL MAE      MFE
1 2008-04-30 2008-05-30        1       1        2          151.9208       8.257217   0 8.257217
  Pct.Net.Trading.PL Pct.MAE   Pct.MFE tick.Net.Trading.PL tick.MAE tick.MFE
1          0.0543521       0 0.0543521            825.7217        0 825.7217

Заглянув в счет портфеля, я нахожу Unrealized.PL = -6.72, который не могу объяснить, но который явно приводит к неожиданному результату End.Eq.

> getAccount(b.strategy)$summary
           Additions Withdrawals Realized.PL Unrealized.PL Interest          Gross.Trading.PL Txn.Fees Net.Trading.PL
2008-01-01         0           0    0.000000          0.00        0         0.000000        0       0.000000
2008-04-30         0           0    0.000000          0.00        0         0.000000        0       0.000000
2008-05-30         0           0    8.257217         -6.72        0         1.535756        0       1.535756
           Advisory.Fees Net.Performance   End.Eq
2008-01-01             0        0.000000 1000.000
2008-04-30             0        0.000000 1000.000
2008-05-30             0        1.535756 1001.536

Подводя итог, у меня два вопроса:

  1. Ищете объяснение того, как появился Unrealized.PL?
  2. Как я могу этого избежать, если это возможно?

person JBlohm    schedule 26.07.2015    source источник


Ответы (1)


Во-первых, вы должны вызывать функции update* только тогда, когда вам нужно пометить книгу. Неэффективно вызывать их после каждой транзакции, если вам на самом деле не нужно использовать некоторые значения, которые они вычисляют.

Во-вторых, вы вызываете функции update* с одной датой, что (обычно) не имеет смысла. Это приводит к тому, что книга помечается только для этой единственной даты, что не особенно полезно. Было бы разумнее использовать диапазон дат, например "2008-04-30/2008-05-30".

Ненулевое значение Unrealized.PL связано с тем, что ваша транзакция закрытия позиции происходит в конец 30 мая 2008 г., что означает, что у вас есть нереализованные прибыли и убытки за этот день.

Модифицированная версия вашего кода ниже должна дать ожидаемые результаты.

require(blotter)
Sys.setenv(TZ="UTC")
rm(list =ls(envir=.blotter), envir=.blotter) 

initDate <- '2008-01-01'
initEq <- 1000

currency("USD")
stock("MDY", currency = "USD", multiplier = 1)
getSymbols("MDY", from='2008-01-01', to='2008-06-30', index.class="POSIXct", adjust=T)

b.strategy <- "b.test"
initPortf(name = b.strategy, symbols = "MDY", initDate = initDate)
initAcct(name = b.strategy, portfolios = b.strategy, initDate = initDate, initEq = initEq)

addTxn(b.strategy, Symbol = "MDY", TxnDate = "2008-04-30",
  TxnPrice = as.numeric(Cl(MDY["2008-04-30"])), TxnQty = 1, TxnFees = 0)
addTxn(b.strategy, Symbol = "MDY", TxnDate = "2008-05-30",
  TxnPrice = as.numeric(Cl(MDY["2008-05-30"])), TxnQty = -1, TxnFees = 0)

updatePortf(b.strategy, Dates = "2008-04-30/2008-05-30")
updateAcct(b.strategy, Dates = "2008-04-30/2008-05-30")
updateEndEq(b.strategy, Dates = "2008-04-30/2008-05-30")

perTradeStats(b.strategy, "MDY")
tradeStats(b.strategy)
getAccount(b.strategy)$summary
getPortfolio(b.strategy)$summary
person Joshua Ulrich    schedule 26.07.2015
comment
Большое спасибо Джошуа! Это помогло. Именно то, что мне было нужно. - person JBlohm; 28.07.2015
comment
@joshua, используя Blotter, я должен записывать транзакции с одними и теми же акциями в один и тот же день. Покупка и продажа в один день. есть ли какой-то конкретный способ? до сих пор это делает длинное значение неправильным. - person Rene Chan; 22.02.2020