© Copyright 1986-2008 by the University of Washington. Written by Joseph Felsenstein. Permission is granted to copy this document provided that no fee is charged for it and that this copyright notice is not removed.
These programs are intended for the use of morphological systematists who are dealing with discrete characters, or by molecular evolutionists dealing with presence-absence data on restriction sites. One of the programs (Pars) allows multistate characters, with up to 8 states, plus the unknown state symbol "?". For the others, the characters are assumed to be coded into a series of (0,1) two-state characters. For most of the programs there are two other states possible, "P", which stands for the state of Polymorphism for both states (0 and 1), and "?", which stands for the state of ignorance: it is the state "unknown", or "does not apply". The state "P" can also be denoted by "B", for "both".
There is a method invented by Sokal and Sneath (1963) for linear sequences of character states, and fully developed for branching sequences of character states by Kluge and Farris (1969) for recoding a multistate character into a series of two-state (0,1) characters. Suppose we had a character with four states whose character-state tree had the rooted form:
1 ---> 0 ---> 2 | | V 3
so that 1 is the ancestral state and 0, 2 and 3 derived states. We can represent this as three two-state characters:
Old State New States --- ----- --- ------ 0 001 1 000 2 011 3 101
The three new states correspond to the three arrows in the above character state tree. Possession of one of the new states corresponds to whether or not the old state had that arrow in its ancestry. Thus the first new state corresponds to the bottommost arrow, which only state 3 has in its ancestry, the second state to the rightmost of the top arrows, and the third state to the leftmost top arrow. This coding will guarantee that the number of times that states arise on the tree (in programs Mix, Move, Penny and Boot) or the number of polymorphic states in a tree segment (in the Polymorphism option of Dollop, Dolmove, Dolpenny and Dolboot) will correctly correspond to what would have been the case had our programs been able to take multistate characters into account. Although I have shown the above character state tree as rooted, the recoding method works equally well on unrooted multistate characters as long as the connections between the states are known and contain no loops.
However, in the default option of programs Dollop, Dolmove, Dolpenny and Dolboot the multistate recoding does not necessarily work properly, as it may lead the program to reconstruct nonexistent state combinations such as 010. An example of this problem is given in my paper on alternative phylogenetic methods (1979).
If you have multistate character data where the states are connected in a branching "character state tree" you may want to do the binary recoding yourself. Thanks to Christopher Meacham, the package contains a program, Factor, which will do the recoding itself. For details see the documentation file for Factor.
We now also have the program Pars, which can do parsimony for unordered character states.
The methods used in these programs make different assumptions about evolutionary rates, probabilities of different kinds of events, and our knowledge about the characters or about the character state trees. Basic references on these assumptions are my 1979, 1981b and 1983b papers, particularly the latter. The assumptions of each method are briefly described in the documentation file for the corresponding program. In most cases my assertions about what are the assumptions of these methods are challenged by others, whose papers I also cite at that point. Personally, I believe that they are wrong and I am right. I must emphasize the importance of understanding the assumptions underlying the methods you are using. No matter how fancy the algorithms, how maximum the likelihood or how minimum the number of steps, your results can only be as good as the correspondence between biological reality and your assumptions!
The input format is as described in the general documentation file. The input starts with a line containing the number of species and the number of characters.
In Pars, each character can have up to 8 states plus a "?" state. In any character, the first 8 symbols encountered will be taken to represent these states. Any of the digits 0-9, letters A-Z and a-z, and even symbols such as + and -, can be used (and in fact which 8 symbols are used can be different in different characters).
In the other discrete characters programs the allowable states are, 0, 1, P, B, and ?. Blanks may be included between the states (i. e. you can have a species whose data is DISCOGLOSS0 1 1 0 1 1 1). It is possible for extraneous information to follow the end of the character state data on the same line. For example, if there were 7 characters in the data set, a line of species data could read "DISCOGLOSS0110111 Hello there").
The discrete character data can continue to a new line whenever needed. The characters are not in the "aligned" or "interleaved" format used by the molecular sequence programs: they have the name and entire set of characters for one species, then the name and entire set of characters for the next one, and so on. This is known as the sequential format. Be particularly careful when you use restriction sites data, which can be in either the aligned or the sequential format for use in Restml but must be in the sequential format for these discrete character programs.
For Pars the discrete character data can be in either Sequential or Interleaved format; the latter is the default.
Errors in the input data will often be detected by the programs, and this will cause them to issue an error message such as 'BAD OUTGROUP NUMBER: ' together with information as to which species, character, or in this case outgroup number is the incorrect one. The program will then terminate; you will have to look at the data and figure out what went wrong and fix it. Often an error in the data causes a lack of synchronization between what is in the data file and what the program thinks is to be there. Thus a missing character may cause the program to read part of the next species name as a character and complain about its value. In this type of case you should look for the error earlier in the data file than the point about which the program is complaining.
Specific information on options will be given in the documentation file associated with each program. However, some options occur in many programs. Options are selected from the menu in each program.
An example is:
001??11
The ancestor information can be continued to a new line and can have blanks between any of the characters in the same way that species character data can. In the program Clique the ancestor is instead to be included as a regular species and no A option is available.
For example, if there were 20 binary characters that had been generated by nine multistate characters having respectively 4, 3, 3, 2, 1, 2, 2, 2, and 1 binary factors you would make the factors file be:
11112223334456677889
although it could equivalently be:
aaaabbbaaabbabbaabba
All that is important is that the symbol for each binary character change only when adjacent binary characters correspond to different mutlistate characters. The factors file contents can continue to a new line at any time except during the initial characters filling out the length of a species name.
WWWCC WWCWC
Note that blanks in the seqence of characters (after the first ones that are as long as the species names) will be ignored, and the information can go on to a new line at any point. So this could equally well have been specified by
WW CCCWWCWC
On the line in that table corresponding to each branch of the tree will also be printed "yes", "no" or "maybe" as an answer to the question of whether this branch is of nonzero length. If there is no evidence that any character has changed in that branch, then "no" will be printed. If there is definite evidence that one has changed, then "yes" will be printed. If the matter is ambiguous, then "maybe" will be printed. You should keep in mind that all of these conclusions assume that we are only interested in the assignment of states that require the least amount of change. In reality, the confidence limit on tree topology usually includes many different topologies, and presumably also then the confidence limits on amounts of change in branches are also very broad.
In addition to the table showing numbers of events, a table may be printed out showing which ancestral state causes the fewest events for each character. This will not always be done, but only when the tree is rooted and some ancestral states are unknown. This can be used to infer states of occurred and making it easy for the user to reconstruct all the alternative patterns of the characters states in the hypothetical ancestral nodes. In Pars you can, using the menu, turn off this dot-differencing convention and see all states at all hypothetical ancestral nodes of the tree.
If you select the proper menu option, a table of the number of events required in each character can also be printed, to help in reconstructing the placement of changes on the tree.
This table may not be obvious at first. A typical example looks like this:
steps in each character: 0 1 2 3 4 5 6 7 8 9 *----------------------------------------- 0! 2 2 2 2 1 1 2 2 1 10! 1 2 3 1 1 1 1 1 1 2 20! 1 2 2 1 2 2 1 1 1 2 30! 1 2 1 1 1 2 1 3 1 1 40! 1The numbers across the top and down the side indicate which character is being referred to. Thus character 23 is column "3" of row "20" and has 2 steps in this case.
I cannot emphasize too strongly that just because the tree diagram which the program prints out contains a particular branch MAY NOT MEAN THAT WE HAVE EVIDENCE THAT THE BRANCH IS OF NONZERO LENGTH. In some of the older programs, the procedure which prints out the tree cannot cope with a trifurcation, nor can the internal data structures used in some of my programs. Therefore, even when we have no resolution and a multifurcation, successive bifurcations may be printed out, although some of the branches shown will in fact actually be of zero length. To find out which, you will have to work out character by character where the placements of the changes on the tree are, under all possible ways that the changes can be placed on that tree.
In Pars, Mix, Penny, Dollop, and Dolpenny the trees will be (if the user selects the option to see them) accompanied by tables showing the reconstructed states of the characters in the hypothetical ancestral nodes in the interior of the tree. This will enable you to reconstruct where the changes were in each of the characters. In some cases the state shown in an interior node will be "?", which means that either 0 or 1 would be possible at that point. In such cases you have to work out the ambiguity by hand. A unique assignment of locations of changes is often not possible in the case of the Wagner parsimony method. There may be multiple ways of assigning changes to segments of the tree with that method. Printing only one would be misleading, as it might imply that certain segments of the tree had no change, when another equally valid assignment would put changes there. It must be emphasized that all these multiple assignments have exactly equal numbers of total changes, so that none is preferred over any other.
I have followed the convention of having a "." printed out in the table of character states of the hypothetical ancestral nodes whenever a state is 0 or 1 and its immediate ancestor is the same. This has the effect of highlighting the places where changes might have occurred and making it easy for the user to reconstruct all the alternative patterns of the characters states in the hypothetical ancestral nodes. In Pars you can, using the menu, turn off this dot-differencing convention and see all states at all hypothetical ancestral nodes of the tree.
On the line in that table corresponding to each branch of the tree will also be printed "yes", "no" or "maybe" as an answer to the question of whether this branch is of nonzero length. If there is no evidence that any character has changed in that branch, then "no" will be printed. If there is definite evidence that one has changed, then "yes" will be printed. If the matter is ambiguous, then "maybe" will be printed. You should keep in mind that all of these conclusions assume that we are only interested in the assignment of states that requires the least amount of change. In reality, the confidence limit on tree topology usually includes many different topologies, and presumably also then the confidence limits on amounts of change in branches are also very broad.
In addition to the table showing numbers of events, a table may be printed out showing which ancestral state causes the fewest events for each character. This will not always be done, but only when the tree is rooted and some ancestral states are unknown. This can be used to infer states of ancestors. For example, if you use the O (Outgroup) and A (Ancestral states) options together, with at least some of the ancestral states being given as "?", then inferences will be made for those characters, as the outgroup makes the tree rooted if it was not already.
In programs Mix and Penny, if you are using the Camin-Sokal parsimony option with ancestral state "?" and it turns out that the program cannot decide between ancestral states 0 and 1, it will fail to even attempt reconstruction of states of the hypothetical ancestors, printing them all out as "." for those characters. This is done for internal bookkeeping reasons -- to reconstruct their changes would require a fair amount of additional code and additional data structures. It is not too hard to reconstruct the internal states by hand, trying the two possible ancestral states one after the other. A similar comment applies to the use of ancestral state "?" in the Dollo or Polymorphism parsimony methods (programs Dollop and Dolpenny) which also can result in a similar hesitancy to print the estimate of the states of the hypothetical ancestors. In all of these cases the program will print "?" rather than "no" when it describes whether there are any changes in a branch, since there might or might not be changes in those characters which are not reconstructed.
For further information see the documentation files for the individual programs.


