One possibilty is to Buy when C rises above the linear regression line and sell when it drops below:
Buy = Cross( C, y );
Sell = Cross( y, C );
Hi Art --
What is your definition of the angle? It is important that it be unaffected by a change in scale of the chart or split of the stock price.
Howard
Short= Close<EMA(Close,200) AND Ref(Close,-1)<Ref(EMA(Close,200),-1);
ShortPrice= Close;
// the system will exit
// 50% of position if FIRST PROFIT TARGET stop is hit
// 50% of position is SECOND PROFIT TARGET stop is hit
// 100% of position if TRAILING STOP is hit
FirstProfitTarget = 5; // profit
SecondProfitTarget = 7.5; // in percent
TrailingStop = 2; // also in percent
priceatshort=0;
lowsinceshort =0;
Cover=0;
exit = 0;
for( i = 0; i < BarCount; i++ )
{
if( priceatshort == 0 AND Short[ i ] )
{
priceatshort = ShortPrice[ i ];
}
if( priceatshort > 0 )
{
Lowsinceshort = Min( Low[ i ], Lowsinceshort ); //Lowest low since short
if( exit == 0 AND
Low[ i ] <= ( 1 - FirstProfitTarget * 0.01 ) * priceatshort ) //Low < 0.95 X ShortPrice (5% below short price)
{
// first profit target hit - scale-out
exit = 1;
Short[ i ] = sigScaleOut; //Sell 50% of position
}
if( exit == 1 AND
Low[ i ] <= ( 1 - SecondProfitTarget * 0.01 ) * priceatshort ) // 7.5% below short price
{
// second profit target hit - exit
exit = 2;
Cover=1;
CoverPrice[ i ] = Close[ i ]; // Sell Remainder at the close
}
// trailing stop
if( High[ i ] >= ( 1 + TrailingStop * 0.01 ) * lowsinceshort ) //High is greater than 2% above the lowest low since short
{
exit = 3;
Cover=1;
CoverPrice[ i ] = Close[i]; // Trailing stop hit - Exit at close
}
if( exit >= 2 )
{
Short[ i ] = 0;
Cover[ i ] = exit ;
exit = 0;
priceatshort = 0; // reset price
lowsinceshort = 0;
}
}
}
SetPositionSize( 50, spsPercentOfEquity );
SetPositionSize( 50, spsPercentOfPosition * ( Short== sigScaleOut ) ); // scale out 50% of position
Short=ExRem(Short,Cover);
Cover=ExRem(Cover,Short);
PlotShapes(shapeDownArrow*Short,colorRed,0,L, -30);
PlotShapes(shapeUpArrow*Cover,colorBrightGreen,0,H, -30);
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorBlack ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() );
_SECTION_BEGIN("Short Targets");
Short= Close<EMA(Close,200) AND Ref(Close,-1)<Ref(EMA(Close,200),-1);
ShortPrice= Close;
// the system will exit
// 100% of position if PROFIT TARGET stop is hit
// 100% of position if TRAILING STOP is hit
ProfitTarget = 5; // profit
TrailingStop = 2; // also in percent
priceatshort=0;
lowsinceshort =0;
Short=0;
Cover=0;
exit=0;
for( i = 0; i < BarCount; i++ )
{
if( priceatshort == 0 AND Short[ i ] )
{
priceatshort = ShortPrice[ i ];
}
if( priceatshort > 0 )
{
Lowsinceshort = Min( Low[ i ], Lowsinceshort );
if( exit == 0 AND
Low[ i ] <= ( 1 - ProfitTarget * 0.01 ) * priceatshort )
{
exit=1;
Cover[i]=1;
CoverPrice[i] = Close [i];
}
if( High[ i ] >= ( 1 + TrailingStop * 0.01 ) * lowsinceshort )
{
exit=1;
Cover [i]=1;
CoverPrice[ i ] = Close[i];
}
if(Exit == 1)
{
Short[i] = 0;
Exit = 0;
PriceatShort = 0;
LowSinceShort = 0;
}
}
}
Short=ExRem(Short,Cover);
Cover=ExRem(Cover,Short);
PlotShapes(shapeDownArrow*Short,colorRed,0,L, -30);
PlotShapes(shapeUpArrow*Cover,colorBrightGreen,0,H, -30);
_SECTION_END();
Hi art27,
I know little of how to code using AFL and particularly loops so I am probably way off the mark but is there a problem with this part of the code:-
Lowsinceshort = Min( Low[ i ], Lowsinceshort );
Given this statement "lowsinceshort =0;" when linked with the above code then the Min of Low and 0 will always be 0.
Cheers,
Rob
FirstProfitTarget = 10; // profit
SecondProfitTarget = 20; // in percent
TrailingStop = 10; // also in percent
priceatbuy=0;
highsincebuy = 0;
exit = 0;
for( i = 0; i < BarCount; i++ )
{
if( priceatbuy == 0 AND Buy[ i ] )
{
priceatbuy = BuyPrice[ i ];
}
if( priceatbuy > 0 )
{
highsincebuy = Max( High[ i ], highsincebuy );
if( exit == 0 AND
High[ i ] >= ( 1 + FirstProfitTarget * 0.01 ) * priceatbuy )
{
// first profit target hit - scale-out
exit = 1;
Buy[ i ] = sigScaleOut;
}
if( exit == 1 AND
High[ i ] >= ( 1 + SecondProfitTarget * 0.01 ) * priceatbuy )
{
// second profit target hit - exit
exit = 2;
SellPrice[ i ] = Max( Open[ i ], ( 1 + SecondProfitTarget * 0.01 ) * priceatbuy );
}
if( Low[ i ] <= ( 1 - TrailingStop * 0.01 ) * highsincebuy )
{
// trailing stop hit - exit
exit = 3;
SellPrice[ i ] = Min( Open[ i ], ( 1 - TrailingStop * 0.01 ) * highsincebuy );
}
if( exit >= 2 )
{
Buy[ i ] = 0;
Sell[ i ] = exit + 1; // mark appropriate exit code
exit = 0;
priceatbuy = 0; // reset price
highsincebuy = 0;
}
}
}
SetPositionSize( 50, spsPercentOfEquity );
SetPositionSize( 50, spsPercentOfPosition * ( Buy == sigScaleOut ) ); // scale out 50% of position
Hi Rob
Thanks for the help. I agree it seems wrong but Im not sure either. I copied it from this formula and reversed it. Ive been staring at it all day and I just cant work it out.
HTML:FirstProfitTarget = 10; // profit SecondProfitTarget = 20; // in percent TrailingStop = 10; // also in percent priceatbuy=0; highsincebuy = 0; exit = 0; for( i = 0; i < BarCount; i++ ) { if( priceatbuy == 0 AND Buy[ i ] ) { priceatbuy = BuyPrice[ i ]; } if( priceatbuy > 0 ) { highsincebuy = Max( High[ i ], highsincebuy ); if( exit == 0 AND High[ i ] >= ( 1 + FirstProfitTarget * 0.01 ) * priceatbuy ) { // first profit target hit - scale-out exit = 1; Buy[ i ] = sigScaleOut; } if( exit == 1 AND High[ i ] >= ( 1 + SecondProfitTarget * 0.01 ) * priceatbuy ) { // second profit target hit - exit exit = 2; SellPrice[ i ] = Max( Open[ i ], ( 1 + SecondProfitTarget * 0.01 ) * priceatbuy ); } if( Low[ i ] <= ( 1 - TrailingStop * 0.01 ) * highsincebuy ) { // trailing stop hit - exit exit = 3; SellPrice[ i ] = Min( Open[ i ], ( 1 - TrailingStop * 0.01 ) * highsincebuy ); } if( exit >= 2 ) { Buy[ i ] = 0; Sell[ i ] = exit + 1; // mark appropriate exit code exit = 0; priceatbuy = 0; // reset price highsincebuy = 0; } } } SetPositionSize( 50, spsPercentOfEquity ); SetPositionSize( 50, spsPercentOfPosition * ( Buy == sigScaleOut ) ); // scale out 50% of position
_SECTION_BEGIN("Price Chart");
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", IIf( C>O, colorDarkGreen, colorRed), styleNoTitle | styleBar| ParamStyle("Style") );
GraphXSpace = 10;
Plot(MA(Close,5),"5 Week SMA",colorViolet,styleDashed);
Plot(MA(Close,30),"30 Week SMA",colorLightBlue,styleThick);
_SECTION_END();
_SECTION_BEGIN("Short Targets");
// Sells 100% on a profit target
// Sells 100% of position if TRAILING STOP is hit
SetTradeDelays(0,0,0,0);
ShortPrice= Close;
CoverPrice= Close;
Short=Cross(MA(C,30),MA(C,5));
Cover=0;
ProfitTarget = 5;
TrailingStop =5;
priceatshort=0;
lowsinceshort =0; // highsincebuy=0; in original formula
exit = 0;
for( i = 0; i < BarCount; i++ )
{
if( priceatshort == 0 AND Short[ i ]==1 )
{
priceatshort = ShortPrice[ i ];
}
else
if( priceatshort > 0 )
{
Lowsinceshort = Min( Low[ i ], Lowsinceshort );
if( exit == 0 AND
Low[ i ] <= ( 1 - ProfitTarget * 0.01 ) * priceatshort )
{
exit = 1;
CoverPrice[ i ] = Min(Open[i],(1-Profittarget * 0.01) * priceatshort);
}
//If the open is below the target - Cover , Otherwise cover when the target is hit.
if( High[ i ] >= ( 1 + TrailingStop * 0.01 ) * lowsinceshort )
{
//Trailing stop hit - exit
exit = 2;
CoverPrice[ i ] = Max(Open [i],( 1 + TrailingStop * 0.01 ) * lowsinceshort ) ;
}
//If the open is above the trailing stop - Cover , Otherwise cover when the trailing stop is hit
if( exit >= 1 )
{
Short[ i ] = 0;
Cover[ i ] = exit + 1 ; // says mark appropriate exit code ( Not sure what this means )Exit next day at open?
exit = 0;
priceatshort = 0; // reset price
lowsinceshort = 0;
}
}
}
SetPositionSize( 100, spsPercentOfEquity );
Short=ExRem(Short,Cover);
Cover=ExRem(Cover,Short);
PlotShapes(shapeDownArrow*Short,colorRed,0,L, -30);
PlotShapes(shapeUpArrow*Cover,colorBrightGreen,0,H, -30);
for( i = 0; i < BarCount; i++ )
{
if( priceatshort == 0 AND Short[ i ]==1 )
{
priceatshort = ShortPrice[ i ];
Lowsinceshort= Low[i];
}
else
if( priceatshort > 0 )
{
Lowsinceshort = Min( Low[ i ], Lowsinceshort );
if( exit == 0 AND
Low[ i ] <= ( 1 - ProfitTarget * 0.01 ) * priceatshort )
{
Hi Howard
I didnt think that through very well did I! I think that using "degrees" is not going to work. Im trying to design a filter.
1. If the 52 week trend (linReg) is flat to slightly up - I have one set of conditions.
(Look at All Ords 1988 to 1993 and also now)
2. If the 52 week trend is Trending up - I have another set of conditions
Im not sure that this will work. I just thought I would give it a try but it has proven to be quite difficult. I have tried using the ROC.
ROCPeriod=("ROC Periods",52,10,100,1);
ROC(Close,RocPeriod)>10; //Up 10% per annum
This has had a positive effect on system results. Choosing a suitable ROC Period is the hard part.
Are their any other methods that I could consider? I liked the LinReg because its easy to view on a chart.
Colion - Thanks for the formula. Im more trying to define the strength of the trend so buying and selling above and below the line wont work. The formula was useful though. It has shown me what variables in the formula I need to refer to. Thanks
Hi I am trying to resolve a data issue with Amibroker and some pattern work off Howard Bandys work. Does anyone have a way (outside inbuilt Amibroker quote editor) to edit a stocks data. I have a large number of stocks with zero volume and O=C=H=L data scattered across the date ranges which kinda makes any form of pattern recognition a wee bit impossible.
Export the data without those O=C=H=L and V=0 quotes and re-import it
fmkdir( "C:\\#AB_Data" );
dn = DateNum();
Buy = !( C == O AND C == H AND C == L AND V == 0) /*AND dn >= 1070101 AND dn <= 1201231 */;
if(Status("action") == actionScan)
{
fh = fopen( "C:\\#AB_Data\\" + Name() + ".csv", "a");
if( fh )
{
y = Year();
m = Month();
d = Day();
r = Hour();
e = Minute();
s = Second();
for( i = 0; i < BarCount; i++ )
{
if( Buy[i] )
{
fputs( Name() + ",", fh ); // export ticker name
//ds = StrFormat( "%02.0f%02.0f%02.0f,", y[ i ], m[ i ], d[ i ] ); // yyyymmdd
//ds = StrFormat("%02.0f/%02.0f/%02.0f,", y[ i ], m[ i ], d[ i ] ); // yyyy/mm/dd
ds = StrFormat("%02.0f.%02.0f.%02.0f,", y[ i ], m[ i ], d[ i ] ); // yyyy.mm.dd
fputs( ds, fh );
//ts = StrFormat( "%02.0f:%02.0f:%02.0f,", r[ i ],e[ i ], s[i]); // hh:mm:ss
ts = StrFormat( "%02.0f:%02.0f,", r[ i ],e[ i ]); // hh:mm
fputs( ts, fh );
qs = StrFormat( "%.2f, %.2f, %.2f, %.2f, %.0f\n", O[ i ], H[ i ], L[ i ], C[ i ], V[ i ] ); // OHLCV and 2 decimal places
//qs = StrFormat( "%.3f, %.3f, %.3f, %.3f, %.0f\n", O[ i ], H[ i ], L[ i ], C[ i ], V[ i ] ); // OHLCV and 3 decimal places
//qs = StrFormat( "%.4f, %.4f, %.4f, %.4f, %.0f\n", O[ i ], H[ i ], L[ i ], C[ i ], V[ i ] ); // OHLCV and 4 decimal places
//qs = StrFormat( "%.5f, %.5f, %.5f, %.5f, %.0f\n", O[ i ], H[ i ], L[ i ], C[ i ], V[ i ] ); // OHLCV and 5 decimal places
fputs( qs, fh );
}
}
fclose( fh );
}
}
Code:fmkdir( "C:\\#AB_Data" ); dn = DateNum(); Buy = !( C == O AND C == H AND C == L AND V == 0) /*AND dn >= 1070101 AND dn <= 1201231 */; if(Status("action") == actionScan) { fh = fopen( "C:\\#AB_Data\\" + Name() + ".csv", "a"); if( fh ) { y = Year(); m = Month(); d = Day(); r = Hour(); e = Minute(); s = Second(); for( i = 0; i < BarCount; i++ ) { if( Buy[i] ) { fputs( Name() + ",", fh ); // export ticker name //ds = StrFormat( "%02.0f%02.0f%02.0f,", y[ i ], m[ i ], d[ i ] ); // yyyymmdd //ds = StrFormat("%02.0f/%02.0f/%02.0f,", y[ i ], m[ i ], d[ i ] ); // yyyy/mm/dd ds = StrFormat("%02.0f.%02.0f.%02.0f,", y[ i ], m[ i ], d[ i ] ); // yyyy.mm.dd fputs( ds, fh ); //ts = StrFormat( "%02.0f:%02.0f:%02.0f,", r[ i ],e[ i ], s[i]); // hh:mm:ss ts = StrFormat( "%02.0f:%02.0f,", r[ i ],e[ i ]); // hh:mm fputs( ts, fh ); qs = StrFormat( "%.2f, %.2f, %.2f, %.2f, %.0f\n", O[ i ], H[ i ], L[ i ], C[ i ], V[ i ] ); // OHLCV and 2 decimal places //qs = StrFormat( "%.3f, %.3f, %.3f, %.3f, %.0f\n", O[ i ], H[ i ], L[ i ], C[ i ], V[ i ] ); // OHLCV and 3 decimal places //qs = StrFormat( "%.4f, %.4f, %.4f, %.4f, %.0f\n", O[ i ], H[ i ], L[ i ], C[ i ], V[ i ] ); // OHLCV and 4 decimal places //qs = StrFormat( "%.5f, %.5f, %.5f, %.5f, %.0f\n", O[ i ], H[ i ], L[ i ], C[ i ], V[ i ] ); // OHLCV and 5 decimal places fputs( qs, fh ); } } fclose( fh ); } }
fmkdir( "C:\\#AB_Data" );
dn = DateNum();
Buy = !( C == O AND C == H AND C == L AND V == 0) /*AND dn >= 1070101 AND dn <= 1201231 */;
if(Status("action") == actionScan)
{
fh = fopen( "C:\\#AB_Data\\" + Name() + ".csv", "a");
//fh = fopen( "C:\\#AB_Data\\AllInOne.csv", "a");
if( fh )
{
y = Year();
m = Month();
d = Day();
r = Hour();
e = Minute();
s = Second();
for( i = 0; i < BarCount; i++ )
{
if( Buy[i] )
{
fputs( Name() + ",", fh ); // export ticker name
//ds = StrFormat( "%02.0f%02.0f%02.0f,", y[ i ], m[ i ], d[ i ] ); // yyyymmdd
//ds = StrFormat("%02.0f/%02.0f/%02.0f,", y[ i ], m[ i ], d[ i ] ); // yyyy/mm/dd
ds = StrFormat("%02.0f.%02.0f.%02.0f,", y[ i ], m[ i ], d[ i ] ); // yyyy.mm.dd
fputs( ds, fh );
//ts = StrFormat( "%02.0f:%02.0f:%02.0f,", r[ i ],e[ i ], s[i]); // hh:mm:ss
ts = StrFormat( "%02.0f:%02.0f,", r[ i ],e[ i ]); // hh:mm
fputs( ts, fh );
qs = StrFormat( "%.2f,%.2f,%.2f,%.2f,%.0f\n", O[ i ], H[ i ], L[ i ], C[ i ], V[ i ] ); // OHLCV and 2 decimal places
//qs = StrFormat( "%.3f,%.3f,%.3f,%.3f,%.0f\n", O[ i ], H[ i ], L[ i ], C[ i ], V[ i ] ); // OHLCV and 3 decimal places
//qs = StrFormat( "%.4f,%.4f,%.4f,%.4f,%.0f\n", O[ i ], H[ i ], L[ i ], C[ i ], V[ i ] ); // OHLCV and 4 decimal places
//qs = StrFormat( "%.5f,%.5f,%.5f,%.5f,%.0f\n", O[ i ], H[ i ], L[ i ], C[ i ], V[ i ] ); // OHLCV and 5 decimal places
fputs( qs, fh );
}
}
fclose( fh );
}
}
Results are better
Annual Return 18.71%
Max Sys DD 37%
61 Trade 3.77% Win
Exp 85.04%
XAO = Foreign("XSO","Close");
XAOMA = MA(XAO, 75);
function XAO_sell(drop)
{
global XAO;
global XAOMA;
global H;
global L;
XAO_exit = ExRem( XAO < XAOMA, XAO > XAOMA);
Last = HighestSince(XAO_exit, Ref(H, -1));
return (XAO < XAOMA AND L < drop * Last);
}
Buy=cond1 AND cond2 AND cond3 AND cond4 AND cond5 AND cond6
AND XAO > XAOMA;
// here we define variables used once in the trade
// removed and replaced by XAO_sell: ApplyStop( stopTypeLoss, stopModePercent, amount=10 );
Sell= Cross(Ref(EMA(L,180),-1),C) // close crosses below yesterdays average of the low
OR XAO_sell( 0.9 );
Still I wouldn't use this strategy since Jan 2011.
This is the one and only purpose of backtesting, to sharpen the hindsight. And 20/20 sight shows that TechTrader is only good in boom times, when everything roars, but produces pathetic results when market goes down or sideways. Since Jan 2011 there have been no signs of the new market bubble, so now there is no point in using TT from now onwards. This now remains constant now, was a year ago and will be in a year, until the new bubble. When every taxi driver and his dog start talking shares again (as in 2004-2008), then it will be the time to return to your love child, but no sooner.However you are clearly well versed in the use of the "hindsite indicator."
This is the one and only purpose of backtesting, to sharpen the hindsight. And 20/20 sight shows that TechTrader is only good in boom times, when everything roars, but produces pathetic results when market goes down or sideways. Since Jan 2011 there have been no signs of the new market bubble, so now there is no point in using TT from now onwards. This now remains constant now, was a year ago and will be in a year, until the new bubble. When every taxi driver and his dog start talking shares again (as in 2004-2008), then it will be the time to return to your love child, but no sooner.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?