Gamestudio Links
Zorro Links
Newest Posts
Data from CSV not parsed correctly
by EternallyCurious. 04/18/24 10:45
StartWeek not working as it should
by Zheka. 04/18/24 10:11
folder management functions
by VoroneTZ. 04/17/24 06:52
lookback setting performance issue
by 7th_zorro. 04/16/24 03:08
zorro 64bit command line support
by 7th_zorro. 04/15/24 09:36
Zorro FIX plugin - Experimental
by flink. 04/14/24 07:48
Zorro FIX plugin - Experimental
by flink. 04/14/24 07:46
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
1 registered members (AndrewAMD), 552 guests, and 1 spider.
Key: Admin, Global Mod, Mod
Newest Members
EternallyCurious, 11honza11, ccorrea, sakolin, rajesh7827
19046 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Page 1 of 2 1 2
MVO testing script #460169
06/18/16 15:49
06/18/16 15:49
Joined: Feb 2015
Posts: 652
Milano, Italy
M
MatPed Offline OP
User
MatPed  Offline OP
User
M

Joined: Feb 2015
Posts: 652
Milano, Italy
Hi,
in the last weeks I played a while with the MVO Algorithm presented by JCL on his blog and the "Momentum and Markowitz: A Golden Combination" paper (I admit not yet fully metabolized).
I have tried to assemble a script that trade the MVO algorithm in a similar way than the new z8. The idea was to compare different settings of the DAYS and CAP parameters (see the code below) with the usual Zorro cockpit (AR PF SR UI R2).

Z8 was a perfect fit I had a properly coded system ready to be compared.

This is the code:
Code:
//////////////////////////////////////////////////////
// Mean Variance Optimization ////////////////////////
//////////////////////////////////////////////////////

#define DAYS			252 	// 1 year
//#define DAYS			6*22 // 6 Months
//#define DAYS			4*22 // 4 Months
//#define DAYS			2*22 // 2 Months

#define WEIGHTCAP 	.25 // Cap 0.15 - 0.5 Range
#define NN				50	 	// max number of assets
#define LEVERAGE 		4	// 1:4 leverage

//////////////////////////////////////////////////////

function run()
{
	BarPeriod = 1440;
	LookBack = DAYS;
	NumYears = 7;
		set(PRELOAD); // allow extremely long lookback period	
		set(LOGFILE);
	Verbose = 0;

//	AssetList = "ETF2016-OK.csv";
	AssetList = "AssetsZ8.csv";

	string		Names[NN];
	string 		Symbols[NN]; // Store the ISIN Code
	vars			Returns[NN];
	var			Means[NN];
	var			Covariances[NN][NN];
	var			Weights[NN];
	static int 	OldLots[NN];

	var TotalCapital = slider(1,25000,10000,50000,"Capital","Total capital to distribute");
	var VFactor = slider(2, 10 ,0, 100,"Risk","Variance factor");
	
	int N = 0;
	while(Names[N] = loop(Assets))
	{
		asset(Names[N]);
		
		if((is(INITRUN) && (strstr(Names[N], "#")== NULL))) {
			assetHistory(Names[N],FROM_YAHOO);
			Symbols[N] = Symbol; // Store the isin code for quick referenze
		}	else 	if(strstr(Names[N], "#")== NULL) Returns[N] = series((priceClose(0)-priceClose(1))/priceClose(1));
					else 										Returns[N] = series(0);
		if(N++ >= NN) break;
	}

		int i,j;
		if(tdm() == 1 ){ 
			for(i=0; i<N; i++) {
				Means[i] = Moment(Returns[i],LookBack,1);
				for(j=0; j<N; j++)
					Covariances[N*i+j] = Covariance(Returns[i],Returns[j],LookBack);	
			}
			var BestVariance = markowitz(Covariances, Means, N, WEIGHTCAP);
			var MinVariance = markowitzReturn(0,0);
			markowitzReturn(Weights,MinVariance+VFactor/100.*(BestVariance-MinVariance));

// 		change the portfolio composition according to new weights		
			for(i=0; i<N; i++)
				if (strstr(Names[i], "#")== NULL){
					asset(Names[i]);
					MarginCost = priceClose()/LEVERAGE;
					int NewLots = TotalCapital*Weights[i]/MarginCost;
					if(NewLots > OldLots[i])	
						enterLong(NewLots-OldLots[i]);
					else if(NewLots < OldLots[i]) exitLong(0,0,OldLots[i]-NewLots);
//					printf("\n%s - %s:  OldLots: %d NewLots: %d %.0f$",Names[i],Symbols[i], OldLots[i], NewLots );
					OldLots[i] = NewLots;
			}
		}
}



