Hi Brian,

return(as.numeric(res)) - same thing, I tried it before posting here. There
is no problem if I use return(100*sign(orderqty)), which indicates the path
dependency I was trying to imply. The problem doesn't seem to occur for
long only positions - it gotta be switching. I believe, the problem is
outside os.all.equity. Notice, it has a lot of debug output and it clearly
indicates that the function returns, and returns a numeric before the
problem is hit. For me it's easy to repro it (although it takes longer)
with the attached script (it needs some adjustments). The problem is hit
for 2001-04-08. I don't touch txnFees anywhere in my code, so I have no
control over this behaviour - it needs to be type casted somewhere - from
what you are saying - taking the type into account.

Thanks for the comments about the testing.

Can you point me to code which computes the portfolio size as you suggested?

>From my experience, it's often needed to be able to show the strategy
performance over years, with all the system on. That's an area quanstrat
lacks - both in terms of examples and testing (I am pretty sure this is a
regression since the last time I looked at it).

Thanks,
Ivan




On Tue, Jan 14, 2014 at 9:26 AM, Brian G. Peterson <[email protected]>wrote:

> You don't actually include how you're calculating txnfees, and your
> example is not reproducible, so I'm forced to guess.
>
> try
>
>  return(as.numeric(res))
>
> in your function.
>
> As noted in the documentation, txnFees can be a string name of a function,
> so forcing it to as.numeric is a really bad idea.
>
> I'll also note that you don't need to call updatePortf every time. That's
> extremely expensive by comparison to just adding up the realized P&L (from
> closed transaction) and Unrealized P&L (from your open position) yourself.
>  You should also be aware that this approach (or yours) will only capture
> equity changes in a single instrument (since instruments are processed one
> at a time).
>
> Most literature on evaluating trading strategies (see e.g. Aronson or
> Tomasini and Jaekle) tends to do system design on fixed trade sizes because
> it is much easier to evaluate whether or not your system really has any
> edge, or is just participating in market drift.  I tend to separate the
> order sizing decisions till very late in the strategy development process.
>
> Regards,
>
> Brian
>
>
> On 01/13/2014 07:15 PM, Ivan Popivanov wrote:
>
>> It only happens when I use a custom function to compute the position size,
>> but it won't happen with a constant size. So it may have something to do
>> with the splitting of orders. My function uses all available equity
>> rounding up - it's at the end. I get the following error:
>>
>> Error in `/.default`(TxnFees, abs(TxnQty)) :
>>    non-numeric argument to binary operator
>>
>> It seems that the fault is in ruleOrderProc, the caller of addTxn,
>> whereabouts txnfees is indeed an xts object. To me the fix is to pass
>> as.numeric(txnfees) to addTxn.
>>
>> Regards,
>> Ivan
>>
>> PS: Is my osAllEquity a good way to implement the compounding growth or is
>> there a better alternative? I think it's worth having an example to
>> illustrate this functionality.
>>
>> osAllEquity = function(
>>        timestamp,
>>        orderqty,
>>        portfolio.name,
>>        symbol,
>>        ...)
>> {
>>     verbose = TRUE
>>     # verbose = FALSE
>>
>>     if(verbose) cat("\n=====")
>>     if(verbose) cat(paste( "\n", timestamp, sep=""))
>>
>>     if(verbose) cat(paste( "\n   orderqty=", orderqty, sep=""))
>>     portfolio = updatePortf(Portfolio=portfolio.name, Dates=paste('::',
>> as.Date(timestamp), sep=''))
>>     # end.eq = getEndEq(portfolio.name, as.Date(timestamp))
>>     # print( end.eq )
>>     pnl = sum(getPortfolio(portfolio.name)$summary$Net.Trading.PL)
>>     end.eq = initEq + pnl
>>     if(verbose) cat(paste( "\n   pnl=", pnl, sep=""))
>>     if(verbose) cat(paste( "\n   equity=", end.eq, sep=""))
>>     close.price = as.numeric(Cl(mktdata[timestamp,]))
>>     if(verbose) cat(paste("\n   close price=", close.price, sep=""))
>>     res = as.numeric( ceiling( end.eq / close.price ) ) * sign( orderqty )
>>     if(verbose) cat(paste("\n   qty=", res, sep=""))
>>     if(verbose) cat("\n=====\n")
>>     # return(sign(orderqty*1000))
>>     # res = 1000*sign(orderqty)
>>     return(res)
>> }
>>
>>         [[alternative HTML version deleted]]
>>
>> _______________________________________________
>> [email protected] mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-sig-finance
>> -- Subscriber-posting only. If you want to post, subscribe first.
>> -- Also note that this is not the r-help list where general R questions
>> should go.
>>
>>
> --
> Brian G. Peterson
> http://braverock.com/brian/
> Ph: 773-459-4973
> IM: bgpbraverock
>
> _______________________________________________
> [email protected] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-sig-finance
> -- Subscriber-posting only. If you want to post, subscribe first.
> -- Also note that this is not the r-help list where general R questions
> should go.
>
require(quantstrat)
require(btutils)

