Registered User Joined: 8/31/2009 Posts: 60
|
I need help in creating a Rule Code to exit Positions using ATR Exit strategy
---------------------------------------------------
Once BUY order is generated,
Set initial StopPrice = Price.close - 2*ATR
subsequent Bars, Adjust StopPrice upwards ...
IF (Price.close - 2*ATR) > StopPrice THEN StopPrice = Price.close - 2*ATR
Generate SELL order if Price.Close < StopPrice
------------------------------------------------------------------
I would like to use a Input Parameter to set ATR_Exit_Value which could default to 2
|
|
Worden Trainer
Joined: 10/7/2004 Posts: 65,138
|
I do not know of a way to access the Entry Price or Entry Date of the Trade in a generalized fashion in a RealCode Rule or in anything besides one of the built in Trade Based Rules. You pretty much need to re-create the entire BackScan in RealCode to know the Entry Price to use it in RealCode. This is rarely practical as the RealCode required can be very complicated and any changes to the BackScan would require similar alterations to the RealCode as well.
-Bruce Personal Criteria Formulas TC2000 Support Articles
|
|
Registered User Joined: 8/31/2009 Posts: 60
|
We could create a single Rule thru RealCode for both BUY / SELL.
'--- Section - BUY---
IF TRADE_STATUS = OPEN
IF <BUY CONDITIONS> are Met...
BUY....
TRADE_STATUS = BUY
end if
end if
---- SELL Section
IF TRADE_STATUS = BUY
If <SELL CONDITIONS> are met
SELL
TRADE_STATUS = OPEN
end if
end if
============================
Question is - Can we use this single RealCode rule in the Back Scanner?
|
|
Worden Trainer
Joined: 10/7/2004 Posts: 65,138
|
If you place all of your Buy Rules into a single Combo Rule and all of your Sell Rules into another Combo Rule, you could Drag and Drop those Combo Rules (along with the ATR Indicator) into the RealCode Editor to use them as part of other RealCode Rules.
You would need to have different Rules for Buy and Sell, these would need to be the only Rules in BackScanner and these Rules would need to be set to Execute 0 Bars from Now. Any changes to this would require different RealCode Rules.
Your Buy Rule would look something like the following:
'Buy Rule
'# ATR = indicator.AverageTrueRange
'# Buy = condition.ComboCondition
'# Sell = condition.ComboCondition.2
Static inTrade As Boolean
Static ATRstop As Single
If isFirstBar Then
inTrade = False
ATRstop = Single.NaN
End If
If inTrade = True Then
If Sell.Value = True OrElse _
Price.Low < ATRstop Then
inTrade = False
End If
ATRstop = System.Math.Max(ATRstop, Price.Last - 2 * ATR.Value)
Else
If Buy.Value = True Then
inTrade = True
ATRStop = Price.Last - 2 * ATR.Value
Pass
End If
End If
And your Sell Rule would look something like the following (identical except for where Pass is located):
'Sell Rule
'# ATR = indicator.AverageTrueRange
'# Buy = condition.ComboCondition
'# Sell = condition.ComboCondition.2
Static inTrade As Boolean
Static ATRstop As Single
If isFirstBar Then
inTrade = False
ATRstop = Single.NaN
End If
If inTrade = True Then
If Sell.Value = True OrElse _
Price.Low < ATRstop Then
inTrade = False
Pass
End If
ATRstop = System.Math.Max(ATRstop, Price.Last - 2 * ATR.Value)
Else
If Buy.Value = True Then
inTrade = True
ATRStop = Price.Last - 2 * ATR.Value
End If
End If
-Bruce Personal Criteria Formulas TC2000 Support Articles
|
|
Registered User Joined: 8/31/2009 Posts: 60
|
Hi Bruce,
System does'nt seem to work...
Here is what I have done
1. BUY when PRICE closes above MA21
2. SELL when PRICE closes below MA21 or PRICE < ATRstop
---------------------------------------------------------------------------------------
Steps:
1. Create BUY Rule "Price History xUp MovAvg 21 of Price History"
2. Create BUY Combo Rule "RY.ATR.Combo.BUY.Rule" - It contains Rule from Step 1
3. Create BUY RuleCode "RY.ATR.BUY.RuleCode"
4. Create SELL Rule "Price History xDown MovAvg 21 of Price History"
2. Create SELL Combo Rule "RY.ATR.Combo.SELL.Rule" - It contains Rule from Step 4
3. Create SELL RuleCode "RY.ATR.SELL.RuleCode"
Setup in Backscanner
* for BUY - "RY.ATR.BUY.RuleCode"
* for SELL - "RY.ATR.SELL.RuleCode"
-------------------------
I have shared my Layout "RYSA Exit Strategy" , If you want to look at the code and the complete setup.
Problem:
It seems to execute either the BUY or the SELL code. What I am missing here.
|
|
Worden Trainer
Joined: 10/7/2004 Posts: 65,138
|
I'm not sure what you are attempting to point out exactly. You have stated, "It seems to execute either the BUY or SELL code.", but I'm not sure what that means. You appear to be getting both Buy and Sell Signals on the Charts. I don't use the debugger, so if it has something to do with that, I wouldn't see what you are attempting to point out. Some additional notes follow.
You have mentioned that you should Buy when Price closes above the Moving Average. If you really mean this, you should probably change the Rule from Price History xUp MovAvg 21 of Price History to Price History Above MovAvg 21 of Price History. That said, a xUp is probably better as otherwise you might immediately go back into a trade after being stopped out. The same applies to your Sell Rule.
You have the Buy Rule and Sell Rule both set to Execute at the Open 1 Bar from Now. The RealCode given expects you to Execute 0 Bars from Now. The RealCode bases its initial Stop on the Close of the Bar when Price History xUp MovAvg 21 for example. The RealCode would need to be altered for Execution 1 Bar from Now (and I'd have to think for a bit about what alterations might be required beyond altering the Initial Stop).
-Bruce Personal Criteria Formulas TC2000 Support Articles
|
|
Registered User Joined: 8/31/2009 Posts: 60
|
Problems:
I have embedded DEBUG LOG messages in both BUY and SELL rulecodes.
1. In BackScanner, If I click on UPDATE - nothing Happens
2. If I open RuleCode for BUY and then click APPLY, I see DEBUG LOG messages pertaining to the BUY code, but nothing related to SELL RealCode
3.If I open RuleCode for SELL and then click APPLY, I see DEBUG LOG messages pertaining to the SELL code, but nothing related to BUY RealCode
Shouldn't Backscanner Execute both BUY and SELL RuleCodes for every Bar ?
|
|
Worden Trainer
Joined: 10/7/2004 Posts: 65,138
|
Please keep in mind that I'm not a programmer and that I never use the debugger.
QUOTE (rysa) In BackScanner, If I click on UPDATE - nothing Happens
I'm pretty sure this is because the RealCode Rules are getting run already from being on the Chart. If I use a Watchlist with more than a single symbol, selecting Update causes lots of activity in the Debug Log.
QUOTE (rysa) If I open RuleCode for BUY and then click APPLY, I see DEBUG LOG messages pertaining to the BUY code, but nothing related to SELL RealCode
That's because you've just executed the RuleCode for the Buy Rule. This doesn't execute the RealCode for the Sell Rule. These RealCode Rules aren't being run simultaneously one bar at a time. Each Rule is being run and then the results of both Rules are being used by BackScanner.
QUOTE (rysa) If I open RuleCode for SELL and then click APPLY, I see DEBUG LOG messages pertaining to the SELL code, but nothing related to BUY RealCode
This is the same as what is happening when you select Apply for the Sell RealCode Rule.
QUOTE (rysa) Shouldn't Backscanner Execute both BUY and SELL RuleCodes for every Bar ?
It does run both the Buy and Sell RealCode Rules. But these RealCode Rules are run once for each symbol and then combined. The program does not increment through each Bar to cause the autolooping in each RealCode Rule to increment simultaneously.
I've created a version that uses a single RealCode Indicator to calculate the Buys and Sells that then has RealCode Rules based on upon the RealCode Indicator to use in BackScanner if you want to see an alternate implementation. You should be able to Open the attached Layout directly into a running copy of StockFinder.Attachments: ATR Exit RC BackScan.sfLayout - 48 KB, downloaded 666 time(s).
-Bruce Personal Criteria Formulas TC2000 Support Articles
|
|
Registered User Joined: 8/31/2009 Posts: 60
|
Hi Bruce,
It works beautifully...
Thanks for taking your time and providing the complete code.
I am trying to duplicate what you have done in few mins and am running into problems. Realcode Manual is not detailed enough to cover the techniques you have used in the system you have developed.
Would it be possible to provide step by step directions on how to create what you did from scratch.
|
|
Registered User Joined: 12/31/2005 Posts: 2,499
|
Was curious and played a bit with Bruce's layout. The average trade length using the Buy and Sell rules was about 8 bars using Dow Jones 15 Utilities. The losing trades were shorter and there were more. based on the trade length there are a couple ways to scan that provide some perspective.
Compared to What?
One of the challenges in backtesting is judging the merit of the result. This is particularly hard as the Ann Return / Trade is not caclulated correctly. The results listed below are against SP500, 5000 days, the red ann return is the incorrect value from StockFinder, The blue is the actual ann return.
test run 1:
One approach is to see what the "average" 8 bar trade does. The buy rule is Buy if price > 0. The sell is exit if trade length > 7 on open after 0 bars.
test run 2:
Another approach is to see how the buy signal with an 8 bar exit performs. The Buy is using the Buy signal. The sell is exit if trade length > 7 on open after 0 bars.
test run 3.
use the BUY and Sell rules.
The results are revealing:
SP500
|
trade length
|
ave return
|
wrong ann return
|
actual ann return
|
win%
|
gain/loss
|
Total Trades |
8 day hold
|
8.0 |
0.52% |
61.00% |
16.38% |
52% |
1.10 |
214,616 |
Buy, 8 day hold
|
7.8 |
2.37% |
282.00% |
76.57% |
60% |
1.30 |
3,514 |
Buy, Sell
|
8.3 |
2.08% |
236.00% |
63.15% |
41% |
3.00 |
5,059 |
BUY, SELL has 1500+ more trades then the BUY and exit after 8. This seems to indicate there is an exit and reenter 1500+ times out of the 3500+ buy signals. So the exit might be too tight. In addition the win% for BUY, SELL is only 41% as compared to 60% for Buy, exit after 8.
Very roughly, the average win% of the SP500 over the last 500 days for 8 day trades is 52%. with an annualized return of 16.38%. The Buy and exit after 8 exceeds these so the Buy signal is doing okay.
To be clear I just took Bruce'slayout and executed a couple runs. This post's intent is not to judge the merit of the strategy, but to present a two ways one can get some perspective:
1. unconditional buy and exit after x bars.
2. use buy rule and exit after x bars
|
|
Registered User Joined: 8/31/2009 Posts: 60
|
This system is for demonstrating ATR Exits.
-------------------------------------------------------------------------------------------------------------
One of the more profitable System using Moving Averages would be the Triple MA.
MA Short - Say MA11
MA Intermediate - MA30
MA Long : MA100
BUY Signal - If MA_Short and MA_Int is above MA_Long, and MA_Short Closes above MA_Int - Buy the next day.
SELL Signal - If MA_Short closes below MA_Int - Sell the following day.
During long Bullish Trends, You can tweak the MA's to get more than 100% Annualized Returns. Again, Backtesting doesn't guarantee future winnings.
-------------------------------------------------------------------
On a different Note:
How to create "BackScan", "ATR Stop", "Trades" Indicators demonstrated in ATR Exit system put together by Bruce.
Any help is appreciated.
|
|
Worden Trainer
Joined: 10/7/2004 Posts: 65,138
|
rysa,
The BackScan Indicator pretty much contains all of the calculations and is based directly on the RealCode from your Shared "RYSA Exit Strategy" Layout:
'BackScanner Indicator
'# MA = indicator.MovingAverage.3
'# ATR = indicator.AverageTrueRange
Static TradeStatus As Integer
'1 = Long
'0 = Not in Trade
Dim Action As Integer = 0
'2 = Sell
'1 = Buy
'0 = No Action
Static ATRstop As Single
If isFirstBar Then
TradeStatus = 0
ATRstop = 0
End If
If Me.CurrentDate.Date >= #01/01/2009# Then
If TradeStatus = 1 Then
If Price.Last < MA.Value AndAlso _
Price.Last(1) >= MA.Value Then
Label = "xDn MA"
TradeStatus = 0
Action = 2
Else If Price.Low < ATRstop Then
Label = "ATR Stop"
TradeStatus = 0
Action = 2
End If
ATRstop = System.Math.Max(ATRstop, Price.Last - 2 * ATR.Value)
Else If TradeStatus = 0
If Price.Last > MA.Value AndAlso _
Price.Last(1) <= MA.Value Then
Label = "xUp MA"
TradeStatus = 1
Action = 1
ATRStop = Price.Last - 2 * ATR.Value
End If
End If
End If
OpenValue = TradeStatus
HighValue = Action
LowValue = ATRstop
Plot = Price.Last
Instead of Dragging and Dropping the Rules into the RealCode and using the results, I just Dragged and Dropped the Moving Average and ATR into the RealCode and checked for the crossovers directly. The only thing I did that is slightly odd is that I output four values by outputting "Bar Data" instead of just outputting a single value. This meant I could calculate and output the Trades and ATRstop using a single Indicator instead of having to calculate these values in more than one Indicator.
The Buy Rule just checks to see if the Action (which is being output as the High of the BackScan Indicator) is 1:
'# BI = indicator.BackScanIndicator
If BI.High = 1 Then Pass
While the Sell Rule just checks to see if the Action is 2:
'# BI = indicator.BackScanIndicator
If BI.High = 2 Then Pass
These Rules were then Dragged and Dropped into BackScanner as a Buy Rule and a Sell Rule set to the Close 0 Bars from Now. The Trades plot is just the one that is built into BackScanner.
The ATR Stop Indicator is similar to the Rules in that it also doesn't do any calculations. It just Plots the Low of the BackScan Indicator:
'# BI = indicator.BackScanIndicator
If BI.Open = 1 Then
Plot = BI.Low
Else
Plot = Single.NaN
End If
One wrinkle in this is that I couldn't output Single.NaN (Not a Number) to force the ATR Stop to not Plot when not in a trade while still outputting values for the rest of the BackScan Indicator. So the ATR Stop Indicator uses the Open of the BackScan Indicator to determine if it is in a Trade and only Plots a Value if the Open of the BackScan Indicator equals 1.
-Bruce Personal Criteria Formulas TC2000 Support Articles
|
|
Registered User Joined: 12/31/2005 Posts: 2,499
|
QUOTE (Bruce_L)
...
...
...
'BackScanner Indicator
'# MA = indicator.MovingAverage.3
'# ATR = indicator.AverageTrueRange
Static TradeStatus As Integer
'1 = Long
'0 = Not in Trade
Dim Action As Integer = 0
'2 = Sell
'1 = Buy
'0 = No Action
Static ATRstop As Single
If isFirstBar Then
TradeStatus = 0
ATRstop = 0
End If
If Me.CurrentDate.Date >= #01/01/2009# Then
If TradeStatus = 1 Then
If Price.Last < MA.Value AndAlso _
Price.Last(1) >= MA.Value Then
Label = "xDn MA"
TradeStatus = 0
Action = 2
Else If Price.Low < ATRstop Then
Label = "ATR Stop"
TradeStatus = 0
Action = 2
End If
ATRstop = System.Math.Max(ATRstop, Price.Last - 2 * ATR.Value)
Else If TradeStatus = 0
If Price.Last > MA.Value AndAlso _
Price.Last(1) <= MA.Value Then
Label = "xUp MA"
TradeStatus = 1
Action = 1
ATRStop = Price.Last - 2 * ATR.Value
End If
End If
End If
OpenValue = TradeStatus
HighValue = Action
LowValue = ATRstop
Plot = Price.Last
...
...
.
Here is a programming technique that can make the code a little more readable. Using enumerations for the possible states instead of cryptic number as in 0, 1, 2, etc.. To add the Enum's you need to edit using the class tab and place the Enums before the function plot declaration.. Here is the modified code (note the first line is excluded.):
...
Public partial Class RealCodeIndicator
Inherits RealCodeIndicator_base
'
' add TradeStatus and Action enumerations
'
Enum Trade_Status As Integer
LongTrade = 1
NotInTrade = 0
End Enum
Enum Trade_Action As Integer
Sell = 2
Buy = 1
NoAction = 0
End Enum
Public Overrides function Plot() as System.Single
'BackScanner Indicator
'# MA = indicator.MovingAverage.3
'# ATR = indicator.AverageTrueRange
Static TradeStatus As Integer
Dim Action As Integer = Trade_Action.NoAction
Static ATRstop As Single
If isFirstBar Then
TradeStatus = Trade_Status.NotInTrade
ATRstop = 0
End If
If Me.CurrentDate.Date >= #01/01/2009# Then
If TradeStatus = Trade_Status.LongTrade then
If Price.Last < MA.Value AndAlso _
Price.Last(1) >= MA.Value Then
Label = "xDn MA"
TradeStatus = Trade_Status.NotInTrade
Action = Trade_Action.Sell
Else If Price.Low < ATRstop Then
Label = "ATR Stop"
TradeStatus = Trade_Status.NotInTrade
Action = Trade_Action.Sell
End If
ATRstop = System.Math.Max(ATRstop, Price.Last - 2 * ATR.Value)
Else If TradeStatus = Trade_Status.NotInTrade then
If Price.Last > MA.Value AndAlso _
Price.Last(1) <= MA.Value Then
Label = "xUp MA"
TradeStatus = Trade_Status.LongTrade
Action = Trade_Action.Buy
ATRStop = Price.Last - 2 * ATR.Value
End If
End If
End If
OpenValue = TradeStatus
HighValue = Action
LowValue = ATRstop
Plot = Price.Last
End Function
End Class
The resulting adjusted code can be more readable, especially later when revisting the code.
|
|
Registered User Joined: 10/7/2004 Posts: 364
|
JAS, any chance you can share the layout? You know how lazy I am.
I found this while searching for a way to determine the entry price in order to create a trailing stop. Without entry price the backscanner is just a toy. Hopefully, version 5 will resolve most of the reported problems in backscanner.
Thanks,
Kermitp
|
|
Guest-1 |