Profit/loss and position valuations over time

In this note we'll look into how to compute the profit/loss and the value of a position over time. Suppose we traded in two stocks, AMZN and MSFT.

```library("PMwR")
library("zoo")
j <- journal(amount = c(10, -10, 20, 5),
instrument = c("MSFT", "MSFT", "MSFT", "AMZN"),
price = c(178, 178.5, 180.7, 2315),
timestamp = as.Date(c("2020-05-04", "2020-05-04",
"2020-05-05", "2020-05-05")))
j
```
```   instrument   timestamp  amount   price
1        MSFT  2020-05-04      10   178.0
2        MSFT  2020-05-04     -10   178.5
3        MSFT  2020-05-05      20   180.7
4        AMZN  2020-05-05       5  2315.0

4 transactions
```

We want to look at the profit/loss and position value for the week from May, 4th to May, 8th. We store these dates in a variable `timestamp`.

```timestamp <- seq(from = as.Date("2020-05-04"),
to   = as.Date("2020-05-08"),
by   = "1 day")
timestamp
```
```[1] "2020-05-04" "2020-05-05" "2020-05-06" "2020-05-07" "2020-05-08"
```

We'll need prices at which to value open position: we prepare them as `zoo` series.

```MSFT <- structure(c(178.84, 180.76, 182.54, 183.6, 184.68),
.Dim = c(5L, 1L),
.Dimnames = list(NULL, "us5949181045"),
index = structure(
c(18386, 18387, 18388, 18389, 18390), class = "Date"),
class = "zoo")

AMZN <- structure(c(2286.04, 2315.99, 2317.8, 2351.26, 2367.61, 2379.61),
.Dim = c(6L, 1L),
.Dimnames = list(NULL, "us0231351067"),
index = structure(
c(18383, 18386, 18387, 18388, 18389, 18390), class = "Date"),
class = "zoo")
AMZN <- AMZN[-4L]
MSFT
AMZN
```
```           us5949181045
2020-05-04       178.84
2020-05-05       180.76
2020-05-06       182.54
2020-05-07       183.60
2020-05-08       184.68

us0231351067
2020-05-01      2286.04
2020-05-04      2315.99
2020-05-05      2317.80
2020-05-07      2367.61
2020-05-08      2379.61
```

Note that the two series are, on purpose, not synchronous, and that AMZN is missing one price.

Next, we create a matrix of prices.

```P <- pricetable(AMZN, MSFT, instrument = c("AMZN", "MSFT"))
P <- P[timestamp, c("MSFT", "AMZN"), missing = "previous"]
P
```
```             MSFT    AMZN
2020-05-04 178.84 2315.99
2020-05-05 180.76 2317.80
2020-05-06 182.54 2317.80
2020-05-07 183.60 2367.61
2020-05-08 184.68 2379.61
```

Note that subsetting a pricetable results in a numeric matrix.

```str(P)
```
```num [1:5, 1:2] 179 181 183 184 185 ...
- attr(*, "dimnames")=List of 2
..\$ : chr [1:5] "2020-05-04" "2020-05-05" "2020-05-06" "2020-05-07" ...
..\$ : chr [1:2] "MSFT" "AMZN"
```

Let us first look at profit/loss first: we only need to provide the journal `j` of the trades as created above, the timestamps at which to compute profit/loss, and the prices for valuing open positions.

```pl(j, along.timestamp = timestamp, vprice = P)
```
```AMZN
timestamp     2020-05-04 2020-05-05 2020-05-06 2020-05-07 2020-05-08
P/L total           0.00      14.00      14.00     263.05     323.05
__ realised            0          0          0          0          0
__ unrealised       0.00      14.00      14.00     263.05     323.05
average sell         NaN
cum. volume            0          5          5          5          5

MSFT
timestamp     2020-05-04 2020-05-05 2020-05-06 2020-05-07 2020-05-08
P/L total            5.0        6.2       41.8       63.0       84.6
__ realised            5          5          5          5          5
__ unrealised        0.0        1.2       36.8       58.0       79.6
average sell       178.5
cum. volume           20         40         40         40         40

‘P/L total’ is in units of instrument;
‘volume’ is sum of /absolute/ amounts.
```

We can also look at the position values over time. Note that the call to `valuation` is similar to that of `pl`: we pass the position, computed at the timestamps defined above; the prices for valuing the open positions, and we also set the argument `use.names` to `TRUE`. This ensures that `valuation` will look at the column names of `P` and associate the prices there with the instruments specified in the journal `j`.

```valuation(position(j, when = timestamp), vprice = P, use.names = TRUE)
```
```               AMZN   MSFT
2020-05-04     0.00    0.0
2020-05-05 11589.00 3615.2
2020-05-06 11589.00 3650.8
2020-05-07 11838.05 3672.0
2020-05-08 11898.05 3693.6

attr(,"position")
AMZN MSFT
2020-05-04    0    0
2020-05-05    5   20
2020-05-06    5   20
2020-05-07    5   20
2020-05-08    5   20
```

Remarks

In function `valuation`, the argument `vprice` had been called `price.table` prior to package version 0.15, but has been renamed because since that version it very much resembles `vprice` in function `pl`. There are two differences, explained below. For clarity, I'll write `pl/vprice` and `valuation/vprice`, to differentiate between the two arguments.

1. `pl/vprice` must always be ordered in time. That is, if you want to compute profit/loss over time, the timestamps must be in ascending order. If the timestamps passed via `along.timestamp` are not ordered, they will get sorted in time, and `pl/vprice` will get appropriately sorted, too.

For valuation, by contrast, prices need not be in temporal order; in fact, `valuation` does not care at all about timestamps. That should be intuitive: profit/loss is essentially a difference between values, so the order of the values matters, which is not the case for positions.

2. There is an argument `use.names` in `valuation`, which controls whether (column) names of `valuation/vprice` are interpreted as instruments and hence elements of `valuation/vprice` are matched accordingly. Default for `use.names` is `FALSE`, so such information is not used and the elements in `valuation/vprice` must directly correspond to the elements in the `position` matrix.

Keeping the default at `FALSE` means that the behaviour prior to package version 0.15 is kept (though this may change in a future release). This default is different from `pl`: names of `pl/vprice` are always interpreted as instruments. The reason is simple: when computing `pl` from a journal, the user typically does not control the order of instruments in the resulting `pl`. Instruments get sorted by the function, but the user is not expected to anticipate this ordering.

This is different when valuing a position: a position is essentially a matrix in which each row corresponds to a valuation timestamp, and each column corresponds to an instrument. So the user knows the structure of the position and can prepare `valuation/vprice` accordingly.