Every day is taco ipsum tuesday. Josh’s taco shack is the best taco shack. These tacos are lit 🔥. Make it a double there pal. Josh’s taco shack is the best taco shack. It’s a wonderful morning for breakfast tacos. Tacos, tacos, tacos. Tacos for breakfast, lunch and dinner. Fish tacos: lettuce or cabbage, pico de gallo, avocado and a sour cream or citrus/mayonnaise sauce, all placed on top of a corn or flour tortilla. You see, the refried beans are really just the adhesive necessary to apply the soft tortilla to the hard taco shell.
Let’s do a beef and a chicken, and one with both. Give me all the tacos, immediately. Give me tacos, or give me death. It’s a wonderful morning for breakfast tacos. Tacos for breakfast, lunch and dinner. Carne asada on corn tortillas. Um, Tabasco? No thanks, do you have any Cholula? Tacos, tacos, tacos. I’ve been following that taco truck around all day.
These tacos are lit 🔥. It’s taco time all the time. Fish tacos: lettuce or cabbage, pico de gallo, avocado and a sour cream or citrus/mayonnaise sauce, all placed on top of a corn or flour tortilla. Does guac cost extra? I’d have to say, those tacos are on fleek. Can you put some peppers and onions on that? It’s raining tacos, from out of the sky, tacos, don’t even ask why. Carne asada on corn tortillas. Let’s do a beef and a chicken, and one with both. CARNITAS!! BARBACOA!!