Considered that JCL plays in another league, I am satisfied with the following results obtained with the same z8 assets list.

Trades 460 Win 75.0% Avg +386.4p Bars 184
AR 22% PF 4.94 SR 1.45 UI 5% R2 0.97


Anyway the code is not polished and has some issues:
  • Starting the script without any history (delete the .bar file from the history dir) I have to press the test button twice before get the results. I am doing something wrong, but I do not understand what.
  • The number of trades are high compared with Z8. Is a mistake in re-balancing the portfolio?
  • the z8 equity line is calculated once per month (as it should be), in my script is plotted once for day. Mistake or just a Z8 better way to plot the equity line?


Ciao

Attached Files etfTS_XRT.png
Re: MVO testing script [Re: MatPed] #460193
06/19/16 15:46
06/19/16 15:46
Joined: May 2016
Posts: 180
Prague
pcz Offline
Member
pcz  Offline
Member

Joined: May 2016
Posts: 180
Prague
I think the number of trades is related to the TotalCapital variable. Try setting it to 1000 and the number will be similar to Z8 backtests with default settings.

Re: MVO testing script [Re: pcz] #460206
06/20/16 09:49
06/20/16 09:49
Joined: Feb 2015
Posts: 652
Milano, Italy
M
MatPed Offline OP
User
MatPed  Offline OP
User
M

Joined: Feb 2015
Posts: 652
Milano, Italy
Good point!
Tested 288 vs 343 z8 tardes. There are, obviously, some differences in the algorithm.

Do you have any suggestion regarding the first issue? Why the first run without pre-loaded history bar works correctly?

Ciao

Re: MVO testing script [Re: MatPed] #460220
06/20/16 13:25
06/20/16 13:25
Joined: Feb 2015
Posts: 652
Milano, Italy
M
MatPed Offline OP
User
MatPed  Offline OP
User
M

Joined: Feb 2015
Posts: 652
Milano, Italy
Solved laugh

Code:
//////////////////////////////////////////////////////
// Mean Variance Optimization ////////////////////////
//////////////////////////////////////////////////////

//#define DAYS			252 	// 1 year
#define DAYS			6*22 // 6 Months
//#define DAYS			4*22 // 4 Months
//#define DAYS			2*22 // 2 Months

#define WEIGHTCAP 	.25 // Cap 0.15 - 0.5 Range
#define NN				50	 	// max number of assets
#define LEVERAGE 		4	// 1:4 leverage

//////////////////////////////////////////////////////

