ProRealCode - Trading & Coding with ProRealTime™
Have added a volatility filter to the original 15 min version, which was optimized over the last 50k bars. Reduces draw down and increases performance so net happy with this minor addition. Will rerun the Walk Forward process but expect little change.
Am also testing the 5 min version which nonetheless kindly posted as this too looks very promising.
I advice you don’t surprise yourself with backtest, or maybe to be sure of the robustness of your code, test Long on some sample down trends and see how it reacts or maybe try with Walk Forward strategy, and I totally agree with you the simpler the better
this answer is for phoentzs, sorry
on the Backtest you only buy half a point ?
I do backtests at the minimum position size, in this case 0.5 pp
This is partly because the M0ney Management is based on the max drawdown @ min position size (line 26)
As for your further comments, my basic attitude is that no matter how good a backtest might look, I assume that it’s completely wrong and totally unreliable, will probably crash and burn.
Run it for months in demo, study the entries and exits – see if it behave the way you expected.
This one got off to a good start yesterday, 4 winning trades, ~400 pts.
maybe you can try to optimise with the Walk Forward method, it’s maybe will help you, I will study if in the future deeply maybe, now I’m not at this level
@samsampop
I haven’t a chance to run your new version but one thing you should change is line 69, should be:
PriceDistance = 4 * pipsize
this is the IG minimum stop distance, so it will change from one instrument to the next.
Quick update – strategy has stayed out of the market since Jan 20th and good job too for a long only strategy.
here’s a revised 5m version – better long term performance with lower drawdown, positionsize = 1
altered the 4h filter and added StochasticRSI
took one loss in Feb, but otherwise managed the Ukraine mess fairly well (so far)
Hi nonetheless
Quick question if I may – how often would you re-optimize the variables for this latest strategy that you have kindly posted?
Thanks very much
I don’t have a fixed policy on that. I rework things as and when I have an idea that might improve some aspect. Obviously, if you’re optimizing on max data on a 12 year backtest you’d hope that those numbers would be worth keeping. Someone else might keep the basic structure of the algo but optimize for maybe 6 years where most of the profit has been made – I guess then you’d want to refresh it more often. Who knows … 🤔
thank you very much for your contribution nonetheless. I quickly looked at the code and tested to remove all code after trailing. was basically the same result.
the 3 functions after the trail are standard bits of code that i add to most algos, the effect varies from one to the next. In this case they collectively add about 3%
If you’d rather not have an extra 3% then I suggest you switch them off immediately 😁
Attached are the results with a constant exposure value of €10k, gives a better visual on the histogram and the curve.
Hello @nonetheless, than you for your work. I am really confused, i’am not having same backtest as you, I am using V4.1 L, and i have add 1h at h1 and h2 because i’m in France. Can you share with us the last itf you have. Thank you very much.
I haven’t done any other work on that one, so v4.1L is the only itf I have. How much discrepancy are you seeing?
@nonetheless Here is my backtest for the same period and Position size 1 MM off so you can see the huge difference :’D . I added also the parametres. Thanks for you help.
the only thing i can think of is the time settings in the DSD section. Try it like this, allowing for the Euro time difference
DSD = 1
if DSD then
once openStrongLong = 0
once openStrongShort = 0
if (time <= 120000 or time >= 170000) then // 070000, 100000
openStrongLong = 0
openStrongShort = 0
endif
//detect strong direction for market open
once rangeOK = rok // 30
once tradeMin = tm // 1000
IF (time >= 120500) AND (time <= 120500 + tradeMin) AND ABS(close - open) > rangeOK THEN
IF close > open and close > open[1] THEN
openStrongLong = 1
openStrongShort = 0
ENDIF
IF close < open and close < open[1] THEN
openStrongLong = 0
openStrongShort = 1
ENDIF
ENDIF
Thank you, it ads a bit of amelioration but still not that great performance that you have.
This is my code, no spread for this backtest, no MM, parametres are the same.
I’m ready to change the time zone for PRT if it will improve my results.
If you can’t see any solution. I will not be a problem. I am already grateful for your contribution.
Thanks
// opt: 01/03/2022
//=======================================================================
DEFPARAM CUMULATEORDERS = FALSE
DEFPARAM preloadbars = 10000
positionsize = 1
//Tradetime
//adjustment for American Daylight Savings time
ADLS =1
if ADLS then
DLS =(Date >= 20100314 and date <=20100328) or (Date >= 20101031 and date <=20101107) or (Date >= 20110313 and date <=20110327) or (Date >= 20111030 and date <=20111106) or (Date >= 20120311 and date <=20120325) or (Date >= 20121028 and date <=20121104) or (Date >= 20130310 and date <=20130331) or (Date >= 20131027 and date <=20131103) or (Date >= 20140309 and date <=20140330) or (Date >= 20141026 and date <=20141102) or (Date >= 20150308 and date <=20150329) or (Date >= 20151025 and date <=20151101) or (Date >= 20160313 and date <=20160327) or (Date >= 20161030 and date <=20161106) or (Date >= 20170312 and date <=20170326) or (Date >= 20171030 and date <=20171105) or (Date >= 20180311 and date <=20180325) or (Date >= 20181028 and date <=20181104) or (Date >= 20190310 and date <=20190331) or (Date >= 20191027 and date <=20191103) or (Date >= 20200308 and date <=20200329) or (Date >= 20201025 and date <=20201101) or (Date >= 20210314 and date <=20210328) or (Date >= 20211031 and date <=20211107) or (Date >= 20220313 and date <=20220327) or (Date >= 20221030 and date <=20221106) or (Date >= 20230312 and date <=20230326) or (Date >= 20231029 and date <=20231105) or (Date >= 20240310 and date <=20240331) or (Date >= 20241027 and date <=20241103)
If DLS then
Tradetime = time >=h1-10000 and time <h2-10000
elsif not DLS then
Tradetime = time >=h1 and time <h2
endif
endif
if not ADLS then
Tradetime = time >=h1 and time <h2
endif
//Long Entry Filter
Timeframe(4 hours)
FMA1 = average[p,t](typicalprice)
//FMA2 = average[p1,t](typicalprice)
cb1 = FMA1 > FMA1[1]
//cs1 = FMA1 < FMA2
Timeframe(15 minutes)
M15 = average[p2,t2](typicalprice)
cb2 = (close>m15)
//cs2 = close<average[p2,t2](typicalprice)
Timeframe(Default)
//Long Entry Criteria
MA1=average[p3,t3](typicalprice)
MA2=average[p4,t3](typicalprice)
cb3 = MA1 crosses over MA2
//cs3 = MA1 crosses under MA2
//Stochastic RSI | indicator
lengthRSI = lr //RSI period
lengthStoch = ls //Stochastic period
smoothK = sk //Smooth signal of stochastic RSI
smoothD = sd //Smooth signal of smoothed stochastic RSI
myRSI = RSI[lengthRSI](close)
MinRSI = lowest[lengthStoch](myrsi)
MaxRSI = highest[lengthStoch](myrsi)
StochRSI = (myRSI-MinRSI) / (MaxRSI-MinRSI)
K = average[smoothK](stochrsi)*100
D = average[smoothD](K)
cb4 = K>D
// Conditions to enter long positions
If Tradetime and cb1 and cb2 and cb3 and cb4 Then
Buy PositionSize CONTRACTS AT MARKET
ENDIF
SET STOP %LOSS sl
SET TARGET %PROFIT tp
// Break even and trailing stop RTS
IF Not OnMarket THEN
// when NOT OnMarket reset values to default values
ts = (tradeprice*pc)/100 // % trailing start
TrailStart = ts //30 Start trailing profits from this point
BasePerCent = base // 0.200 20.0% Profit percentage to keep when setting BerakEven
StepSize = ss //10 Pip chunks to increase Percentage
PerCentInc = pci // 0.100 10.0% PerCent increment after each StepSize chunk
BarNumber = bn //10 Add further % so that trades don't keep running too long
BarPerCent = bpc // 0.100 10% Add this additional percentage every BarNumber bars
RoundTO = 0 //-0.5 rounds always to Lower integer, +0.4 rounds always to Higher integer, 0 defaults PRT behaviour
PriceDistance = 4 * pipsize //IG minimun distance from current price
y1 = 0 //reset to 0
y2 = 0 //reset to 0
ProfitPerCent = BasePerCent //reset to desired default value
TradeBar = BarIndex
ELSIF LongOnMarket AND close > (TradePrice + (y1 * pipsize)) THEN
//LONG positions
//
// compute the value of the Percentage of profits, if any, to lock in for LONG trades
//
x1 = (close - tradeprice) / pipsize //convert price to pips
IF x1 >= TrailStart THEN // go ahead only if N+ pips
Diff1 = abs(TrailStart - x1) //difference from current profit and TrailStart
Chunks1 = max(0,round((Diff1 / StepSize) + RoundTO)) //number of STEPSIZE chunks
ProfitPerCent = BasePerCent + (BasePerCent * (Chunks1 * PerCentInc)) //compute new size of ProfitPerCent
// compute number of bars elapsed and add an additionl percentage
// (this percentage is different from PerCentInc, since it's a direct percentage, not a Percentage of BasePerCent)
// (if BasePerCent is 20% and this is 10%, the whole percentage will be 30%, not 22%)
BarCount = BarIndex - TradeBar
IF BarCount MOD BarNumber = 0 THEN
ProfitPerCent = ProfitPerCent + BarPerCent
ENDIF
//
ProfitPerCent = max(ProfitPerCent[1],min(100,ProfitPerCent)) //make sure ProfitPerCent doess not exceed 100%
y1 = max(x1 * ProfitPerCent, y1) //y1 = % of max profit
ENDIF
ELSIF ShortOnMarket AND close < (TradePrice - (y2 * pipsize)) THEN
//SHORT positions
//
// compute the value of the Percentage of profits, if any, to lock in for SHORT trades
//
x2 = (tradeprice - close) / pipsize //convert price to pips
IF x2 >= TrailStart THEN // go ahead only if N+ pips
Diff2 = abs(TrailStart - x2) //difference from current profit and TrailStart
Chunks2 = max(0,round((Diff2 / StepSize) + RoundTO)) //number of STEPSIZE chunks
ProfitPerCent = BasePerCent + (BasePerCent * (Chunks2 * PerCentInc)) //compute new size of ProfitPerCent
// compute number of bars elapsed and add an additionl percentage
// (this percentage is different from PerCentInc, since it's a direct percentage, not a Percentage of BasePerCent)
// (if BasePerCent is 20% and this is 10%, the whole percentage will be 30%, not 22%)
BarCount = BarIndex - TradeBar
IF BarCount MOD BarNumber = 0 THEN
ProfitPerCent = ProfitPerCent + BarPerCent
ENDIF
//
ProfitPerCent = max(ProfitPerCent[1],min(100,ProfitPerCent)) //make sure ProfitPerCent doess not exceed 100%
y2 = max(x2 * ProfitPerCent, y2) //y2 = % of max profit
ENDIF
ENDIF
IF y1 THEN //Place pending STOP order when y1 > 0 (LONG positions)
SellPrice = Tradeprice + (y1 * pipsize) //convert pips to price
//
// check the minimun distance between ExitPrice and current price
//
IF abs(close - SellPrice) > PriceDistance THEN
//
// place either a LIMIT or STOP pending order according to current price positioning
//
IF close >= SellPrice THEN
SELL AT SellPrice STOP
ELSE
SELL AT SellPrice LIMIT
ENDIF
ELSE
//
//sell AT MARKET when EXITPRICE does not meet the broker's minimun distance from current price
//
SELL AT Market
ENDIF
ENDIF
IF y2 THEN //Place pending STOP order when y2 > 0 (SHORT positions)
ExitPrice = Tradeprice - (y2 * pipsize) //convert pips to price
//
// check the minimun distance between ExitPrice and current price
//
IF abs(close - ExitPrice) > PriceDistance THEN
//
// place either a LIMIT or STOP pending order according to current price positioning
//
IF close <= ExitPrice THEN
EXITSHORT AT ExitPrice STOP
ELSE
EXITSHORT AT ExitPrice LIMIT
ENDIF
ELSE
//
//ExitShort AT MARKET when EXITPRICE does not meet the broker's minimun distance from current price
//
EXITSHORT AT Market
ENDIF
ENDIF
//----------------------------------------------------------------------------
//EXIT ZOMBIE TRADE
EZT = 1
if EZT then
IF (longonmarket and barindex-tradeindex(1)>= b1 and positionperf>0) or (longonmarket and barindex-tradeindex(1)>= b2 and positionperf<0) then
sell at market
endif
IF (shortonmarket and barindex-tradeindex(1)>= 4000 and positionperf>0) or (shortonmarket and barindex-tradeindex(1)>= 4000 and positionperf<0) then
exitshort at market
endif
endif
//----------------------------------------------------------------------------
RSIexit = 1 // in profit
if RSIexit then
myrsi2=rsi[r](close)
if myrsi2<rl and barindex-tradeindex>1 and longonmarket and positionperf>0 then
sell at market
endif
if myrsi2>70 and barindex-tradeindex>1 and shortonmarket and positionperf>0 then
exitshort at market
endif
endif
//----------------------------------------------------------------------------
DSD = 1
if DSD then
once openStrongLong = 0
once openStrongShort = 0
if (time <= 120000 or time >= 170000) then // 070000, 100000
openStrongLong = 0
openStrongShort = 0
endif
//detect strong direction for market open
once rangeOK = rok // 30
once tradeMin = tm // 1000
IF (time >= 120500) AND (time <= 120500 + tradeMin) AND ABS(close - open) > rangeOK THEN
IF close > open and close > open[1] THEN
openStrongLong = 1
openStrongShort = 0
ENDIF
IF close < open and close < open[1] THEN
openStrongLong = 0
openStrongShort = 1
ENDIF
ENDIF
ENDIF
Simple Moving Average Crossover Strategy
This topic contains 95 replies,
has 12 voices, and was last updated by CRISRJ
3 years, 1 month ago.
| Forum: | ProOrder: Automated Strategies & Backtesting |
| Language: | English |
| Started: | 01/26/2022 |
| Status: | Active |
| Attachments: | 39 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.