journal {PMwR} | R Documentation |
Journal
Description
Create and manipulate a journal of financial transactions.
Usage
journal(amount, ...)
as.journal(x, ...)
is.journal(x)
## Default S3 method:
journal(amount, price, timestamp, instrument,
id = NULL, account = NULL, ...)
## S3 method for class 'journal'
c(..., recursive = FALSE)
## S3 method for class 'journal'
length(x)
## S3 method for class 'journal'
aggregate(x, by, FUN, ...)
## S3 method for class 'journal'
print(x, ...,
width = getOption("width"), max.print = getOption("max.print"),
exclude = NULL, include.only = NULL)
## S3 method for class 'journal'
sort(x, decreasing = FALSE, by = "timestamp", ..., na.last = TRUE)
## S3 method for class 'journal'
summary(object, by = "instrument", drop.zero = TRUE,
na.rm = FALSE, ...)
## S3 method for class 'journal'
subset(x, ...)
## S3 method for class 'journal'
x[i, match.against = NULL,
ignore.case = TRUE, perl = FALSE, fixed = FALSE,
useBytes = FALSE, ..., invert = FALSE]
## S3 replacement method for class 'journal'
x[i, match.against = NULL,
ignore.case = TRUE, ..., invert = FALSE] <- value
## S3 method for class 'journal'
as.data.frame(x, row.names = NULL, optional = FALSE, ...)
## S3 method for class 'journal'
head(x, n = 6L, ..., by = "instrument")
## S3 method for class 'journal'
tail(x, n = 6L, ..., by = "instrument")
Arguments
timestamp |
An atomic vector of mode numeric or character. Timestamps should typically be sortable. |
amount |
numeric |
price |
numeric |
instrument |
character or numeric (though typically character) |
id |
An atomic vector. Default is |
account |
An atomic vector. Default is |
... |
For For For For |
x |
a |
object |
a |
width |
integer. See |
decreasing |
passed to |
by |
|
na.rm |
logical |
drop.zero |
logical |
na.last |
arguments passed to sort |
max.print |
maximum number of transactions to print |
exclude |
character: fields that should not be printed |
include.only |
character: print only those fields. (Not supported yet.) |
row.names |
see |
optional |
see |
recursive |
ignored (see |
i |
integer, logical or character. The latter is interpreted as a
regexp (see |
n |
integer |
match.against |
character vector of field names. Default is |
ignore.case |
logical: passed to |
perl |
logical: passed to |
fixed |
logical: passed to |
useBytes |
logical: passed to |
invert |
logical. If |
FUN |
either a function that takes as input a journal and evaluates to a journal, or a list of named functions |
value |
a replacement value |
Details
The journal
function creates a list of its arguments
and attaches a class attribute (‘journal
’).
It is a generic function; the default method creates a
journal from atomic vectors. The btest
method
extracts the journal from the results of a backtest; see
btest
.
as.journal
coerces an object to a journal and is
primarily used for creating a journal from a
data.frame
.
Calling as.journal
on an unnamed numeric vector
interprets the vector as amounts. If the vector is named,
these are interpreted as instruments; see Examples. Calling
as.journal
on a journal returns the journal itself.
journal
methods are available for several generic
functions, for instance:
all.equal
compare contents of two journals
aggregate
Splits a journal according to
by
, applies a function to every sub-journal and recombines the results into a journal.as.data.frame
Coerce journal to
data.frame
.c
Combine several journals into one. Note that the first argument to
c.journal
must inherit fromjournal
, or else the method dispatch will fail. For empty journals, usejournal()
(notNULL
).length
number of transactions in a journal; it uses the length of
amount
split
Splits a journal according to
f
, yielding a list of journals. Often used interactively to have information per sub-journal printed.subset
evaluates an expression in an environment that can access all fields of the journal. The function is meant for interactive analysis; care is needed when it is used within other functions: see Examples and the Manual.
summary
provides summary statistics, such as number of trades and average buy/sell prices
toOrg
converts a journal to an Org table; package orgutils must be available
For journals that have a length, missing arguments will be
coded as NA
except for id
and
account
, which become NULL
. In
zero-length (i.e. ‘empty’) journals, all fields have
length 0. A zero-length journal is created, for instance,
by saying journal()
or when an zero-row
data.frame
is passed to as.journal
.
Value
An object of class journal
, which is a list of atomic
vectors.
Author(s)
Enrico Schumann <es@enricoschumann.net>
References
Schumann, E. (2023) Portfolio Management with R.
https://enricoschumann.net/R/packages/PMwR/;
in particular, see
https://enricoschumann.net/R/packages/PMwR/manual/PMwR.html#journals
See Also
Examples
j <- journal(timestamp = 1:3,
amount = c(1,2,3),
price = 101:103,
instrument = c("Stock A", "Stock A", "Stock B"))
## *** subset *** in functions
## this should work as expected ...
t0 <- 2.5
subset(j, timestamp > t0)
## ... but here?!
tradesAfterT <- function(j, t0)
subset(j, timestamp > t0)
tradesAfterT(j, 0)
## if really required
tradesAfterT <- function(j, t0) {
e <- substitute(timestamp > t0, list(t0 = t0))
do.call(subset, list(j, e))
}
tradesAfterT(j, 0)
## ... or much simpler
tradesAfterT <- function(j, t0)
j[j$timestamp > t0]
tradesAfterT(j, 0)
## *** aggregate ***
## several buys and sells on two days
## aim: find average buy/sell price per day
j <- journal(timestamp = structure(c(15950, 15951, 15950, 15951, 15950,
15950, 15951, 15951, 15951, 15951),
class = "Date"),
amount = c(-3, -4, -3, -1, 3, -2, 1, 3, 5, 3),
price = c(104, 102, 102, 110, 106, 104, 104, 106, 108, 107),
instrument = c("B", "B", "A", "A", "B", "B", "A", "B", "A", "A"))
by <- list(j$instrument, sign(j$amount), as.Date(j$timestamp))
fun <- function(x) {
journal(timestamp = as.Date(x$timestamp[1]),
amount = sum(x$amount),
price = sum(x$amount*x$price)/sum(x$amount),
instrument = x$instrument[1L])
}
aggregate(j, by = by, FUN = fun)
## *** iterate over transactions in (previously defined) journal ***
for (j in split(j, seq_along(j)))
print(j)
## as.journal with numeric vector
as.journal(1:3)
## amount
## 1 1
## 2 2
## 3 3
##
## 3 transactions
## as.journal with *named* numeric vector
x <- 1:3; names(x) <- LETTERS[1:3]
as.journal(x)
## instrument amount
## 1 A 1
## 2 B 2
## 3 C 3
##
## 3 transactions
x <- 1:3; names(x) <- c("A", "B", "A")
as.journal(x)
## instrument amount
## 1 A 1
## 2 B 2
## 3 A 3
##
## 3 transactions