function run()
{
	BarPeriod = 1440;
	LookBack = DAYS;
	NumYears = 7;
		set(PRELOAD); // allow extremely long lookback period	
		set(LOGFILE);
	Verbose = 0;
	set(watch);

//	AssetList = "ETF2016-OK.csv";
	AssetList = "AssetsZ8.csv";

	string		Names[NN];
	string 		Symbols[NN]; // Store the ISIN Code
	vars			Returns[NN];
	var			Means[NN];
	var			Covariances[NN][NN];
	var			Weights[NN];
	static int 	OldLots[NN];

	var TotalCapital = slider(1,1000,1000,50000,"Capital","Total capital to distribute");
	var VFactor = slider(2, 10 ,0, 100,"Risk","Variance factor");
	
	int N = 0;
	while(Names[N] = loop(Assets))
	{
		
		if(is(INITRUN) && strstr(Names[N], "#")== NULL) {
			assetHistory(Names[N], FROM_YAHOO);
			Symbols[N] = Symbol; // Store the isin code for quick referenze	
		}	
		 	
		if(strstr(Names[N], "#")== NULL && is(RUNNING)) {
			asset(Names[N]);
			Returns[N] = series((priceClose(0)-priceClose(1))/priceClose(1));
		}
		if(strstr(Names[N], "#")!= NULL && is(RUNNING)) Returns[N] = series(0);
		
		if(N++ >= NN) break;
	}

		if(tdm() == 1 && !is(LOOKBACK)){ 
			int i,j;
			for(i=0; i<N; i++) {
				Means[i] = Moment(Returns[i],LookBack,1);
				for(j=0; j<N; j++)
					Covariances[N*i+j] = Covariance(Returns[i],Returns[j],LookBack);	
			}
			var BestVariance = markowitz(Covariances, Means, N, WEIGHTCAP);
			var MinVariance = markowitzReturn(0,0);
			markowitzReturn(Weights,MinVariance+VFactor/100.*(BestVariance-MinVariance));

// 		change the portfolio composition according to new weights		
			for(i=0; i<N; i++)
				if (strstr(Names[i], "#")== NULL){
					asset(Names[i]);
					MarginCost = priceClose()/LEVERAGE;
					int NewLots = TotalCapital*Weights[i]/MarginCost;
					if(NewLots > OldLots[i])	
						enterLong(NewLots-OldLots[i]);
					else if(NewLots < OldLots[i]) exitLong(0,0,OldLots[i]-NewLots);
//					printf("\n%s - %s:  OldLots: %d NewLots: %d %.0f$",Names[i],Symbols[i], OldLots[i], NewLots );
					OldLots[i] = NewLots;
			}
		}
}


Re: MVO testing script [Re: MatPed] #461411
08/04/16 12:30
08/04/16 12:30
Joined: May 2016
Posts: 180
Prague
pcz Offline
Member
pcz  Offline
Member

Joined: May 2016
Posts: 180
Prague
Two additional notes:
- maybe it would be more proper to use longer time period - to include (for example) crash of 2008 or 2002 downturn. Without it the results might be too optimistic.
- could be worth to simulate the choosing of the assets year by year. In the past some of the current assets did not exist so if you traded this strategy, you would probably use different ones.

Re: MVO testing script [Re: pcz] #461430
08/04/16 20:39
08/04/16 20:39
Joined: Feb 2015
Posts: 652
Milano, Italy
M
MatPed Offline OP
User
MatPed  Offline OP
User
M

Joined: Feb 2015
Posts: 652
Milano, Italy
yes, that was only one testing setting regarding the longer period, that is a key point. On my to do list is to develop a script to test an etf and decide if it has enough data from a quality and quantitative point of view.
ETF in Italy does not have such a long data history.

Another point is the trading costs. I am trying to simulate fixed cost for each transaction. Still ea lot to do...

Re: MVO testing script [Re: MatPed] #461992
09/01/16 10:19
09/01/16 10:19
Joined: Feb 2015
Posts: 652
Milano, Italy
M
MatPed Offline OP
User
MatPed  Offline OP
User
M

Joined: Feb 2015
Posts: 652
Milano, Italy
I am located in iTaly and I have seen that the MVO script trade at 4 pm (local time).
Is someone aware how to ask the system to trade at 9.00 am (local time))

I have read the manual regarding timezone, but I am a bit confused.

Thank you in advance

Re: MVO testing script [Re: MatPed] #461993
09/01/16 14:08
09/01/16 14:08
Joined: Feb 2015
Posts: 652
Milano, Italy
M
MatPed Offline OP
User
MatPed  Offline OP
User
M