Super Eagles off to Lesotho Saturday
by The Eagle OnlineThree-time African champions, the Super Eagles, is billed to depart the country for Maseru on Saturday for their second AFCON 2021 qualifying group game against the Squirrels of Lesotho.
Toyin Ibitoye, the team’s media officer, disclosed this in a telephone interview on Friday.
According to Ibitoye, arrangements have been concluded for the team travel to Maseru on Saturday, saying the date was strategically made to ensure the lads are in good stead for the game.
He informed: “Lesotho is a high altitude region and we have been advise on when to arrive the country in to avoid terrible conditions that might affect the player.
“So, we would traveling tomorrow, Saturday, for the game on Sunday.”
The Nigerian side is expected travel from Nigeria to Lesotho for six hours, 22 minutes.
Checks also revealed that the city of Maseru would be partly cloudy, 30 per cent degree centigrade and could be windy on match day.
The 20,000 capacity Setsoto Stadium, which was renovated and enlarged in 2011, hosts the game.
Meanwhile, Super Eagles’ captain, Ahmed Musa, has expressed concerns over the synthetic pitch for the game against Lesotho will make it even more difficult.
Must said: “As you can see, it was a tough game against Benin but at the end of 90 minutes, we have three points so we are going over there to have another win because we know that the game is going to be very tough.
“We are going to play on an artificial pitch.
“It is not that easy because some of the players are not used to playing on a synthetic pitch.
“But we know what everybody expects from us so we are going there to do our best to win.”
Ranked 138th in the latest FIFA ranking, Lesotho registered an impressive 1-1 draw against hosts Sierra Leone (117th) in their Africa Cup of Nations qualifiers Group L opener in Freetown.
Previous Post
Atiku mourns Alex Akinyele
Next Post
NFF not owing Rohr salaries — Pinnick


