- exponential moving average crossovers of periods 10-20 and 20-50
- triple moving average crossover system with periods 10-20-50
- Bollinger band breakouts of periods 20 and 50 with 1 & 2 standard deviations for exits and entries
- donchian channel breakouts with periods 20-10 and 50-25
# This function takes as inputs vectors of opening and closing prices
# and creates a basic benchmark output suite of system equity curves
# for the following basic trend following systems
# exponential moving average crossovers of 10-20 and 20-50
# triple moving average crossovers of 10-20-50
# bollinger band breakouts of 20 and 50 with 1 & 2 standard deviations
# donchian channel breakouts of 20-10 and 50-25
# The libraries required to compile this function are
# "Rcpp," "inline" and "compiler." The function is compiled by the command
# > source("basic_benchmark_equity.r") in the console/terminal.
library(Rcpp) # load the required library
library(inline) # load the required library
library(compiler) # load the required library
src <- '
#include
#include
Rcpp::NumericVector open(a) ;
Rcpp::NumericVector close(b) ;
Rcpp::NumericVector market_mode(c) ;
Rcpp::NumericVector kalman(d) ;
Rcpp::NumericVector tick_size(e) ;
Rcpp::NumericVector tick_value(f) ;
int n = open.size() ;
Rcpp::NumericVector sma_10(n) ;
Rcpp::NumericVector sma_20(n) ;
Rcpp::NumericVector sma_50(n) ;
Rcpp::NumericVector std_20(n) ;
Rcpp::NumericVector std_50(n) ;
// create equity output vectors
Rcpp::NumericVector market_mode_long_eq(n) ;
Rcpp::NumericVector market_mode_short_eq(n) ;
Rcpp::NumericVector market_mode_composite_eq(n) ;
Rcpp::NumericVector sma_10_20_eq(n) ;
Rcpp::NumericVector sma_20_50_eq(n) ;
Rcpp::NumericVector tma_eq(n) ;
Rcpp::NumericVector bbo_20_eq(n) ;
Rcpp::NumericVector bbo_50_eq(n) ;
Rcpp::NumericVector donc_20_eq(n) ;
Rcpp::NumericVector donc_50_eq(n) ;
Rcpp::NumericVector composite_eq(n) ;
// position vectors for benchmark systems
Rcpp::NumericVector sma_10_20_pv(1) ;
sma_10_20_pv[0] = 0.0 ; // initialise to zero, no position
Rcpp::NumericVector sma_20_50_pv(1) ;
sma_20_50_pv[0] = 0.0 ; // initialise to zero, no position
Rcpp::NumericVector tma_pv(1) ;
tma_pv[0] = 0.0 ; // initialise to zero, no position
Rcpp::NumericVector bbo_20_pv(1) ;
bbo_20_pv[0] = 0.0 ; // initialise to zero, no position
Rcpp::NumericVector bbo_50_pv(1) ;
bbo_50_pv[0] = 0.0 ; // initialise to zero, no position
Rcpp::NumericVector donc_20_pv(1) ;
donc_20_pv[0] = 0.0 ; // initialise to zero, no position
Rcpp::NumericVector donc_50_pv(1) ;
donc_50_pv[0] = 0.0 ; // initialise to zero, no position
Rcpp::NumericVector comp_pv(1) ;
comp_pv[0] = 0.0 ; // initialise to zero, no position
// fill the equity curve vectors with zeros for "burn in" period
// and create the initial values for all indicators
for ( int ii = 0 ; ii < 50 ; ii++ ) {
if ( ii >= 40 ) {
sma_10[49] += close[ii] ; }
if ( ii >= 30 ) {
sma_20[49] += close[ii] ; }
sma_50[49] += close[ii] ;
std_20[ii] = 0.0 ;
std_50[ii] = 0.0 ;
market_mode_long_eq[ii] = 0.0 ;
market_mode_short_eq[ii] = 0.0 ;
market_mode_composite_eq = 0.0 ;
sma_10_20_eq[ii] = 0.0 ;
sma_20_50_eq[ii] = 0.0 ;
bbo_20_eq[ii] = 0.0 ;
bbo_50_eq[ii] = 0.0 ;
tma_eq[ii] = 0.0 ;
donc_20_eq[ii] = 0.0 ;
donc_50_eq[ii] = 0.0 ;
composite_eq[ii] = 0.0 ; } // end of initialising loop
sma_10[49] = sma_10[49] / 10.0 ;
sma_20[49] = sma_20[49] / 20.0 ;
sma_50[49] = sma_50[49] / 50.0 ;
// the main calculation loop
for ( int ii = 50 ; ii < n-2 ; ii++ ) {
// calculate the smas
sma_10[ii] = ( sma_10[ii-1] - sma_10[ii-10] / 10.0 ) + ( close[ii] / 10.0 ) ;
sma_20[ii] = ( sma_20[ii-1] - sma_20[ii-20] / 20.0 ) + ( close[ii] / 20.0 ) ;
sma_50[ii] = ( sma_50[ii-1] - sma_50[ii-50] / 50.0 ) + ( close[ii] / 50.0 ) ;
// calculate the standard deviations
for ( int jj = 0 ; jj < 50 ; jj++ ) {
if ( jj < 20 ) {
std_20[ii] += ( close[ii-jj] - sma_20[ii] ) * ( close[ii-jj] - sma_20[ii] ) ; } // end of jj if
std_50[ii] += ( close[ii-jj] - sma_50[ii] ) * ( close[ii-jj] - sma_50[ii] ) ; } // end of standard deviation loop
std_20[ii] = sqrt( std_20[ii] / 20.0 ) ;
std_50[ii] = sqrt( std_50[ii] / 50.0 ) ;
//-------------------------------------------------------------------------------------------------------------------
// calculate the equity values of the market modes
// market_mode uwr and unr long signals
if ( market_mode[ii] == 1 || market_mode[ii] == 2 ) {
market_mode_long_eq[ii] = market_mode_long_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ;
market_mode_short_eq[ii] = market_mode_short_eq[ii-1] ;
market_mode_composite_eq[ii] = market_mode_composite_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ; }
// market_mode dwr and dnr short signals
if ( market_mode[ii] == 3 || market_mode[ii] == 4 ) {
market_mode_long_eq[ii] = market_mode_long_eq[ii-1] ;
market_mode_short_eq[ii] = market_mode_short_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ;
market_mode_composite_eq[ii] = market_mode_composite_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ; }
// calculate the equity values of the market modes
// market_mode cyc long signals
if ( market_mode[ii] == 0 && kalman[ii] > kalman[ii-1] ) {
market_mode_long_eq[ii] = market_mode_long_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ;
market_mode_short_eq[ii] = market_mode_short_eq[ii-1] ;
market_mode_composite_eq[ii] = market_mode_composite_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ; }
// market_mode cyc short signals
if ( market_mode[ii] == 0 && kalman[ii] < kalman[ii-1] ) {
market_mode_long_eq[ii] = market_mode_long_eq[ii-1] ;
market_mode_short_eq[ii] = market_mode_short_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ;
market_mode_composite_eq[ii] = market_mode_composite_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ; }
//----------------------------------------------------------------------------------------------------------------------------
// calculate the equity values and positions of each benchmark system
// sma_10_20_eq
if ( sma_10[ii] > sma_20[ii] ) {
sma_10_20_eq[ii] = sma_10_20_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ;
sma_10_20_pv[0] = 1.0 ; } // long
// sma_10_20_eq
if ( sma_10[ii] < sma_20[ii] ) {
sma_10_20_eq[ii] = sma_10_20_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ;
sma_10_20_pv[0] = -1.0 ; } // short
// sma_10_20_eq
if ( sma_10[ii] == sma_20[ii] && sma_10[ii-1] > sma_20[ii-1] ) {
sma_10_20_eq[ii] = sma_10_20_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ;
sma_10_20_pv[0] = 1.0 ; } // long
// sma_10_20_eq
if ( sma_10[ii] == sma_20[ii] && sma_10[ii-1] < sma_20[ii-1] ) {
sma_10_20_eq[ii] = sma_10_20_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ;
sma_10_20_pv[0] = -1.0 ; } // short
//-----------------------------------------------------------------------------------------------------------
// sma_20_50_eq
if ( sma_20[ii] > sma_50[ii] ) {
sma_20_50_eq[ii] = sma_20_50_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ;
sma_20_50_pv[0] = 1.0 ; } // long
// sma_20_50_eq
if ( sma_20[ii] < sma_50[ii] ) {
sma_20_50_eq[ii] = sma_20_50_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ;
sma_20_50_pv[0] = -1.0 ; } // short
// sma_20_50_eq
if ( sma_20[ii] == sma_50[ii] && sma_20[ii-1] > sma_50[ii-1] ) {
sma_20_50_eq[ii] = sma_20_50_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ;
sma_20_50_pv[0] = 1.0 ; } // long
// sma_20_50_eq
if ( sma_20[ii] == sma_50[ii] && sma_20[ii-1] < sma_50[ii-1] ) {
sma_20_50_eq[ii] = sma_20_50_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ;
sma_20_50_pv[0] = -1.0 ; } // short
//-----------------------------------------------------------------------------------------------------------
// tma_eq
if ( tma_pv[0] == 0.0 ) {
// default position
tma_eq[ii] = tma_eq[ii-1] ;
// unless one of the two following conditions is true
if ( sma_10[ii] > sma_20[ii] && sma_20[ii] > sma_50[ii] ) {
tma_eq[ii] = tma_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ;
tma_pv[0] = 1.0 ; } // long
if ( sma_10[ii] < sma_20[ii] && sma_20[ii] < sma_50[ii] ) {
tma_eq[ii] = tma_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ;
tma_pv[0] = -1.0 ; } // short
} // end of tma_pv == 0.0 loop
if ( tma_pv[0] == 1.0 ) {
// default long position
tma_eq[ii] = tma_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ; // long
// unless one of the two following conditions is true
if ( sma_10[ii] < sma_20[ii] && sma_10[ii] > sma_50[ii] ) {
tma_eq[ii] = tma_eq[ii-1] ;
tma_pv[0] = 0.0 ; } // exit long, go neutral
if ( sma_10[ii] < sma_20[ii] && sma_20[ii] < sma_50[ii] ) {
tma_eq[ii] = tma_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ;
tma_pv[0] = -1.0 ; } // short
} // end of tma_pv == 1.0 loop
if ( tma_pv[0] == -1.0 ) {
// default short position
tma_eq[ii] = tma_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ; // short
// unless one of the two following conditions is true
if ( sma_10[ii] > sma_20[ii] && sma_10[ii] < sma_50[ii] ) {
tma_eq[ii] = tma_eq[ii-1] ;
tma_pv[0] = 0.0 ; } // exit short, go neutral
if ( sma_10[ii] > sma_20[ii] && sma_20[ii] > sma_50[ii] ) {
tma_eq[ii] = tma_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ;
tma_pv[0] = 1.0 ; } // long
} // end of tma_pv == -1.0 loop
//------------------------------------------------------------------------------------------------------------
// bbo_20_eq
if ( bbo_20_pv[0] == 0.0 ) {
// default position
bbo_20_eq[ii] = bbo_20_eq[ii-1] ;
// unless one of the two following conditions is true
if ( close[ii] > sma_20[ii] + 2.0 * std_20[ii] ) {
bbo_20_eq[ii] = bbo_20_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ;
bbo_20_pv[0] = 1.0 ; } // long
if ( close[ii] < sma_20[ii] - 2.0 * std_20[ii] ) {
bbo_20_eq[ii] = bbo_20_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ;
bbo_20_pv[0] = -1.0 ; } // short
} // end of bbo_20_pv == 0.0 loop
if ( bbo_20_pv[0] == 1.0 ) {
// default long position
bbo_20_eq[ii] = bbo_20_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ; // long
// unless one of the two following conditions is true
if ( close[ii] < sma_20[ii] + std_20[ii] && close[ii] > sma_20[ii] - 2.0 * std_20[ii] ) {
bbo_20_eq[ii] = bbo_20_eq[ii-1] ;
bbo_20_pv[0] = 0.0 ; } // exit long, go neutral
if ( close[ii] < sma_20[ii] - 2.0 * std_20[ii] ) {
bbo_20_eq[ii] = bbo_20_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ;
bbo_20_pv[0] = -1.0 ; } // short
} // end of bbo_20_pv == 1.0 loop
if ( bbo_20_pv[0] == -1.0 ) {
// default short position
bbo_20_eq[ii] = bbo_20_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ; // short
// unless one of the two following conditions is true
if ( close[ii] > sma_20[ii] - std_20[ii] && close[ii] < sma_20[ii] + 2.0 * std_20[ii] ) {
bbo_20_eq[ii] = bbo_20_eq[ii-1] ;
bbo_20_pv[0] = 0.0 ; } // exit short, go neutral
if ( close[ii] > sma_20[ii] + 2.0 * std_20[ii] ) {
bbo_20_eq[ii] = bbo_20_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ;
bbo_20_pv[0] = 1.0 ; } // long
} // end of bbo_20_pv == -1.0 loop
//-------------------------------------------------------------------------------------------------
// bbo_50_eq
if ( bbo_50_pv[0] == 0.0 ) {
// default position
bbo_50_eq[ii] = bbo_50_eq[ii-1] ;
// unless one of the two following conditions is true
if ( close[ii] > sma_50[ii] + 2.0 * std_50[ii] ) {
bbo_50_eq[ii] = bbo_50_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ;
bbo_50_pv[0] = 1.0 ; } // long
if ( close[ii] < sma_50[ii] - 2.0 * std_50[ii] ) {
bbo_50_eq[ii] = bbo_50_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ;
bbo_50_pv[0] = -1.0 ; } // short
} // end of bbo_50_pv == 0.0 loop
if ( bbo_50_pv[0] == 1.0 ) {
// default long position
bbo_50_eq[ii] = bbo_50_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ; // long
// unless one of the two following conditions is true
if ( close[ii] < sma_50[ii] + std_50[ii] && close[ii] > sma_50[ii] - 2.0 * std_50[ii] ) {
bbo_50_eq[ii] = bbo_50_eq[ii-1] ;
bbo_50_pv[0] = 0.0 ; } // exit long, go neutral
if ( close[ii] < sma_50[ii] - 2.0 * std_50[ii] ) {
bbo_50_eq[ii] = bbo_50_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ;
bbo_50_pv[0] = -1.0 ; } // short
} // end of bbo_50_pv == 1.0 loop
if ( bbo_50_pv[0] == -1.0 ) {
// default short position
bbo_50_eq[ii] = bbo_50_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ; // short
// unless one of the two following conditions is true
if ( close[ii] > sma_50[ii] - std_50[ii] && close[ii] < sma_50[ii] + 2.0 * std_50[ii] ) {
bbo_50_eq[ii] = bbo_50_eq[ii-1] ;
bbo_50_pv[0] = 0.0 ; } // exit short, go neutral
if ( close[ii] > sma_50[ii] + 2.0 * std_50[ii] ) {
bbo_50_eq[ii] = bbo_50_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ;
bbo_50_pv[0] = 1.0 ; } // long
} // end of bbo_50_pv == -1.0 loop
//-----------------------------------------------------------------------------------------------------
// donc_20_eq
if ( donc_20_pv[0] == 0.0 ) {
// default position
donc_20_eq[ii] = donc_20_eq[ii-1] ;
// unless one of the two following conditions is true
if ( close[ii] > *std::max_element( &close[ii-20], &close[ii] ) ) {
donc_20_eq[ii] = donc_20_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ;
donc_20_pv[0] = 1.0 ; } // long
if ( close[ii] < *std::min_element( &close[ii-20], &close[ii] ) ) {
donc_20_eq[ii] = donc_20_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ;
donc_20_pv[0] = -1.0 ; } // short
} // end of donc_20_pv == 0.0 loop
if ( donc_20_pv[0] == 1.0 ) {
// default long position
donc_20_eq[ii] = donc_20_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ; // long
// unless one of the two following conditions is true
if ( close[ii] < *std::min_element( &close[ii-10], &close[ii] ) && close[ii] > *std::min_element( &close[ii-20], &close[ii] ) ) {
donc_20_eq[ii] = donc_20_eq[ii-1] ;
donc_20_pv[0] = 0.0 ; } // exit long, go neutral
if ( close[ii] < *std::min_element( &close[ii-20], &close[ii] ) ) {
donc_20_eq[ii] = donc_20_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ;
donc_20_pv[0] = -1.0 ; } // short
} // end of donc_20_pv == 1.0 loop
if ( donc_20_pv[0] == -1.0 ) {
// default short position
donc_20_eq[ii] = donc_20_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ; // short
// unless one of the two following conditions is true
if ( close[ii] > *std::max_element( &close[ii-10], &close[ii] ) && close[ii] < *std::max_element( &close[ii-20], &close[ii] ) ) {
donc_20_eq[ii] = donc_20_eq[ii-1] ;
donc_20_pv[0] = 0.0 ; } // exit short, go neutral
if ( close[ii] > *std::max_element( &close[ii-20], &close[ii] ) ) {
donc_20_eq[ii] = donc_20_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ;
donc_20_pv[0] = 1.0 ; } // long
} // end of donc_20_pv == -1.0 loop
//-------------------------------------------------------------------------------------------------
// donc_50_eq
if ( donc_50_pv[0] == 0.0 ) {
// default position
donc_50_eq[ii] = donc_50_eq[ii-1] ;
// unless one of the two following conditions is true
if ( close[ii] > *std::max_element( &close[ii-50], &close[ii] ) ) {
donc_50_eq[ii] = donc_50_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ;
donc_50_pv[0] = 1.0 ; } // long
if ( close[ii] < *std::min_element( &close[ii-50], &close[ii] ) ) {
donc_50_eq[ii] = donc_50_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ;
donc_50_pv[0] = -1.0 ; } // short
} // end of donc_50_pv == 0.0 loop
if ( donc_50_pv[0] == 1.0 ) {
// default long position
donc_50_eq[ii] = donc_50_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ; // long
// unless one of the two following conditions is true
if ( close[ii] < *std::min_element( &close[ii-25], &close[ii] ) && close[ii] > *std::min_element( &close[ii-50], &close[ii] ) ) {
donc_50_eq[ii] = donc_50_eq[ii-1] ;
donc_50_pv[0] = 0.0 ; } // exit long, go neutral
if ( close[ii] < *std::min_element( &close[ii-50], &close[ii] ) ) {
donc_50_eq[ii] = donc_50_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ;
donc_50_pv[0] = -1.0 ; } // short
} // end of donc_50_pv == 1.0 loop
if ( donc_50_pv[0] == -1.0 ) {
// default short position
donc_50_eq[ii] = donc_50_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ; // short
// unless one of the two following conditions is true
if ( close[ii] > *std::max_element( &close[ii-25], &close[ii] ) && close[ii] < *std::max_element( &close[ii-50], &close[ii] ) ) {
donc_50_eq[ii] = donc_50_eq[ii-1] ;
donc_50_pv[0] = 0.0 ; } // exit short, go neutral
if ( close[ii] > *std::max_element( &close[ii-50], &close[ii] ) ) {
donc_50_eq[ii] = donc_50_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ;
donc_50_pv[0] = 1.0 ; } // long
} // end of donc_50_pv == -1.0 loop
//-------------------------------------------------------------------------------------------------
// composite_eq
comp_pv[0] = sma_10_20_pv[0] + sma_20_50_pv[0] + tma_pv[0] + bbo_20_pv[0] + bbo_50_pv[0] + donc_20_pv[0] + donc_50_pv[0] ;
if ( comp_pv[0] > 0 ) {
composite_eq[ii] = composite_eq[ii-1] + tick_value[0] * ( (open[ii+2]-open[ii+1])/tick_size[0] ) ; } // long
if ( comp_pv[0] < 0 ) {
composite_eq[ii] = composite_eq[ii-1] + tick_value[0] * ( (open[ii+1]-open[ii+2])/tick_size[0] ) ; } // short
if ( comp_pv[0] == 0 ) {
composite_eq[ii] = composite_eq[ii-1] ; } // neutral
} // end of main for loop
// Now fill in the last two spaces in the equity vectors
market_mode_long_eq[n-1] = market_mode_long_eq[n-3] ;
market_mode_long_eq[n-2] = market_mode_long_eq[n-3] ;
market_mode_short_eq[n-1] = market_mode_short_eq[n-3] ;
market_mode_short_eq[n-2] = market_mode_short_eq[n-3] ;
market_mode_composite_eq[n-1] = market_mode_composite_eq[n-3] ;
market_mode_composite_eq[n-2] = market_mode_composite_eq[n-3] ;
sma_10_20_eq[n-1] = sma_10_20_eq[n-3] ;
sma_10_20_eq[n-2] = sma_10_20_eq[n-3] ;
sma_20_50_eq[n-1] = sma_20_50_eq[n-3] ;
sma_20_50_eq[n-2] = sma_20_50_eq[n-3] ;
tma_eq[n-1] = tma_eq[n-3] ;
tma_eq[n-2] = tma_eq[n-3] ;
bbo_20_eq[n-1] = bbo_20_eq[n-3] ;
bbo_20_eq[n-2] = bbo_20_eq[n-3] ;
bbo_50_eq[n-1] = bbo_50_eq[n-3] ;
bbo_50_eq[n-2] = bbo_50_eq[n-3] ;
donc_20_eq[n-1] = donc_20_eq[n-3] ;
donc_20_eq[n-2] = donc_20_eq[n-3] ;
donc_50_eq[n-1] = donc_50_eq[n-3] ;
donc_50_eq[n-2] = donc_50_eq[n-3] ;
composite_eq[n-1] = composite_eq[n-3] ;
composite_eq[n-2] = composite_eq[n-3] ;
return List::create(
_["market_mode_long_eq"] = market_mode_long_eq ,
_["market_mode_short_eq"] = market_mode_short_eq ,
_["market_mode_composite_eq"] = market_mode_composite_eq ,
_["sma_10_20_eq"] = sma_10_20_eq ,
_["sma_20_50_eq"] = sma_20_50_eq ,
_["tma_eq"] = tma_eq ,
_["bbo_20_eq"] = bbo_20_eq ,
_["bbo_50_eq"] = bbo_50_eq ,
_["donc_20_eq"] = donc_20_eq ,
_["donc_50_eq"] = donc_50_eq ,
_["composite_eq"] = composite_eq ) ; '
basic_benchmark_equity <- cxxfunction(signature(a = "numeric", b = "numeric", c = "numeric",
d = "numeric", e = "numeric", f = "numeric"), body=src,
plugin = "Rcpp")
This Rcpp function is then called thus, using Rstudio
library(xts) # load the required library
# load the "indicator" file
data <- read.csv(file="usdyenind",head=FALSE,sep=,)
tick_size <- 0.01
tick_value <- 12.50
# extract other vectors of interest
open <- data[,2]
close <- data[,5]
market_mode <- data[,228]
kalman <- data[,283]
results <- basic_benchmark_equity(open,close,market_mode,kalman,tick_size,tick_value)
# coerce the above results list object to a data frame object
results_df <- data.frame( results )
df_max <- max(results_df) # for scaling of results plot
df_min <- min(results_df) # for scaling of results plot
# and now create an xts object for plotting
results_xts <- xts(results_df,as.Date(data[,'V1']))
# a nice plot of the results_xts object
par(col="#0000FF")
plot(results_xts[,'market_mode_long_eq'],main="USDYEN Pair",ylab="$ Equity Value",ylim=c(df_min,df_max),type="l")
par(new=TRUE,col="#B0171F")
plot(results_xts[,'market_mode_short_eq'],main="",ylim=c(df_min,df_max),type="l")
par(new=TRUE,col="#00FF00")
plot(results_xts[,'market_mode_composite_eq'],main="",ylim=c(df_min,df_max),type="l")
par(new=TRUE,col="#808080")
plot(results_xts[,'sma_10_20_eq'],main="",ylim=c(df_min,df_max),type="l")
par(new=TRUE)
plot(results_xts[,'sma_20_50_eq'],main="",ylim=c(df_min,df_max),type="l")
par(new=TRUE)
plot(results_xts[,'tma_eq'],main="",ylim=c(df_min,df_max),type="l")
par(new=TRUE)
plot(results_xts[,'bbo_20_eq'],main="",ylim=c(df_min,df_max),type="l")
par(new=TRUE)
plot(results_xts[,'bbo_50_eq'],main="",ylim=c(df_min,df_max),type="l")
par(new=TRUE)
plot(results_xts[,'donc_20_eq'],main="",ylim=c(df_min,df_max),type="l")
par(new=TRUE)
plot(results_xts[,'donc_50_eq'],main="",ylim=c(df_min,df_max),type="l")
par(new=TRUE,col="black")
plot(results_xts[,'composite_eq'],main="",ylim=c(df_min,df_max),type="l")
to output .png files which I have strung together in this video
Non-embedded view here.
The light grey equity curves are the individual curves for the benchmark systems and the black is the "committee" 1 contract equity curve. Also shown are the long and short 1 contract equity curves ( blue and red respectively ), along with a green combined equity curve for these, for my Naive Bayesian Classifier following the simple rules
- be long 1 contract if the market type is uwr, unr or cyclic with my Kalman filter pointing upwards
- be short 1 contract if the market type is dwr, dnr or cyclic with my Kalman filter pointing downwards
No comments:
Post a Comment