Joined: Feb 2015
Posts: 652
Milano, Italy
Why this script is not trading today?
Any Idea?

//////////////////////////////////////////////////////
// Mean Variance Optimization ////////////////////////
//////////////////////////////////////////////////////

//#define DAYS 252 // 1 year 252
//#define DAYS 231 // 11 Months
//#define DAYS 210 // 10 Months
#define DAYS 189 // 9 Months
//#define DAYS 168 // 8 Months
//#define DAYS 147 // 7 Months
//#define DAYS 126 // 6 Months

#define NN 300 // max number of assets
#define WEIGHTCAP 0.25 // Cap 0.15 - 0.5 Range
#define LEVERAGE 4 // 1-20 leverage
//#define MAXETF 7
//////////////////////////////////////////////////////

string Names[NN];
string Symbols[NN]; // Store the ISIN Code
vars Returns[NN];
var Means[NN];
var Covariances[NN][NN];
var Weights[NN];
int OldLots[NN];
var ThePrice[NN];
int N = 0;


function run()
{
BarPeriod = 1440;
LookBack = DAYS;
NumYears = 6;
AssetZone = WET;

set(PRELOAD+BALANCE); // allow extremely long lookback period
set(LOGFILE);
Verbose = 0;

// AssetList = "Lyxsor.csv";
// AssetList = "AzionarioSettoriali.csv";
// AssetList = "ETF2016-OK.csv";
// AssetList = "ETF2016-7.csv";
AssetList = "AssetsZ8-originale.csv";

vars Returns[NN];
var TotalCapital = slider(1,20000,1000,50000,"Capital","Total capital to distribute");
var VFactor = slider(2, 0 ,0, 100,"Risk","Variance factor");

if(is(INITRUN)) {
while(Names[N]=loop(Assets)) {
if(strstr(Names[N], "#")== NULL)
{
assetHistory(Names[N], FROM_YAHOO);
asset(Names[N]);
Symbols[N] = Symbol; // Store the isin code for quick referenze
// printf("\n Names, Asset, Symbol %d: %s - %s - %s", N, Names[N], Asset, Symbol);
if(N++ >= NN) break;
}
}
}

int i;
// for(i=0; i<N; i++) printf("\n%d - %s",i, Names[i]);
for(i=0; i<N; i++){
// if(!is(INITRUN)){
asset(Names[i]);
Returns[i] = series((priceClose(0)-priceClose(1))/priceClose(1));
// }
}

if(tdm() == 1 && !is(LOOKBACK)){
int j;
for(i=0; i<N; i++) {
Means[i] = Moment(Returns[i],LookBack,1);
// printf("\n%d - %s: %f",i, Names[i], Means[i]);
for(j=0; j<N; j++) Covariances[N*i+j] = Covariance(Returns[i],Returns[j],LookBack);
}
var BestVariance = markowitz(Covariances, Means, N, WEIGHTCAP);
var MinVariance = markowitzReturn(0,0);
markowitzReturn(Weights,MinVariance+VFactor/100.*(BestVariance-MinVariance));

#ifdef MAXETF
int* idx = sortIdx(Weights,N);
var TotalWeight = 0;
Spread = RollLong = RollShort = Commission = Slippage = 0;

for(i=N-MAXETF; i<N; i++) // sum up the 4 highest weights
TotalWeight += Weights[idx[i]];
for(i=0; i<N; i++) {
if(idx[i] < N-MAXETF)
Weights[i] = 0;
else // adjust weights so that their sum is still 1
Weights[i] /= TotalWeight;
}
#endif

// change the portfolio composition according to new weights
// var TheCapital = TotalCapital + WinTotal;
printf ( "\n\n --- %s ---",datetime());
for(i=0; i<N; i++) {
asset(Names[i]);
MarginCost = priceClose()/LEVERAGE;

// RollShort = RollLong =0;
// Spread = FIXEDCOM;

int NewLots = TotalCapital * Weights[i] / MarginCost;

if(NewLots > OldLots[i]) {
enterLong(NewLots-OldLots[i]);
}
else if(NewLots < OldLots[i]){
exitLong(0, 0, OldLots[i]-NewLots );
}
// printf("\nBestV: %f - MinV: %f", BestVariance, MinVariance);
printf("\n%-15.10s- %s: OldLots: %d NewLots: %d Price: %.2f",Names[i],Symbols[i], OldLots[i], NewLots, priceClose() );
OldLots[i] = NewLots;
}
}
}