{% extends 'base.html' %} {% load crispy_forms_tags %} {% block content %}
Already have an account? Sign In


| Constructor and Description |
|---|
InMemoryAtomStore() |
| Modifier and Type | Method and Description |
|---|---|
io.reactivex.Observable<AtomObservation> |
getAtomObservations(RadixAddress address)
Retrieve a never ending observable of atom observations (STORED and DELETED)
which are then processed by the local store.
|
java.util.List<ParticleGroup> |
getStagedAndClear(java.lang.String uuid)
Retrieves all staged particle groups and clears the staging area
for the given uuid.
|
java.util.stream.Stream<Atom> |
getStoredAtoms(RadixAddress address)
Retrieve the current set of validated atoms at a given shardable
|
java.util.stream.Stream<Particle> |
getUpParticles(RadixAddress address,
java.lang.String stagedUuid)
Retrieve the current set of validated up particles at a given shardable.
|
io.reactivex.Observable<java.lang.Long> |
onSync(RadixAddress address)
Temporary interface for propagating when the current store
is synced with some node on a given address.
|
void |
stageParticleGroup(java.lang.String uuid,
ParticleGroup particleGroup)
Adds the particle group to the staging area for the given uuid
|
void |
store(RadixAddress address,
AtomObservation atomObservation)
Store an atom under a given destination
|
public void stageParticleGroup(java.lang.String uuid, ParticleGroup particleGroup)
AtomStore
stageParticleGroup
in interface AtomStore
uuid
- the uuid to add the particle group toparticleGroup
- the particle group to add to staging areapublic java.util.List<ParticleGroup> getStagedAndClear(java.lang.String uuid)
AtomStore
getStagedAndClear
in interface AtomStore
uuid
- uuid to retrieve the staged particle groups forpublic void store(RadixAddress address, AtomObservation atomObservation)
address
- address to store underatomObservation
- the atom to storepublic io.reactivex.Observable<java.lang.Long> onSync(RadixAddress address)
AtomStore
public java.util.stream.Stream<Atom> getStoredAtoms(RadixAddress address)
AtomStore
getStoredAtoms
in interface AtomStore
address
- the address to get the atoms underpublic java.util.stream.Stream<Particle> getUpParticles(RadixAddress address, @Nullable java.lang.String stagedUuid)
AtomStore
getUpParticles
in interface AtomStore
address
- the address to get the particles understagedUuid
- uuid of staged particles to includepublic io.reactivex.Observable<AtomObservation> getAtomObservations(RadixAddress address)
AtomStore
getAtomObservations
in interface AtomStore
address
- the address to get the updates from


|
My Project
|
Compute VaR of a portfolio through Monte Carlo simulation. More...
#include <ptf_var.h>
Public Types | |
| typedef MCEngine< rng, V > | engine |
| typedef std::vector< V > | processes |
Public Member Functions | |
| VaRPtfMCCompute (const shared_ptr< Portfolio > &_ptf, T &_model, const processes &_processes_, rng &_rng_, double _alpha=.05) | |
| virtual | ~VaRPtfMCCompute () |
| double | computeVaR () |
| Vec | computeVaRWholePath () |
| compute VaR over whole path More... | |
| Public Member Functions inherited from VaRPtfCompute | |
| VaRPtfCompute (const shared_ptr< Portfolio > &_ptf, double _alpha=.05) | |
| virtual | ~VaRPtfCompute () |
| VaRPtfCompute (const VaRPtfCompute &other) | |
| double | getPtfVaR () const |
| Compute dollar ptf's VaR. More... | |
| double | computeIncrementalVaR (double amount) const |
| Measure the change in VaR if new position is added to the ptf. More... | |
| Vec | computeMarginalVaR () const |
| Measure the change in ptf VaR resulting adding add $ to a component. More... | |
| Vec | computeComponentVaR () const |
| Vec | computeIndividualVaR () const |
| Compute VaR of each single position. More... | |
| void | setAlpha (double _alpha) |
Additional Inherited Members | |
| Protected Attributes inherited from VaRPtfCompute | |
| shared_ptr< Portfolio > | ptf |
| double | alpha |
| Vec | beta |
| size_t | nbAssets |
Compute VaR of a portfolio through Monte Carlo simulation.
Simulate each component separately
| typedef MCEngine<rng,V> VaRPtfMCCompute< T, V >::engine |
| typedef std::vector<V> VaRPtfMCCompute< T, V >::processes |
|
inline |
|
inlinevirtual |
|
inline |
|
inline |
compute VaR over whole path


