TMF that cancels pending orders and enters trades

Posted By: boatman

TMF that cancels pending orders and enters trades - 06/09/15 07:48

How would I implement a TMF that:
  • Cancels other pending orders when one is hit
  • When a trade is stopped out, sets a new pending order at last week's close in the opposite direction to the stopped trade

The strategy is an implementation of something I read on the web. Its rules: At the market open after the weekend, the set pending orders 50 pips above and below last week's close. Set a stop loss of 30 pips, no profit target. If stopped out, enter a new pending order in the opposite direction at last week's close with a stop loss of 30 pips. Hold the position until late in Friday's trading.

Its a simple strategy and one that I don't expect to work, still I would like to get the TMF working as this is something that I have yet to grasp fully.

My code for the strategy is below. The issues that I see at the moment are that the opposite pending order isn't cancelled when it should and that new trades are not entered at the previous week's close. I'm wondering if I am using the TradeVars inappropriately? I've plagiarised code that I found in the manual and the forums for performing similar functions.

Any advice much appreciated!

Cheers

Code:
#define H1 (60/BarPeriod)
#define H24 (1440/BarPeriod)
#define W1 (7200/BarPeriod)
#define LastWeekClose TradeVar[0]
#define CancelOtherTrades TradeVar[1]

int myTMF() { //if stopped out, set pending at W1close in opp direction
	if (TradeIsLong and TradeIsStop) {
		//enter at last close
		Entry = LastWeekClose;
		Stop = 30*PIP;
		enterShort(myTMF);
	}
	if (TradeIsShort and TradeIsStop) {
		Entry = LastWeekClose;
		Stop = 30*PIP;
		enterLong(myTMF);
	}
	if(TradeIsPending and CancelOtherTrades == 1)
	return 1;
	if(TradeIsOpen) {
		CancelOtherTrades = 1;
		ThisTrade->manage = 0; // terminate the TMF
	}
	return 0;
}

function frameAlign(BOOL Event){ 
	TimeFrame = 1;
	vars Num = series(0); // use a series for storing Num between calls
	Num[0] = Num[1]+1;    // count Num up once per bar  
	if(!Event) 
	TimeFrame = 0;      // continue current time frame  
	else {
		TimeFrame = -Num[0]; // start a new time frame
		Num[0] = 0;          // reset the counter  
	}
}

function run() {
	set(TICKS);  // normally needed for TMF
	Weekend = 3; // don't run TMF at weekend
	StartDate = 20141201;
	EndDate = 20141231; //preserve 2015 data for OOS testing
	BarPeriod = 60;
	if (is(INITRUN)) CancelOtherTrades = 0;
	
	TimeFrame = W1;
	frameAlign(dow() == 7 and hour() == 23);
	vars closeW1 = series(priceClose());
	LastWeekClose = closeW1[0];
	
	TimeFrame = H1;
	int exitDay = 5;
	int exitHour = 16;
	

	if (!(dow() == exitDay and hour() >= exitHour)) {
		Entry = closeW1[0] + 50*PIP;
		Stop = 30*PIP; 
		if (NumOpenLong == 0) {	enterLong(myTMF, LastWeekClose); } 
		Entry = closeW1[0] - 50*PIP;
		if (NumOpenShort == 0) enterShort(myTMF, LastWeekClose);
	}
	
	if (dow() == exitDay and hour() == exitHour) {exitLong("*"); exitShort("*");}
	
	
	plot("closeW1", closeW1, MAIN, RED);
}

Posted By: jcl

Re: TMF that cancels pending orders and enters trades - 06/09/15 08:22

TradeVar are trade-specific variables. This means that every trade has its own set of TradeVars. If you want a variable not to belong to a specific trade, just use a global variable.
Posted By: boatman

Re: TMF that cancels pending orders and enters trades - 06/09/15 09:09

Thanks, that makes sense. I've changed my script to use global variables instead of TradeVars. My script now enters just one trade for the entire simulation period. After it is stopped out, no new trades are entered. Therefore, I think there is an error in the TMF script. Any ideas?