os.all.equity = function(
   timestamp,
   orderqty,
   portfolio.name,
   symbol,
   ...)
{
   verbose = TRUE
   # verbose = FALSE
   
   if(verbose) cat("\n=====")
   if(verbose) cat(paste( "\n", timestamp, sep=""))
   if(verbose) cat(paste( "\n   orderqty = ", orderqty, sep=""))
   portfolio = updatePortf(Portfolio=portfolio.name, Dates=paste('::', as.Date(timestamp), sep=''))
   # end.eq = getEndEq(portfolio.name, as.Date(timestamp))
   # print( end.eq )
   pnl = sum(getPortfolio(portfolio.name)$summary$Net.Trading.PL)
   end.eq = initEq + pnl
   if(verbose) cat(paste( "\n   pnl = ", pnl, sep=""))
   if(verbose) cat(paste( "\n   equity = ", end.eq, sep=""))
   close.price = as.numeric(Cl(mktdata[timestamp,]))
   if(verbose) cat(paste( "\n   close price = ", close.price, sep=""))
   res = as.numeric( ceiling( end.eq / close.price ) ) * sign( orderqty )
   if(verbose) cat(paste( "\n   qty = ", res, sep=""))
   if(verbose) cat("\n=====\n")
   return( res )
}

sma.indicator = function(prices) {
   return(MACD(prices, nFast=1, nSlow=50)[,1])
}

suppressWarnings(rm("order_book.sma", pos=.strategy))
suppressWarnings(rm("account.sma", "portfolio.sma", pos=.blotter))
suppressWarnings(rm("strat.sma"))

# Setup
symbol="SPY"
symbolFile="~/yahoo.data/SPY.RData"
initDate = "1950-01-01"
startDate = "2012-01-01"
endDate = "2012-12-31"
initEq = 100000
# stopLoss = 0.025
stopLoss = NULL

orderQty = initEq

port.st = "sma"

verbose = TRUE
# verbose = FALSE

strat.sma = strategy("sma")

strat.sma = add.indicator(
   strategy=strat.sma,
   name="sma.indicator",
   label="sma",
   arguments=list(prices=quote(Cl(mktdata)), nFast=1, nSlow=50))

strat.sma = add.signal(
   strategy=strat.sma,
   name="sigThreshold",
   arguments = list(threshold=0,
                    column="sma",
                    relationship="lt",
                    cross=TRUE),
   label="sma.above")

strat.sma = add.signal(
   strategy=strat.sma,
   name="sigThreshold",
   arguments = list(threshold=0,
                    column="sma",
                    relationship="gte",
                    cross=TRUE),
   label="sma.below")

# long entry
strat.sma = add.rule(
   strategy=strat.sma,
   name='ruleSignal',
   arguments=list(sigcol="sma.below",
                  sigval=TRUE,
                  orderqty=100,
                  ordertype="market",
                  pricemethod="market",
                  orderside="long",
                  osFUN=os.all.equity),
   type="enter",
   label="enter.long")

# long exit
strat.sma = add.rule(
   strategy=strat.sma,
   name='ruleSignal',
   arguments=list(sigcol="sma.above",
                  sigval=TRUE,
                  orderqty="all",
                  ordertype="market",
                  pricemethod="market",
                  orderside="long"),
   type="exit",
   label="exit.long")

# short entry
strat.sma = add.rule(
   strategy=strat.sma,
   name='ruleSignal',
   arguments=list(sigcol="sma.above",
                  sigval=TRUE,
                  orderqty=-orderQty,
                  ordertype="market",
                  pricemethod="market",
                  orderside="short",
                  osFUN=os.all.equity),
   type="enter",
   label="enter.short")

# short exit 
strat.sma = add.rule(
   strategy=strat.sma,
   name='ruleSignal',
   arguments=list(sigcol="sma.below",
                  sigval=TRUE,
                  orderqty="all",
                  ordertype="market",
                  pricemethod="market",
                  orderside="short"),
   type="exit",
   label="exit.short")

currency("USD")
stock(symbol, currency="USD", multiplier=1)
load(file=symbolFile)
SPY = SPY[paste('::', endDate, sep='')]

initPortf(port.st, symbols=symbol, initDate=initDate)
initAcct(port.st, portfolios=port.st, initDate=initDate, initEq=initEq)
initOrders(portfolio=port.st, initDate=initDate)

if(verbose) print("setup completed")

# Process the indicators and generate trades
# mktdata=mktdata[paste(startDate, "/", endDate, sep="")]
out = applyStrategy(strategy=strat.sma, portfolios=port.st)

updatePortf(port.st, Symbols=symbol, Dates=paste('::',as.Date(Sys.time()),sep=''))
updateAcct(port.st)
updateEndEq(port.st, Dates=paste(startDate, endDate, sep="::"))

# chart.Posn(Portfolio=port.st, Symbol=symbol, Dates="2012-07-01/")

eq = getEndEq(port.st, Sys.time())
book = getOrderBook(port.st)
stats = tradeStats(port.st, symbol)
rets  = PortfReturns(port.st)
txns  = getTxns(port.st, symbol)
_______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should 
go.

Reply via email to