Plot a list of functions --- in particular optimal price
functions or expected value functions or derivatives of the
expected value functions. Such a list is assumed to occur as
a component of an object produced by xsolve()
of
vsolve()
. The functions in the list are functions
of residual time. The indices of the list correspond to the
number of items available for sale and possibly (for optimal
price functions) the size of the arriving group of customers.
# S3 method for AssetPricing
plot(x,witch=c("price","expVal","vdot"),
xlim=NULL,ylim=NULL,lty=NULL,cols=NULL,xlab=NULL,
ylab=NULL,main=NULL,main.panel= NULL,groups=NULL,
add=FALSE,gloss=FALSE,glind=NULL,extend=0.3,col.gloss=1,
cex.gloss=0.8,mfrow=NULL,...)
A text string indicating which of the three possible components
of x
should be plotted. May be abbreviated, e.g. to
p
, e
or v
.
The x
limits of the plot. Defaults to the tlim
attribute of the object x[[witch]]
. If this attribute does not
exist and xlim
is not supplied then an error is given.
The y
limits of the plot. Defaults to the ylim
attribute of the object x[[witch]]
. If this attribute does not
exist and ylim
is not supplied then an error is given.
A vector of line types. It will be replicated to have a length
equal to the number of rows of groups
(see below).
Defaults to having all entries of the vector equal to 1
,
i.e. solid lines.
A vector of colours for the plotted lines. It will be replicated
to have a length equal to the number of rows of groups
(see below). Defaults to having all entries of the vector equal
to 1
, i.e. black.
A text string giving a label for the x
axis (or axes).
Defaults to the null string. Ignored if add
is TRUE
.
A text string giving a label for the y
axis (or axes).
Defaults to the null string. Ignored if add
is TRUE
.
A text string giving an overall title for the plot or for each
page of plots if there is more than one. Defaults to the null
string and is ignored if add
is TRUE
.
A text string which is replicated “np” times (where
“np” is the total number of panels) or a vector of text
strings of length equal to “np”. Note that “np” will
be equal to the number of unique entries of groups$group
.
(See below.) The \(i^{th}\) entry of the vector is
used as the title of the \(i^{th}\) panel of the plots
that are created. If main.panel
is left NULL
the \(i^{th}\) entry of the vector is set equal to
paste("group",i)
. This argument is ignored if there
is only a single panel.
A data frame with one, two or three columns, named group
,
q
and j
. The total number of rows should be less
than or equal to the total number of entries of the function
list x[[witch]]
. Only those function traces corresponding to a
row of groups
are plotted. The traces corresponding to
an individual value in the group
column are plotted in the
same panel of a multi-panel array of plots. See Details.
Logical scalar; should the plot be added to an existing plot?
Either a logical scalar (should a ``marginal
gloss'' be added to the plot? --- if TRUE
then the gloss
is constructed internally; see Details) or a vector of
character strings of which the marginal gloss is to consist.
A logical vector indicating which entries of
gloss
should actually be used (plotted). I.e. marginal
gloss is added for the graphs of functions whose corresponding
values in the entries of glind
are TRUE
. Ignored if
gloss
is FALSE
. If gloss
is TRUE
or
is explicitly provided, then if glind
is not specified it
defaults to a vector, of the same length as gloss
all of
whose entries are TRUE
.
A scalar, between 0 and 1, indicating how much
the x
-axis should be extended (to the right) in order to
accommodate the marginal gloss.
Scalar specifying the colour in which the
marginal gloss is to be added, e.g. "red"
(or equivalently
2
). The default, i.e. 1
, is black.
Character expansion (cex
) specifier for
the marginal gloss.
The dimensions of the array(s) of panels in which
the functions are plotted. If this argument is left as NULL
then the software makes a “sensible” choice for its value.
If this argument is set equal to NA
then the current value
of mfrow
for the plotting device is left “as is”. This
permits the setting up of an array of panels vi a call to par(mfrow=…)
a priori without the resulting setting being over-ridden by
the internal code of this plotting method. One might wish to do this
e.g. for the purpose of adding plotted material to each
panel.
Extra arguments to be passed to plot
(effectively to plot.function()
or to
plot.stepfun()
).
None. This function exists only for its side effect, i.e. the production of a plot or plots.
If the argument groups
is specified then:
it must always have a column q
. The values
in this column should be integers between 1
and qmax
(see below).
if jmax
(see below) is greater than 1 it must also
have a column j
. The entries of this column should be
integers between 1
and jmax
.
if jmax
is equal to 1
then column j
need not be present. In this case, it is internally set equal
to a column of 1
-s.
if the group
column is present its entries
should be (consecutive) positive integers running from 1
to the total number of groups.
if the group
column is not present then this column
is internally set equal to a column of 1
-s i.e. there is
a single group of traces.
The value of qmax
is the maximum number of items that
are available for sale in the time period under consideration.
It may be obtained as attr(x,"qmax")
.
The value of jmax
is, when “double indexing”
applies, the maximum size of an arriving group of customers,
and is otherwise equal to 1
. It may be obtained as
attr(x,"jmax")
. Note that “double indexing” can
only apply when x[[witch]]
is a list of price
functions, i.e. when witch
is equal to price
.
Hence “double indexing” does not apply when witch
is equal to expVal
or to vdot
. In these cases
jmax
is equal to 1
.
If groups
is not specified then it defaults to a data
frame with number of rows equal to the length of x[[witch]]
, The
group
column has entries all equal to 1, i.e. there is
a single group of traces. The q
and j
columns
contain all possible (valid) combinations of stock size and
customer group size.
If gloss
is FALSE
then no marginal gloss is plotted.
If gloss
is TRUE
then the marginal gloss is created
from the values of the q
and j
entries in the
columns of groups
using paste()
.
Note that if add
is TRUE
then the gloss may not
actually appear in the plot, since it is placed at the right
hand edge of the plot and may consequently be outside of the
plotting region. Thus if you wish to use a gloss when adding to
an existing plot you will probably need to take steps to ensure
that there is room in the right hand margin for the plot to appear,
or possibly set par(xpd=NA)
.
If “double indexing” applies then x[[i]]
corresponds
to a stock size of q
and a customer group size of j
where i = (j-1)*(qmax - j/2) + q
.
To get traces plotted in individual panels (one trace per panel)
set the group
column of groups
to be 1:n
where n
is the total number of traces being plotted.
This function (i.e. plot.AssetPricing()
calls upon an
“internal” function plot.flap()
to do the hard
yakka. (Note that flap
stands for dQuotefunction list
for asset pricing.)
The function plot.flap()
makes use of a modified
version of plot.stepfun()
, rather than the one which
appears in package:stats
. The modification causes
plot.stepfun()
to treat the xlim
argument in a manner
similar to the way in which it is treated by plot.function
.
Note that plot.stepfun()
is not exported from
this package. On the advice of Kurt Hornik (31/03/2018) I
created a new generic plot()
function in this package
(i.e. AssetPricing
) with default method equal to
graphics::plot()
, so as to properly accommodate the
existence of this modified plot.stepfun()
method.
P. K. Banerjee, and T. R. Turner (2012). A flexible model for the pricing of perishable assets. Omega 40:5, 533--540. DOI https://doi.org/10.1016/j.omega.2011.10.001
Rolf Turner, Pradeep Banerjee and Rayomand Shahlori (2014). Optimal Asset Pricing. Journal of Statistical Software 58:11, 1--25. DOI https://doi.org/10.18637/jss.v058.i11
# NOT RUN {
S <- expression(exp(-kappa*x/(1+gamma*exp(-beta*t))))
attr(S,"parvec") <- c(kappa=10/1.5,gamma=9,beta=1)
LAMBDA <- function(tt){
if(tt<0 | tt> 1) 0 else 36*(1-tt)
}
OUT <- xsolve(S=S,lambda=LAMBDA,gprob=(5:1)/15,tmax=1,qmax=30,
alpha=0.5,type="dip",verbInt=2)
GLND <- rep(FALSE,30)
GLND[c(1:5,10,15,20,30)] <- TRUE
plot(OUT,witch="e",xlab="residual time",ylab="expected revenue",
gloss=TRUE,glind=GLND)
GRPS <- data.frame(group=rep(1:6,each=5),q=1:30)
GLND <- c(TRUE,FALSE,TRUE,FALSE,TRUE,rep(c(rep(FALSE,4),TRUE),5))
plot(OUT,witch="e",groups=GRPS,xlab="residual time",ylab="expected revenue",
gloss=TRUE,glind=GLND)
GRPS <- data.frame(group=rep(1:5,each=6),j=rep(1:5,each=6))
GRPS$q <- with(GRPS,pmax(j,rep(c(1,6,11,16,21,26),5)))
GLND <- rep(c(TRUE,TRUE,rep(FALSE,3),TRUE),5)
plot(OUT,witch="p",groups=GRPS,mfrow=c(3,2),gloss=TRUE,glind=GLND,xlab="price")
# Pretty messy looking:
GRPS$group <- 1
GLND <- unlist(lapply(1:5,function(k){(1:6)==k}))
plot(OUT,witch="p",groups=GRPS,gloss=TRUE,glind=GLND,cols=GRPS$j,xlab="price")
# }
Run the code above in your browser using DataLab