Updated script:
Code:
#define H1 (60/BarPeriod)
#define H24 (1440/BarPeriod)
#define W1 (7200/BarPeriod)
var LastWeekClose;
int CancelOtherTrades;

int myTMF() { //if stopped out, set pending at W1close in opp direction
	if (TradeIsLong and TradeIsStop) {
		//enter at last close
		Entry = LastWeekClose;
		Stop = 30*PIP;
		enterShort(myTMF);
	}
	if (TradeIsShort and TradeIsStop) {
		Entry = LastWeekClose;
		Stop = 30*PIP;
		enterLong(myTMF);
	}
	if(TradeIsPending and CancelOtherTrades == 1)
	return 1;
	if(TradeIsOpen) {
		CancelOtherTrades = 1;
		ThisTrade->manage = 0; // terminate the TMF
	}
	return 0;
}

function frameAlign(BOOL Event){ 
	TimeFrame = 1;
	vars Num = series(0); // use a series for storing Num between calls
	Num[0] = Num[1]+1;    // count Num up once per bar  
	if(!Event) 
	TimeFrame = 0;      // continue current time frame  
	else {
		TimeFrame = -Num[0]; // start a new time frame
		Num[0] = 0;          // reset the counter  
	}
}

function run() {
	set(TICKS);  // normally needed for TMF
	Weekend = 3; // don't run TMF at weekend
	StartDate = 20141201;
	EndDate = 20141231; //preserve 2015 data for OOS testing
	BarPeriod = 60;
	if (is(INITRUN)) CancelOtherTrades = 0;
	
	TimeFrame = W1;
	frameAlign(dow() == 7 and hour() == 23);
	vars closeW1 = series(priceClose());
	LastWeekClose = closeW1[0];
	
	TimeFrame = H1;
	int exitDay = 5;
	int exitHour = 16;
	

	if (!(dow() == exitDay and hour() >= exitHour)) {
		Entry = closeW1[0] + 50*PIP;
		Stop = 30*PIP; 
		if (NumOpenLong == 0) {	enterLong(myTMF, LastWeekClose); } 
		Entry = closeW1[0] - 50*PIP;
		if (NumOpenShort == 0) enterShort(myTMF, LastWeekClose);
	}
	
	if (dow() == exitDay and hour() == exitHour) {exitLong("*"); exitShort("*");}
	
	
	plot("closeW1", closeW1, MAIN, RED);

Posted By: jcl

Re: TMF that cancels pending orders and enters trades - 06/09/15 09:45

As far as I see at a quick glance, you're never setting CancelOtherTrades back to 0, which you should when all trades are cancelled.


Also, another idea: If you want to make a portfolio version out of this script one day, you would want CancelOtherTrades to be an AssetVar.
Posted By: boatman

Re: TMF that cancels pending orders and enters trades - 06/09/15 11:47

Thanks jcl! I've set the CancelOtherTrades variable back to 0 after all trades are cancelled. However, the TMF as written doesn't enter trades in the opposite direction at the weekly close. I'm sure the solution must be a simple one, but I just don't know what I'm missing. Is it something to do with the "Entry" parameter not being used correctly in the TMF?
Posted By: boatman

Re: TMF that cancels pending orders and enters trades - 06/09/15 12:04

In the TMF, I've changed 'Entry' to 'TradeEntryLimit' and 'Stop' to 'TradeStopLimit'. No change in result. Here's the updated code and a screenshot showing expected behviour.

Code:
#define H1 (60/BarPeriod)
#define H24 (1440/BarPeriod)
#define W1 (7200/BarPeriod)
//var LastWeekClose;
//#define CancelOtherTrades AssetVar[0]; 

int myTMF() { //if stopped out, set pending at W1close in opp direction
	var LastWeekClose = AssetVar[1];
	if (TradeIsLong and TradeIsStop) {
		//enter at last close
		TradeEntryLimit = LastWeekClose;
		TradeStopLimit = 30*PIP;
		enterShort(myTMF);
	}
	if (TradeIsShort and TradeIsStop) {
		TradeEntryLimit = LastWeekClose;
		TradeStopLimit = 30*PIP;
		enterLong(myTMF);
	}
	if(TradeIsPending and AssetVar[0] == 1) {
	return 1;
	
}
	if(TradeIsOpen) {
		AssetVar[0] = 1;
		ThisTrade->manage = 0; // terminate the TMF
	}

	return 0;
}

function frameAlign(BOOL Event){ 
	// Let time frame start when Event == true
	// f.i. frameAlign(hour() == 0); aligns to midnight 
	TimeFrame = 1;
	vars Num = series(0); // use a series for storing Num between calls
	Num[0] = Num[1]+1;    // count Num up once per bar  
	if(!Event) 
	TimeFrame = 0;      // continue current time frame  
	else {
		TimeFrame = -Num[0]; // start a new time frame
		Num[0] = 0;          // reset the counter  
	}
}

function run() {
	set(TICKS);  // normally needed for TMF
	Weekend = 3; // don't run TMF at weekend
	StartDate = 20141201;
	EndDate = 20141231; //preserve 2015 data for OOS testing
	BarPeriod = 60;
	if (is(INITRUN)) AssetVar[0] = 0;
//	CancelOtherTrades = 0;
	
	TimeFrame = W1;
	frameAlign(dow() == 7 and hour() == 23); //align weekly chart to a UTC open time of Sunday 2200 
	vars closeW1 = series(priceClose());
	AssetVar[1] = closeW1[0];
	
	TimeFrame = H1;
	int exitDay = 5;
	int exitHour = 16;
	
	if (!(dow() == exitDay and hour() >= exitHour)) {
		Entry = closeW1[0] + 50*PIP;
		Stop = 30*PIP; 
		if (NumOpenLong == 0) {	enterLong(myTMF); } 
		Entry = closeW1[0] - 50*PIP;
		if (NumOpenShort == 0) enterShort(myTMF);
	}
	if (NumPendingLong + NumPendingShort == 0) AssetVar[0] = 0;
	if (dow() == exitDay and hour() == exitHour) {exitLong("*"); exitShort("*");}
	
	
	plot("closeW1", closeW1, MAIN, RED);
}



Attached picture Reverse at weekly close.png
Posted By: forexcoder

Re: TMF that cancels pending orders and enters trades - 06/11/15 12:00

I hope that the topic relating to the TMF will be better explained in the manual, because as it is explained as now, the topic is not at all clear (at least to me). I too, in fact, I'm finding a lot of difficulty using the TMF. Jcl could you enter more practical examples on this topic? Thank you.
Posted By: jcl

Re: TMF that cancels pending orders and enters trades - 06/11/15 13:42

It would be better when you tell me what is not clear to you. There are already many TMF examples in the manual, so one more probably won't help unless it deals specifically with the points that were unclear.

- boatman: can you contact Support? I am not seeing the problem immediately, so this would now require going through your code and finding what's wrong, and the support has better eyes to do that. The first thing they'll probably suggest is that you put print() statements in your TMF for seeing if the relevant code parts are executed at all.
Posted By: boatman

Re: TMF that cancels pending orders and enters trades - 06/12/15 03:17

For those that are interested, here is my solution to the problem of changing the entry level of the second trade to the weekly close. I used counters and a second TMF. I'm sure there would be a more elegant solution, but this one works.

As to the profitability of the system, that is another story altogether. If anyone has any ideas for improving the performance, I'd love to hear them.

Code:
#define H1 (60/BarPeriod)
#define H24 (1440/BarPeriod)
#define W1 (7200/BarPeriod)

int myTMF1() {
	if (TradeIsEntry) { 
		AssetVar[2] += 1; 
			if (TradeIsLong) AssetVar[3] += 1;
			if (TradeIsShort) AssetVar[4] += 1;
	}
	return 0;
}

int myTMF() { 

	if (TradeIsEntry) {AssetVar[2] = AssetVar[2] + 1; 
		if (TradeIsLong) AssetVar[3] += 1;
		if (TradeIsShort) AssetVar[4] += 1;
	}
	if (TradeIsLong and TradeIsStop and AssetVar[4] < 1){
		enterShort(myTMF);
	}
	return 0;
	if (TradeIsShort and TradeIsStop and AssetVar[3] < 1) {
		enterLong(myTMF);	
	}	
	return 0;

	return 0;
}

function frameAlign(BOOL Event){ 
	// Let time frame start when Event == true
	// f.i. frameAlign(hour() == 0); aligns to midnight 
	TimeFrame = 1;
	vars Num = series(0); // use a series for storing Num between calls
	Num[0] = Num[1]+1;    // count Num up once per bar  
	if(!Event) 
	TimeFrame = 0;      // continue current time frame  
	else {
		TimeFrame = -Num[0]; // start a new time frame
		Num[0] = 0;          // reset the counter  
	}
}

function run() {
	set(TICKS|PARAMETERS|FACTORS|LOGFILE); 
	Weekend = 3; // don't run TMF at weekend
	StartDate = 20140901;
	EndDate = 20141231; //preserve 2015 data for OOS testing
	BarPeriod = 60;
	LookBack = 209;
	if (is(INITRUN)) { AssetVar[0] = 0; AssetVar[1] = 0; AssetVar[2] = 0; AssetVar[3] = 0; AssetVar[4] = 0; }
	
	TimeFrame = W1;
	frameAlign(dow() == 7 and hour() == 23); //align weekly chart to a UTC open time of Sunday 2200 (note it is 2100 in summer)
	vars closeW1 = series(priceClose());
	AssetVar[1] = closeW1[0];
	
	TimeFrame = H1;
	if (dow() == 7 and hour() == 23) { AssetVar[2] = 0; AssetVar[3] = 0; AssetVar[4] = 0; } //reset to zero at start of each week
	int exitDay = 5;
	int exitHour = 16;
	
	var entryMultiple = 4;//
	Stop = 30 *PIP;
	Trail =2 * entryMultiple * ATR(168); // optimize(0.5, 0.25, 3.0, 0.25) * entryMultiple * ATR(168); //
		
	if (AssetVar[2] == 0) {
		if (!(dow() == exitDay and hour() >= exitHour)) {
			Entry = closeW1[0] + entryMultiple*ATR(168);
			if (NumOpenLong == 0) enterLong(myTMF1);
			Entry = closeW1[0] - entryMultiple*ATR(168);
			if (NumOpenShort == 0) enterShort(myTMF1); 
			}
		}
	if (AssetVar[2] > 0) {
		if (!(dow() == exitDay and hour() >= exitHour)) {
			Entry = closeW1[0];
			if (NumOpenLong == 0 and AssetVar[3] < 1) {	enterLong(myTMF);} 
			if (NumOpenShort == 0 and AssetVar[4] < 1) { enterShort(myTMF);}
			}
		}
		
		if (dow() == exitDay and hour() == exitHour) {exitLong("*"); exitShort("*");}
		plot("closeW1", closeW1, MAIN, RED);
	
}

Posted By: forexcoder

Re: TMF that cancels pending orders and enters trades - 06/12/15 07:17

Hi Jcl. For example I didn't understand the use of the TradeVar[0]...TradeVar[7] and AssetVar[0]...AssetVar[7].
Posted By: jcl

Re: TMF that cancels pending orders and enters trades - 06/15/15 07:31

They are individual variables of a trade or asset, and not necessarily related to TMFs. For example, a TradeVar can be used to store the value of a certain indicator at the moment of entering a trade, for statistical purposes. And an AssetVar could be used for counting the number of trades that were entered with that asset.

But the usual case is using TradeVars in a TMF for storing values that need to be preserved between TMF calls. For instance, counting something or storing the maximum or minimum of something.
Posted By: forexcoder

Re: TMF that cancels pending orders and enters trades - 06/15/15 10:02

Thanks jcl. Could you do an example? So it is more clear!
Posted By: jcl

Re: TMF that cancels pending orders and enters trades - 06/15/15 11:23

Problem is that I have no real example: AFAIK in none of our scripts we've used a TradeVar or AssetVar. But the original script of the thread starter would need two AssetVars if it were a portfolio script. They would be defined this way:

#define LastWeekClose AssetVar[0]
#define CancelOtherTrades AssetVar[1]

and then can be set and reset in a TMF as well as in the main script.
© 2024 lite-C Forums