Nothing
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU Library General
# Public License along with this library; if not, write to the
# Free Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
###############################################################################
# FUNCTION: DESCRIPTION:
# stabilityAnalytics Retroactive stability analytics
# FUNCTION: DESCRIPTION:
# turnsAnalytics Retroactive turning point analytics
# drawdownsAnalytics Retroactive maximum drawdown analytics
# garchAnalytics Retroactive Garch volatility analytics
# riskmetricsAnalytics Retroactive Riskmetrics analytics
# bcpAnalytics Retroactive Bayesian changepoints analytics
# pcoutAnalytics Retroactive Principal component outlier analytics
# FUNCTION: DESCRIPTION:
# addRainbow Adds rainbow colored stability indicators
# FUNCTION: DESCRIPTION:
# waveletSpectrum Retroactive Morlet wavelet analytics
# FUNCTION: DESCRIPTION:
# parAnalytics Graph frame settings for a desired analytics
###############################################################################
stabilityAnalytics <-
function(index, method=c("turns", "drawdowns", "garch",
"riskmetrics", "bcp", "pcout"), ...)
{
# A function implemented by Diethelm Wuertz and Tobias Setz
# Description:
# Retroactive stability analytics
# FUNCTION:
# Run Analytics:
method <- match.arg(method)
FUN <- paste(method, "Analytics", sep = "")
fun <- match.fun(FUN)
# Return Value:
fun(index, ...)
}
###############################################################################
turnsAnalytics <-
function(index, spar=0.5, main=NULL,
trace=TRUE, doplot=TRUE, at=pretty(index), format="%m/%y")
{
# A function implemented by Diethelm Wuertz and Tobias Setz
# Description:
# Retroactive Turning Points Analytics
# Arguments:
# index - an index or price S4 'timeSeries' object
# spar - a numeric between 0 and, the degree of smoothness
# main - main plot title
# trace - a logical, should the results be traced?
# plot - a logical, should the results be plotted
# at - generate pretty axis positions
# format - a string describing the label format
# Note:
# The lowess and supsmu smoothers are by far not as good as the
# spline smoother.
# FUNCTION:
# Settings:
stopifnot(isUnivariate(index))
if (is.null(main)) main <- "Retroactive Turnpoints Analytics"
# Smooth Return Series:
rets <- returns(index)
indexSmu <- smoothSpline(log(index), spar=spar)
# Turnpoints:
warn <- getOption("warn")
options(warn=-1)
indexTurns <- turns(indexSmu[, 2])
options(warn=warn)
indexTurns <- indexTurns[indexTurns[, 2] !=0, ]
# Add Verical Lines:
turns.tps <- format(time(indexTurns))
n.tps <- length(turns.tps)
# Trace Results:
if (trace){
cat("Series:\n", colnames(index), "\n")
cat("Turning Points:", n.tps, "\n")
print(turns.tps)
}
# Positions:
positions <- sign(returns(exp(indexSmu[, 2]), trim=FALSE))
positions[1, 1] <- 0
ablines <- time(positions)[as.vector(positions) < 0]
# Plot:
if (doplot) {
# Turnpoints:
range <- range(log(index))
ylim <- c(range[1], range[2] + diff(range(log(index)))/4)
plot(indexSmu[, 1], ylim=ylim, main="", ylab="", xlab="", las=2,
at=at, format=format, col="black")
title(main=main, ylab=paste("log Index", colnames(index)), xlab="")
abline(v=ablines, lty=3, lwd=2, col="steelblue")
lines(indexSmu[, 1], col="black")
lines(indexSmu[, 2], col="red")
if (turns.tps[2] > 0) points(indexTurns[, 1], pch=19, col="red")
abline(v=as.POSIXct(at), col="darkgrey", lty=3)
box(col="white")
box(bty="l")
# Add Returns:
center <- range[2] + diff(range(log(index)))/4/2
scale <- diff(range(log(index)))/4
returnsScaled <- (rets-mean(rets))/max(abs(rets)) * scale/2 + center
lines(returnsScaled, col="orange")
abline(h=mean(returnsScaled), col="darkgrey", lty=3)
box(col="white")
box(bty="l")
# Add Rmwtrics - Do not Remove!
mtext("Rmetrics", adj=0, side=4, cex=0.7, col="darkgrey")
}
# Check Turnpoints:
if ( turns.tps[1] == "1" & turns.tps[2] == "0")
n.tps <- 0
# Return Value:
invisible(list(
data=indexSmu,
turns=turns.tps,
positions=positions,
ablines=ablines,
n=n.tps,
smooth=spar))
}
###############################################################################
drawdownsAnalytics <-
function(index, spar=0.5, main=NULL,
trace=TRUE, doplot=TRUE, at=pretty(index), format="%m/%y")
{
# A function implemented by Diethelm Wuertz and Tobias Setz
# Description:
# Retroactive Maximum Drawdown Analytics
# Arguments:
# index - an index or price S4 'timeSeries' object
# spar - a numeric between 0 and, the degree of smoothness
# main - main plot title
# trace - a logical, should the results be traced?
# plot - a logical, should the results be plotted
# at - generate pretty axis positions
# format - a string describing the label format
# FUNCTION:
# Settings:
stopifnot(isUnivariate(index))
if (is.null(main)) main <- "Retroactive Drawdowns Analytics"
# Series:
rets<- returns(index)
# Turning Points:
tps <- turnsAnalytics(index=index, spar=spar, trace=trace, doplot=FALSE)
ablines <- tps$ablines
# Drawdowns:
maxdd <- drawdowns(rets)
# Plot:
if(doplot) {
# Plot:
plot(maxdd, main=main, xlab="", ylab=paste("Drawdwons", colnames(index)),
las=2, at=at, format=format)
abline(v=ablines, lty=3, lwd=2, col="steelblue")
lines(maxdd)
box(col="white")
box(bty="l")
# Add Rmwtrics - Do not Remove!
mtext("Rmetrics", adj=0, side=4, cex=0.7, col="darkgrey")
}
# Return Value:
invisible(list(
index = index,
series = maxdd))
}
###############################################################################
garchAnalytics <-
function (index, spar = 0.5, main=NULL,
trace=TRUE, doplot=TRUE, at=pretty(index), format="%m/%y")
{
# A function implemented by Diethelm Wuertz and Tobias Setz
# Arguments:
# index - an index or price S4 'timeSeries' object
# spar - a numeric between 0 and, the degree of smoothness
# main - main plot title
# trace - a logical, should the results be traced?
# plot - a logical, should the results be plotted
# at - generate pretty axis positions
# format - a string describing the label format
# Description:
# Retroactive Garch11 Volatility Analytics
# FUNCTION:
# Load Library:
# require(fGarch)
# Settings:
stopifnot(isUnivariate(index))
if (is.null(main)) main <- "Retroactive Garch Analytics"
# Fit Garch11 Model:
fit <- fGarch::garchFit(data = 100 * returns(index), trace=trace)
xseries <- as.timeSeries(fit@data)/100
Index <- cumulated(xseries)
colnames(Index) <- colnames(index)
# Turning Points:
tps <- turnsAnalytics(index=index, spar=spar, trace=trace, doplot=FALSE)
ablines <- tps$ablines
# Plot Return Series and Standard Deviations:
xcsd <- timeSeries(data = fit@sigma.t/100, charvec = time(xseries))
if (doplot) {
# Plot:
sdPlus <- mean(xseries) + 2 * xcsd
sdMinus <- mean(xseries) - 2 * xcsd
range <- range(xseries, sdPlus, sdMinus)
plot(xseries,
main=main, xlab="", ylab=paste("Volatility", colnames(index)),
at=at, format=format,
# type="l",
col="steelblue", ylim=range)
abline(v = ablines, lty = 3, lwd = 2, col = "grey")
lines(xseries, col = "steelblue")
lines(sdPlus, col = "red", lwd = 2)
lines(sdMinus, col = "red", lwd = 2)
abline(h = 0, col = "grey", lty = 3)
box(col = "white")
box(bty = "l")
# Margin Text:
# mtext("Volatility Band: 2 sd", adj = 0, side = 4, cex = 0.7,
# col = "darkgrey")
# Add Rmwtrics - Do not Remove!
mtext("Rmetrics", adj=0, side=4, cex=0.7, col="darkgrey")
}
# Return Value:
invisible(list(
index = index,
residuals = xseries,
volatility = xcsd,
fit = fit))
}
###############################################################################
riskmetricsAnalytics <-
function(index, spar=0.5, lambda=0.9, main=NULL,
trace=TRUE, doplot=TRUE, at=pretty(index), format="%m/%y")
{
# A function implemented by Diethelm Wuertz and Tobias Setz
# Description:
# Retroactive riskmetrics analytics
# Arguments:
# index - an index or price S4 'timeSeries' object
# spar - a numeric between 0 and, the degree of smoothness
# main - main plot title
# trace - a logical, should the results be traced?
# plot - a logical, should the results be plotted
# at - generate pretty axis positions
# format - a string describing the label format
# FUNCTION:
# Settings:
stopifnot(isUnivariate(index))
if (is.null(main)) main <- "Retroactive RiskMetrics Analytics"
# Series:
rets <- returns(index)
# Turning Points:
tps <- turnsAnalytics(index=index, spar=spar, trace=trace, doplot=FALSE)
ablines <- tps$ablines
# Indicator:
sigma <- .emaIndicator(abs(rets), lambda)
sd <- sqrt(.emaIndicator(rets^2, lambda))
# Plot:
if(doplot) {
# Plot:
sdPlus <- mean(rets) + 2 * sd
sdMinus <- mean(rets) - 2 * sd
range <- range(rets, sdPlus, sdMinus)
plot(rets,
main="", xlab="", ylab=paste("Volatility", colnames(index)),
at=at, format=format,
ylim=range)
abline(v=ablines, lty=3, lwd=2, col="grey")
lines(rets, col="steelblue")
lines(mean(rets) + 2*sd, col="orange", lwd=2)
lines(mean(rets) - 2*sd, col="orange", lwd=2)
lines(mean(rets) + 2*sigma, col="red", lwd=2)
lines(mean(rets) - 2*sigma, col="red", lwd=2)
abline(h=0, col="grey", lty=3)
box(col="white")
box(bty="l")
# Margin Text:
# mtext(paste("sd/var Volatility Bands: 2 sd | lambda", lambda),
# adj=0, side=4, cex=0.7, col="darkgrey")
# Add Rmwtrics - Do not Remove!
mtext("Rmetrics", adj=0, side=4, cex=0.7, col="darkgrey")
}
# Return Value:
invisible(list(
index = index,
analytics = sigma))
}
###############################################################################
bcpAnalytics <-
function (index, spar=0.5, FUN=returns, method=c("prob", "mean", "var"),
main=NULL, trace=TRUE, doplot=TRUE, at=pretty(index), format="%m/%y")
{
# A function implemented by Diethelm Wuertz and Tobias Setz
# Description:
# Retroactive Bayesian Change Points Analytics
# Arguments:
# index - an index or price S4 'timeSeries' object
# spar - a numeric between 0 and, the degree of smoothness
# main - main plot title
# trace - a logical, should the results be traced?
# plot - a logical, should the results be plotted
# at - generate pretty axis positions
# format - a string describing the label format
# FUNCTION:
# Load Library:
# require(bcp)
# Settings:
stopifnot(isUnivariate(index))
if (is.null(main)) main <- "Retroactive Change Points Analytics"
# Turning Points:
tps <- turnsAnalytics(index=index, spar=spar, trace=trace, doplot=FALSE)
positions <- tps$positions
ablines <- tps$ablines
# BCP Analytics:
fun <- match.fun(FUN)
series <- fun(index)
analytics <- bcp::bcp(series)
# Compose Series:
method <- match.arg(method)
select <- c(mean="posterior.mean", var="posterior.var", prob="posterior.prob")
series(series) <- analytics[[select[method]]]
# Compose y-axis Label:
ylab <- c(mean="Mean", var="Variance", prob="Probability")
ylab <- paste("Posterior", ylab[method], colnames(index))
# Select:
if (method == "prob") {
ylim <- c(0, 1)
prob <- timeSeries(data=analytics$posterior.prob, charvec=time(series))
prob <- na.omit(prob)
} else {
ylim <- range(na.omit(series))
prob <- NA
}
# Plot:
if (doplot) {
# Plot:
plot(series, type="h", ylim=ylim, las=2, col="grey",
main=main, xlab="", ylab=ylab,
at=at, format=format)
abline(v=ablines, lty=3, lwd=2, col="steelblue")
points(series, pch=19, cex=0.5)
box(col = "white")
box(bty = "l")
# MarginText:
# mtext(paste("Smooth:", spar), adj = 0, side = 4, cex = 0.7, col = "darkgrey")
# Add Rmwtrics - Do not Remove!
mtext("Rmetrics", adj=0, side=4, cex=0.7, col="darkgrey")
}
# Return Value:
invisible(list(
index = index,
analytics = analytics,
prob = prob))
}
###############################################################################
pcoutAnalytics <-
function (index, spar=0.5, main=NULL,
trace=TRUE, doplot=TRUE, at=pretty(index), format="%m/%y",
strong=TRUE, k=2, cs=0.25, outbound=0.25)
{
# A function implemented by Diethelm Wuertz and Tobias Setz
# Description:
# Retroactive PCA outlier analytics
# Arguments:
# index - an index or price S4 'timeSeries' object
# spar - a numeric between 0 and, the degree of smoothness
# main - main plot title
# trace - a logical, should the results be traced?
# plot - a logical, should the results be plotted
# at - generate pretty axis positions
# format - a string describing the label format
# FUNCTION:
# Load Library:
# require(mvoutlier)
# Settings:
stopifnot(isUnivariate(index))
if (is.null(main)) main <- "Retroactive Outlier Analytics"
# Turning Points:
tps <- turnsAnalytics(index=index, spar=spar, trace=trace, doplot=FALSE)
positions <- tps$positions
ablines <- tps$ablines
# Series Settings:
X <- log(index)
Y <- returns(index)
Z <- cbind(X[-1, ], Y)
u <- Y
v <- lag(u, k=-k:k, trim=TRUE)
U <- u[time(v), ]
# Principal Component Outlier Analytics:
ans <- mvoutlier::pcout(v, makeplot=FALSE, explvar=0.99, crit.M1=1/3,
crit.c1=2.5, crit.M2=1/4, crit.c2=0.99, cs=cs,
outbound=outbound)
# Plot:
colnames(X) <- paste(colnames(X), "X", sep=":")
colnames(Y) <- paste(colnames(Y), "Y", sep=":")
Z <- cbind(X[time(v), ], Y[time(v), ])
Z@recordIDs <- data.frame(wfinal01=ans$wfinal01, wfinal=ans$wfinal,
wloc=ans$wloc, wscat=ans$wscat, x.dist1=ans$x.dist1,
x.dist2=ans$x.dist2)
rownames(Z@recordIDs) <- rownames(Z)
wfinal01 <- ans$wfinal01
if (strong) {
V <- as.timeSeries(Z@recordIDs)[, "wfinal01"]
W <- lag(V, k=k, trim=TRUE)
S <- timeSeries(data=rowSums(W))
Sfinal <- S == 0
z <- timeSeries(charvec=time(Z), data=ans$wfinal01)
z[time(S), ] <- as.integer(!Sfinal)
wfinal01 <- as.numeric(z)
Z@recordIDs[, "wfinal01"] <- wfinal01
}
ans$wfinal <- ans$wfinal01 <- ans$wloc <- ans$wscat <- NULL
ans$x.dist1 <- ans$x.dist2 <- NULL
U <- Z[, 1]
wfinal01 <- Z@recordIDs$wfinal01
datapoints <- length(U)
U <- Z[, 2]
outliers <- length(U) - sum(wfinal01)
percent <- round(100 * outliers/length(U), 2)
weights <- as.timeSeries(Z@recordIDs)[, "wfinal"]
# Analytics:
Indicator <- 1 - weights
invWeights <- as.vector(Indicator)
extreme = sum(invWeights[invWeights > 0.75]) / length(invWeights)
analytics <- c(
mean = mean(1-weights),
sd = sd(1-weights),
extreme75 = extreme,
indicator = Indicator)
ylab <- paste("PC Outlier Prob", colnames(index))
# Plot:
if(doplot) {
# Plot:
plot(Indicator, type="h", ylim=c(0, 1), las=2, col="grey",
main=main, xlab="", ylab=ylab,
at=at, format=format)
abline(v=ablines, lty=3, lwd=2, col="steelblue")
points(Indicator, pch=19, cex=0.5)
# Add Grid and Box:
grid(NA, ny=NULL)
box(col="white")
box(bty="l")
# Margin Text:
# mtext(paste("Smooth:", spar), adj=0, side=4, cex=0.7, col="darkgrey")
# Add Rmetrics - Do not Remove!
mtext("Rmetrics", adj=0, side=4, cex=0.7, col="darkgrey")
}
# Return Value:
ans <- invisible(list(
index = index,
pcout = ans,
series = Z,
analytics = analytics,
prob = Indicator))
class(ans) <- c("analytics", "list")
ans
}
# -----------------------------------------------------------------------------
addRainbow <-
function(analytics, palette=rainbow, a=0.3, b=0.8, K=100)
{
# A function implemented by Diethelm Wuertz and Tobias Setz
# Example:
# analytics <- pcoutAnalytics(index); addRainbow(analytics)
# analytics <- bcpAnalytics(index); addRainbow(analytics)
# FUNCTION:
# Get Probability Indicator:
Indicator <- analytics$prob
# Check:
stopifnot(isUnivariate(Indicator))
stopifnot(min(Indicator) >= 0)
stopifnot(max(Indicator) <= 1)
# Add Spline Smoothed Indicators:
k.spar <- seq(a, b, length=K)
for (k in 1:K) {
curve <- timeSeries::smoothSpline(Indicator, spar=k.spar[k])[, 2]
if (k == 1) curve1 <- curve
if (k == K) diff <- curve - curve1
lines(curve, lwd=2, col=palette(K)[k]) }
# Add Difference Indicator Line:
lines(diff + 0.5, lwd=2)
abline(h=0.5, lwd=2, col="orange")
# Return Value:
invisible()
}
###############################################################################
waveletSpectrum <-
function(index, spar=0.5, main=NULL,
trace=TRUE, doplot=TRUE, at=pretty(index), format="%m/%y")
{
# A function implemented by Diethelm Wuertz and Tobias Setz
# Description:
# Morlet Wavelet Analytics
# Arguments:
# index - an index or price S4 'timeSeries' object
# spar - a numeric between 0 and, the degree of smoothness
# main - main plot title
# trace - a logical, should the results be traced?
# plot - a logical, should the results be plotted
# at - generate pretty axis positions
# format - a string describing the label format
# FUNCTION:
# Load Library:
# require(dplR)
# Settings:
stopifnot(isUnivariate(index))
if (is.null(main)) main <- "Morlet Wavelet Spectrum"
# Index Returns:
returns <- returns(index)
Time <- 2:length(index)
Returns <- as.vector(returns)
ans <- dplR::morlet(y1=returns, x1=Time)
# Returns a list containing:
# y Numeric. The original time series.
# x Numeric. The time values.
# wave Complex. The wavelet transform.
# coi Numeric. The cone of influence.
# period Numeric. The period.
# Scale Numeric. The scale.
# Signif Numeric. The significant values.
# Power Numeric. The squared power.
# Turning Points:
tps <- turnsAnalytics(index=index, spar=spar, trace=trace, doplot=FALSE)
# Wavelet Spectrum:
p <- as.vector(ans$Power)
vec <- c(mean=mean(p), sd=sd(p), skew=skewness(p), kurt=kurtosis(p))
mat <- c(
O = base::norm(ans$Power, "O"), # "One Norm"
I = base::norm(ans$Power, "I"), # "Inf Norm"
F = base::norm(ans$Power, "F"), # "Frobenius"
M = base::norm(ans$Power, "M")) # "Max Modulus"
if (trace) {
cat("Stats Measures:\n")
print(vec)
print(mat)
}
analytics <- c(vec, mat)
# Wavelet Parameters:
wave.list <- ans
wavelet.levels <- quantile(wave.list$Power, probs=seq(from=0, to=1, by=0.1))
add.coi <- TRUE
add.sig <- TRUE
crn.lab <- "RWI"
key.cols <- rev(heat.colors(length(wavelet.levels)))
key.lab <- expression(paste("Power"^2))
nyrs=NULL
crn.col <- "black"
crn.lwd <- 1
crn.ylim <- range(wave.list$y) * 1.1
# Settings:
y <- wave.list$y
x <- wave.list$x
wave <- wave.list$wave
period <- wave.list$period
Signif <- wave.list$Signif
coi <- wave.list$coi
coi[coi == 0] <- 1e-12
Power <- wave.list$Power
siglvl <- wave.list$siglvl
Signif <- t(matrix(Signif, dim(wave)[2], dim(wave)[1]))
Signif <- Power/Signif
period2 <- log(period)/log(2)
ytick <- unique(trunc(period2))
ytickv <- 2^(ytick)
coi2 <- log(coi)/log(2)
coi2[coi2 < 0] <- 0
coi2.yy <- c(coi2, rep(max(period2, na.rm=TRUE), length(coi2)))
coi2.yy[is.na(coi2.yy)] <- coi[2]
yr.vec.xx <- c(x, rev(x))
# DW
# par.orig <- par(c("mar", "las", "mfrow"))
# on.exit(par(par.orig))
nlevels <- length(wavelet.levels)
key.labs <- formatC(wavelet.levels, digits=4, format="f")
asp <- NA
las <- 1
xlim <- range(x, finite=TRUE)
ylim <- range(period2, finite=TRUE)
ylim[2] <- ylim[2] * 1.1
# Image Plot:
# DW
# ... now you can create more than one plot on one page
# plot.new()
# plot.window(xlim, ylim, xaxs="r", yaxs="r")
# Use instead:
plot(xlim, ylim, xaxs = "r", yaxs = "r",
col = "white", axes=FALSE, frame=FALSE, ann=FALSE)
# DW
# .Internal(filledcontour()) no longer works on 3.0.
# .Internal(filledcontour(
# as.double(x), as.double(period2), Power,
# as.double(wavelet.levels), col=key.cols))
# Use instead:
graphics::.filled.contour(
x = as.double(x),
y = as.double(period2),
z = Power,
levels = as.double(wavelet.levels),
col = key.cols)
title(main=main, xlab="", ylab=paste("Period", colnames(index)))
box(col="white")
box(bty="l")
# Add Contours:
contour(x, period2, Signif, levels=1, labels=siglvl,
drawlabels=FALSE, axes=FALSE, frame.plot=FALSE,
add=TRUE, lwd=2, col="black")
# Add Coin of Influence:
polygon(yr.vec.xx, coi2.yy, density=c(10, 20),
angle=c(-45, 45), col="black")
# Add Axis Labels:
xtick <- NULL
for (i in 1:length(time(index)))
xtick <- c(xtick, which.min(abs(time(index) - at[i])))
axis(1, at=xtick, labels=format(at, format=format))
axis(2, at=ytick, labels=ytickv, las=2)
# Add Scale Legend:
nCol<- length(key.cols)
positions <- seq(min(x), max(x), length=nCol+1)
colLevels <- paste(signif(wavelet.levels,2))
for (i in 1:nCol) {
lines(x=c(positions[i], positions[i+1]),
y=c(1.03,1.03)*max(period2), lwd=3, col=key.cols[i])
text(x=(positions[i]+positions[i+1])/2, 1.07*max(period2),
colLevels[i], cex=0.6) }
points(positions, rep(1.03*max(period2), length=nCol+1),
pch=19, cex=0.7)
# Add Rmetrics - Do not Remove!
mtext("Rmetrics", adj=0, side=4, cex=0.7, col="darkgrey")
# Return Value:
invisible(list(
index = index,
spar = spar,
wavelet = ans,
analytics = list(Time=x, Period=period2, Power=Power)))
}
###############################################################################
parAnalytics <-
function()
{
# A function implemented by Diethelm Wuertz and Tobias Setz
# Description:
# Sets the graph frame for an analytics chart
# FUNCTION:
# Graph Frame:
par(mfrow = c(2, 1))
par(mar = c(2, 4, 2, 2) + 0.1)
par(omi = 0.2*c(1, 0.7, 1, 0.7))
# Return Value:
invisible()
}
###############################################################################
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.