journal: Journal

View source: R/journal.R

journalR 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 NULL.

account

An atomic vector. Default is NULL.

...

For journal: further arguments, which must all be named.

For subset: an expression that evaluates to a logical vector. The expression may use all fields of the passed journal; see Examples.

For `[`: arguments other than ignore.case to be passed to grep.

For sort: arguments passed to sort.

x

a journal or an object to be coerced to class journal (for as.journal) or to be checked if it inherits from journal (for is.journal)

object

a journal

width

integer. See options.

decreasing

passed to sort

by

sort: sort by field. head/tail: by field (default is instrument). summary: a vector of keywords (or NULL); supported are "instrument", "year" and "month".

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 as.data.frame

optional

see as.data.frame

recursive

ignored (see c)

i

integer, logical or character. The latter is interpreted as a regexp (see grep)

n

integer

match.against

character vector of field names. Default is NULL, which means to match against all character fields.

ignore.case

logical: passed to grepl

perl

logical: passed to grepl

fixed

logical: passed to grepl

useBytes

logical: passed to grepl

invert

logical. If TRUE, invert selection (when i is of mode character, select journal entries that do not match regular expression)

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 from journal, or else the method dispatch will fail. For empty journals, use journal() (not NULL).

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. http://enricoschumann.net/R/packages/PMwR/; in particular, see
http://enricoschumann.net/R/packages/PMwR/manual/PMwR.html#journals

See Also

position, pl

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

enricoschumann/PMwR documentation built on April 13, 2024, 12:18 p.m.