Become an expert in R — Interactive courses, Cheat Sheets, certificates and more!
Get Started for Free

pl

Profit and Loss


Description

Compute profit and (or) loss of financial transactions.

Usage

pl(amount, ... )

## Default S3 method:
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,
   footnotes = TRUE, ... )

## S3 method for class '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 class 'pl'
pl(amount, ... )

## S3 method for class 'pl'
print(x, ..., use.crayon = NULL, na.print = ".",
        footnotes = TRUE)

## S3 method for class '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

logical; or a a vector of timestamps. If the latter, vprice must be specified as well. See the vignette “Profit/Loss for Open Positions” (pl_open_positions) for details. Timestamps must be in ascending order and will be sorted if they are not (and vprice will then be sorted as well).

initial.position

a 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

footnotes

logical, with default TRUE: collect and print notes?

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). Profit/loss over time is always computed with time in ascending order: so if the timestamps in along.timestamp are not sorted, the function will sort them (and vprice as well).

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.

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.

Author(s)

Enrico Schumann <es@enricoschumann.net>

References

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

See Also

Examples

J <- journal(timestamp = c(  1,   2,   3),
             amount    = c(  1,   1,  -2),
             price     = c(100, 102, 101))
pl(J)

pl(amount = c(  1,   1,  -2),
   price  = 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))  ## a single data.frame
##        pl buy sell volume
## Bond A  0 101  101      4
## Bond B  8 101  105      4

lapply(pl(J), as.data.frame)  ## => a list of data.frames
## $`Bond A`
##   pl realised unrealised buy sell volume
## 1  0       NA         NA 101  101      4
##
## $`Bond B`
##   pl realised unrealised buy sell volume
## 1  8       NA         NA 101  105      4

pl(pl(J))  ## P/L as a numeric vector
## Bond A Bond B
##      0      8




## 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))

## End(Not run)

PMwR

Portfolio Management with R

v0.16-0
GPL-3
Authors
Enrico Schumann [aut, cre] (<https://orcid.org/0000-0001-7601-6576>)
Initial release
2021-01-19

We don't support your browser anymore

Please choose more modern alternatives, such as Google Chrome or Mozilla Firefox.