{% extends "base.html" %} {% block title %}
Medieval catalogues > SCOTLAND
{% endif %}
All data was derived from the List of Identifications by Professor Richard Sharpe.
{% if not printing %}
A key to codes used in the List is available (opens in new tab).{% endif %}


| Modifier and Type | Method and Description |
|---|---|
static SetVar |
VariableFactory.set(String NAME,
int[] ENVELOPE,
SetType ENV_TYPE,
int[] KERNEL,
SetType KER_TYPE,
Solver SOLVER)
Builds a set variable with an initial domain given by ENVELOP and KERNEL.
|
| Constructor and Description |
|---|
SetVarImpl(String name,
int[] env,
SetType envType,
int[] ker,
SetType kerType,
Solver solver)
Creates a Set variable
|
| Modifier and Type | Method and Description |
|---|---|
SetType |
UndirectedGraph.getType() |
SetType |
IGraph.getType()
Get the type of data structures used in the graph
|
SetType |
DirectedGraph.getType() |
| Constructor and Description |
|---|
DirectedGraph(int n,
SetType type,
boolean allNodes)
Creates an empty graph.
|
DirectedGraph(Solver solver,
int n,
SetType type,
boolean allNodes)
Creates an empty backtrable graph of n nodes
Allocates memory for n nodes (but they should then be added explicitly,
unless allNodes is true).
|
UndirectedGraph(int n,
SetType type,
boolean allNodes)
Creates an empty (non-backtrackable) undirected graph.
|
UndirectedGraph(Solver solver,
int n,
SetType type,
boolean allNodes)
Creates an empty backtrable undirected graph.
|
| Modifier and Type | Field and Description |
|---|---|
static SetType |
SetType.ENVELOPE_BEST |
static SetType |
SetType.KERNEL_BEST |
| Modifier and Type | Method and Description |
|---|---|
SetType |
Set_Trail.getSetType() |
SetType |
Set_Std_BitSet.getSetType() |
SetType |
Set_Full.getSetType() |
SetType |
Set_Copy.getSetType() |
SetType |
ISet.getSetType() |
static SetType |
SetType.valueOf(String name)
Returns the enum constant of this type with the specified name.
|
static SetType[] |
SetType.values()
Returns an array containing the constants of this enum type, in
the order they are declared.
|
| Modifier and Type | Method and Description |
|---|---|
static ISet |
SetFactory.makeSet(SetType type,
int maximumSize)
Make a set of integers in the range [0,maximumSize-1]
|
static ISet |
SetFactory.makeStoredSet(SetType type,
int maximumSize,
Solver solver)
Make a stored set of integers in the range [0,maximumSize-1]
Such a set is restored after a backtrack
|
| Modifier and Type | Method and Description |
|---|---|
SetType |
Set_LinkedList.getSetType() |
SetType |
Set_2LinkedList.getSetType() |
| Modifier and Type | Method and Description |
|---|---|
SetType |
Set_Std_Array.getSetType() |
SetType |
Set_BitSet.getSetType() |
SetType |
Set_Array.getSetType() |
| Modifier and Type | Method and Description |
|---|---|
SetType |
Set_Swap_Hash.getSetType() |
SetType |
Set_Swap_Array.getSetType() |
Copyright © 2015. All rights reserved.


