ProRealCode - Trading & Coding with ProRealTime™
The EquityDD_OwnVariables_L.itf – Robo is working. I have used it on the DAX 1m and 5m-chart over several different candle periods.
Feel free to use this robo as good start for further improvements or your own strategies and please tell if you fixed any errors or limitations.
It would be nice to see successful trading strategies using this algo to pause trading and restart trading in a proper manner, avoiding trading in periods where the core strategy should not be trading.
We stop our robots, once the max DD as of backtesting has been exceeded. Now it is possible to track simulated equity curve and see when the robot is back on track! Then we can restart it.
Have fun and Good Trading!
🙂 Peter
And could the bot be paused and started automatically with these indicators?
it is possible to track simulated equity curve and see when the robot is back on track! Then we can restart it.
…having just missed a nice set of winning trades and just in time for the next set of losing trades. Simulated trading can keep you off the market during winning periods as easily as it can keep you on the market during losing periods! Yes simulated trading can make a back test look better by missing a few losing trades less than the winning trades it also misses but we can never know the distribution of winners and losers in the future which may be very different to the distribution of winners and losers in our historical data.
And could the bot be paused and started automatically with these indicators?
Yes… but you may miss a whole load of winners and get back on the market just in time for a whole bunch of losers so it is not the holy grail that will make a bad or even average strategy any better. It could just as easily make it worse in the future with just the right distribution of winners and losers.
A simple example. We have a strategy that stops trading if we have a loser and starts trading again if we have a simulated winner. The wins and losses come in the following order: LWLWLWLWLWLW. Our simulated trading just managed to hit every losing trade and miss every winning trade. Say we change it so that it stops trading after two losers in a row and you have to have two simulated winners in a row before it starts trading live again and then the winners and losers come like this: LLWWLLWWLLWWLLWW. Once again we get to trade every loser and miss every winner.
It can be the same for equity curve simulated trading. We start with one big loser that puts us in 5% drawdown from our starting capital so we switch to simulated trading and the next six trades make 1% each but we missed them all but as we are back in a simulated positive equity we turn trading back to live and the next trade is a loser so we turn trading back to simulated and the next trade is a winner…but once again we missed it…. and so on and so on until our simulated trading empties our bank account.
Yes, I understand and I know.
But so far my systems win 80-90% of trades.
They carry out between 100 and 250 operations in 3 years.
Losing trades are widely spread in those 3 years, with 2 consecutive trades with losses being the longest losing streak.
I think maybe they would earn a little less money, but the trade would be much safer … maybe it would be worth it.
So you have very rare losing trades very evenly spaced throughout history and never more than 2 losing trades in a row…. and how exactly will simulated trading avoid you trading those losing evenly spaced trades?
If you had said that you had 90% winners but sometimes a streak of 10 losers in a row then simulated trading might help avoid some of those losers… and also quite a few winners too.
Your strategy does not sound like it would benefit in any way from simulated trading at all. Better to just put a QUIT in the strategy if there are three losers in a row and then manually decide if it has failed or something major has changed the way the markets are behaving.
And how to program an indicator with “Equity”, “DDlevel”, and “Runuplevel” of the Pedros code?
Vonasi, I think the results will impress you.
It doesnt work.
🙁
This code calculates
Only Long trading so far. Room for improvement!
You can use this code for your own robots to pause trading and simulate trading during this time. The information gathered from simulated trading might be helpful to decide when to re-start trading.
// --------------------------------------------------------------------------//
// EquityDD_OwnVariables_L_V3a //
// --------------------------------------------------------------------------//
// [EquityDD_SystemVariables_L (Reference Algo!)]
// 05.03.21
// This robot simulates trading and calculates the equity curve, maxDD and max
// drawdown candles. The algo is supposed to be used when trading shall be put
// at hold for a certain time but information is required how a core trading
// strategy would have performed during that trading hold period.
// The information gathered from simulated trading might be helpful to decide
// when trading should be considered to be restarted!
// USE THE "GraphSWITCH" TO SEE THE RESULTS OF THE CALCULATIONS!!
// KNOWN ISSUES / LIMITATIONS:
// - no parameters included for currency trading
// - or trading other contract sizes than "1"
// - no short trading so far
// for your own algo:
// make sure you fill the variable "LongInMarket" at the precise moment you
// enter or exit a position!
// --------------------------------------------------------------------------//
DEFPARAM CumulateOrders=false
DEFPARAM PreLoadBars = 8000 //PRT uses maximum of 10k candles!
Once tradeflag=0 //tradeflag eliminates problems with DEFPARAM PreLoadBars!
If tradeflag=0 and OnMarket THEN //once live ONMARKET, virtual trading starts!
tradeflag=1
ENDIF
//VARIABLES
Once Capital = 10000 //chose your capital invested or set it to "0"
Once Equity = Capital
Once Spread = 2 //You can set a backtesting spread here!
Halfspread = Spread/2
Once Ordersize = 1
//sample core trading strategy ------------------------------------------------
daysOK = dayofweek<>6 and dayofweek<>0
timeOK = time>080000 and time<180000
GeneralCondOK = daysOK and timeOK
indicator1 = Average[3](RSI[14](close))
buyL1 = indicator1 crosses over 30
exitL1 = indicator1 crosses over 40 or indicator1 crosses under 20
//entry and exit signals
BuyLong = GeneralCondOK and buyL1
ExitLong = exitL1
// end of sample trading strategy --------------------------------------------
///////////////////////////////////////////////////////////////////////////////
//VIRTUAL TRADING! ///////////////////////////////////////////////////////////
If tradeflag=1 THEN
//CALCULATE EQUITY CURVE ++++++++++++++++++++++++++++++++++++++++++++++++++++++
//after position exit reset variables at beginning of calculation cycle
IF reset=1 THEN
reset=0
TradePL=0
LongEntryPrice=0
LongInMarket=0
ENDIF
//Dont change steps!
//step1: enter long trade on long signal, use open price next candle for calculation!
IF NOT LongInMarket[1] AND BuyLong[1] THEN
//LastTradeEquity = Equity
LongEntryPrice = open + Halfspread
LongInMarket=1
ENDIF
//step2: exit long trade on exit signal, use open price next candle for calculation!
IF (LongInMarket[1] and ExitLong[1]) THEN
LongExitPrice = open - Halfspread
LongInMarket=0
ENDIF
//step3: while LongInMarket use close prices for PL calculation!
IF LongInMarket THEN
TradePL = (close-LongEntryPrice)
Equity = Equity + TradePL - TradePL[1]
ENDIF
//step4: position closed, no matter what reason, use entry- and exit prices
IF LongInMarket[1]=1 and LongInMarket=0 THEN
TradePL = (LongExitPrice - LongEntryPrice)
Equity = Equity + TradePL - TradePL[1]
//Equity = LastTradeEquity + TradePL
reset=1
ENDIF
//CALCULATE DRAWDOWNS +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
IF LongInMarket[1] or LongInMarket THEN
//check on new equity high / runup high
IF Equity>=RunupLevel THEN
RunupLevel=Equity
DDLevel=Equity
RunupIndex=BarIndex
ENDIF
//New drawdown level low in equity curve?
IF Equity<=DDLevel THEN
DDLevel=Equity
ENDIF
//calculate DD (negativ sign) depending on algebraic level signs
IF ((RunupLevel>0) AND (DDLevel>0)) THEN
DD = -(RunupLevel - DDLevel)
ELSIF RunupLevel>=0 AND DDLevel<0 THEN
DD = (-RunupLevel + DDLevel)
ENDIF
//if new low in DD then save it to variable MaxDD
IF DD<MaxDD THEN
MaxDD=DD
ENDIF
ENDIF
//CALCULATE DRAWDOWN CANDLES +++++++++++++++++++++++++++++++++++++++++++++++++
DDCandles = BarIndex-RunupIndex //For graph function only (testing purposes)
IF MaxDD<MaxDD[1] THEN
MaxDDCandles = BarIndex-RunUpIndex
ENDIF
ENDIF
//END OF VIRTUAL TRADING /////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//Live Trading //////////////////////////////////////////////////////////////
//entry long
IF NOT LongOnMarket AND buyLong THEN
buy Ordersize contract at market
ENDIF
//exitLong
IF LongOnMarket and ExitLong THEN
sell at market
ENDIF
//END OF LIVE TRADING /////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//RESULTS//////////////////////////////////////////////////////////////////////
//GRAPH FUNCTIONS /////////////////////////////////////////////////////////////
//select graph output
GraphSWITCH = 1 //1=Equity
// //2=maxDD - set "ONCE equity=0" to improve graph layout
// //3=MaxDDCandles+MostDDCandles
IF GraphSWITCH=1 THEN //Equity
Graph Equity as "Equity"
ELSIF GraphSWITCH=2 THEN //Drawdown
Graph Equity as "Equity"
Graph MaxDD coloured(200,0,0) as "MaxDD"
Graph DD coloured(150,0,0) as "DD"
Graph RunupLevel coloured(0,0,200) as "RunupLevel"
graph DDLevel as "DDLevel"
ELSIF GraphSWITCH=3 THEN //Candles
Graph DDCandles as "DDCandles"
//Graph RunupIndex coloured(0,200,0) as "RunupIndex"
Graph MaxDDCandles coloured(200,0,0) as "MaxDDCandles"
ELSIF GraphSWITCH=4 THEN //temporary
//Graph RunupLevel coloured(0,0,200) as "RunupLevel"
Graph MaxDD coloured(200,0,0) as "MaxDD"
Graph DDCandles as "DDCandles"
//Graph RunupIndex coloured(0,200,0) as "RunupIndex"
Graph MaxDDCandles coloured(200,0,0) as "MaxDDCandles"
ENDIF
//eof /////////////////////////////////////////////////////////////////////////
Added Runup and number of Runup Candles!
Note: this code is only the part where virtual trading parameters are calculated!
Live trading (“buy” and “sell” orders) in this code is only used to check on results of simulated trading and make the robot run!
Without “buy” and “sell” orders the code would not start running!
Using this code within an own robot means there is still some work to do!
There are no variables yet when to stop live trading or re-start live trading!
After re-starting live-trading I recommend to synchronise variable “equity” and PRT system variable “Strategyprofit” (equity=strategyprofit) and to reset relevant virtual trading variables respectively.
🙂
// ----------------------------------------------------------------------------//
// EquityDD_OwnVariables_L_V3c //
// ----------------------------------------------------------------------------//
// [EquityDD_SystemVariables_L (Reference Algo!)]
// 06.03.21
// This robot simulates trading and calculates the equity curve, max DD,
// max drawdown candles, max RU and max RU candles. The algo is supposed to
// be used when trading shall be put on hold for a certain period of time
// but information is required how a core trading strategy would have
// performed during that trading hold period.
// The information gathered from simulated trading might be helpful to decide
// when trading should be considered to be restarted!
// USE THE "GraphSWITCH" TO SEE THE RESULTS OF THE CALCULATIONS!!
// KNOWN ISSUES / LIMITATIONS:
// - DEFPARAM Preloadbars causes severe problems. Introduced "tradeflag"
// variable mitigating this problem. However, there are still problems if
// Preloadbars exceed no. of chart candles in backtesting! No clue why!
// (1) PreLoadbars=0, tradeflag=1 -> hardly any errors
// (2) Preloadbars>chart candles, tradeflag=1 -> severe errors
// (3) Preloadbars>Chart candles, tradeflag=0 -> small errors
// Any ideas about this problem? And what's gonna happen in livetrading?
// - no parameters included for currency trading
// - or trading other contract sizes than "1", $2-contracts
// - no short trading so far
// for your own algo:
// make sure you fill the variable "LongInMarket" at the precise moment you
// enter or exit a position!
// ----------------------------------------------------------------------------//
DEFPARAM CumulateOrders=false
DEFPARAM PreLoadBars = 50 //PRT uses maximum of 10k candles!
Once tradeflag=0 //tradeflag=0 mitigates problems with DEFPARAM PreLoadBars!
If tradeflag=0 and OnMarket THEN //once live ONMARKET, virtual trading starts!
tradeflag=1
ENDIF
//VARIABLES TRADING ENVIRONMENT
Once Capital = 10000 //chose your capital invested or set it to "0"
Once Equity = Capital
Once Spread = 2 //You can set a backtesting spread here!
Halfspread = Spread/2
Once Ordersize = 1
//sample core trading strategy --------------------------------------------------
daysOK = dayofweek<>6 and dayofweek<>0
timeOK = time>080000 and time<180000
GeneralCondOK = daysOK and timeOK
indicator1 = Average[3](RSI[14](close))
buyL1 = indicator1 crosses over 30
exitL1 = indicator1 crosses over 40 or indicator1 crosses under 20
//entry and exit signals
BuyLong = GeneralCondOK and buyL1
ExitLong = exitL1
// end of sample trading strategy ----------------------------------------------
/////////////////////////////////////////////////////////////////////////////////
//VIRTUAL TRADING! /////////////////////////////////////////////////////////////
If tradeflag=1 THEN
//CALCULATE EQUITY CURVE +++++++++++++++++++++++++++++++++++++++++++++++++++++
//after position exit reset variables at beginning of calculation cycle
IF reset=1 THEN
reset=0
TradePL=0
LongEntryPrice=0
LongInMarket=0
ENDIF
//Don't change step order!
//step1: enter long trade, use open price next candle for calculation!
IF NOT LongInMarket[1] AND BuyLong[1] THEN
LongEntryPrice = open + Halfspread
LongInMarket=1
ENDIF
//step2: exit long trade, use open price next candle for calculation!
IF (LongInMarket[1] and ExitLong[1]) THEN
LongExitPrice = open - Halfspread
LongInMarket=0
ENDIF
//step3: while LongInMarket use close prices for PL calculation!
IF LongInMarket THEN
TradePL = (close-LongEntryPrice) * ordersize
Equity = Equity + TradePL - TradePL[1]
ENDIF
//step4: position closed, no matter what reason, use entry- and exit prices
IF LongInMarket[1]=1 and LongInMarket=0 THEN
TradePL = (LongExitPrice - LongEntryPrice) * ordersize
Equity = Equity + TradePL - TradePL[1]
reset=1
ENDIF
//CALCULATE DRAWDOWNS ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
IF LongInMarket[1] or LongInMarket THEN
//check on new equity high / runup high
IF Equity>=RunupLevel THEN
RunupLevel=Equity
DDLevel=Equity
RunupIndex=BarIndex
ENDIF
//New drawdown level low in equity curve?
IF Equity<=DDLevel THEN
DDLevel=Equity
ENDIF
//calculate DD (negativ sign) depending on algebraic level signs
IF ((RunupLevel>0) AND (DDLevel>0)) THEN
DD = -(RunupLevel - DDLevel)
ELSIF RunupLevel>=0 AND DDLevel<0 THEN
DD = (-RunupLevel + DDLevel)
ENDIF
//if new low in DD then save it to variable MaxDD
IF DD<MaxDD THEN
MaxDD=DD
ENDIF
ENDIF
//CALCULATE RUNUPS +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//check on new equity low / rundown low
Once RUDDLevel=Equity
Once RULevel=Equity
IF Equity<=RUDDLevel THEN
RUDDLevel=Equity
RULevel=Equity
RUDDIndex=BarIndex
ENDIF
//New runup level high in equity curve?
IF Equity>=RULevel THEN
RULevel=Equity
ENDIF
//calculate DD (negativ sign) depending on algebraic level signs
IF (RULevel>0) AND (RUDDLevel>=0) THEN //beide +
RU = RULevel - RUDDLevel
ELSIF (RULevel<0) AND (RUDDLevel<0) THEN //beide -
RU = abs(RUDDLevel) - abs(RULevel)
ELSIF (RULevel>0) AND (RUDDLevel<0) THEN // RULevel+ RUDDLevel-
RU = RULevel - RUDDLevel
ENDIF
IF RU>MaxRU THEN
MaxRU=RU
ENDIF
//CALCULATE DRAWDOWN CANDLES +++++++++++++++++++++++++++++++++++++++++++++++++
DDCandles = BarIndex-RunupIndex //for graph function only (testing purposes)
IF MaxDD<MaxDD[1] THEN
MaxDDCandles = BarIndex-RunUpIndex
ENDIF
//CALCULATE RUNUP CANDLES ++++++++++++++++++++++++++++++++++++++++++++++++++++
RUCandles = BarIndex-RUDDIndex //for graph function only (testing purposes)
IF MaxRU>MaxRU[1] THEN
MaxRUCandles = BarIndex-RUDDIndex
ENDIF
ENDIF
//END OF VIRTUAL TRADING ////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//Live Trading //////////////////////////////////////////////////////////////////
//entry long
IF NOT LongOnMarket AND buyLong THEN
buy Ordersize contract at market
ENDIF
//exitLong
IF LongOnMarket and ExitLong THEN
sell at market
ENDIF
//END OF LIVE TRADING ///////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//RESULTS////////////////////////////////////////////////////////////////////////
GraphSWITCH = 9 //1=Equity 2=DD 3=DDCandles 4=RU 5=RUCandles 9=tmp
IF GraphSWITCH=1 THEN //Equity
Graph Equity as "Equity"
ELSIF GraphSWITCH=2 THEN //DD value
Graph Equity as "Equity"
Graph MaxDD coloured(200,0,0) as "MaxDD"
Graph DD coloured(150,0,0) as "DD"
Graph RunupLevel coloured(0,0,200) as "RunupLevel"
graph DDLevel as "DDLevel"
ELSIF GraphSWITCH=3 THEN //DD Candles
Graph RunupIndex coloured(0,200,0) as "RunupIndex"
Graph MaxDDCandles coloured(200,0,0) as "MaxDDCandles"
ELSIF GraphSWITCH=4 THEN //Runup value
Graph Equity as "Equity"
Graph MaxRU coloured(200,0,0) as "MaxRU"
Graph RU coloured(150,0,0) as "RU"
Graph RUDDLevel coloured(0,0,200) as "RUDDLevel"
graph RULevel as "RULevel"
ELSIF GraphSWITCH=5 THEN //Runup Candles
Graph RUCandles coloured(0,0,200) as "RUCandles"
Graph MaxRUCandles coloured(0,0,200) as "MaxRUCandles"
ELSIF GraphSWITCH=9 THEN //individual
Graph Equity as "Equity"
Graph MaxDD coloured(200,0,0) as "MaxDD"
Graph MaxRU coloured(0,200,0) as "MaxRU"
Graph DD coloured(150,0,0) as "DD"
Graph RU coloured(0,200,0) as "RU"
Graph RunupLevel coloured(0,0,200) as "RunupLevel"
graph DDLevel as "DDLevel"
graph RUDDLevel as "RUDDLevel"
graph RULevel as "RULevel"
ENDIF
//eof ///////////////////////////////////////////////////////////////////////////
Hi I’am starting to test your idea. First thing I run into is I don’t have exits on a long only strategy based on a crossing. It’s only based on %loss & %gain.
So how would you tackle that? You can’t use a set command nor you can’t use positionperf if your not on market.
You must convert the % profit or loss into a price value and then check at each candle if that candle has crossed that value (value < high and value > low). Then do the calculation to work out what you would have lost or won exiting at that value and add that to your simulated equity.
Yes, the entry is easy to calculate, it’s more coding involved with the exit. Although I agree with Vonasis previous posts regarding this subject, I was too curious not to try it out on a couple of systems, one good and one bad.
I tried some different approaches, e.g. the one with setting the strategy on hold after a certain amount of draw-down, then starting it again when it has reached a new high in the equity curve.
I also optimized the variables involved, but not one combination led to a better equity curve than the original (without stopping the strategy).
However, with the bad strategy, once it stopped it never started again (due to not reaching a new high in the equity curve. So that strategy actually made better result not trading at all. 🙂
This is the latest version so far (3d). I think I fixed the “DEFPARAM Preloadbars” problem. One additional problem was, that the level-variables have to be adjusted to possible capital variable settings!! Since I did this “initializing” of the variables all is perfectly fine. At least I did not see wrong results for equity, DDMax and RUmax anymore! All good!?
Please help testing this code before using it. If have any results different from PRT please tell! Thank you!
. . Of course this is just one possible idea how to use this code. I am sure there are plenty of other ways to use it.
🙂 PeterSimulated trading
This topic contains 54 replies,
has 7 voices, and was last updated by Mattias
4 years, 10 months ago.
| Forum: | ProOrder: Automated Strategies & Backtesting |
| Language: | English |
| Started: | 02/27/2021 |
| Status: | Active |
| Attachments: | 11 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.