使用该blotter
软件包,我想分析一系列预先存在的投资组合。正如在 stackoverflow 其他地方所讨论的,Blotter 默认使用原始价格,可以使用adjustOHLC()
. 但是,我的主要问题是在拆分股份的情况下处理交易数量(股份数量)。由于这些是已经输入数量的预先存在的投资组合,我需要想出一个策略来处理买卖交易中这些不匹配的数量。
此代码试图澄清我面临的问题。我已经在代码注释本身中列出了这些问题,因为我发现它比单独编写时更容易阅读。
#rm(list=ls())
require(quantmod)
require(blotter)
TCS<- getSymbols("TCS.NS", auto.assign = F)
colnames(TCS)<- gsub("TCS.NS.","",colnames(TCS)) #not needed
head(TCS)
splits<- getSplits("TCS.NS")
splits
# Stock was split 1:1 on 2009-06-16
chartSeries(TCS["2009-06"],theme = chartTheme('white'))
# Focusing only on this period
TCS<- TCS["2009-05::2009-07"]
# into the blotter realm
# === Rerun the code from here to check solution 2 ====
rm(list =ls(envir=.blotter), envir=.blotter)
Sys.setenv(TZ="UTC")
initDate <- '2009-05-15'
initEq <- 1000
currency("INR")
stock("TCS", currency = "INR", multiplier = 1)
b.strategy <- "b.test"
initPortf(name = b.strategy, symbols = "TCS", initDate = initDate)
initAcct(name = b.strategy, portfolios = b.strategy, initDate = initDate, initEq = initEq)
# add 2 transactions, one before the split and one after
#1. user buys one share
addTxn(b.strategy, Symbol = "TCS", TxnDate = "2009-06-02",
TxnPrice = as.numeric(Cl(TCS["2009-06-02"])), TxnQty = 1, TxnFees = 0)
# 1.5 un-comment only on second run
# addTxn(b.strategy, Symbol = "TCS", TxnDate = "2009-06-16",
# TxnPrice = 0, TxnQty = 1, TxnFees = 0)
#2. sells all 2 shares some time after spilt
addTxn(b.strategy, Symbol = "TCS", TxnDate = "2009-06-29",
TxnPrice = as.numeric(Cl(TCS["2009-06-29"])), TxnQty = -2, TxnFees = 0)
(coredata(TCS["2009-06-29"])/coredata(TCS["2009-06-02"]))-1
(coredata(TCS["2009-06-29"])-coredata(TCS["2009-06-02"]))
# so we get a simple return -44% if we use raw Close , and a profit of 12% if we use adjusted (true picture)
# calculate and update account
updatePortf(b.strategy, Dates = "2009-05-15/2009-07-30")
updateAcct(b.strategy, Dates = "2009-05-15/2009-07-30")
updateEndEq(b.strategy, Dates = "2009-05-15/2009-07-30")
chartSeries(TCS)
tradeStats(b.strategy)
getAccount(b.strategy)$summary
getPortfolio(b.strategy)$summary
# ==== ISSUES =====
# at this point the account is showing 1 share as short (Short.Value)
# It has also calculated a wrong realised P/L value
#it is also calculating a day to day tally of unrealised P/L on the imaginary short position
(cumsum(getAccount(b.strategy)$summary$Net.Trading.PL))
# Here's a visual depiction for this issue
# as the price rises, the erronous short position creates notional losses
chart.Posn(b.strategy )
plot(getAccount(b.strategy)$summary$End.Eq)
# ============end of code ==========
# ===== Probable Solutions ======
# one possible solution , use Adjusted values AND increase the TxnQty of first transaction to 2
# (probable issue: This won't work when actual Transactoin Price is already provided by user )
# other possible solution, use Unadjusted price but allot extra shares at 0 cost on split date
# (probable issue: may cause divided-by-zero trouble with per period calculations. Not tested )
# uncoomenting the commented out transation above and rerunning the code will represent this strategy
addTxn(b.strategy, Symbol = "TCS", TxnDate = "2009-06-16",
TxnPrice = 0, TxnQty = 1, TxnFees = 0)
# NOTE: it seems to work correctly only if old blotter env is wiped clean
# and this is inserted between the two transactions abovem
#i.e., all transactions are in order
我想知道处理这个问题的标准/最佳实践策略是什么。
我还发布了代码,希望人们能发现缺陷并提出改进建议。
PS:使用收盘价进行演示,因为实际价格会在它们附近