# Copyright 2018 Goldman Sachs.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
#
# Chart Service will attempt to make public functions (not prefixed with _) from this module available. Such functions
# should be fully documented: docstrings should describe parameters and the return value, and provide a 1-line
# description. Type annotations should be provided for parameters.
from datetime import date, time, timedelta
from numbers import Real
import numpy as np
from .helper import *
from ..errors import MqValueError
from ..datetime.date import DayCountConvention, PaymentFrequency, day_count_fraction
from ..datetime.date import date_range as _date_range
"""
Date and time manipulation for timeseries, including date or time shifting, calendar operations, curve alignment and
interpolation operations. Includes sampling operations based on daif dates[0]te or time manipulation
"""
def __interpolate_step(x: pd.Series, dates: pd.Series = None) -> pd.Series:
if x.empty:
raise MqValueError('Cannot perform step interpolation on an empty series')
first_date = pd.Timestamp(dates.index[0]) if isinstance(x.index[0], pd.Timestamp) else dates.index[0]
# locate previous valid date or take first value from series
prev = x.index[0] if first_date < x.index[0] else x.index[x.index.get_loc(first_date, 'pad')]
current = x[prev]
curve = x.align(dates, 'right', )[0] # only need values from dates
for knot in curve.iteritems():
if np.isnan(knot[1]):
curve[knot[0]] = current
else:
current = knot[1]
return curve
[docs]@plot_function
def align(x: Union[pd.Series, Real], y: Union[pd.Series, Real], method: Interpolate = Interpolate.INTERSECT) -> \
Union[List[pd.Series], List[Real]]:
"""
Align dates of two series or scalars
:param x: first timeseries or scalar
:param y: second timeseries or scalar
:param method: interpolation method (default: intersect). Only used when both x and y are timeseries
:return: timeseries with specified dates or two scalars from the input
**Usage**
Align the dates of two series using the specified interpolation method. Returns two series with dates based on the
method of interpolation, for example, can be used to intersect the dates of two series, union dates with a defined
manner to compute missing values.
Interpolation methods:
========= ========================================================================
Type Behavior
========= ========================================================================
intersect Resultant series only have values on the intersection of dates /times.
nan Resultant series have values on the union of dates /times. Values will
be NaN for dates or times only present in the other series
zero Resultant series have values on the union of dates / times. Values will
be zero for dates or times only present in the other series
step Resultant series have values on the union of dates / times. Each series
will use the value of the previous valid point if requested date does
not exist. Values prior to the first date will be equivalent to the
first available value
time Resultant series have values on the union of dates / times. Missing
values surrounded by valid values will be interpolated given length of
interval. Input series must use DateTimeIndex.
========= ========================================================================
**Examples**
Stepwize interpolation of series based on dates in second series:
>>> a = generate_series(100)
>>> b = generate_series(100)
>>> align(a, b)
**See also**
:func:`sub`
"""
if isinstance(x, Real) and isinstance(y, Real):
return [x, y]
if isinstance(x, Real):
return [pd.Series(x, index=y.index), y]
if isinstance(y, Real):
return [x, pd.Series(y, index=x.index)]
if method == Interpolate.INTERSECT:
return x.align(y, 'inner')
if method == Interpolate.NAN:
return x.align(y, 'outer')
if method == Interpolate.ZERO:
return x.align(y, 'outer', fill_value=0)
if method == Interpolate.TIME:
new_x, new_y = x.align(y, 'outer')
new_x.interpolate('time', limit_area='inside', inplace=True)
new_y.interpolate('time', limit_area='inside', inplace=True)
return [new_x, new_y]
if method == Interpolate.STEP:
new_x, new_y = x.align(y, 'outer')
new_x.fillna(method='ffill', inplace=True)
new_y.fillna(method='ffill', inplace=True)
new_x.fillna(method='bfill', inplace=True)
new_y.fillna(method='bfill', inplace=True)
return [new_x, new_y]
else:
raise MqValueError('Unknown intersection type: ' + method)
[docs]@plot_function
def interpolate(x: pd.Series, dates: Union[List[date], List[time], pd.Series] = None,
method: Interpolate = Interpolate.INTERSECT) -> pd.Series:
"""
Interpolate over specified dates or times
:param x: timeseries to interpolate
:param dates: array of dates/times or another series to interpolate
:param method: interpolation method (default: intersect)
:return: timeseries with specified dates
**Usage**
Interpolate the series X over the dates specified by the dates parameter. This can be an array of dates or another
series, in which case the index of the series will be used to specify dates
Interpolation methods:
========= ========================================================================
Type Behavior
========= ========================================================================
intersect Resultant series only has values on the intersection of dates /times.
Will only contain intersection of valid dates / times in the series
nan Resultant series only has values on the intersection of dates /times.
Value will be NaN for dates not present in the series
zero Resultant series has values on all requested dates / times. The series
will have a value of zero where the requested date or time was not
present in the series
step Resultant series has values on all requested dates / times. The series
will use the value of the previous valid point if requested date does
not exist. Values prior to the first date will be equivalent to the
first available value
========= ========================================================================
**Examples**
Stepwize interpolation of series based on dates in second series:
>>> a = generate_series(100)
>>> b = generate_series(100)
>>> interpolate(a, b, Interpolate.INTERSECT)
**See also**
:func:`sub`
"""
if dates is None:
dates = x
if isinstance(dates, pd.Series):
align_series = dates
else:
align_series = pd.Series(np.nan, dates)
if method == Interpolate.INTERSECT:
return x.align(align_series, 'inner')[0]
if method == Interpolate.NAN:
return x.align(align_series, 'right')[0]
if method == Interpolate.ZERO:
align_series = pd.Series(0.0, dates)
return x.align(align_series, 'right', fill_value=0)[0]
if method == Interpolate.STEP:
return __interpolate_step(x, align_series)
else:
raise MqValueError('Unknown intersection type: ' + method)
[docs]@plot_function
def value(x: pd.Series, date: Union[date, time], method: Interpolate = Interpolate.STEP) -> pd.Series:
"""
Value at specified date or time
:param x: timeseries
:param date: requested date or time
:param method: interpolation method (default: step)
:return: value at specified date or time
**Usage**
Returns the value of series X at the specified date:
:math:`Y_t = X_{date}`
If the requested date or time is not present in the series, the value function will return the value from the
previous available date or time by default. Caller can specify other interpolation styles via the method param:
Interpolation methods:
========= ========================================================================
Type Behavior
========= ========================================================================
intersect Only returns a value for valid dates
nan Value will be NaN for dates not present in the series
zero Value will be zero for dates not present in the series
step Value of the previous valid point if requested date does not exist.
Values prior to the first date will be equivalent to the first available
value
========= ========================================================================
**Examples**
Value of series on 5Mar18:
>>> a = generate_series(100)
>>> value(a, date(2019, 1, 3)
**See also**
:func:`interpolate`
"""
values = interpolate(x, [date], method)
return values.get(0)
[docs]@plot_function
def day(x: pd.Series) -> pd.Series:
"""
Day of each value in series
:param x: time series
:return: day of observations
**Usage**
Returns the day as a numeric value for each observation in the series:
:math:`Y_t = day(t)`
Day of the time or date is the integer day number within the month, e.g. 1-31
**Examples**
Day for observations in series:
>>> series = generate_series(100)
>>> days = day(series)
**See also**
:func:`month` :func:`year`
"""
return pd.to_datetime(x.index.to_series()).dt.day
[docs]@plot_function
def month(x: pd.Series) -> pd.Series:
"""
Month of each value in series
:param x: time series
:return: month of observations
**Usage**
Returns the month as a numeric value for each observation in the series:
:math:`Y_t = month(t)`
Month of the time or date is the integer month number, e.g. 1-12
**Examples**
Day for observations in series:
>>> series = generate_series(100)
>>> days = month(series)
**See also**
:func:`day` :func:`year`
"""
return pd.to_datetime(x.index.to_series()).dt.month
[docs]@plot_function
def year(x: pd.Series) -> pd.Series:
"""
Year of each value in series
:param x: time series
:return: year of observations
**Usage**
Returns the year as a numeric value for each observation in the series:
:math:`Y_t = year(t)`
Year of the time or date is the integer year number, e.g. 2019, 2020
**Examples**
Year for observations in series:
>>> series = generate_series(100)
>>> days = year(series)
**See also**
:func:`day` :func:`month`
"""
return pd.to_datetime(x.index.to_series()).dt.year
[docs]@plot_function
def quarter(x: pd.Series) -> pd.Series:
"""
Quarter of each value in series
:param x: time series
:return: quarter of observations
**Usage**
Returns the quarter as a numeric value for each observation in the series:
:math:`Y_t = quarter(t)`
Quarter of the time or date is the integer quarter number, e.g. 1, 2, 3, 4
**Examples**
Quarter for observations in series:
>>> series = generate_series(100)
>>> days = quarter(series)
**See also**
:func:`day` :func:`month`
"""
return pd.to_datetime(x.index.to_series()).dt.quarter
[docs]@plot_function
def weekday(x: pd.Series) -> pd.Series:
"""
Weekday of each value in series
:param x: time series
:return: weekday of observations
**Usage**
Returns the weekday as a numeric value for each observation in the series:
:math:`Y_t = weekday(t)`
Weekday of the time or date is the integer day of the week, e.g. 0-6, where 0 represents Monday
**Examples**
Weekday for observations in series:
>>> series = generate_series(100)
>>> days = weekday(series)
**See also**
:func:`day` :func:`month`
"""
return pd.to_datetime(x.index.to_series()).dt.weekday
@plot_function
def day_count_fractions(
dates: Union[List[date], pd.Series],
convention: DayCountConvention = DayCountConvention.ACTUAL_360,
frequency: PaymentFrequency = PaymentFrequency.MONTHLY
) -> pd.Series:
"""
Day count fractions between dates in series
:param dates: time series or array of dates
:param convention: day count convention (default: Actual/360 ISDA)
:param frequency: payment frequency of instrument (optional)
:return: series of day count fractions
**Usage**
Returns the day count fraction between dates in the series
:math:`Y_t = DCF(t_{-1}, t)`
Default is Actual/360 per ISDA specification:
:math:`Y_t = \frac{Days(t_{-1}, t)}{360}`
For a full list of available conventions, see
`Day Count Conventions <https://developer.gs.com/docs/gsquant/guides/Dates/1-day-count-conventions>`_.
For more information on day count conventions, see the
`day count conventions <https://en.wikipedia.org/wiki/Day_count_convention>`_ page on Wikipedia
**Examples**
Weekday for observations in series:
>>> series = generate_series(100)
>>> days = day_count_fractions(series)
**See also**
:func:`day` :func:`month` :func:`year`
"""
if isinstance(dates, pd.Series):
date_list = list(dates.index)
else:
date_list = dates
if len(date_list) < 2:
return pd.Series([])
start_dates = date_list[0:-1]
end_dates = date_list[1:len(date_list)]
dcfs = map(lambda a, b: day_count_fraction(a, b, convention, frequency), start_dates, end_dates)
return pd.Series(data=[np.NaN] + list(dcfs), index=date_list[0:len(date_list)])
[docs]@plot_function
def date_range(x: pd.Series, start_date: Union[date, int], end_date: Union[date, int],
weekdays_only: bool = False) -> pd.Series:
"""
Create a time series from a (sub-)range of dates in an existing time series.
:param x: time series
:param start_date: start date for the sliced time series. If integer, number of observations after the first
:param end_date: end date for the sliced time series. If integer, number of observations before the last
:param weekdays_only: whether to include only weekdays in the sliced ranges
:return: sliced time series
**Usage**
Returns a restricted ("sliced") time series based on start and end dates:
:math:`Y_t = R_t |_{start < t < end}`
**Examples**
Slice the first and last week of a time series:
>>> series = generate_series(100)
>>> sliced_series = date_range(series,7,7)
**See also**
:func:`day` :func: `lag`
"""
if not (x.index.is_all_dates or all(map(lambda a: isinstance(a, date), x.index.values))):
raise MqValueError('input is not a time series')
if isinstance(start_date, int):
start_date = x.index[start_date]
if isinstance(end_date, int):
end_date = x.index[- (1 + end_date)]
try:
start_date = start_date.date()
end_date = end_date.date()
except AttributeError:
pass
if weekdays_only:
week_mask = None
wd = start_date.weekday()
if wd > 4:
start_date += timedelta(days=7 - wd)
else:
week_mask = tuple([True] * 7)
return x.loc[x.index.intersection(list(_date_range(start_date, end_date, week_mask=week_mask)))]
[docs]@plot_function
def prepend(x: List[pd.Series]) -> pd.Series:
"""
Prepend data series
:param x: an array of timeseries
:return: concatenated timeseries
**Usage**
For input series [:math:`x_1`, :math:`x_2`, ... , :math:`X_n`], takes data from series :math:`X_i` until
the first date for which :math:`X_{i+1}` has data, useful when a higher quality series has a shorter history
than a lower quality series.
**Examples**
Prepend two series:
>>> x = generate_series(100)
>>> y = generate_series(100)
>>> prepend([x, y])
**See also**
:func:`union`
"""
res = pd.Series(dtype='float64')
for i in range(len(x)):
this = x[i]
if i == len(x) - 1:
return res.append(this)
end = x[i + 1].index[0]
res = res.append(this.loc[this.index < end])
return res
[docs]@plot_function
def union(x: List[pd.Series]) -> pd.Series:
"""
Fill in missing dates or times of one series with another
:param x: an array of timeseries
:return: combined series
**Usage**
Starting from :math:`i=1`, takes points from series :math:`x_i`. Where points are missing from :math:`x_i`,
returns points from :math:`x_{i+1}`.
**Examples**
Union of two series:
>>> x = generate_series(100)
>>> y = generate_series(100)
>>> union([x, y])
**See also**
:func:`prepend`
"""
res = pd.Series(dtype='float64')
for series in x:
res = res.combine_first(series)
return res