I used the above code provided by TrendXplorer which was a demo with some hard coded data .... and added some code to read a watchlist and process the issues in watchlist... in order to get a better appreciation of the MVP method.
My code is set to read a watchlist named "SP Sectors".
The code looks at 60 bar ROC to use as expected returns. (the 60 day setting is set as a parameter. Another parameter , lookback, in included to look at earlier data as a debug helper.
Have a couple of questions:
-
I understand that MVP in general is very sensitive to inputs of expected returns and their distributions. Has anyone used MVP enough to have an opinion?
-
The computation of portfolio Standard deviation is SD = ( ( MxTranspose( W ) @ A ) @ W ) * sqrt( 12 ); What is the purpose of the term sqrt(12)?
-
Has anyone read the paper "Estimating the Global Minimum Variance Portfolio" by Alexander Kempf and Christoph Memmel? They seem to address the issue of distributions ... or at least evaluate them
Their paper can be found at https://www.researchgate.net/publication/23544904_Estimating_the_Global_Minimum_Variance_Portfolio
Appreciate any feedback
Ara
My code additions are below:
//File: DEV MV Portfolio-2
// February 2018
//
//
//
//This program calculates Global Minimum Variance Portfolio, Tangency Portfolio and Long Only portfolio
//
// Program uses matrix algebra to do calculation
// based on paper "Portfolio Theory with matrix Algebra" - November 9 2011 - Author not specified
// MVP calculation segment from Amibroker Forum - posted by TrendXplorer
// The code copied from the forum works with hard codes sample data and prints out debug data in interpretation window.
//
// Data needed:
// Expected Returns: Momentum for and standard deviation for specified period
//
// Calculate variances of expected returns (sigma squared) and co-variances - fill in matrix
//
// Sample of Variance and co-variance matrix for 3 element portfolio (A,B,C)
// s2A corrAB*sA*sB corrAC*sA*sC s is standard deviation, 2 signifies squared, sA is standard deviation for A
// corrAB*sA*sB s2B corrBC*sB*sC
// corrAC*sA*sC corrBC*sB*sC s2C
//
// Parameters:
// - period: sample period for momentum (expected return proxy) and standard deviation
// - lookback: useful for debug purposes - moves back sample period by specified number of bars
// - testdata: Uses the sample data provided by original code (for debug purposes)
//
// Enhancements to original code copied from Amibroker forum:
// - Code reads from specified watch list and computes the portfolios and displays all data on screen. The watchlist name is hard coded.
// - The code was developed with 23 inch monitor. Only minimal effort was spent to accomodate other size screens.
// - This code has been tested with a watchlist containg up to 12 symbols. Program will automatically adjust for the number of symbols.
// - The original printing in interpretation window is retained.
//
testdata = Param( "testdata", 0, 0, 1, 1 );
SetBarsRequired( 100000, 100000 );
//
// =====================================================================================================================================
//Read Watchlist and compute number of items, momentum and standard deviation
//Compute number of issues
WL_Name = "SP Sectors"; //"MVP Develop";
WL_Num = CategoryFind( WL_Name, CategoryWatchlist );
WL_List = CategoryGetSymbols( CategoryWatchlist, WL_Num, 0 ) ; // Get ticker symbols in CSV format
WL_Count = StrCount( WL_List, "," ) + 1 ;
//
if( testdata ) WL_Count = 3; // Number of symbols in watchlist
printf( "Count " + WL_Count + "\n" );
//
//
// =====================================================================================================================================
// Create expected return matricx
//
ERmx = Matrix( WL_count, 1, 0 ); // Expected Returns (% momentum)
//
// =====================================================================================================================================
// Print the Watchlist Issues, Momentum and Standard Deviation, as inputs to system
period = Param( "period", 60, 20, 252, 10 ); // Momentum and standard deviation
Lookback = Param( "Lookback", 0, 0, 264, 22 ); // ignore last lookback bars - for debug only
//
_TRACE( "MVP-array - barIndex " + WriteVal( LastValue( BarIndex(), 1.0 ) ) );
//
// for( i = 0; ( sym = StrExtract( WL_List, i ) ) != ""; i++ )
for( i = 0; ( sym = StrExtract( WL_List, i ) ) != "" AND i < WL_Count; i++ )
//for( i = 0; i<3; i++ )
{
Price = Foreign( sym, "C" );
momentum = Ref( ROC( price, period ), -Lookback ); // expected return
St_dev = Ref( StDev( price, period ) / 100, -Lookback );
/*
for (k=41; k<44; k++)
{
_TRACE( "MVP-array - barcount " + WriteVal(BarCount,1.0) + " k " + Writeval( k, 1.0 ) + " sym = " + sym + WriteVal(price[k],1.2) );
}
*/
VarSetText( "name_" + NumToStr( i, 1.0 ) , sym );
VarSet( "mom_" + NumToStr( i, 1.0 ) , momentum );
VarSet( "stdev_" + NumToStr( i, 1.0 ) , St_dev );
VarSet( "price_" + NumToStr( i, 1.0 ) , price );
//
//Enter values into Matrix form
ERmx[i][0] = LastValue( momentum ) ; // Verify if last value is end of period or end of array ??????? ZZZZZZZZZZZ
//Test data
if( testdata )
{
VarSetText( "name_" + NumToStr( 0, 1.0 ) , "A" );
VarSet( "mom_" + NumToStr( 0, 1.0 ) , 20.0253 );
VarSet( "stdev_" + NumToStr( 0, 1.0 ) , 0.1 );
ERmx[0][0] = 20.0253;
//
VarSetText( "name_" + NumToStr( 1, 1.0 ) , "B" );
VarSet( "mom_" + NumToStr( 1, 1.0 ) , 20.0869 );
VarSet( "stdev_" + NumToStr( 1, 1.0 ) , .1044 );
ERmx[1][0] = 20.0869;
//
VarSetText( "name_" + NumToStr( 2, 1.0 ) , "C" );
VarSet( "mom_" + NumToStr( 2, 1.0 ) , 16.3860 );
VarSet( "stdev_" + NumToStr( 2, 1.0 ) , .1411 );
ERmx[2][0] = 16.3860;
}
//
printf( "Symbol " + VarGetText( "name_" + NumToStr( i, 1.0 ) ) + " mom " + VarGet( "mom_" + NumToStr( i, 1.0 ) ) + " price " + VarGet( "price_" + NumToStr( i, 1.0 ) ) + " std " + VarGet( "stdev_" + NumToStr( i, 1.0 ) ) + "\n" );
printf( "Symbol " + VarGetText( "name_" + NumToStr( i, 1.0 ) ) + " mom " + LastValue( momentum ) + " price " + VarGet( "price_" + NumToStr( i, 1.0 ) ) + " std " + LastValue( St_dev ) + "\n" );
}
//GfxDrawText( "AAPL",x1, (y2 + (3*y_inc)), (x1 + textblock), (y2 + (4*y_inc)) , TA_Center );
//printf("x1 " + x1 + " y1 " + y2 + " textblock " + textblock + " y_inc " + y_inc +"\n");
//printf("x1 " + x1 + " y1 " + (y2 + (3*y_inc)) + " x2 " + (x1 + textblock) + " y2 " + (y2 + (4*y_inc)) + "\n");
//
// =====================================================================================================================================
//Compute covariance values and populate matrices
//WL_Count = 3;
// lookback = 60;
VarMx = Matrix( WL_Count, WL_Count, 0 );
//
//
//
for( i = 0; i < WL_Count; i++ )
{
for( j = 0; j < WL_Count; j++ )
{
Corrxy = Correlation( VarGet( "price_" + NumToStr( i, 1.0 ) ), VarGet( "price_" + NumToStr( j, 1.0 ) ), period ); // OK
Covarxy = Corrxy * VarGet( "stdev_" + NumToStr( i, 1.0 ) ) * VarGet( "stdev_" + NumToStr( j, 1.0 ) ) ; // OK
//
//Corrxy = LastValue(Correlation(VarGet( "price_" + NumToStr( i, 1.0 )), VarGet( "price_" + NumToStr( j, 1.0 )), period));
//Covarxy = Corrxy * LastValue(VarGet( "stdev_" + NumToStr( i, 1.0 ) ) * VarGet( "stdev_" + NumToStr( j, 1.0 ))) ;
printf( "i " + i + " j " + j + "Corrxy " + WriteVal( LastValue( corrxy ), 1.4 ) + " covarxy " + WriteVal( LastValue( covarxy ), 1.4 ) + "\n" );
VarMx[i][j] = LastValue( covarxy );
//
printf( "i " + i + " i-std " + LastValue( VarGet( "stdev_" + NumToStr( i, 1.0 ) ) ) + " j " + j + " j-std " + LastValue( VarGet( "stdev_" + NumToStr( j, 1.0 ) ) )
+ " sij " + LastValue( VarGet( "stdev_" + NumToStr( i, 1.0 ) ) ) * LastValue( VarGet( "stdev_" + NumToStr( j, 1.0 ) ) ) + "\n" );
//
if( testdata )
{
VarMx[0][0] = 0.01012086;
VarMx[0][1] = 0.00665194;
VarMx[0][2] = -0.00489317;
VarMx[1][0] = 0.00665194;
VarMx[1][1] = 0.00877455;
VarMx[1][2] = 0.00091096;
VarMx[2][0] = -0.00489317;
VarMx[2][1] = 0.00091096;
VarMx[2][2] = 0.01827133;
}
}
}
R = ERMx;
A = VarMx;
//
//
// --- minimum variance portfolio (unconstrained) ---
//
B = Matrix( WL_Count , 1 , 1 );
X = Matrix( WL_Count , 1 , 0 );
//
//X = MxInverse( A ) @ B;
X = MxSolve( A, B );
Y = MxSum( X );
W = X / Y; // Portfolio weights
T = MxSum( W );
SD = ( ( MxTranspose( W ) @ A ) @ W ) * sqrt( 12 / 30 * period ); // sqrt(12) - annualize standard deviation
SD = MxSum( SD );
SD = sqrt( SD ) * 100;
P = MxTranspose( R ) @ W;
P = MxSum( P );
//
SD1 = SD;
P1 = P;
W1 = W; // Save Matrix for printing
printf( " Covariance matrix: " + "\n" + MxToString( A ) + "\n" );
printf( " Expected returns: " + "\n" + MxToString( R ) + "\n" );
printf( " ############################################################ " + "\n" );
printf( "\n" );
printf( " Minimum Variance Portfolio (Unconstrained) " + "\n" );
printf( "\n" );
printf( " Matrix W: " + "\n" + MxToString( W * 100 ) + "\n" );
printf( " Sum W : " + NumToStr( T * 100 ) + "\n" );
printf( " Return : " + P + "\n" );
printf( " SD : " + SD + "\n" );
//
/*
//Fill in Weight Matrix
for (i=0; i<WL_Count; i++)
{
WeightMx[i][0] = W1[i][0]*100
}
//
*/
// ============================================================================================================================================
//
// ============================================================================================================================================
// --- tangency portfolio (unconstrained) ---
E = R - 5;
//X = MxInverse( A ) @ E;
X = MxSolve( A, E );
Y = MxSum( X );
W = X / Y; // Portfolio weights
T = MxSum( W );
SD = ( ( MxTranspose( W ) @ A ) @ W ) * sqrt( 12 / 30 * period );
SD = MxSum( SD );
SD = sqrt( SD ) * 100;
P = MxTranspose( R ) @ W;
P = MxSum( P );
//
SD2 = SD;
P2 = P;
W2 = W;
//
//WeightMx[0][0] =
printf( " ############################################################ " + "\n" );
printf( "\n" );
printf( " Tangency Portfolio (Unconstrained, RF=5%%) " + "\n" );
printf( "\n" );
printf( " Matrix W: " + "\n" + MxToString( W * 100 ) + "\n" );
printf( " Sum W : " + NumToStr( T * 100 ) + "\n" );
printf( " Return : " + P + "\n" );
printf( " SD : " + SD + "\n" );
printf( " ############################################################ " + "\n" );
//
// --- minimum variance portfolio (long only) ---
printf( "\n" );
printf( " Long Only Minimum Variance Portfolio " );
// init values ---
MinV = 100;
cnt = 0;
for( i = 100 ; i >= 0; i-- )
{
jMax = 100 - i;
for( j = jMax ; j >= 0 ; j-- )
{
if( i + j == 100 )
{
X[0][0] = i;
X[1][0] = j;
X[2][0] = 0;
}
else
{
X[0][0] = i;
X[1][0] = j;
X[2][0] = 100 - i - j;
}
cnt++;
X = X / 100;
SD = ( ( MxTranspose( X ) @ A ) @ X ) * sqrt( 12 / 30 * period );
SD = MxSum( SD );
SD = sqrt( SD ) * 100;
P = MxTranspose( R ) @ X;
P = MxSum( P );
// printf( MxToString( X * 100 ) + "\n" + " Sum: " + NumToStr( MxSum( X * 100 ) ) + " & SD: " + NumToStr( SD ) + " & Return: " + NumToStr( P ) + "\n" );
if( SD < MinV ) W = X;
MinV = Min( MinV, SD );
}
}
printf( " (Weight Combinations: " + NumToStr( cnt ) + ")" + "\n" );
printf( "\n" );
SD = ( ( MxTranspose( W ) @ A ) @ W ) * sqrt( 12 ); / 30 * period );
SD = MxSum( SD );
SD = sqrt( SD ) * 100;
P = MxTranspose( R ) @ W;
P = MxSum( P );
//
SD3 = SD;
P3 = P;
W3 = W;
//
printf( " Matrix W: " + "\n" + MxToString( W * 100 ) + "\n" );
printf( " Sum W: " + NumToStr( T * 100 ) + "\n" );
printf( " Return : " + P + "\n" );
printf( " SD : " + SD + " (Min.SD: " + MinV + ")" + "\n" );
//
printf( " ############################################################ " + "\n" );
//
//
//Draw Screen background
TA_CENTER = 1; // Used for gfx text formating
TA_Left = 0;
TA_Right = 2;
//
x1 = 5;
x2 = x1 + 100;
x3 = x2 + 100;
x4 = 400;
x5 = x4 + 100;
x6 = x5 + 100;
x7 = 830;
y_header = 20;
y1 = 100;
y2 = 80;
y3 = 350;
headerBlock = 300;
textblock = 120;
//
n = 0;
pxheight = Status( "pxheight" );
pxwidth = Status( "pxwidth" );
hd_font = Min(int(pxwidth / 55),18);
tx_font = Min(int(pxwidth / 80),12);
y_inc = Min(int(pxheight / 40),18); //20;
//
printf("PW " + pxwidth + "\n");
//Create Screeen Text and Headings
// =====================================================================================================================================
//Create Graphics background and text headings
GfxSetTextColor( colorBlack );
GfxSelectSolidBrush( colorLightYellow );
GfxSetBkColor( colorLightYellow );
//
GfxRectangle( 1, 1, pxwidth, pxheight );
GfxSelectFont( "Arial", pointsize = hd_font, weight = 1, italic = False, underline = False, orientation = 0 ) ;
GfxDrawText( "Minimum Variance Portfolio-2", pxwidth / 2 - HeaderBlock, y_header, pxwidth / 2 + HeaderBlock , y_header + 30, TA_Center );
//
GfxSelectFont( "Arial", pointsize = tx_font, weight = 1, italic = False, underline = False, orientation = 0 ) ;
GfxDrawText( "Portfolio", x1, y2, x1 + TextBlock , y2 + y_inc, TA_Center );
GfxDrawText( "Components", x1, y2 + y_inc, x1 + TextBlock , y2 + ( 2 * y_inc ), TA_Center );
GfxDrawText( "Momentum", x2, y2, x2 + TextBlock , y2 + y_inc, TA_Center );
GfxDrawText( "%", x2, y2 + y_inc, x2 + TextBlock , y2 + ( 2 * y_inc ), TA_Center );
GfxDrawText( "StDev", x3, y2, x3 + TextBlock , y2 + y_inc, TA_Center );
GfxDrawText( "%", x3, y2 + y_inc, x3 + TextBlock , y2 + ( 2 * y_inc ), TA_Center );
//
x_offset1 = 100;
x_offset2 = 200;
GfxDrawText( "Weights %", x5, y2, x5 + TextBlock , y2 + y_inc, TA_Center );
GfxDrawText( "Normal", x4, y2 + y_inc, x4 + TextBlock , y2 + ( 2 * y_inc ), TA_Center );
GfxDrawText( "Tangent", x5, y2 + y_inc, x5 + TextBlock , y2 + ( 2 * y_inc ), TA_Center );
GfxDrawText( "Long Only", x6, y2 + y_inc, x6 + TextBlock , y2 + ( 2 * y_inc ), TA_Center );
//
GfxDrawText( "Parameters", x7, y2 + (1*y_inc), x7 + TextBlock , y2 + ( 2 * y_inc ), TA_Center );
GfxDrawText( "Period:", x7-10, y2 + (3*y_inc), x7-10 + TextBlock , y2 + ( 4 * y_inc ), TA_Left );
GfxDrawText( "Lookback:", x7-10, y2 + (4*y_inc), x7-10 + TextBlock , y2 + ( 5 * y_inc ), TA_Left );
GfxDrawText( NumToStr(period,1.0), x7, y2 + (3*y_inc), x7 + TextBlock , y2 + ( 4 * y_inc ), TA_Right );
GfxDrawText( NumToStr(lookback,1.0), x7, y2 + (4*y_inc), x7 + TextBlock , y2 + ( 5 * y_inc ), TA_Right );
//
// =====================================================================================================================================
//
//Draw All input data (Issues, Mementum, StDev) and computed portfolio weights
x_offset = 0;
y_offset = 3;
x_inc = 100;
numblock = 85;
textblock = 130;
//Print Assigned weights to screen
for( i = 0; i < WL_Count; i++ )
{
//Momentum and Standard Deviation values shown on screen are multiplied by 100 to show as percentages - NOT DONE
GfxDrawText( NumToStr( i, 1.0 ), 5, y2 + ( ( y_offset + i )*y_inc ), x1 + 20, y2 + ( ( y_offset + i + 1 )*y_inc ) , TA_Right );
GfxDrawText( VarGetText( "name_" + NumToStr( i, 1.0 ) ), x1 - 30, y2 + ( ( y_offset + i )*y_inc ), x1 + TextBlock, y2 + ( ( y_offset + i + 1 )*y_inc ) , TA_Center ); // Display symbol
GfxDrawText( NumToStr( LastValue( VarGet( "mom_" + NumToStr( i, 1.0 ) ) ), 1.4 ), x2, y2 + ( ( y_offset + i )*y_inc ), x2 + NumBlock, y2 + ( ( y_offset + i + 1 )*y_inc ) , TA_Right ); // Display momentum
GfxDrawText( NumToStr( LastValue( VarGet( "stdev_" + NumToStr( i, 1.0 ) )*100 ), 1.4 ), x3, y2 + ( ( y_offset + i )*y_inc ), x3 + NumBlock, y2 + ( ( y_offset + i + 1 )*y_inc ) , TA_Right ); // Display standard Deviation
//_TRACE( "MVP - i " + Writeval( i, 1.0 ) + " sym = " + sym + " mom " + Writeval(VarGet("mom_" + NumToStr(i,1.0)),1.4) + " price " + Writeval(VarGet("price_" + NumToStr(i,1.0)),1.2)
// + " std " + Writeval(VarGet("stdev_" + NumToStr(i,1.0)),1.2) );
_TRACE( "MVP - i " + Writeval( i, 1.0 ) + " sym = " + sym + " mom " + Writeval( LastValue( momentum ), 1.4 ) + " price " + Writeval( price, 1.2 )
+ " std " + Writeval( LastValue( St_dev ), 1.2 ) ) ;
GfxDrawText( NumToStr( W1[i][0] * 100, 1.2 ), x4, y2 + ( ( y_offset + i )*y_inc ), x4 + NumBlock, y2 + ( ( y_offset + i + 1 )*y_inc ) , TA_Right );
GfxDrawText( NumToStr( W2[i][0] * 100, 1.2 ), x5, y2 + ( ( y_offset + i )*y_inc ), x5 + NumBlock, y2 + ( ( y_offset + i + 1 )*y_inc ) , TA_Right );
GfxDrawText( NumToStr( W3[i][0] * 100, 1.2 ), x6, y2 + ( ( y_offset + i )*y_inc ), x6 + NumBlock, y2 + ( ( y_offset + i + 1 )*y_inc ) , TA_Right );
}
//
//Display covariance matrix
x_inc = WL_Count * 70 / 2;
y3 = y2 + ( ( y_offset + i + 1 ) * y_inc );
numblock = pxwidth / WL_Count * 0.8;
GfxDrawText( "Covariance Matrix x 1000", x1 + ( x_inc ), y3, x1 + ( x_inc ) + TextBlock * 1.5 , y3 + y_inc, TA_Center );
for( i = 0; i < WL_Count; i++ )
{
for( j = 0; j < WL_Count; j++ )
{
GfxDrawText( NumToStr( 1000 * VarMx[i][j], 1.4 ), x1 + ( i * numblock ), y3 + ( ( j + y_offset - 1 )*y_inc ), x1 + ( i * numblock ) + NumBlock, y3 + ( ( j + y_offset )*y_inc ) , TA_Right );
}
}
// Display Results
//Create headers for Portfolio results
textblock = 50;
x11 = pxwidth * 0.30;
x21 = pxwidth * 0.50;
x31 = pxwidth * 0.70;
x_offset = 50;
y4 = pxheight - 100;
//
GfxDrawText( "Portfolio", x21 - Textblock, y4, x21 + TextBlock , y4 + y_inc, TA_Center );
//GfxDrawText( "Portfolio", pxwidth * 0.50 - TextBlock, y4, pxwidth * 0.50 + TextBlock , y4 + y_inc, TA_Center );
GfxDrawText( "Unconstrained", x11 - TextBlock, y4 + ( 1 * y_inc ), x11 + TextBlock , y4 + ( 2 * y_inc ), TA_Center );
GfxDrawText( "Tangential", x21 - TextBlock, y4 + ( 1 * y_inc ), x21 + TextBlock , y4 + ( 2 * y_inc ), TA_Center );
GfxDrawText( "Long Only", x31 - TextBlock, y4 + ( 1 * y_inc ), x31 + TextBlock , y4 + ( 2 * y_inc ), TA_Center );
//
GfxDrawText( "Returns", x11 - x_Offset - textblock, y4 + ( 2 * y_inc ), x11 - x_Offset + textblock , y4 + ( 3 * y_inc ), TA_Center );
GfxDrawText( "StDev", x11 + x_Offset - textblock, y4 + ( 2 * y_inc ), x11 + x_Offset + textblock , y4 + ( 3 * y_inc ), TA_Center );
GfxDrawText( "Returns", x21 - x_Offset - textblock, y4 + ( 2 * y_inc ), x21 - x_Offset + textblock , y4 + ( 3 * y_inc ), TA_Center );
GfxDrawText( "StDev", x21 + x_Offset - textblock, y4 + ( 2 * y_inc ), x21 + x_Offset + textblock , y4 + ( 3 * y_inc ), TA_Center );
GfxDrawText( "Returns", x31 - x_Offset - textblock, y4 + ( 2 * y_inc ), x31 - x_Offset + textblock , y4 + ( 3 * y_inc ), TA_Center );
GfxDrawText( "StDev", x31 + x_Offset - textblock, y4 + ( 2 * y_inc ), x31 + x_Offset + textblock , y4 + ( 3 * y_inc ), TA_Center );
//
//Print to screen portfolio returns and standard deviation for standard MVP
GfxDrawText( NumToStr( P1, 1.4 ), x11 - x_offset - textblock, y4 + ( 3 * y_inc ), x11 - x_offset + textblock, y4 + ( ( 4 )*y_inc ) , TA_Center );
GfxDrawText( NumToStr( SD1, 1.4 ), x11 + x_offset - textblock, y4 + ( 3 * y_inc ), x11 + x_offset + textblock, y4 + ( ( 4 )*y_inc ) , TA_Center );
//
//Print to screen portfolio returns and standard deviation for Tangency MVP
GfxDrawText( NumToStr( P2, 1.4 ), x21 - x_offset - textblock, y4 + ( 3 * y_inc ), x21 - x_offset + textblock, y4 + ( ( 4 )*y_inc ) , TA_Center );
GfxDrawText( NumToStr( SD2, 1.4 ), x21 + x_offset - textblock, y4 + ( 3 * y_inc ), x21 + x_offset + textblock, y4 + ( ( 4 )*y_inc ) , TA_Center );
//
//Print to screen portfolio returns and standard deviation Long Only portfolio
x_offset = 50;
GfxDrawText( NumToStr( P3, 1.4 ), x31 - x_offset - textblock, y4 + ( 3 * y_inc ), x31 - x_offset + textblock, y4 + ( ( 4 )*y_inc ) , TA_Center );
GfxDrawText( NumToStr( SD3, 1.4 ), x31 + x_offset - textblock, y4 + ( 3 * y_inc ), x31 + x_offset + textblock, y4 + ( ( 4 )*y_inc ) , TA_Center );
//
RequestTimedRefresh( 1 );
//
Title = "MVPortfolio Development";
//type or paste code here