1

使用该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:使用收盘价进行演示,因为实际价格会在它们附近

4

0 回答 0