Professional Documents
Culture Documents
Long Exit (LX) level on the indicator (for optional indicator-based long
trade profit-taking)
Short Exit (SX) level on the indicator (for optional indicator-based short
trade profit-taking)
LRS_Base_Period
LRS_Smooth_Period
LRS_LowLvl
LRS_HighLvl
LX_Above_Lvl
SX_Below_Lvl
StopLossPct
PftTgtPct
TrailStopPct
TradingMode
SignalType
FilterType
LongShortBoth
InvertSignals
SingleContract
DayTrade Settings
SO, IN GENERAL, YOU WILL NOT NEED TO EDIT THE CODE TO SCOPE YOUR
OPTIMIZATION.
To generate a feature list from the Windows command line (if grep is
installed):
Regarding use with IO: As of this writing, it is not possible to have built-
in AB optimizer choice features and
use of IO from the same file. However, every effort has been made to
minimize the required differences.
Search on "non-IO" to find the 3 instructions (###) regarding changes for use
with/without IO.
Author's note:
By beginning with this code, you get to avoid _alot_ of trial and error.
If what you see here seems clear and obvious upon reading, that is the hoped-
for intent <g>.
However, getting to this point has been a both a journey and a labor.
This code is provided in return for a fee, which is relied upon for part of
my livelihood.
Knowing the time/effort spent to produce it, I can assure you that this code
is a deep-bargain-at-the-price
(that's my business model). However, YMMV.
Thanks to Tomasz Janeczko for AmiBroker, and to the many in the AB community
who have documented and coded
for AB before me. This code builds on everything I could find and absorb so
far.
Hopefully, this code will help you to shorten your journey, and lighten your
labor ...
Enjoy!
- Progster
*/
// Copyright 2009 by Steve Johns, aka Progster, all rights reserved, worldwide.
// Exclusive distribution by CodeForTraders.com. Other distribution prohibited.
_SECTION_BEGIN("#P_LRS_06a.afl");
/*
function ParmVary( ParamTitle, defaultVal, minv, maxv, step )
{
return Optimize( ParamTitle, Param( ParamTitle, defaultVal, minv, maxv, step ),
minv, maxv, step );
}
if (Mode) {
retval = Optimize( ParmTitle, Param( ParmTitle, defaultVal, minv,
maxv, step ), minv, maxv, step ) ;
}
else {
retval = Param( ParmTitle, defaultVal, minv, maxv, step ) ;
}
return retval ;
}
*/
//transform year
yy = StrToNum(yy) + 1900; //CORRECT BEFORE AND AFTER 2000
//return string
return mm + "/" + dd + "/" + NumToStr(yy, 1, False);
}
Vary_SignalType_0 = 0 ;
Vary_FilterType_0 = 0 ;
Vary_TradingMode_0 = 0 ;
SignalType_0 = 1 ;
FilterType_0 = 0 ;
TradingMode_0 = 1 ;
Vary_LRS_Base_Period_0 = 1 ;
Vary_LRS_Smooth_Period_0 = 1 ;
LRS_Base_Period_0 = 2 ;
LRS_Smooth_Period_0 = 3 ;
Vary_LRS_LowLvl_0 = 1 ;
Vary_LRS_HighLvl_0 = 1 ;
LRS_LowLvl_0 = -.5 ;
LRS_HighLvl_0 = .5 ;
LongShortBoth_0 = 3 ;
InvertSignals_I0 = 0 ;
SingleContract_I0 = 1 ;
ExploreType_I0 = 1 ;
ExtraDecimals_I0 = 0 ;
EquitySend_0 = 1 ;
UseIndLvlExits_I0 = 1;
Vary_LX_Above_Lvl_I0 = 1 ;
Vary_SX_Below_Lvl_I0 = 1 ;
LX_Above_Lvl_0 = .4 ;
SX_Below_Lvl_0 = -.4 ;
UseStopsAndTgts_I0 = 1 ;
VaryStops_I0 = 0; // hold constant
VaryTgts_I0 = 0; // hold constant
VaryTrailStop_I0 = 0; // hold constant
StopLossPct_0 = 1 ;
PftTgtPct_0 = 5 ;
TrailStopPct_0 = 20;
CustomMetrics_I0 = 1 ;
ShowSignalsHistogram_I0 = 1 ;
// ### Comment out this block when not doing parameter substitution via batch
automation
// ### Note: This inclusion is only appropriate for non-IO use.
// printf( "Included: <Module_Data\\#P_LRS_06a\\parameters.afl>\n" ) ;
// #include <Module_Data\#P_LRS_06a\parameters.afl> // override the
settings above (e.g. for batch automation)
/*
The OptIterReload file is used to overwrite the formula parameter defaults
with a different set
of initial values, generally a set that was written out by Progster's Excel
VB macro 'AB_Opt_Params_Export()'.
IOW, the parameters used for a specific optimizer iteration may now be
reloaded without manual typing!
By including this file here, we set the parameter defaults values to same.
5. Open the AB parameters dialog and press the 'Reset' button. Your
parameters are now set as desired.
The above works for both chart loading and backtest loading. Therefore, it
is now possible to quickly and
easily view/evaluate _all_ the pertinent info for _any_ iteration of any
optimization.
Note: It is possible that the spreadsheet will not contain a column for
every operative parameter.
When comparing "reload" results to an optimization interation line, beware
the effects of unrepresented
parameters.
Note: because we are including this file, it must be present for this AFL to
run. However, it is OK
for the file to be empty. So, until you've generated a "real"
OptIterReload_0.afl, just make sure there
is an empty one at the include location.
Alternatively, just comment out the include line (which disables this
functionality).
*/
// ### Name the indicator(s) in use. This name will be used in many places.
EnableTextOutput(False);
Formula_Name = "#P_LRS_06a" ;
LRS_Name = "LRS" ;
EnableTextOutput(True);
sp2 = " "; // two spaces, used for indenting grouped parameters
// This works if you want to use a different price than Close (but no optimization
provided)
//BasePrice = ParamField("BasePrice", 3) ;
//BasePricePlotStyle = ParamList("BasePricePlotStyle", "Line|NoPlot", 1);
// Parameter definitions.
// In this formula, parameters are grouped at the top and ordered for sensible
display in the Parameter dialog.
// An alternative (not done here), is to place parameter definitions throughout
the file near the code that uses them.
// Note: This construction fails in IO. The brackets _must not_ be on the same
line .
/*
if (Vary_RSI_Smooth_Period) { RSI_Smooth_Period = Optimize( RSI_Name +
"_Smooth_Period", RSI_Smooth_Period_Param, 1, 20, 1) ; }
else { RSI_Smooth_Period = RSI_Smooth_Period_Param ; }
*/
// UsingIO = 1 ;
// IO needs to know about your #include directory, if you are including files
// You should be able to tell it in 'AmiBroker\IO\IO Defaults.txt'. But if
not, tell it here.
////IO: IncludeDir: c:\AmiBroker_Formula_Root\Include
// Conceptually, this is what we want, but AB does not allow for conditional
#include
// if (! UsingIO) { #include <OptOptionChoices.afl> }
// ### Uncomment this for non-IO use. For use with IO, comment this out.
// #include <OptOptionChoices.afl> // contents reproduced
below
if (UsingIO){
}
else{
// Pointless and dangerous when using IO
OType = ParamList("---- OType", "Exhaustive|CMAE|Tribes|SPSO", OType_I0); //
default: CMAE, (Note: "OType" instead of "Opti-mizerType" for IO compatibility)
VaryRuns = Param( "---- VaryRuns", VaryRuns_0, 0, 10, 1);
VaryMaxEval = Param( "---- VaryMaxEval", VaryMaxEval_0, 0, 10000, 1);
if (OType == "Exhaustive"){
VaryRuns = 0;
VaryMaxEval = 0;
}
}
// ******************** End of: OptOptionChoices.afl
********************
if (Vary_TradingMode){
TradingMode = Optimize( "TradingMode", TradingMode_Param, 1, 4, 1) ;
}
else{
TradingMode = TradingMode_Param ;
}
if (Vary_SignalType){
SignalType = Optimize( "SignalType", SignalType_Param, 1, 2, 1) ;
}
else{
SignalType = SignalType_Param ;
}
if (Vary_FilterType){
FilterType = Optimize( "FilterType", FilterType_Param, 1, 2, 1) ;
}
else{
FilterType = FilterType_Param ;
}
if (Vary_LRS_Base_Period){
LRS_Base_Period = Optimize( LRS_Name + "_Base_Period", LRS_Base_Period_Param, 2,
50, 1) ;
}
else{
LRS_Base_Period = LRS_Base_Period_Param ;
}
if (Vary_LRS_Smooth_Period) {
LRS_Smooth_Period = Optimize( LRS_Name + "_Smooth_Period",
LRS_Smooth_Period_Param, 1, 20, 1) ;
}
else{
LRS_Smooth_Period = LRS_Smooth_Period_Param ;
}
if (Vary_LRS_LowLvl){
LRS_LowLvl = Optimize( LRS_Name + "_LowLvl", LRS_LowLvl_Param, -10, 0, .1) ;
}
else{
LRS_LowLvl = LRS_LowLvl_Param ;
}
if (Vary_LRS_HighLvl){
LRS_HighLvl = Optimize( LRS_Name + "_HighLvl", LRS_HighLvl_Param, 0, 10, .1) ;
}
else{
LRS_HighLvl = LRS_HighLvl_Param ;
}
if(CustomMetrics){
SetOption("UseCustomBacktestProc", True );
//exp1 =
stats.GetValue("WinnersAvgProfit")*stats.GetValue("WinnersPercent")/100 +
stats.GetValue("LosersAvgLoss")*stats.GetValue("LosersPercent")/100;
exp2 = stats.GetValue("NetProfit")/ (stats.GetValue("WinnersQty") +
stats.GetValue("LosersQty")) ;
// Conceptually, this is what we want, but AB does not allow for conditional
#include
// if (! UsingIO) { #include <OptChoiceActions.afl> }
// ### Uncomment this for non-IO use. For use with IO, comment out this line.
// ### Comment this out if you prefer your extra columns (parms) at the end rather
than in front
// ### Also, comment this out if not running in AB 5.23 or later !
SetOption("ExtraColumnsLocation", 1 ); // put parameter columns up-front after
optimization
In this case, we cannot report the EntryPrice at the signal bar without looking
into the future.
We can, however, report it 1 bar later (as done in the Title, below)
*/
switch( TradingMode ){
case 1:
// "Next bar at Open" trading
BuyDelay = 1; BuyPrice = Open ; // LE at Open price of next bar
ShortDelay = 1; ShortPrice = Open ; // SE at Open price of next bar
SellDelay = 1; SellPrice = Open ; // LX at Open price of next bar
CoverDelay = 1; CoverPrice = Open ; // SX at Open price of next bar
break;
case 2:
// "This bar at Close" trading
BuyDelay = 0; BuyPrice = Close ; // LE at Close price of signal bar
ShortDelay = 0; ShortPrice = Close ; // SE at Close price of signal bar
SellDelay = 0; SellPrice = Close ; // LX at Close price of signal bar
CoverDelay = 0; CoverPrice = Close ; // SX at Close price of signal bar
break;
case 3:
// Mixed mode trading, enter "Next bar at Open", exit "This bar at Close"
BuyDelay = 1; BuyPrice = Open ; // LE at Open price of next bar
ShortDelay = 1; ShortPrice = Open ; // SE at Open price of next bar
SellDelay = 0; SellPrice = Close ; // LX at Close price of signal bar
CoverDelay = 0; CoverPrice = Close ; // SX at Close price of signal bar
break;
/*
case 4: // bad results for reversal trades! - this is a bogus case!
// Mixed mode trading, , enter "This bar at Close", exit "Next bar at Open"
BuyDelay = 0; BuyPrice = Close ; // LE at Close price of signal bar
ShortDelay = 0; ShortPrice = Close ; // SE at Close price of signal bar
SellDelay = 1; SellPrice = Open ; // LX at Open price of next bar
CoverDelay = 1; CoverPrice = Open ; // SX at Open price of next bar
break;
*/
// Re-Scale the TA plots (i.e. for FX) when there is a ScaleFactor other than 1
if (LRS_ScaleFactor != 1){
theLRS = theLRS * LRS_ScaleFactor ;
SmoothedLRS = SmoothedLRS * LRS_ScaleFactor ;
}
LRS_IsLow = LRS_IsHigh = 0 ;
if (LongShortBoth == 1){
Sell = Short = Cover = 0 ;
if (InvertSignals){
Buy = LRS_IsHigh;
// Sell = LRS_IsLow;
}
else {
Buy = LRS_IsLow;
// Sell = LRS_IsHigh;
}
}
else if (LongShortBoth == 2){
Buy = Sell = Short = 0 ;
if (InvertSignals){
Short = LRS_IsLow;
// Cover = LRS_IsHigh;
}
else {
Short = LRS_IsHigh;
// Cover = LRS_IsLow;
}
}
else if (LongShortBoth == 3){
// Beware - incorrect!
/*
Buy = LRS_IsLow;
Short = LRS_IsHigh ;
Sell = Cover = 0 ;
*/
// ===Dbg
// printf( "a Buy: " + Buy + " Sell: " + Sell + " Short: " + Short + " Cover: "
+ Cover + "\n" ) ;
if (FilterType != 0){
Buy = Buy AND LongOK ;
Short = Short AND ShortOK ;
}
// ===Dbg
// printf( "b Buy: " + Buy + " Sell: " + Sell + " Short: " + Short + " Cover: "
+ Cover + "\n" ) ;
// ***** Code for limiting trading to an intraday time window (i.e. daytrading)
if (UseStopsAndTgts){
SellReason = "" ;
CoverReason = "" ;
if (UseIndLvlExits){
_N(
CoverReason = CoverReason +
WriteIf( Cover == 1, "Regular Exit\n",
WriteIf( Cover == 2, "Max Loss\n",
WriteIf( Cover == 3, "Profit Tgt\n",
WriteIf( Cover == 4, "Trailing Stop\n",
WriteIf( Cover == 5, "N-bar Stop\n",
WriteIf( Cover == 6, "Ruin stop\n", "" ) ) ) ) ) )
);
case 1:
printf( "Mode 1: Next bar at Open trading (delay entries AND exits)" + "\n" ) ;
break;
case 2:
printf( "Mode 2: This bar at Close trading (no delay of entries OR exits)" + "\n"
) ;
break;
case 3:
printf( "Mode 3: Mixed mode trading, enter Next bar at Open, exit This bar at
Close (delay entries, NOT exits)" + "\n" ) ;
break;
/*
case 4:
printf( "Mode 4: Mixed mode trading, enter This bar at Close, exit Next bar at
Open (delay exits, not entries)" + "\n" ) ;
break;
*/
if (ShowSignalsHistogram){
HistBaseVal = .5; HistMinVal = 0; HistMaxVal = 15;
Plot( HistBaseVal + 1/Buy,"Buy",colorGreen,styleHistogram|styleOwnScale,
HistMinVal, HistMaxVal); // Buy - Green
Plot( HistBaseVal + 1/Sell,"Sell",colorRed,styleHistogram|styleOwnScale,
HistMinVal, HistMaxVal); // Sell - Red
Plot( HistBaseVal + 1/Short,"Short",colorOrange,styleHistogram|styleOwnScale,
HistMinVal, HistMaxVal); // Short - Orange
Plot( HistBaseVal + 1/Cover,"Cover",colorAqua,styleHistogram|styleOwnScale,
HistMinVal, HistMaxVal); // Cover - Aqua
}
// ***** Code for passing NetPft to cooperating display indicator in another chart
pane.
IE = GetOption("InitialEquity") ;
if (ExploreType == "Current"){
IsLastBar = DateTime() == LastValue(DateTime()) ; // filter on this to show
current bar signals only in Exploration
ExpDateCon = IsLastBar ;
}
else if (ExploreType == "Today"){
IsLastDate = DateNum() == LastValue(DateNum()) ; // filter on this to show last
day's signals only in Exploration
ExpDateCon = IsLastDate ;
}
else if (ExploreType == "Historical"){
ExpDateCon = 1 ; // allow historical signals in Exploration
}
if (LongShortBoth == 1){
Filter = ExpDateCon AND (Buy OR Sell) ;
AddColumn( Buy, "Buy Next Bar", 1.0, colorDefault, IIf(Buy, colorGreen,
colorDefault) );
AddColumn( Sell, "Sell Next Bar", 1.0, colorDefault, IIf(Sell, colorRed,
colorDefault) );
}
else if (LongShortBoth == 2){
Filter = ExpDateCon AND (Short OR Cover) ;
AddColumn( Short, "Short Next Bar", 1.0, colorDefault, IIf(Short, colorRed,
colorDefault) );
AddColumn( Cover, "Cover Next Bar", 1.0, colorDefault, IIf(Cover, colorGreen,
colorDefault) );
}
else if (LongShortBoth == 3){
Filter = ExpDateCon AND (Buy OR Short) ;
AddColumn( Buy, "Buy Next Bar", 1.0, colorDefault, IIf(Buy, colorGreen,
colorDefault) );
AddColumn( Short, "Short Next Bar", 1.0, colorDefault, IIf(Short, colorRed,
colorDefault) );
}
// ***** Code for on-chart plotting of price, signal arrows, and trade
duration/direction bar coloring
// Enable/disable plotting of up/down arrows on the entry and exit signal bars.
// This show location of signal generation, regardless of actual entry.
if(PlotEntryArrows){
PlotShapes( shapeUpArrow * (Buy > 0), colorGreen,0, L, -20); // arrows at long
entry bars
PlotShapes( shapeDownArrow * (Short > 0), colorRed,0,H, -20) ; // arrows at
short entry bars
}
if(PlotExitArrows){
// Don't plot exit arrows for reversal case - let the entry arrows indicate that
instead
PlotShapes( ( Buy == 0 ) * shapeUpArrow * (Cover > 0) , colorYellow,0, L, -20);
// arrows at long exit bars
PlotShapes( ( Short == 0 ) * shapeDownArrow * (Sell > 0), colorYellow,0,H,
-20) ; // arrows at short exit bars
}
if ( (PlotRawPrice) )
{
switch( TradingMode ){
case 1:
// "Next bar at Open" trading (delay entries and exits)
AmLong = Flip( Ref(Buy, -BuyDelay), Ref(Sell, IIf(SellDelay == 0, -1,
-SellDelay) ) OR Ref(Short, -ShortDelay) ) ;
AmShort = Flip( Ref(Short, -ShortDelay), Ref(Cover, IIf(CoverDelay == 0, -1,
-CoverDelay)) OR Ref(Buy, -BuyDelay) ) ;
printf( "Next bar at Open trading (delay entries AND exits)" + "\n" ) ;
break;
case 2:
// "This bar at Close" trading (no delay of entries or exits)
AmLong = Flip( Ref(Buy, -1), Ref(Sell, -1) OR Ref(Short, -1) ) ;
AmShort = Flip( Ref(Short, -1), Ref(Cover, -1) OR Ref(Buy, -1) ) ;
break;
case 3:
// Mixed mode trading, enter "Next bar at Open", exit "This bar at Close"
(delay entries, not exits)
AmLong = Flip( Ref(Buy, -BuyDelay), Ref(Sell, -1) OR Ref(Short, -1) ) ;
AmShort = Flip( Ref(Short, -ShortDelay), Ref(Cover, -1) OR Ref(Buy, -1) ) ;
break;
/*
case 4:
// Mixed mode trading, , enter "This bar at Close", exit "Next bar at Open"
(delay exits, not entries)
AmLong = Flip( Ref(Buy, -1), Ref(Sell, IIf(SellDelay == 0, -1, -SellDelay) ) OR
Ref(Short, -1) ) ;
AmShort = Flip( Ref(Short, -1), Ref(Cover, IIf(CoverDelay == 0, -1,
-CoverDelay)) OR Ref(Buy, -1) ) ;
break;
*/
}
}
SetChartOptions(0,chartShowArrows|chartShowDates);
}
else {
// 2-decimal precision. Good for stocks and futures. For FX, more decimals are
typically needed
// _N() keeps this silent for later use.
_N(TitlePriceStr = StrFormat( "O %.2f, H %.2f, L %.2f, C %.2f \nNetPft %.0f", O,
H, L, C, NetPft )) ;
}
// Configure a multi-line chart title, using the TitlePriceStr, and sometimes more.
// Unknown - In Interpretation: why NetPft is 0, why BuySignal disappears ...
// Note that for for stop-and-reverse case, we don't want to display the exit part
if the old-exit/new-entry pair.
// This is accomplished by suppressing exit display when entry is also present.
+ WriteIf(Buy, "Buy Signal ", "") + WriteIf(Sell AND !Short, "Sell Signal - " +
SellReason, "")
+ WriteIf(Short, "Short Signal ", "") + WriteIf(Cover AND !Buy, "Cover Signal - "
+ CoverReason, "")
// These report the trade prices on the bar after the signal (where they are
available).
// This is appropriate when trading "open next bar"
+ WriteIf(Ref(Buy, -BuyDelay), StrFormat("Buy at %g", BuyPrice), "")
+ WriteIf(Ref(Short,-ShortDelay), StrFormat("Short at %g", ShortPrice), "")
+ WriteIf(Ref(Sell,-SellDelay) AND !Ref(Short,-ShortDelay), StrFormat(" Sell at
%g", SellPrice), "")
+ WriteIf(Ref(Cover,-CoverDelay) AND !Ref(Buy,-BuyDelay), StrFormat(" Cover at
%g", CoverPrice), "")
+ "\n" ;
_SECTION_END();
if (ShowMAs){
_SECTION_BEGIN("MA1");
P = ParamField("Price field", 3);
Periods = Param("Periods", 200, 2, 200, 1, 0 );
Plot( MA( P, Periods ), _DEFAULT_NAME(), ParamColor( "Color", colorCycle ),
ParamStyle("Style") );
_SECTION_END();
_SECTION_BEGIN("MA2");
P = ParamField("Price field", 3);
Periods = Param("Periods", 50, 2, 50, 1, 0 );
Plot( MA( P, Periods ), _DEFAULT_NAME(), ParamColor( "Color", colorCycle ),
ParamStyle("Style") );
_SECTION_END();