Learn R Programming

PMwR (version 0.11-0)

pl: Profit and Loss

Description

Compute profit and (or) loss of financial transactions.

Usage

pl(amount, … )

# S3 method for default pl(amount, price, timestamp = NULL, instrument = NULL, multiplier = 1, multiplier.regexp = FALSE, along.timestamp = FALSE, approx = FALSE, initial.position = NULL, initial.price = NULL, vprice = NULL, tol = 1e-10, do.warn = TRUE, do.sum = FALSE, pl.only = FALSE, … )

# S3 method for journal pl(amount, multiplier = 1, multiplier.regexp = FALSE, along.timestamp = FALSE, approx = FALSE, initial.position = NULL, initial.price = NULL, vprice = NULL, tol = 1e-10, do.warn = TRUE, … )

# S3 method for pl pl(amount, … )

# S3 method for pl print(x, …, use.crayon = NULL, na.print = ".")

# S3 method for pl as.data.frame(x, … )

.pl(amount, price, tol = 1e-10, do.warn = TRUE)

Arguments

amount

numeric or a journal

price

numeric

instrument

character or numeric (though typically character)

timestamp

An atomic vector of mode numeric or character. Timestamps should typically be sortable.

along.timestamp

a logical

initial.position
initial.price

prices to evaluate initial position.

vprice

valuation price; a numeric vector. With several instruments, the prices must be named, e.g. c(stock1 = 100, stock2 = 101). See Details.

multiplier

numeric vector. When instrument is specified and the vector is named, the names will be matched against instruments.

multiplier.regexp

logical. If TRUE, the names of multiplier are interpreted as regular expressions. See Examples.

approx

logical

tol

numeric: threshold to consider a position zero.

x

a pl object to be printed or to be coerced to a data.frame

further argument

use.crayon

logical

na.print

character: how to print NA values

do.warn

logical: issue warnings?

do.sum

logical: sum profit/loss across instruments?

pl.only

logical: if TRUE, return only numeric vector of profit/loss

Value

For pl, an object of class pl, which is a list of lists: one list for each instrument. Each such list contains numeric vectors: pl, realised, unrealised, buy, sell, volume.

For .pl, a numeric vector with four elements: profit/loss in units of the instrument, sum of absolute amounts, average buy price, average sell price.

Details

Computes profit and/or loss and returns a list with several statistics (see Section Value, below). To get only the profit/loss numbers as a numeric vector, set argument pl.only to TRUE.

pl is a generic function: The default input is vectors for amount, price, etc. Alternatively (and often more conveniently), the function may also be called with a journal or a data.frame as its input. For data frames, columns must be named amount, price, and so on, as in a journal.

pl may be called in two ways: either to compute total profit/loss from a list of trades, possibly broken down by instrument and account; or to compute profit/loss over time. The latter case typically requires setting arguments along.timestamp and/or vprice (see Examples).

Using vprice: when along.timestamp is logical (FALSE or TRUE) , vprice can be used to value an open position. For a single asset, it should be a single number; for several assets, it should be named vector, with names indicating the instrument. When along.timestamp is used to pass a custom timestamp: for a single asset, vprice must be a vector with the same length as along.timestamp; for several assets, it must be a numeric matrix with dimension length(along.timestamp) times number of assets.

To use package crayon -- which is only sensible in interactive use --, either explicitly set use.crayon to TRUE or set an option PMwR.use.crayon to TRUE.

References

Schumann, E. (2018) Portfolio Management with R. http://enricoschumann.net/PMwR/

See Also

btest, returns

Examples

Run this code
# NOT RUN {
J <- journal(timestamp = c(  1,   2,   3),
             amount    = c(  1,   1,  -2),
             price     = c(100, 102, 101))
pl(J)
pl(c(1, 1, -2), c(100,102, 101))  ## without a 'journal'


J <- journal(timestamp  = c(  1,   2,   3,   1,   2,   3),
             amount     = c(  1,   1,  -2,   1,   1,  -2),
             price      = c(100, 102, 101, 100, 102, 105),
             instrument = c(rep("Bond A", 3), rep("Bond B", 3)))

pl(J)
## Bond A
##   P/L total       0
##   average buy   101
##   average sell  101
##   cum. volume     4
##
## Bond B
##   P/L total       8
##   average buy   101
##   average sell  105
##   cum. volume     4
##
## 'P/L total' is in units of instrument;
## 'volume' is sum of /absolute/ amounts.

as.data.frame(pl(J))
##        pl buy sell volume
## Bond A  0 101  101      4
## Bond B  8 101  105      4

pl(pl(J))  ## P/L as a numeric vector




## Example for 'vprice'
instrument  <- c(rep("Bond A", 2), rep("Bond B", 2))
amount <- c(1, -2, 2, -1)
price <- c(100, 101, 100, 105)

## ... no p/l because positions not closed:
pl(amount, price, instrument = instrument, do.warn = FALSE)

## ... but with vprice specified, p/l is computed:
pl(amount, price, instrument = instrument,
   vprice = c("Bond A" = 103, "Bond B" = 100))

### ... and is, except for volume, the same as here:
instrument  <- c(rep("Bond A", 3), rep("Bond B", 3))
amount <- c(1, -2, 1, 2, -1, -1)
price <- c(100, 101, 103, 100, 105, 100)
pl(amount, price, instrument = instrument)



## p/l over time: example for 'along.timestamp' and 'vprice'
j <- journal(amount = c(1, -1),
             price = c(100, 101),
             timestamp  = as.Date(c("2017-07-05", "2017-07-06")))
pl(j)

pl(j,
   along.timestamp = TRUE)

pl(j,
   along.timestamp = seq(from = as.Date("2017-07-04"),
                         to = as.Date("2017-07-07"),
                         by = "1 day"),
   vprice = 101:104)



## Example for 'multiplier'
jnl <- read.table(text =
"instrument, price, amount
 FGBL MAR 16, 165.20,  1
 FGBL MAR 16, 165.37, -1
 FGBL JUN 16, 164.12,  1
 FGBL JUN 16, 164.13, -1
 FESX JUN 16,   2910,  5
 FESX JUN 16,   2905, -5",
header = TRUE, stringsAsFactors = FALSE, sep = ",")


jnl <- as.journal(jnl)
pl(jnl,  multiplier.regexp = TRUE, ## regexp matching is case sensitive
   multiplier = c("FGBL" = 1000, "FESX" = 10))



## use package 'crayon'
# }
# NOT RUN {
## on Windows, you may also need 'options(crayon.enabled = TRUE)'
options(PMwR.use.crayon = FALSE)
pl(amount = c(1, -1), price = c(1, 2))
options(PMwR.use.crayon = TRUE)
pl(amount = c(1, -1), price = c(1, 2))
# }
# NOT RUN {
# }

Run the code above in your browser using DataLab