ProRealCode - Trading & Coding with ProRealTime™
Hello everyone.
I have been trading manually since 2011 this method with goods results and i would like to test it in PRT but it takes me long time to get to anywhere.
I would really appreciate if anyone could help me.
The idea is:
1.-Buy when price breaks up an historical maximum
2.- Once i have bought, i set the stop in the minimum between the historical máximun and when i bought (new maximum)
If we have a correction (today low is lower than previous low) we have a new historical high, so:
3.- When the price goes above that point again i move the stop upwards to the lowest of the new two points, ie the lowest of the new two maximums.
i have attached an example.
In have built this in PRT, but it doesn´t work 🙁
defparam CumulateOrders = false
if not longonmarket and high>highest[300](close)then
buy 2000 cash at high stop
endif
velainicial= Barindex-1
Velaactual = Barindex
exit= lowest[velaactual-velainicial](low)
if longonmarket and low<exit then
sell at exit stop
endif
i know i have used highest of 300 bars instead of the historical high but i think PRT doesn´t allow us to set it.
(i have been thinking use this code given by Nicolas to find out the maximum price):
once previousbar = 0
once hh = 0
once ll = low
if(barindex>previousbar) then
previousbar=barindex
hh=MAX(hh[1],high)
ll=MIN(ll[1],low)
endif
RETURN hh
any help would be really appreciated.
thanks a lot
[attachment file=12871]
Hello quo,
Firstly, you are not the first one to get stuck with the comparison between current high and the highest one. You need to test the breach of the highest high from at least 1 period in the past, otherwise, you are testing if the current candlestick high is above its own value, it does not make sense:
if not longonmarket and high>highest[300](high)[1] then
buy 2000 cash at high stop
endif
Then to set a pending stop order with the calculation you made about your ‘exit’ level, don’t test if the current price is already below it to add it on market. Just add it on market and then price reach this level, the trade will exit.
if longonmarket then
sell at exit stop
endif
I don’t have verify your ‘exit’ variable calculation, maybe there is still a bug with it.
Thanks for your help Nicolas, i am better than before but i am still stuck. I can´t codified the logic i have. i give up, too many hours with this 🙁
Do you know if PRT support can help me?
thanks
Ignacio
Don’t give up, please don’t give up 😉
I can help you, maybe you can share me the code you already made?
Hi quo, although I’m not by any means an expert (neither in fact an user except for some screeners) on this PRT platform , as a programming exercice and to leave Nicolas rest a bit, I’ve just coded a solution based approx. on your description of the strategy.
Maybe it’s not yet 100% depured and it’s taken me some time too. It’s not as straightforward as your idea so don’t despair if you don’t get it all at first glance.
Feel free to prove it , tamper with it and comment if you want or need (I’m Spanish… just in case…). For your information, I’ve used a correction in the high not the low of the following bar to define the precedent high as a new historic maximum.
This is my go, my excuses to the native English speakers for the odd wrong preposition!
// TS name: Historic_Maximum_BO
// Description: Buy at historic maximum breakouts.
// Sell at relative minimums (or lows) between consecutive historic
// maximums.
// A new historic maximum is defined by a correction in the
// high value (high < high[1]) from a current maximum
// Instruments: Stocks/ETFs
// Time frame: Daily / Weekly
// Features: Only long system. No money management in this version
// Version: 01
//
// Comments: System should give a few operations with a low ratio wins/losses.
// Profitability greatly depending on entering and riding at least
// one big bullish movement.
// minTradeBars should be > 0 (20 for instance for daily TF) to avoid the
// effects of very close consecutive minimums with little inter-maximums
// corrections (exitPrice too close to current prices).
// Ditto for SL and the possible big corrections from very far-off
// historic maximums (exitPrice too far from current prices).
// *********************************************************************************
DEFPARAM PRELOADBARS = 10000
// customizable or optional parameters
once startDate = 20110101 // Example date in YYYYMMDD format for backtesting.
// Today's date for production
once size = 2000 // Example fixed capital to trade
once enterFilter = 0 // Optional. % above maximum to enter position
once exitFilter = 0 // Optional. % under minimum to exit position
once TP = 0 // Optional. Take profit in %
once SL = 0 // Recommended. Stop loss in %
once minTradedBars = 0 // Recommended. Minimal trade span before selling
// variables declaration
once historicMax = 0 // historic maximum
once currentMax = 0 // current maximum candidate to historic maximum
once barHistoricMax = 0 // historic maximum barIndex
once barCurrentMax = 0 // current maximum barIndex
once exitPrice = 0 // exit price
once buyPrice = 0 // buy price
once barOffset = 0 // aux counter used to set exitPrice
once countBars = 0 // idem for measuring trade duration
once waitForBuyPrice = 0 // semaphore to lock updating of historic maximum
// find out historic maximum until startDate
if date < startDate then
if high > historicMax then
historicMax = high
barHistoricMax = barIndex
endif
endif
IF DATE >= STARTDATE THEN
if not onmarket then
// open position at historic maximum plus filter
buyPrice = historicMax * (1 + enterFilter/100)
buy size cash at buyPrice stop // set buy stop order
// if price doesn't reach buyPrice because of the filter
// not to update historic maximum until position is entered
if high > historicMax and high < buyPrice then
waitForBuyPrice = 1 // updating not permitted
endif
// set new historic maximum after exit
if not waitForBuyPrice then
if high > historicMax then
historicMax = high
barHistoricMax = barIndex
endif
endif
// if position is exited precisely in the correction bar
// that updates new historic maximum
if currentMax > historicMax then
historicMax = currentMax
barHistoricMax = barCurrentMax
endif
countBars = 0 // reset countBars
endif
// if entered position, set new historic maximum and first exitPrice
if onmarket and barIndex = TRADEINDEX(1) then
exitPrice = lowest[barIndex - barHistoricMax + 1](low) * (1 - exitFilter/100)
historicMax = high
barHistoricMax = TRADEINDEX(1)
waitForBuyPrice = 0 // updating permitted
endif
// set sell stop order
if onmarket then
if countBars >= minTradedBars then
sell at exitPrice stop
endif
endif
// manage updating of new historic maximum and new exitPrice
if onmarket then
countBars = countBars + 1
// keep track of candidates to new historic maximum
if high > currentMax then
currentMax = high
barCurrentMax = barIndex
elsif high = currentMax then
// keep track of bars with same high = current maximum
barOffset = barOffset + 1
elsif high < currentMax and currentMax <> historicMax then
// if correction from current maximum then update
exitPrice = lowest[barIndex - barHistoricMax + 1 + barOffset](low) * (1 - exitFilter/100)
historicMax = currentMax // update historic maximum
barHistoricMax = barCurrentMax // update historic maximum barIndex
endif
endif
ENDIF
SET TARGET %PROFIT TP
SET STOP %LOSS SL
Wow Tikitaka what an effort, thank you very much, amazing.
I have used this system with monthly graphs. No filter in the entry but a 3% filter at the exit. After a fundamental and sector filter i apply the rules i said. I exclude those trades with a big stop because as i risk a fix ammount the quantity sometimes is too little in these trades. Results 90% profit, 35% winning trades. Want to check through PRT rest of variables (DD,PF,etc).
I have been tamperig with it and i would like to say:
1.-Sometimes there is no entry because you put a start date in 2011 and preloads bar of 10.000. I would like the system detect a maximum from the beginning, in fact in the IPO this system works well.
2.- There isn´t SL or TP
3.- I don´t use a filter when i enter a position and 3% in the exit, so i put it directly in the formula. The same with size position, always 2000 cash. No MM to simplify.
4.- i don´t consider mintradebars necessary.
For these 4 points i erased your first part (hope i am not spoiling it)
It looks like gives good entries but it doesn´t go out where it should do. I don´t know why. Maybe was my fault and i didn´t explained it well. I attach the result code and another explanation of the exit process.
// variables declaration
once historicMax = 0 // historic maximum
once currentMax = 0 // current maximum candidate to historic maximum
once barHistoricMax = 0 // historic maximum barIndex
once barCurrentMax = 0 // current maximum barIndex
once exitPrice = 0 // exit price
once buyPrice = 0 // buy price
once barOffset = 0 // aux counter used to set exitPrice
once countBars = 0 // idem for measuring trade duration
once waitForBuyPrice = 0 // semaphore to lock updating of historic maximum
// find out historic maximum until startDate
if high > historicMax then
historicMax = high
barHistoricMax = barIndex
endif
if not onmarket then
// open position at historic maximum plus filter
buyPrice = historicMax
buy 2000 cash at buyPrice stop // set buy stop order
// if price doesn't reach buyPrice because of the filter
// not to update historic maximum until position is entered
if high > historicMax and high < buyPrice then
waitForBuyPrice = 1 // updating not permitted
endif
// set new historic maximum after exit
if not waitForBuyPrice then
if high > historicMax then
historicMax = high
barHistoricMax = barIndex
endif
endif
// if position is exited precisely in the correction bar
// that updates new historic maximum
if currentMax > historicMax then
historicMax = currentMax
barHistoricMax = barCurrentMax
endif
countBars = 0 // reset countBars
endif
// if entered position, set new historic maximum and first exitPrice
if onmarket and barIndex = TRADEINDEX(1) then
exitPrice = lowest[barIndex - barHistoricMax + 1](low) * (1 - 3/100)
historicMax = high
barHistoricMax = TRADEINDEX(1)
waitForBuyPrice = 0 // updating permitted
endif
// set sell stop order
if onmarket then
sell at exitPrice stop
endif
// manage updating of new historic maximum and new exitPrice
if onmarket then
countBars = countBars + 1
// keep track of candidates to new historic maximum
if high > currentMax then
currentMax = high
barCurrentMax = barIndex
elsif high = currentMax then
// keep track of bars with same high = current maximum
barOffset = barOffset + 1
elsif high < currentMax and currentMax <> historicMax then
// if correction from current maximum then update
exitPrice = lowest[barIndex - barHistoricMax + 1 + barOffset](low) * (1 - 3/100)
historicMax = currentMax // update historic maximum
barHistoricMax = barCurrentMax // update historic maximum barIndex
endif
endif
Thanks for your patience. I didn´t know was so complicated. If we hit the exit we´ll have it, and i will have to invite something to all of you. 😉
Hi Quo.
Did you consider using the MFE trailingstop code?
just add it to the end of yours.
Cheers Kasper
//======================TralingSTOP MFE=======================
//trailing stop
trailingstop = 20//x1
//resetting variables when no trades are on market
if not onmarket then
MAXPRICE = 0
MINPRICE = close
priceexit = 0
endif
//case SHORT order
if shortonmarket then
MINPRICE = MIN(MINPRICE,close) //saving the MFE of the current trade
if tradeprice(1)-MINPRICE>=trailingstop*pointsize then //if the MFE is higher than the trailingstop then
priceexit = MINPRICE+trailingstop*pointsize //set the exit price at the MFE + trailing stop price level
endif
endif
//case LONG order
if longonmarket then
MAXPRICE = MAX(MAXPRICE,close) //saving the MFE of the current trade
if MAXPRICE-tradeprice(1)>=trailingstop*pointsize then //if the MFE is higher than the trailingstop then
priceexit = MAXPRICE-trailingstop*pointsize //set the exit price at the MFE - trailing stop price level
endif
endif
//exit on trailing stop price levels
if onmarket and priceexit>0 then
EXITSHORT AT priceexit STOP
SELL AT priceexit STOP
endif
//================================================================
Hi quo, I’m back on it. It might take a while.
No RSVP. Just to keep you informed.
Hello quo, here I come again.
It’s taken me hours, but finally I’ve got ready the new slimmer version of your strategy, editing out what you don’t need or want and making the needed changes to meet your requirements. Well, at least me thinks. More than 15 years without writing a code line has taken its toll, evidently. That and probably the fact that I am not a boy anymore.
What has mainly kept me “entertained” for ages, and counting, it’s the trade showed in the attached picture. The position should be closed not at the bar selected by the system but at the previous one. Despite all my efforts, I’ve been unable to pin down where the problem is. It’s a minor issue that doesn’t happen, at least for that stock, in weekly test nor in diary with the exit filter set to 3%, but there it is to haunt me :-). If you or any other guy want to jump in and search for the answer, please be my guest.
Anyway, never mind the time long or short. This is the code and, apart from that rare case, should do the trick.
Or will it?
// TS name: Historical Maximum_Breakout
// Description: Buy at historical maximum breakouts.
// Sell at relative minimums (or lows) between consecutive historical
// maximums.
// A new historical maximum is defined by a correction in the
// low value of the bar or bars (low < low[1]) after a new maximum
// Instruments: Stocks/ETFs
// Time frame: Daily / Weekly / Monthly
// Features: Only long system. No money management
// Version: 02.1
// *********************************************************************************
// customizable and optional parameters
once capital = 2000 // Fixed capital
once exitFilter = 3 // % below minimum to exit position
// variables declaration
once historicMax = 0 // historical maximum
once currentMax = 0 // current maximum candidate to historical maximum
once barHistoricMax = 0 // historical maximum barIndex
once barCurrentMax = 0 // current maximum barIndex
once exitPrice = 3 // exit price
once buyPrice = 0 // buy price
// let's begin losing money.. I mean, trading
if not onmarket and barindex > 0 then
if high >= currentMax then
//keep track of candidates to new historical maximum
currentMax = high
barCurrentMax = barIndex
elsif high < currentMax and currentMax > historicMax then
if low < low[1] then
// correction so update historical maximum and buyPrice
historicMax = currentMax
barHistoricMax = barCurrentMax
buyPrice = historicMax
endif
endif
// open position at new historical maximum
if buyPrice > 0 then
buy capital cash at buyPrice stop // set buy stop order
endif
endif
// ***************************************************************************
// if position entered, calculate initial exitPrice and set sell stop order
if onmarket and barIndex = TRADEINDEX(1) then
exitPrice = lowest[barIndex - barHistoricMax + 1](low) * (1 - exitFilter/100)
endif
if onmarket and exitPrice > 0 then
sell at exitPrice stop // set sell stop order
endif
//manage updating of historical maximum and exitPrice
if onmarket then
if high >= currentMax then
currentMax = high
barCurrentMax = barIndex
elsif high < currentMax and currentMax > historicMax then
if low < low[1] then
// correction so update exit price and then the rest
exitPrice = lowest[barIndex - barHistoricMax + 1](low) * (1 - exitFilter/100)
historicMax = currentMax
barHistoricMax = barCurrentMax
buyPrice = historicMax
endif
endif
endif
Hi,
Now I’m getting the hack of it.
Here is the version 2.02 of the strategy: it’s more compact without repeated code and free of the issue mentioned in my previous post!
Should be the final one in no money management mode, if I’ve understood well your concept of correction. Indeed the solution was rather simple, but all is well that ends well.
Cheers
// TS name: Historical Maximum Breakout
// Description: Buy at historical maximum breakouts.
// Sell at relative minimums (or lows) between consecutive
// historical maximums.
// A new historical maximum is defined by a correction in the
// low value of the bar or bars (low < low[1]) after a new maximum
// Instruments: Stocks/ETFs
// Time frame: Daily / Weekly / Monthly
// Features: Only long system. No money management
// Version: 02.2
// ****************************************************************************
// customizable and optional parameters
once capital = 2000 // Fixed capital
once exitFilter = 3 // % below minimum to exit position
// variables declaration
once historicMax = 0 // historical maximum
once currentMax = 0 // current maximum candidate to historical maximum
once barHistoricMax = 0 // historical maximum barIndex
once barCurrentMax = 0 // current maximum barIndex
once exitPrice = 0 // exit price
once buyPrice = 0 // buy price
// let's begin losing money.. I mean, trading
if high >= currentMax then
//keep track of candidates to new historical maximum
currentMax = high
barCurrentMax = barIndex
elsif high < currentMax and currentMax > historicMax then
if low < low[1] then
// correction so update historical maximum and buy and exit prices
if historicMax = 0 then
exitPrice = lowest[barIndex - barHistoricMax](low) * (1 - exitFilter/100)
else
exitPrice = lowest[barIndex - barHistoricMax + 1](low) * (1 - exitFilter/100)
endif
historicMax = currentMax
barHistoricMax = barCurrentMax
buyPrice = historicMax
endif
endif
// open position at new historical maximum
if not onmarket and buyPrice > 0 then
buy capital cash at buyPrice stop // set buy stop order
endif
// close position at exitPrice
if onmarket and exitPrice > 0 then
sell at exitPrice stop // set sell stop order
endif
Hi Kasper, thanks for the suggestion. I use trailing stops in other systems but i only trade stocks and long orders so i use percentages. What add this stop to a simply set trailing%stop 10 por example? Will this new modified code works in long stocks? thanks
//======================TralingSTOP MFE=======================
//trailing stop
trailingstop = 10//x1
//resetting variables when no trades are on market
if not onmarket then
MAXPRICE = 0
MINPRICE = close
priceexit = 0
endif
//case LONG order
if longonmarket then
MAXPRICE = MAX(MAXPRICE,close) //saving the MFE of the current trade
if MAXPRICE-tradeprice(1)>=trailingstop*close then //if the MFE is higher than the trailingstop then
priceexit = MAXPRICE-trailingstop*close //set the exit price at the MFE - trailing stop price level
endif
endif
//exit on trailing stop price levels
if onmarket and priceexit>0 then
SELL AT priceexit STOP
endif
Hi Tikitaka, sorry for my late answer, too much work.
Thanks for your work. I´ve been checking it and it seen it doesn´t work well. Entry is almost always right but the main problem is the exit.
In graph one (ACX) entry is right but it never exit, i have written what the stop should do.
In graph 2 ACR entries are wrong (no historical max) and exit take place later.
I have tried to find out where is the error but is a lost cause.
thank you anyway, your welcome to come to Almeria and eat some prawns for the effort 🙂
Cheers
Nacho
Hi, back in town.
Bloody hell, you keep trying the system on monthly bars and I keep debugging it only in daily timeframes, where it seemed to be working well. But you’re so right, it doesn’t.
My time is limited now as I’have just begun painstakingly (a matter of try and error) to make changes to my own manual strategies after two losing months in a row but I’ll try and find where the problem is as soon as possible.
Cheers and saludos
High quo and all,
long time no see but as we say in Spanish, “first obligation than devotion” or in better English, business comes before pleasure.
So, I’ve made some little changes in the code to cope with the fact that, to my big surprise, functions (or constants as PRT calls them), such as barIndex, high and low, seem to behave differently for US stocks and for non-US stocks. Don’t ask me why, your guess is as good as mine. Maybe a bug in ProBacktest? I really don’t know.
Anyway, I’ve tested the new code on some Spanish (and US) stocks in monthly timeframe, your market and timeframe of election I presume, and it seems to do OK. Let me a couple of days to test it on daily bars too, for my peace of mind.
Meanwhile, just for wrapping up all, I’ve still got a doubt about your concept of correction: in the attached picture for instance, when does the correction happen, at the 08-apr-2004 bar or at the 12-apr-2004 one? I’ve been coding the first (low < low[1]) but the second seems more ‘canonical’ (you know, lower highs and lower lows). Please, do clarify.
Enough for now. Cheers
Help to program an idea that worked
This topic contains 42 replies,
has 4 voices, and was last updated by quo
9 years, 3 months ago.
| Forum: | ProOrder: Automated Strategies & Backtesting |
| Language: | English |
| Started: | 09/08/2016 |
| Status: | Active |
| Attachments: | No files |
The information collected on this form is stored in a computer file by ProRealCode to create and access your ProRealCode profile. This data is kept in a secure database for the duration of the member's membership. They will be kept as long as you use our services and will be automatically deleted after 3 years of inactivity. Your personal data is used to create your private profile on ProRealCode. This data is maintained by SAS ProRealCode, 407 rue Freycinet, 59151 Arleux, France. If you subscribe to our newsletters, your email address is provided to our service provider "MailChimp" located in the United States, with whom we have signed a confidentiality agreement. This company is also compliant with the EU/Swiss Privacy Shield, and the GDPR. For any request for correction or deletion concerning your data, you can directly contact the ProRealCode team by email at privacy@prorealcode.com If you would like to lodge a complaint regarding the use of your personal data, you can contact your data protection supervisory authority.