Ciao

Last edited by MatPed; 09/01/16 14:10.
Re: MVO testing script [Re: MatPed] #462441
09/29/16 20:50
09/29/16 20:50
Joined: Sep 2016
Posts: 1
C
C33 Offline
Guest
C33  Offline
Guest
C

Joined: Sep 2016
Posts: 1
Hi all!

I have been working on an implementation of MVO and the Markowitz portfolio theory similarly to MatPed's work here. My goal is to backtest an actual implementation including transaction costs.

There is a curious problem. I wrote a function current_position() to get the position in an Asset. Theoretically, open_position and oldLots[i] should be the same. However, as the check at the end of run() shows, this is not always the case.


Possible reasons:

1. current_position doesn't do what it is supposed to do. Should I use open_trades? Check if TradeIsOpen? Can someone confirm this function does what it is supposed to do? Is there a better way?

2. Zorro sells the positions from time to time. Why? According to which rule?

This would mean that the calls enterLong(newLot - oldLots[i]) and exitLong(0, 0, oldLots[i] - newLot) would need to be changed. According to my reading of the manual, they are correct (all defaults are 0).

(I am actually using a different asset list csv file, but this shouldn't matter at all.)


Currently, the backtesting doesn't work correctly, as Zorro reduces the positions and then the portfolio is not balanced according to the weights[]. Any help would be appreciated. I think this code is very close, but I guess I am missing some enterLong or exitLong magic.

Cheers

PS: I'd be happy to post improved versions if we can figure out the problem and if people are interested.

PPS: It seems as if the indentation gets messed up.



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#define NN 50 // maximum number of assets

const var LEVERAGE = 4.0;
const bool verbose = FALSE;

function current_position(string asset_name) {
int sum = 0;
for (current_trades) {
if (TRUE) { // (TradeIsOpen) { //(0 == strcmp(Asset, asset_name)) {
sum += TradeLots;}}
return sum;}

function run() {
set(PRELOAD);
set(LOGFILE);
set(PLOTNOW);

AssetZone = WET;
NumYears = 7;
BarPeriod = 1440;
LookBack = 1 * 252; // 1 year
AssetList = "AssetsZ8.csv";

static int N = 0;
static string names[NN];
static int oldLots[NN];
vars returns[NN]; // series
var means[NN];
var covariances[NN][NN];
var weights[NN];

var totalCapital
= slider(1, 10000, 1000, 50000, "Capital", "Total capital to distribute");
var vFactor
= slider(2, 100, 0, 100, "Variance", "Variance factor, 0 = minimal variance, 100 = best variance");
var weightConstraintFactor
= slider(3, 50, 10, 90, "Max. w.", "maximum weight = (this value)/100");

if (is(INITRUN)) {
while (asset(loop(Assets))) {
names[N] = Asset;
printf("\nDownloading asset %d %s", N, names[N]);
assetHistory(Asset, FROM_YAHOO);
printf("\nAsset %d: name %s", N, names[N]);
oldLots[N] = 0;

if (++N >= NN) {
break;}}

printf("\n%d assets", N);}

int i;
for (i=0; i<N; i++) {
asset(names[i]);
returns[i] = series((priceClose(0)-priceClose(1)) / priceClose(1));
// printf("\nAsset %d %s: return %f", i, names[i], (returns[i])[0]);
}

if (1 == tdm() && !is(LOOKBACK)) {
int i, j;
for (i=0; i<N; i++) {
means[i] = Moment(returns[i], LookBack, 1);
for (j=0; j<N; j++) {
covariances[i*N + j] = Covariance(returns[i], returns[j], LookBack);}}

var bestVariance = markowitz(covariances, means, N, weightConstraintFactor/100.0);
var minVariance = markowitzReturn(0, 0);

markowitzReturn(weights, minVariance + (bestVariance-minVariance) * vFactor/100.0);

if (verbose) {
printf("\n\n%s", datetime());}
int i;
for (i=0; i<N; i++) {
asset(names[i]);
MarginCost = priceClose() / LEVERAGE;
int newLot = totalCapital * weights[i] / MarginCost;

if (verbose && (0 != oldLots[i] || 0 != newLot)) {
printf("\n%d %s: %d lots at %.2f$",
i, Asset, newLot, priceClose());
printf("\noldLots = %i, newLot = %i", oldLots[i], newLot);}

// if (verbose) {
// printf("\n%s: oldLots = %i, current_position = %i", Asset, oldLots[i], current_position(Asset));}

if (newLot > oldLots[i]) {
enterLong(newLot - oldLots[i]);}
if (newLot < oldLots[i]) {
exitLong(0, 0, oldLots[i] - newLot);}

oldLots[i] = newLot;}}

int i;
for (i=0; i<N; i++) {
asset(names[i]);
if (oldLots[i] != current_position(Asset)) {
printf("\n### %s: %s: oldLots = %i, current = %i", datetime(), Asset, oldLots[i], current_position(Asset));}}
}

Re: MVO testing script [Re: C33] #464096
01/22/17 07:05
01/22/17 07:05
Joined: Jan 2017
Posts: 11
Israel
D
dBc Offline
Newbie
dBc  Offline
Newbie
D

Joined: Jan 2017
Posts: 11
Israel
I compered the performance of Z8 vs MatPed's provided script (DAYS = 6 months) and I found the following figures:
1) Z8 capital=1000 AR=26%
2) Z8 capital=7000 AR=24%
3) MVO capital=1000 AR=17%
4) MVO capital=7000 AR=11%
I don't understand why so big differences between 3) and 4)?

MVO compiling..........
Assets........................
Test: MVO portfolio 2011..2016
Account AssetsZ8.csv
Monte Carlo Analysis... Median AR 17%
Profit 935$ MI 14$ DD 71$ Capital 1012$
Trades 221 Win 70.6% Avg +140.7p Bars 56
AR 17% PF 4.45 SR 1.53 UI 2% R2 0.52



Test: MVO portfolio 2011..2016
Account AssetsZ8.csv
Monte Carlo Analysis... Median AR 11%
Profit 4593$ MI 69$ DD 559$ Capital 7492$
Trades 337 Win 67.1% Avg +61.0p Bars 45
AR 11% PF 3.11 SR 1.10 UI 3% R2 0.84



Z8 (oP group) ..
Z8.5: PH M 1000 H 5 W 2 V 2
24 assets loaded
Assets........................
Test: Z8 portfolio 2011..2016
Account AssetsZ8 (NFA)
Monte Carlo Analysis... Median AR 28%
Profit 1863$ MI 26$ DD 150$ Capital 1180$
Trades 368 Win 73.6% Avg +181.0p Bars 69
AR 26% PF 4.13 SR 1.49 UI 4% R2 0.95
Chart... ok


Z8 (oP group) ..
Z8.5: PH M 1000 H 5 W 2 V 2
24 assets loaded
Assets........................
Test: Z8 portfolio 2011..2016
Account AssetsZ8 (NFA)
Monte Carlo Analysis... Median AR 26%
Profit 13305$ MI 183$ DD 1544$ Capital 9233$
Trades 561 Win 70.1% Avg +147.7p Bars 61
AR 24% PF 3.44 SR 1.42 UI 4% R2 0.93
Chart... ok

Page 1 of 2 1 2

Moderated by  Petra 

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1