Click on a month to see code for that issue of Active Trader:
September 2000
For "Pivotal Trading" by John Ehlers, starting on p. 54:
Vars: Pivot(0), S1(0), S2(0), R1(0), R2(0);
Pivot = (H[1] + L[1] + C[1]) / 3;
R1 = 2*Pivot - L[1];
S1 = 2*Pivot - H[1];
R2 = Pivot + (R1 - S1);
S2 = Pivot - (R1 - S1);
Plot1(R1, "R1");
Plot2(S1, "S1");
TradeStation (EasyLanguage) code for "Moving beyond the closing price" by Thomas Stridsman, starting on p. 60
Inputs: LookBack(20);
Variable: PercChange(0),
NewLevel(0),
AvgPercChange(0);
PercChange = (Close -
Close[1])/Close[1];
AvgPercChange =
Average(PercChange,20);
NewLevel = Close *
(1 + AvgPercChange);
Plot1[1](NewLevel,);
**
Inputs: StDevs(1);
Variable:StdDevChange(0),
UpLevel(0), DownLevel(0);
StdDevChange =
StdDev(PercChange, 20);
UpLevel = Close *
(1 + AvgPercChange +
StDevs * StdDevChange);
DownLevel = Close *
(1 + AvgPercChange -
StDevs * StdDevChange);
Plot2[-1](UpLevel,);
Plot3[-1](DownLevel,);
**
HighPercChange = (High - Close[1])/Close[1];
**
Input: VSStd(1);
Vars: SumVS(0), AvgVS(0), DiffVS(0), StdVS(0), SetArr(0),
SumArr(0), DiffArr(0), VSLow(0), VSMid(0), VSHigh(0);
{First we define the array}
Array: VS[20](0);
{Then we‰re using a loop function to fill it with the different price changes}
For SetArr = 0 To 4 Begin
VS[SetArr * 4 + 0] = (O[SetArr] - C[SetArr + 1]) / C[SetArr + 1];
VS[SetArr * 4 + 1] = (H[SetArr] - C[SetArr + 1]) / C[SetArr + 1];
VS[SetArr * 4 + 2] = (L[SetArr] - C[SetArr + 1]) / C[SetArr + 1];
VS[SetArr * 4 + 3] = (C[SetArr] - C[SetArr + 1]) / C[SetArr + 1];
End;
For SumArr = 0 To 19 Begin
If SumArr = 0 Then
SumVS = 0;
SumVS = SumVS + VS[SumArr];
If SumArr = 19 Then
{Here we calculate the average price change over the period}
AvgVS = SumVS / 20;
For DiffArr = 0 To 19 Begin
If DiffArr = 0 Then
DiffVS = 0;
{Then we calculate the standard deviation}
DiffVS = DiffVS + Square(VS[DiffArr] - AvgVS);
If DiffArr = 19 Then
StdVS = SquareRoot(DiffVS / 20);
End;
End;
{Finally, we add the moving average (and the standard deviations) to the latest close for an indication of tomorrow‰s trading range}
VSLow = C * (1 + (AvgVS - StdVS * VSStd));
VSMid = C * (1 + AvgVS);
VSHigh = C * (1 + (AvgVS + StdVS * VSStd));
Plot1[-1](VSLow, ‹VS Low);
Plot2[-1](VSMid, ‹VS Mid);
Plot3[-1](VSHigh, ‹VS High);
For "Trading the momentum of market breadth" by Brown, starting on p. 40:
{Data1 = Either the SPY S&P 500 index tracking stock or the S&P 500 commodity futures contract.
Data2 = Advancing issues of the Nyse.}
Inputs: RL(7), BZ(3), SZ(1);
If ROC(Close Data2, RL) > BZ Then Buy;
If ROC(Close Data2, RL) < SZ Then Sell;
For "Doubly adaptive profit targets" by Chuck LeBeau, starting on p. 78:
Vars: TrendIndicator(0), RiskReward(0);
If ADX(14) > ADX(14)[1] Then
TrendIndicator = 4;
If ADX(14) <= ADX(14)[1] Then
TrendIndicator = 2;
Condition1 = MarketPosition = 0 and Close > Average(Close, 50) and Open
Tomorrow > High and TrendIndicator = 4;
If Condition1 Then Begin
Buy Tomorrow at High Limit;
RiskReward = AvgTrueRange(20);
End;
If MarketPosition = 1 Then Begin
ExitLong ("Profit") Tomorrow at (EntryPrice + RiskReward * TrendIndicator)
Limit;
ExitLong ("Loss") Tomorrow at (EntryPrice - RiskReward * TrendIndicator)
Stop;
If Close < Average(Close, 50) Then ExitLong ("Trend") at Market;
End;
For "Better System Performance measures" by Thomas Stridsman, p. 62:
Vars: TotTr(0), Prof(0), TradeStr2(""), CumProf(1), ETop(0), TradeStr2(""),CumProf(1), EBot(0), EDraw(0), TradeStr2("");
TotTr = TotalTrades;
If TotTr > TotTr[1] Then Begin
Prof = 1 + PositionProfit(1) / (EntryPrice(1) * BigPointValue);
CumProf = CumProf * Prof;
ETop = MaxList(ETop, CumProf);
EBot = MinList(EBot, CumProf);
EDraw = CumProf / ETop;
TradeStr2 = NumToStr((Prof - 1) * 100, 2) + "," + NumToStr((CumProf - 1) * 100, 2) + "," + NumToStr((ETop - 1) * 100, 2) + "," + NumToStr((EBot - 1) * 100, 2) + "," + NumToStr((EDraw - 1) * 100, 2) + NewLine;
{Make sure that you have a temp directory on your hard drive, or re-write the path inside the FileAppend command to an exsisting directory of your choice.}
FileAppend("C:TempChap1-2.csv", TradeStr2);
End;
TradeStation (EasyLanguage) for "Trading the VIX" by Price Headley, starting on p. 52:
Data1 is the OEX and Data2 is the VIX index.
{Code by Price Headley, BigTrends.com}
If Close of Data1 > Average(Close of Data1, 10) and Close of Data2[5] < BollingerBand(Close of Data2, 21, 2)[5] and Close of Data2[6] > BollingerBand(Close of Data2, 21, 2)[6] Then
Buy on Close of Data1;
If BarsSinceEntry = 5 and Close of Data1 < Close of Data1[5] Then
ExitLong on Close of Data1;
If Close of Data1 < Average(Close of Data1, 10) and Close of Data2[10] > BollingerBand(Close of Data2, 21, -2)[10] and Close of Data2[11] < BollingerBand(Close of Data2, 21, -2)[11] Then
Sell on Close of Data1;
If BarsSinceEntry = 5 and Close of Data1 > Close of Data1[5] Then
ExitShort on Close of Data1;
For "Avoiding system testing traps" by Thomas Stridsman, starting on p. 96:
Inputs: Len(63);
Vars: PointRange(0), SumPosRange(0), SumNegRange(0), AvgPosRange(0), AvgNegRange(0);
PointRange = High - Low;
If Close > Close[1] Then
SumPosRange = SumPosRange * (Len - 1) / Len + PointRange;
If Close < Close[1] Then
SumNegRange = SumNegRange * (Len - 1) / Len + PointRange;
AvgPosRange = SumPosRange / Len;
AvgNegRange = SumNegRange / Len;
{Plot statements to use in indicator only}
Plot1(AvgPosRange, "");
Plot2(AvgNegRange, "");
{Buy/sell statements to use in system only}
{This identifies the up trend}
If PosRange > NegRange and MarketPosition = 0 Then
Buy on O;
If PosRange < NegRange Then
ExitLong ("Down Trend") on Open;
{This identifies the down trend}
If NegRange > PosRange * 1.06 and NegRange >= NegRange[1] and PosRange < PosRange[1] and MarketPosition = 0 Then
Sell on O;
If NegRange < PosRange * 1.06 Then
ExitShort ("Up Trend") on O;
{This is the short-term trading rules within the up trend}
If BarsSinceEntry >=1 Then Begin
ExitLong ("Loss Long") tomorrow at EntryPrice - NegRange stop;
ExitLong ("Trail Long") tomorrow at Open tomorrow - NegRange stop;
ExitLong ("Profit Long 2") tomorrow at Open tomorrow + 3*PosRange limit;
ExitLong ("Profit Long 1") tomorrow at EntryPrice + 6*PosRange limit;
End;
{This is the short-term trading rules within the down trend}
If BarsSinceEntry >=1 Then Begin
ExitShort ("Loss Short") tomorrow at EntryPrice + PosRange stop;
ExitShort ("Trail Short") tomorrow at Open tomorrow + PosRange stop;
ExitShort ("Profit Short 2") tomorrow at Open tomorrow - 2*NegRange limit;
ExitShort ("Profit Short 1") tomorrow at EntryPrice - 4*NegRange limit;
End;
For "Measuring Trend Momentum" by Tushar Chande, starting on p. 62:
{Tushar Chande 2001: VIDYA/CDMA}
Input: Len(10);
Vars: Diff(0), MyConst(0), MyAdx(0), Varma(0), EmaIndex(0);
{… Index of EMA …}
If Len > 0 then EmaIndex = (2 / (1 + Len)) else EmaIndex = 0.20;
{… Stochastic oscillator using ADX …}
MyAdx = ADX(20);
Diff = Highest(MyAdx, 20) - Lowest(MyAdx, 20);
If Diff > 0 then MyConst = (MyAdx - Lowest(MyAdx, 20))/Diff else MyConst = EmaIndex;
{… Clamp length to that implied by input value of Len …}
If MyConst > EmaIndex then MyConst = EmaIndex;
{… Create the variable MA …}
If CurrentBar < 50 then Varma = Close else Varma = (1 - MyConst) * Varma[1] + MyConst * Close;
Plot1(Varma, "VarMA") ;
Plot2(XAverage(Close, Len), "XAvg"
Programming code for 3L-R and GAP-2H patternsfrom "Keeping it simple" by Michael Harris, starting on p. 82:
{*****************************************************
Description : 3L-R Pattern Entry Signal
Developed By : Michael Harris, Tradingpatterns.com
*****************************************************}
if l[1] < l[2] and l[2] < l[3] and h[0] > h[3] then
buy ("3L-R") next bar on the open;
{*****************************************************
Description : 3L-R Pattern Long Exit Signal
Developed By : Michael Harris, Tradingpatterns.com
Comments: ptarget and stopl are in percentage terms
*****************************************************}
variables: profitprice(0), stopprice(0);
input: ptarget(8), stopl(8);
profitprice = entryprice*(1+ptarget/100);
stopprice = entryprice*(1-stopl/100);
if marketposition =1 then begin
exitlong ("3L-R Exit") at profitprice limit;
exitlong ("3L-R Stop") at stopprice stop;
end;
**
{***********************************************
Description : GAP-2H Pattern Entry Signal
Developed By : Michael Harris, Tradingpatterns.com
***********************************************}
if h[0] > h[1] and h[2] > l[2] and l[0] > l[1] and l[1] > h[2] and
h[1] > l[0] then
buy ("GPA-2H") next bar on the open;
{***********************************************
Description : GAP-2H Pattern Long Exit Signal
Developed By : Michael Harris, Tradingpatterns.com
Comments: ptarget and stopl are in percentage terms
***********************************************}
variables: profitprice(0), stopprice(0);
input: ptarget(7), stopl(7);
profitprice = entryprice*(1+ptarget/100);
stopprice = entryprice*(1-stopl/100);
if marketposition =1 then begin
exitlong ("GAP-2H Exit") at profitprice limit;
exitlong ("GAP-2H Stop") at stopprice stop;
end;
For "True Strength Index (TSI)" by Thom Hartle, starting on p. 58:
TSI(close,r,s) = 100*EMA(EMA(mtm,r),s)/EMA(EMA(|mtm|,r),s)
where mtm = closetoday - closeyesterday
EMA(mtm,r) = exponential moving average of mtm with alpha = r
EMA(EMA(mtm,r),s) = exponential moving average of EMA(mtm,r) with alpha = s
|mtm| = absolute value of mtm
r = 25, s = 13
**
For MetaStock, use the Indicator Builder:
100*(Mov(Mov((CLOSE - Ref(CLOSE,-1)),25,E),13,E))/(Mov(Mov(Abs(CLOSE - Ref(CLOSE,-1)),25,E),13,E))
For CQGNet, you first create the momentum (MTM) value, then create the TSI indicator in the custom studies module:
Under the User Values tab create a new User Value "MTM" (Figure 2):
Close(@) - Close (@)[-1]
Next, under the Custom Studies tab create the new Custom Study TSI (Figure 3):
100*( MA(MA( V.mtm(@),Exp,25.000),Exp,13.000) )/( MA(MA( Abs( V.mtm(@)),Exp,25.000),Exp,13.000) )
For "Putting stops to the test" by Thomas Stridsman, p. 82:
{This code is for a ShowMe}
If High[1] < High[3] and Close[1] < Open[1] and Open < High[1] and High > High[1] Then
Plot1(High * 1.01, "");
If Low[1] > Low[3] and Close[1] > Open[1] and Open > Low[1] and Low < Low[1] Then
Plot2(Low * 0.99, "");
{End ShowMe}
{This code is for a signal}
Inputs: TestRuns(9), ExitLevels(0);
Variables: EntryTrigger(0), LongStopLoss(0), ShortStopLoss(0), ExitTrigger(0);
EntryTrigger = IntPortion(Random(2));
ExitTrigger = (ExitLevels / 5 + 0.2) / 100;
If EntryTrigger = 1 and MarketPosition = 0 Then Begin
If High < High[2] and Close < Open and Open Next Bar < High Then Begin
Buy Next Bar at High Stop;
LongStopLoss = 1 - ExitTrigger;
End;
If Low > Low[2] and Close > Open and Open Next Bar > Low Then Begin
Sell Next Bar at Low Stop;
ShortStopLoss = 1 + ExitTrigger;
End;
End;
If MarketPosition = 1 Then
ExitLong Next Bar at EntryPrice * LongStopLoss Stop;
If MarketPosition = -1 Then
ExitShort Next Bar at EntryPrice * ShortStopLoss Stop;
If BarsSinceEntry = 4 Then Begin
ExitLong Next Bar at Market;
ExitShort Next Bar at Market;
End;
Variables: NoTrades(0), MarPos(0), TrProfit(0), SumTrProfit(0), AvgTrade(0), TestString(""), FileString("");
NoTrades = TotalTrades;
MarPos = MarketPosition;
If NoTrades > NoTrades[1] Then Begin
If MarPos[1] = 1 Then
TrProfit = (ExitPrice(1) - EntryPrice(1)) * 100 / EntryPrice(1);
If MarPos[1] = -1 Then
TrProfit = (EntryPrice(1) - ExitPrice(1)) * 100 / EntryPrice(1);
SumTrProfit = SumTrProfit + TrProfit;
End;
If LastCalcDate = Date + 1 Then Begin
AvgTrade = SumTrProfit / NoTrades;
TestString = LeftStr (GetSymbolName, 5) + "," + NumToStr(TestRuns, 0) + "," + NumToStr(ExitTrigger*100, 2) + "," + NumToStr(AvgTrade, 2) + NewLine;
FileString = "D:TempStopTest-" + RightStr(NumToStr(CurrentDate, 0), 4) + ".csv";
FileAppend(FileString, TestString);
End;
{End Signal}
For "Balancing stop size and trade length" by Thomas Stridsman, p. 66:
Inputs: TestRuns(9), ExitLevels(0), BarsInTrade(0);
Variables: EntryTrigger(0), LongStopLoss(0), ShortStopLoss(0), ExitTrigger(0);
EntryTrigger = IntPortion(Random(2));
ExitTrigger = (ExitLevels / 5 + 0.2) / 100;
If EntryTrigger = 1 and MarketPosition = 0 Then Begin
If High < High[2] and Close < Open and Open Next Bar < High Then Begin
Buy Next Bar at High Stop;
LongStopLoss = 1 - ExitTrigger;
End;
If Low > Low[2] and Close > Open and Open Next Bar > Low Then Begin
Sell Next Bar at Low Stop;
ShortStopLoss = 1 + ExitTrigger;
End;
End;
If MarketPosition = 1 Then
ExitLong Next Bar at EntryPrice * LongStopLoss Stop;
If MarketPosition = -1 Then
ExitShort Next Bar at EntryPrice * ShortStopLoss Stop;
If BarsSinceEntry = BarsInTrade+1 Then Begin
ExitLong Next Bar at Market;
ExitShort Next Bar at Market;
End;
Variables: NoTrades(0), MarPos(0), TrProfit(0), SumTrProfit(0), AvgTrade(0), TestString(""), FileString("");
NoTrades = TotalTrades;
MarPos = MarketPosition;
If NoTrades > NoTrades[1] Then Begin
If MarPos[1] = 1 Then
TrProfit = (ExitPrice(1) - EntryPrice(1)) * 100 / EntryPrice(1);
If MarPos[1] = -1 Then
TrProfit = (EntryPrice(1) - ExitPrice(1)) * 100 / EntryPrice(1);
SumTrProfit = SumTrProfit + TrProfit;
End;
If LastCalcDate = Date + 1 Then Begin
AvgTrade = SumTrProfit / NoTrades;
TestString = LeftStr(GetSymbolName, 5) + "," + NumToStr(TestRuns, 0) + "," + NumToStr(ExitTrigger*100, 2) + "," +
NumToStr(BarsInTrade+1, 2) + "," + NumToStr(AvgTrade, 2) + NewLine;
FileString = "D:TempStopTest-" + RightStr(NumToStr(CurrentDate, 0), 4) + ".csv";
FileAppend(FileString, TestString);
End;
For "Looking for a target" by Thomas Stridsman, p. 84:
Inputs: BarsInTrade(0), ProfitExit(0), LossExit(0);
Variables: EntryTrigger(0), LongStop(0), ShortStop(0), LongTarget(0), ShortTarget(0), LimitExit(0), StopExit(0);
EntryTrigger = IntPortion(Random(2));
LimitExit = (ProfitExit / 2 + 0.5) / 100;
StopExit = (LossExit / 5 + 0.2) / 100;
If EntryTrigger = 1 and MarketPosition = 0 Then Begin
If High < High[2] and Close < Open and Open Next Bar < High Then Begin
Buy Next Bar at High Stop;
LongStop = 1 - StopExit;
LongTarget = 1 + LimitExit;
End;
If Low > Low[2] and Close > Open and Open Next Bar > Low Then Begin
Sell Next Bar at Low Stop;
ShortStop = 1 + StopExit;
ShortTarget = 1 - LimitExit;
End;
End;
If MarketPosition = 1 Then Begin
ExitLong Next Bar at EntryPrice * LongStop Stop;
ExitLong Next Bar at EntryPrice * LongTarget Limit;
End;
If MarketPosition = -1 Then Begin
ExitShort Next Bar at EntryPrice * ShortStop Stop;
ExitShort Next Bar at EntryPrice * ShortTarget Limit;
End;
If BarsSinceEntry = BarsInTrade+1 Then Begin
ExitLong Next Bar at Market;
ExitShort Next Bar at Market;
End;
Variables: NoTrades(0), MarPos(0), TrProfit(0), SumTrProfit(0), AvgTrade(0), TestString(""), FileString("");
NoTrades = TotalTrades;
MarPos = MarketPosition;
If NoTrades > NoTrades[1] Then Begin
If MarPos[1] = 1 Then
TrProfit = (ExitPrice(1) - EntryPrice(1)) * 100 / EntryPrice(1);
If MarPos[1] = -1 Then
TrProfit = (EntryPrice(1) - ExitPrice(1)) * 100 / EntryPrice(1);
SumTrProfit = SumTrProfit + TrProfit;
End;
If LastCalcDate = Date + 2 Then Begin
AvgTrade = SumTrProfit / NoTrades;
TestString = LeftStr(GetSymbolName, 5) + "," + NumToStr(BarsInTrade+1, 2) + "," + NumToStr(LimitExit*100, 2) + "," +
NumToStr(StopExit*100, 2) + "," + NumToStr(AvgTrade, 2) + NewLine;
FileString = "D:TempStopTest-" + RightStr(NumToStr(CurrentDate, 0), 4) + ".csv";
FileAppend(FileString, TestString);
End;
MetaStock formula for the StochRSI, p. 52:
(Sum(RSI(5)-LLV(RSI(5),3),3)/Sum(HHV(RSI(5),3)-LLV(RSI(5),3),3))*100
For "Simple but Effective" by Michael Harris, p. 64:
T-Bond C-6 PATTERN
MetaStock Code
{Long positions only, profit target = 1 point, stop-loss = 1 point, entry at the open of next day}
(Ref(c,-5)>Ref(c,-4)) and (Ref(c,-4)>Ref(c,-3)) and (Ref(c,-3)>Ref(c,-2)) and (Ref(c,-2)>Ref(c,0)) and Ref(c,0)>Ref(c,-1))
EasyLanguage Code (2000i)
input:targetpoints(0), stoppoints(0), multiplier(1);
variables: profitprice(0), stopprice(0);
If c[5]>c[4] and c[4]>c[3] and c[3]>c[2] and c[2]>c[0] and c[0]>c[1] then begin
Buy next bar on the open;
If marketposition = 0 then begin
exitlong next bar at open of tomorrow+ (targetpoints * multiplier) points limit;
exitlong next bar at open of tomorrow- (stoppoints * multiplier) points stop;
end;
end:
if marketposition = 1 then begin
profitprice = entryprice + (targetpoints * multiplier) points;
stopprice = entryprice - (stoppoints * multiplier) points;
exitlong at profitprice limit;
exitlong at stopprice stop:
end;
S&P 500 C-6 PATTERN
MetaStock Code
{Long positions only, profit target = 3%, stop-loss = 3% (of entry price), entry at the open of next day}
(Ref(c,0)>Ref(c,-2)) and (Ref(c,-2)>Ref(c,-1)) and (Ref(c,-1)>Ref(c,-3)) and (Ref(c,-3)>Ref(c,-4)) and Ref(c,-4)>Ref(c,-5))
EasyLanguage Code (2000i)
input:ptarget(0), stop1(0);
variables: profitprice(0), stopprice(0);
If c[0]>c[2] and c[2]>c[1] and c[1]>c[3] and c[3]>c[4] and c[4]>c[5] then begin
Buy next bar on the open;
If marketposition = 0 then begin
exitlong next bar at open of tomorrow * (1 + ptarget/100) limit;
exitlong next bar at open of tomorrow * (1 - stop1/100) stop;
end;
end:
if marketposition = 1 then begin
profitprice = entryprice * (1 + ptarget/100) points;
stopprice = entryprice * (1 - stop1/100) points;
exitlong at profitprice limit;
exitlong at stopprice stop:
end;
MSFT C-6 PATTERN
MetaStock Code
{Long positions only, profit target = 10%, stop-loss = 10% (of entry price), entry at the open of next day}
(Ref(c,-1)>Ref(c,0)) and (Ref(c,0)>Ref(c,-2)) and (Ref(c,-2)>Ref(c,-3)) and (Ref(c,-3)>Ref(c,-4)) and Ref(c,-4)>Ref(c,-5))
EasyLanguage Code (2000i)
input:ptarget(0), stop1(0);
variables: profitprice(0), stopprice(0);
If c[1]>c[0] and c[0]>c[2] and c[2]>c[3] and c[3]>c[4] and c[4]>c[5] then begin
Buy next bar on the open;
If marketposition = 0 then begin
exitlong next bar at open of tomorrow * (1 + ptarget/100) limit;
exitlong next bar at open of tomorrow * (1 - stop1/100) stop;
end;
end:
if marketposition = 1 then begin
profitprice = entryprice * (1 + ptarget/100) points;
stopprice = entryprice * (1 - stop1/100) points;
exitlong at profitprice limit;
exitlong at stopprice stop:
end;
For "Happy Trails" by Thomas Stridsman, p. 76
The EntryTrigger at the top of the code ensures that each signal will be traded at random so that every trading sequence will be unique. The bottom part of the code exports the necessary data for further analysis in Excel. Note: If you use the system in live trading, you need to get rid of the EntryTrigger variable.
Inputs: BarsInTrade(0), ProfitExit(0), LossExit(0);
Variables: EntryTrigger(0), LongStop(0), ShortStop(0), LongTarget(0), ShortTarget(0), LimitExit(0), StopExit(0), Top(0), Bottom(0);
EntryTrigger = IntPortion(Random(2));
LimitExit = (ProfitExit / 2 + 0.5) / 100;
StopExit = (LossExit / 5 + 0.2) / 100;
If EntryTrigger = 1 and MarketPosition = 0 Then Begin
If High < High[2] and Close < Open and Open Next Bar < High Then Begin
Buy Next Bar at High Stop;
Top = High;
LongStop = 1 - StopExit;
LongTarget = 1 + LimitExit;
End;
If Low > Low[2] and Close > Open and Open Next Bar > Low Then Begin
Sell Next Bar at Low Stop;
Bottom = Low;
ShortStop = 1 + StopExit;
ShortTarget = 1 - LimitExit;
End;
End;
If MarketPosition = 1 Then Begin
Top = MaxList(Top, High);
ExitLong Next Bar at Top * LongStop Stop;
ExitLong Next Bar at EntryPrice * LongTarget Limit;
End;
If MarketPosition = -1 Then Begin
Bottom = MinList(Bottom, Low);
ExitShort Next Bar at Bottom * ShortStop Stop;
ExitShort Next Bar at EntryPrice * ShortTarget Limit;
End;
If BarsSinceEntry = BarsInTrade+1 Then Begin
ExitLong Next Bar at Market;
ExitShort Next Bar at Market;
End;
Variables: NoTrades(0), MarPos(0), TrProfit(0), SumTrProfit(0), AvgTrade(0), TestString(""), FileString("");
NoTrades = TotalTrades;
MarPos = MarketPosition;
If NoTrades > NoTrades[1] Then Begin
If MarPos[1] = 1 Then
TrProfit = (ExitPrice(1) - EntryPrice(1)) * 100 / EntryPrice(1);
If MarPos[1] = -1 Then
TrProfit = (EntryPrice(1) - ExitPrice(1)) * 100 / EntryPrice(1);
SumTrProfit = SumTrProfit + TrProfit;
End;
If LastCalcDate = Date + 2 Then Begin
AvgTrade = SumTrProfit / NoTrades;
TestString = LeftStr(GetSymbolName, 5) + "," + NumToStr(BarsInTrade+1, 2) + "," + NumToStr(LimitExit*100, 2) + "," +
NumToStr(StopExit*100, 2) + "," + NumToStr(AvgTrade, 2) + NewLine;
FileString = "D:TempStopTest-" + RightStr(NumToStr(CurrentDate, 0), 4) + ".csv";
FileAppend(FileString, TestString);
End;
eSignal formula for the Chaikin Money Flow featured in "Fundamentally Technical Trading" by Thom Hartle, p. 48:
function preMain() {
setStudyTitle("Chaikin Money Flow");
setCursorLabelName("CMF");
// Default plot type is Line
setPlotType(PLOTTYPE_HISTOGRAM);
}
function main(nInputLength) {
// If the user did not provide an input length, set a default
if(nInputLength == null) {
nInputLength = 21;
}
// Get the last 21 bars of L, H, C, V data
var arClose = close(0, -21);
var arLow = low(0, -21);
var arHigh = high(0, -21);
var arVolume = volume(0, -21);
// Not enough data to process (yet).
if(arClose == null || arLow == null || arHigh == null || arVolume == null)
return;
var i;
var vSumVolume = 0;
var vSum = 0;
// Sum up the values
for(i = 0; i < 21; i++) {
vSum += (((arClose[i]-arLow[i])-(arHigh[i]-arClose[i]))/(arHigh[i]-arLow[i]))*arVolume[i];
vSumVolume += arVolume[i];
}
return vSum / vSumVolume;
}
For "The good, the bad and the volatility" by Thomas Stridsman, p. 56:
Variables: VQI(0), SumVQI(0);
If TrueRange <> 0 and (High - Low) <> 0 Then
VQI = ((Close - Close[1]) / TrueRange + (Close - Open) / (High - Low)) * 0.5
Else
VQI=VQI[1];
VQI = AbsValue(VQI) * ((Close - Close[1] + (Close - Open)) * 0.5);
SumVQI = SumVQI + VQI;
Plot1(SumVQI,"");
Plot2(Average(SumVQI,9),"");
Plot3(Average(SumVQI,200),"");
For "QQQ system" by Michael Harris, p. 70:
Metastock code:
{LONG, %, TARGET: 7.0, STOP: 7.0, ENTRY AT: OPEN}
(Ref(h,-3)> Ref(h,-2)) and (Ref(h,-2) > Ref(l,-3)) and (Ref(l,-3) > Ref(h,-1)) and (Ref(h,-1) > Ref(l,-2)) and (Ref(l,-2) > Ref(h,0)) and (Ref(h,0) > Ref(l,-1)) and (Ref(l,-1) > Ref(l,0))
TradeStation code:
input: ptarget(0), stop(0);
variables: profitprice(0); stopprice(0);
If h[3] > h[2] and h[2] > l[3] and l[3] > h[1] and h[1] > l[2] and l[2] > h[0] and h[0] > l[1] and l[1] > l[0] then begin
Buy Next Bar on the open;
If Marketposition = 0 then begin
exitlong next bar at 0 of tomorrow*1(1+ptarget/100) limit;
exitlong next bar at 0 of tomorrow*1(1-stop/100)stop;
end;
end;
if marketposition= 1 then begin
profitprice= entryprice * (1 + ptarget/100);
stopprice= entryprice * (1 - stop/100);
exitlong at profitprice limit;
exitlong at stopprice stop;
end;
For the Meander System in "Keeping track of the odds: The trader's equation" by Shirley, p. 84:
{Run with Stop loss at 250, shares = 500 and fees and slippage of .0225/share}
input: Mlt(2);
input: MaLength(45);
{{Compute the Standard Deviations of the movements relative to the open}}
Value1 = Stddev((High-open),5);
Value2 = Stddev((open - low),5);
{{Fade movements beyond Mlt standard deviations that are against the prevailing trend as defined by ma of length MaLength}}
If Marketposition = 0 then Begin
If (AverageFC(Close,MaLength) - AverageFC(Close[1],MaLength)) > 0 then begin
Buy ("LongScalp") next bar at open of next bar - (Value2*Mlt) limit;
Sell next bar at open of next bar + (Value1*Mlt) limit;
end;
If (AverageFC(Close,MaLength) - AverageFC(Close[1],MaLength)) < 0 then begin
Sell short ("ShortScalp") next bar at open of next bar + (Value1*Mlt) limit;
buy to cover ("Cover#1") next bar at open of next bar - (Value2*Mlt) limit;
end;
end;
If Marketposition = 1 then
Sell next bar at open of next bar + (Value1*Mlt) limit;
If Marketposition = -1 then
buy to cover next bar at open of next bar - (Value2 * Mlt) limit;
Amibroker code for the True Strength Index (TSI) mentioned in "In phase with the market" by Dudella, p. 52:
u=3;
r=5;
s=8;
x=100*EMA(EMA(ROC(C,u),r),s)/EMA(EMA(abs(ROC(C,u)),r),s);
Plot(x,"TSI",IIf(x>Ref(x,-1),colorGreen,colorRed),styleHistogram);
Plot(MA(x,5),"MA of TSI",colorYellow,1);
MetaStock code for "Give your system a KISS" by Mark Seleznov, p. 38.
Enter long C>(Ref(HHV(H,1),-1)*(1.005))
Close long C<(Ref(LLV(L,1),-1)*(1.005))
Enter short C<(Ref(LLV(L,1),-1)*(1.005))
Close short C>(Ref(HHV(H,1),-1)*(1.005))
Initial equity: N/A
Positions: Long and short
Entry trade price: Close
Entry trade delay: 0
Exit trade price: Close
Exit trade delay: 0
Entry commission: 0 points
Exit commission: 0 points
Interest rate: N/A
Margin req: N/A
Code for the StochRSI
Value1 = RSI( Close, 5 );
Value2 = Lowest( Value1, 3 ) ;
Value3 = Highest( Value1, 3 ) ;
Plot1( ( Summation( Value1 - Value 2, 3 ) / Summation( Value3 - Value2, 3 ) ) * 100 );
TradeStation code for "One Step at a Time" by Bodri, p. 66:
Basic channel breakout:
Buy at Highest (H, ChLen) stop;
Sell at Lowest (L, ChLen) stop:
Filter:
If C
If C>C[1] then Sell at Lowest(L, ChLen) stop;
Advanced filter:
If C
For "Outside bars: Testing, 1-2-3" by Andrews, p. 42
The following is generic "code" that can be modified for a particular
software program:
Bullish outside reversal bar
high > high[1] and
low < low[1] and
(high - close)/(high - low) < .50 and
close > open and
close > close[2] and
10-day EMA < 10-day EMA[1] and
low < 10-day EMA
The definition is reversed (i.e., low replacing high, high replacing low,
"greater than" replacing "less than" and "less than" replacing "greater
than") for bearish outside reversal bars.
Tradestation (EasyLanguage) code for dymamic position-sizing version of intraday breakout system found in "Dynamic position sizing" by Dan Shirley, p. 78:
{Intraday breakout after McNutt}
Input: Size(100), DoLong(True), DoShort(True), Start1(1000), Stop1(1200), Start2(1345), Stop2(1600);
Input:BailLimit(350),FloorAmt(350);
Var:
ThreeUp(False),ThreeDown(False),TrueSize(100),TrueRisk(0),NotThreeDown(True),
NotFourUp(True),
AvPositionProfit(0),GapDown(False),Netvol(0);
{construct logicals}
ThreeDown = (CloseD(1) < CloseD(2)) and (CloseD(2) < CloseD(3)) and
(CloseD(3) < CloseD(4));
NotThreeDown = (CloseD(1) > CloseD(2)) or (CloseD(2) > CloseD(3)) or
CloseD(3) > CloseD(4));
NotFourUp = (CloseD(1) < CloseD(2)) or CloseD(2) < CloseD(3)) or
(CloseD(3) < CloseD(4)) or CloseD(4) < CloseD(5);
GapDown = OpenD(0) < LowD(1);
Condition3 = (Time > Start1 and Time < Stop1) or (Time > Start2 and Time < Stop2);
Condition4 = DailyWinners(Date) = 0 and DailyLosers(Date) = 0;
{NYSE up volume in data2 and NYSE down volume in data3}
netvol = close of data2 - close of data3;
TrueSize = Size;
{adjust risk}
If ((Threedown or GapDown or netvol > 100000) and MarketPosition = 1) or
(netvol < -100000 and marketposition = -1) then
TrueRisk = BailLimit*2
Else Begin
TrueRisk = BailLimit;
End;
{set entry stops}
If Condition3 and Condition4 and DoShort and NotThreeDown Then Begin
If NetVol < -100000 then Truesize = size*2;
Sell Short TrueSize shares Next Bar LowD(0) - .02 stop;
end;
If Condition3 and Condition4 and DoLong and NotFourUp Then begin
If Threedown or Gapdown or netvol > 100000 Then TrueSize = Size*2;
Buy TrueSize Shares Next Bar HighD(0) + .02 Stop;
End;
{Exit conditions => bail at break-even after floor is reached}
Condition5 = MaxPositionProfit > FloorAmt;
If Condition5 and MarketPosition = 1 and PositionProfit <=0 then Begin
If Threedown or Gapdown or netvol > 100000 then TrueSize = size*2;
Sell TrueSize shares next bar (High + Low)/2 Limit;
End
If Condition5 and Marketposition = -1 and PositionProfit <=0 Then Begin
If netvol < -100000 then truesize = size*2;
Buy to cover TrueSize shares next bar (High + Low)/2 limit;
End;
{Stop Loss}
setstopposition;
SetstopLoss(TrueRisk);
MetaStock code for BandWidth indicator used in "Setting up trades with Relative Bandwidth," p. 52:
BandWidth = (BBandTop(C,10,S,2)-BBandBot(C,10,S,2)/Mov(C,10,S)*100
MetaStock code for stochastic oscillator of the BandWidth indicator:
(Sum(Fml("BandWidth") - LLV(Fml
("BandWidth"),10),3)/Sum(HHV(Fml("BandWidth"),10)-
LLV(Fml("BandWidth"),10),3))*100; 20; 80
Spreadsheet for "Relative volume analysis" by Thom Hartle, p. 22:
TradeStation code for Gartley 222 pattern found in "Trading the Gartley 222" by Aaron Behle and Mark Conway, p. 38:
Inputs:
Length(100),
Strength(8),
Tolerance(0.10),
BullColor(Blue),
BearColor(Red);
Variables:
F1(0.618),
F2(0.786),
F3(1.27),
F4(1.618),
P1Bar(-1),
P2Bar(-1),
T1Bar(-1),
T2Bar(-1),
P1(0.0),
P2(0.0),
T1(0.0),
T2(0.0),
PTValid(False),
HLValid(False),
InZone(False),
GD(0.0),
XA(0.0),
AB(0.0),
BC(0.0),
CD(0.0),
AD(0.0),
C1(False),
C2(False),
C3(False),
C4(False),
ABdXA(0.0),
BCdAB(0.0),
CDdBC(0.0),
ADdXA(0.0),
TL1(-1),
TL2(-1),
TL3(-1),
TL4(-1),
TL5(-1),
TL6(-1);
P1Bar = SwingHighBar(1, High, Strength, Length);
P2Bar = SwingHighBar(2, High, Strength, Length);
T1Bar = SwingLowBar(1, Low, Strength, Length);
T2Bar = SwingLowBar(2, Low, Strength, Length);
If P1Bar <> -1 and
P2Bar <> -1 and
T1Bar <> -1 and
T2Bar <> -1 Then Begin
{Test for a bullish 222}
{Trough X is T2}
T2 = Low[T2Bar];
{Peak A is P2}
P2 = High[P2Bar];
{Trough B is T1}
T1 = Low[T1Bar];
{Peak C is P1}
P1 = High[P1Bar];
{D is the buy point}
GD = Low;
PTValid = P1Bar < T1Bar and T1Bar < P2Bar and P2Bar < T2Bar;
HLValid = P1 < P2 and T1 > T2 and P1 > T1;
InZone = GD < T1 and GD > T2 and P2 >= Highest(High, T2Bar);
If PTValid and HLValid and InZone Then Begin
XA = P2 - T2;
AB = P2 - T1;
BC = P1 - T1;
CD = P1 - GD;
AD = P2 - GD;
ABdXA = AB / XA; {AB should be 61.8% of XA}
C1 = ABdXA > F1 - Tolerance and ABdXA < F1 + Tolerance;
BCdAB = BC / AB; {BC should be 61.8-78.6% of AB}
C2 = BCdAB > F1 - Tolerance and BCdAB < F2 + Tolerance;
CDdBC = CD / BC; {CD should be 127-161.8% of BC}
C3 = CDdBC > F3 - Tolerance and CDdBC < F4 + Tolerance;
ADdXA = AD / XA; {AD should be 78.6% of XA}
C4 = ADdXA > F2 - Tolerance and ADdXA < F2 + Tolerance;
If C1 and C2 and C3 and C4 Then Begin
TL1 = TL_New(Date[T2Bar], Time[T2Bar], T2, Date[P2Bar], Time[P2Bar], P2);
If TL1 >= 0 Then Begin
TL_SetColor(TL1, BullColor);
TL_SetStyle(TL1, Tool_Solid);
TL_SetSize(TL1, 2);
End;
TL2 = TL_New(Date[P2Bar], Time[P2Bar], P2, Date[T1Bar], Time[T1Bar], T1);
If TL2 >= 0 Then Begin
TL_SetColor(TL2, BullColor);
TL_SetStyle(TL2, Tool_Solid);
TL_SetSize(TL2, 2);
End;
TL3 = TL_New(Date[T1Bar], Time[T1Bar], T1, Date[P1Bar], Time[P1Bar], P1);
If TL3 >= 0 Then Begin
TL_SetColor(TL3, BullColor);
TL_SetStyle(TL3, Tool_Solid);
TL_SetSize(TL3, 2);
End;
TL4 = TL_New(Date[P1Bar], Time[P1Bar], P1, Date, Time, GD);
If TL4 >= 0 Then Begin
TL_SetColor(TL4, BullColor);
TL_SetStyle(TL4, Tool_Solid);
TL_SetSize(TL4, 2);
End;
TL5 = TL_New(Date[T1Bar], Time[T1Bar], T1, Date, Time, GD);
If TL5 >= 0 Then Begin
TL_SetColor(TL5, BullColor);
TL_SetStyle(TL5, Tool_Dotted);
End;
TL6 = TL_New(Date[T2Bar], Time[T2Bar], T2, Date, Time, GD);
If TL6 >= 0 Then Begin
TL_SetColor(TL6, BullColor);
TL_SetStyle(TL6, Tool_Dotted);
End;
End;
End;
{Test for a bearish 222}
{Peak X is P2}
{Trough A is T2}
{Peak B is P1}
{Trough C is T1}
{GD is the short point}
GD = High;
PTValid = T1Bar < P1Bar and P1Bar < T2Bar and T2Bar < P2Bar;
HLValid = T1 > T2 and P1 < P2 and T1 < P1;
InZone = GD > P1 and GD < P2 and T2 <= Lowest(Low, P2Bar);
If PTValid and HLValid and InZone Then Begin
XA = P2 - T2;
AB = P1 - T2;
BC = P1 - T1;
CD = GD - T1;
AD = GD - T2;
ABdXA = AB / XA; {AB should be 61.8% of XA}
C1 = ABdXA > F1 - Tolerance and ABdXA < F1 + Tolerance;
BCdAB = BC / AB; {BC should be 61.8-78.6% of AB}
C2 = BCdAB > F1 - Tolerance and BCdAB < F2 + Tolerance;
CDdBC = CD / BC; {CD should be 127-161.8% of BC}
C3 = CDdBC > F3 - Tolerance and CDdBC < F4 + Tolerance;
ADdXA = AD / XA; {AD should be 78.6% of XA}
C4 = ADdXA > F2 - Tolerance and ADdXA < F2 + Tolerance;
If C1 and C2 and C3 and C4 Then Begin
TL1 = TL_New(Date[P2Bar], Time[P2Bar], P2, Date[T2Bar], Time[T2Bar], T2);
If TL1 >= 0 Then Begin
TL_SetColor(TL1, BearColor);
TL_SetStyle(TL1, Tool_Solid);
TL_SetSize(TL1, 2);
End;
TL2 = TL_New(Date[T2Bar], Time[T2Bar], T2, Date[P1Bar], Time[P1Bar], P1);
If TL2 >= 0 Then Begin
TL_SetColor(TL2, BearColor);
TL_SetStyle(TL2, Tool_Solid);
TL_SetSize(TL2, 2);
End;
TL3 = TL_New(Date[P1Bar], Time[P1Bar], P1, Date[T1Bar], Time[T1Bar], T1);
If TL3 >= 0 Then Begin
TL_SetColor(TL3, BearColor);
TL_SetStyle(TL3, Tool_Solid);
TL_SetSize(TL3, 2);
End;
TL4 = TL_New(Date[T1Bar], Time[T1Bar], T1, Date, Time, GD);
If TL4 >= 0 Then Begin
TL_SetColor(TL4, BearColor);
TL_SetStyle(TL4, Tool_Solid);
TL_SetSize(TL4, 2);
End;
TL5 = TL_New(Date[P1Bar], Time[P1Bar], P1, Date, Time, GD);
If TL5 >= 0 Then Begin
TL_SetColor(TL5, BearColor);
TL_SetStyle(TL5, Tool_Dotted);
End;
TL6 = TL_New(Date[P2Bar], Time[P2Bar], P2, Date, Time, GD);
If TL6 >= 0 Then Begin
TL_SetColor(TL6, BearColor);
TL_SetStyle(TL6, Tool_Dotted);
End;
End;
End;
End;
Wealth-Lab code:
procedure Gartley222
(
VPFactor: float;
Tolerance: float;
Lookback: integer;
HoldBars: integer;
VolMin: integer
);
begin
var ATRValue, VP, Reversal: float;
var F1, F2, F3, F4, P1, P2, T1, T2: float;
var Bar, P1Bar, P2Bar, T1Bar, T2Bar, p: integer;
var XA, AB, BC, CD, AD, D, XD, DT, ABdXA, BCdAB, CDdBC, ADdXA: float;
var PTValid, HLValid, InZone, C1, C2, C3, C4: boolean;
var BT, BS, ST, SS: float;
{Fibonacci Constants}
F1 := 0.618;
F2 := 0.786;
F3 := 1.27;
F4 := 1.618;
InstallTimeBasedExit(HoldBars);
for Bar := Lookback to BarCount() - 1 do
begin
ApplyAutoStops(Bar);
ATRValue := ATR(Bar, Lookback);
SetShareSize( 1000 * Int( 10 / ATRValue ) );
VP := 100 * ATRValue / PriceClose(Bar);
{Find peaks and troughs}
Reversal := Int(VPFactor * VP);
P1 := Peak(Bar, #High, F1 * Reversal);
P1Bar := PeakBar(Bar, #High, F1 * Reversal);
P2 := Peak(P1Bar, #High, Reversal);
P2Bar := PeakBar(P1Bar, #High, Reversal);
T1 := Trough(Bar, #Low, F1 * Reversal);
T1Bar := TroughBar(Bar, #Low, F1 * Reversal);
T2 := Trough(T1Bar, #Low, Reversal);
T2Bar := TroughBar(T1Bar, #Low, Reversal);
{Test for a bullish 222}
{Trough X is T2}
{Peak A is P2}
{Trough B is T1}
{Peak C is P1}
{D is the buy zone}
D := PriceLow(Bar);
PTValid := (P1Bar > T1Bar) and (T1Bar > P2Bar) and (P2Bar > T2Bar);
HLValid := (P1 < P2) and (T1 > T2) and (P1 > T1);
InZone := (D < T1) and (D > T2);
if (MarketPosition = 0) and
(SMA(Bar, #Volume, Lookback) >= VolMin) and
(PTValid) and (HLValid) and (InZone) then
begin
XA := P2 - T2;
AB := P2 - T1;
BC := P1 - T1;
XD := P2 - (F2 * XA);
CD := P1 - XD;
AD := P2 - XD;
ABdXA := AB / XA; {AB should be 61.8% of XA}
C1 := (ABdXA > F1 - Tolerance) and (ABdXA < F1 + Tolerance);
BCdAB := BC / AB; {BC should be 61.8-78.6% of AB}
C2 := (BCdAB > F1 - Tolerance) and (BCdAB < F2 + Tolerance);
CDdBC := CD / BC; {CD should be 127-161.8% of BC}
C3 := (CDdBC > F3 - Tolerance) and (CDdBC < F4 + Tolerance);
ADdXA := AD / XA; {AD should be 78.6% of XA}
C4 := (ADdXA > F2 - Tolerance) and (ADdXA < F2 + Tolerance);
if C1 and C2 and C3 and C4 then
begin
DrawLine(P2Bar, P2, T2Bar, T2, 0, #Blue, #Solid);
DrawLine(T1Bar, T1, P2Bar, P2, 0, #Blue, #Solid);
DrawLine(P1Bar, P1, T1Bar, T1, 0, #Blue, #Solid);
DrawLine(Bar, D, P1Bar, P1, 0, #Blue, #Solid);
DrawLine(Bar, D, T1Bar, T1, 0, #Blue, #Dotted);
DrawLine(Bar, D, T2Bar, T2, 0, #Blue, #Dotted);
AnnotateBar('B', Bar, True, #Blue, 10);
BuyAtLimit(Bar, XD, 'G222 LE');
DT := F1 * CD;
BT := XD + DT;
BS := T2;
end;
end;
{Test for a bearish 222}
{Peak X is P2}
{Trough A is T2}
{Peak B is P1}
{Trough C is T1}
{D is the short zone}
D := PriceHigh(Bar);
PTValid := (T1Bar > P1Bar) and (P1Bar > T2Bar) and (T2Bar > P2Bar);
HLValid := (T1 > T2) and (P1 < P2) and (T1 < P1);
InZone := (D > P1) and (D < P2);
if (MarketPosition = 0) and
(PriceClose( Bar ) >= 5) and
(SMA(Bar, #Volume, Lookback) >= VolMin) and
(PTValid) and (HLValid) and (InZone) then
begin
XA := P2 - T2;
AB := P1 - T2;
BC := P1 - T1;
XD := T2 + (F2 * XA);
CD := XD - T1;
AD := XD - T2;
ABdXA := AB / XA; {AB should be 61.8% of XA}
C1 := (ABdXA > F1 - Tolerance) and (ABdXA < F1 + Tolerance);
BCdAB := BC / AB; {BC should be 61.8-78.6% of AB}
C2 := (BCdAB > F1 - Tolerance) and (BCdAB < F2 + Tolerance);
CDdBC := CD / BC; {CD should be 127-161.8% of BC}
C3 := (CDdBC > F3 - Tolerance) and (CDdBC < F4 + Tolerance);
ADdXA := AD / XA; {AD should be 78.6% of XA}
C4 := (ADdXA > F2 - Tolerance) and (ADdXA < F2 + Tolerance);
if C1 and C2 and C3 and C4 then
begin
DrawLine(T2Bar, T2, P2Bar, P2, 0, #Red, #Solid);
DrawLine(P1Bar, P1, T2Bar, T2, 0, #Red, #Solid);
DrawLine(T1Bar, T1, P1Bar, P1, 0, #Red, #Solid);
DrawLine(Bar, D, T1Bar, T1, 0, #Red, #Solid);
DrawLine(Bar, D, P1Bar, P1, 0, #Red, #Dotted);
DrawLine(Bar, D, P2Bar, P2, 0, #Red, #Dotted);
AnnotateBar('S', Bar, False, #Red, 10);
ShortAtLimit(Bar, XD, 'G222 SE');
DT := F1 * CD;
ST := XD - DT;
SS := P2;
end;
end;
if LastPositionActive then
begin
if MarketPosition = 1 then begin
SellAtLimit(Bar+1, BT, #All, 'G222 LX+');
SellAtStop(Bar+1, BS, #All, 'G222 LX-');
end;
if MarketPosition = -1 then begin
CoverAtLimit(Bar+1, ST, #All, 'G222 LX+');
CoverAtStop(Bar+1, SS, #All, 'G222 LX-');
end;
end;
end;
end;
Gartley222(2.0, 0.1, 20, 7, 2000000);
TradeStation code for S&P breakout system used in "George Pruitt: The trend is still a friend" by Mark Etzkorn, p. 64:
For "Rounding out a trading strategy" by Andrews and Mark Etzkorn, p. 58:
Modified outside bar rule:
high > high[1] and low < low[1] and
(high - close)/(high - low) < .50 and
close > open and
close > close[2] and
close > 20-day moving average and
(high[1] > 20-day moving average[1] or
high[2] > 20-day moving average[2])
Invert the rules for bearish outside bars and short trades.
MetaStock Code:
These formulas can be used in an Indicator builder, expert advisor or
system tester.
Modified outside bar rule
Bullish (BUY) :
BCD:=H>Ref(H,-1) AND L<.5="">O AND
C>Ref(C,-2)
AND C>Mov(C,20,S) AND (Ref(H,-1)>Ref(Mov(C,20,S),-1) OR Ref(H,-2)
>Ref(Mov(C,20,S),-2));
SCD:=HRef(L,-1) AND (H-C)/(H-L)>.5 AND C
C
AND C
BCD AND BarsSince(Ref(BCD,-1))>BarsSince(Ref(SCD,-1))
Bearish (SELL) :
BCD:=H>Ref(H,-1) AND L<.5="">O AND
C>Ref(C,-2)
AND C>Mov(C,20,S) AND (Ref(H,-1)>Ref(Mov(C,20,S),-1) OR Ref(H,-2)
>Ref(Mov(C,20,S),-2));
SCD:=HRef(L,-1) AND (H-C)/(H-L)>.5 AND C
C
AND C
Ref(H,-2)
SCD AND BarsSince(Ref(BCD,-1))
MetaStock code for "Put/Call VXO indicator (PCVXO)" by Jay Kaeppel, p. 28:
Depending on your data vendor, the ticker symbols for the put/call ratio
and the VXO will be different. This formula assumes the ticker symbols
are $PCR and $VXO, respectively. The below formulas also assume the
data is stored locally in the folder c:metastock dataindex. If either the ticker symbols or the data path is different, your will need to
change the appropriate values in the first two lines.
s1:=security("c:metastock dataindex$PCR",C);
s2:=security("c:metastock dataindex$VXO",C);
r1:= mov(s1,10,s)/mov(s1,65,s);
r2:= mov(s2,10,s)/mov(s2,65,s);
100*((r1+r2)/2)
AmiBroker code:
Replace ^VXO and ^PCR below with your data vendor symbols for VXO and CBOE put/call ratio
Vxo = Foreign("^VXO", "C" );
Pcr = Foreign("^PCR", "C" );
VxoRatio = MA( Vxo, 10 ) / MA( Vxo, 65 );
PcrRatio = MA( Pcr, 10 ) / MA( Pcr, 65 );
PCVXO = 100*(VxoRadio + PcrRatio)/2;
Plot( PCVXO, "Put/Call VXO indicator", colorRed );
TradeStation code for the "CCI-stochastic indicator (CCI-STO)" by Star, p. 52:
*Code courtesy of Mark Mills
{Average(3,(Today's 14-day CCI reading - Lowest 14-day CCI reading (over the past 5 periods)/Highest 14-day
CCI reading (over the past 5 periods) - Lowest 14-day CCI reading (over the past 5 periods))*100)
CCI-Stochastic}
inputs:
CCILength( 14 ),
HighLowPeriod( 5 ),
Smooth( 3 ) ;
variables:
TodayCCI( 0 ),
TodayLowCCI( 0 ),
TodayHighCCI( 0 ),
CCISto( 0 ) ;
TodayCCI = CCI( CCILength ) ;
TodayLowCCI = Lowest( TodayCCI, HighLowPeriod ) ;
TodayHighCCI = Highest( TodayCCI, HighLowPeriod ) ;
if CurrentBar > Smooth + HighLowPeriod then
begin
CCISto = Average((TodayCCI - TodayLowCCI)/(TodayHighCCI - TodayLowCCI), Smooth );
Plot1( CCISto, "CCISto");
end ;
AmiBroker code:
function CCISTO( perCCI, perSTO, perMA )
{
vCCI = CCI( perCCI );
Cs = 100 * ( vCCI - LLV( vCCI, perSTO ) )/
( HHV( VCCI, perSTO ) - LLV( VCCI, perSTO ) );
return MA( Cs, perMA );
}
Plot( CCISTO( 14, 5, 3 ), "CCISTO", colorRed );
Metastock code:
(Sum(CCI(14)-LLV(CCI(14),5),3)/
Sum(HHV(CCI(14),5)-LLV(CCI(14),5),3))*100
eSignal code:
function preMain() {
setStudyTitle("Stochastic of CCI");
setCursorLabelName("SoCCI %K", 0);
setCursorLabelName("SoCCI %D", 1);
setDefaultBarFgColor(Color.blue, 0);
setDefaultBarFgColor(Color.red, 1);
setStudyMax(110);
setStudyMin(-5);
// Study Parameters
var sp1 = new FunctionParameter("nCCILength", FunctionParameter.NUMBER);
sp1.setLowerLimit(1);
sp1.setDefault(14); //Edit this value to set a new default
var sp2 = new FunctionParameter("nCCISource", FunctionParameter.STRING);
sp2.setName("CCISource");
sp2.addOption("Close");
sp2.addOption("High");
sp2.addOption("Low");
sp2.addOption("Open");
sp2.addOption("HL/2");
sp2.addOption("HLC/3");
sp2.addOption("OHLC/4");
sp2.setDefault("Close"); //Edit this value to set a new default
var sp4 = new FunctionParameter("nKlength2", FunctionParameter.NUMBER);
sp4.setName("Stoch2 %K Length");
sp4.setLowerLimit(1);
sp4.setDefault(14);
var sp5 = new FunctionParameter("nKsmooth2", FunctionParameter.NUMBER);
sp5.setName("Stoch2 %K Smoothing");
sp5.setLowerLimit(1);
sp5.setDefault(1);
var sp6 = new FunctionParameter("nDlength2", FunctionParameter.NUMBER);
sp6.setName("Stoch2 %D Length");
sp6.setLowerLimit(1);
sp6.setDefault(3);
// Formula Parameters
var fp1 = new FunctionParameter("nBand1", FunctionParameter.NUMBER);
fp1.setName("Upper Band");
fp1.setDefault(80);
var fp2 = new FunctionParameter("nBand2", FunctionParameter.NUMBER);
fp2.setName("Lower Band");
fp2.setDefault(20);
var fp3 = new FunctionParameter("cBands", FunctionParameter.COLOR);
fp3.setName("Band's Color");
fp3.setDefault(Color.black);
var fp4 = new FunctionParameter("bBands", FunctionParameter.STRING);
fp4.setName("Display Bands");
fp4.addOption("True");
fp4.addOption("False");
fp4.setDefault("True");
}
var bEdit = true;
var study = null;
var vCCI = null;
var vK2 = null;
var vD2 = null;
var aCCI = null;
var aStochK2 = null;
function main(nCCILength, nCCISource, nKlength2, nKsmooth2, nDlength2, nBand1, nBand2, cBands, bBands) {
var nState = getBarState();
if (bEdit == true) {
addBand(nBand1, PS_SOLID, 1, cBands, "SoS Upper");
addBand(nBand2, PS_SOLID, 1, cBands, "SoS Lower");
if (bBands == "False") {
removeBand("SoS Upper");
removeBand("SoS Lower");
}
if (aCCI == null) aCCI = new Array((Math.round(nKlength2) + Math.round(nKsmooth2) -1));
if (aStochK2 == null) aStochK2 = new Array(Math.round(nDlength2));
bEdit = false;
}
if (nState == BARSTATE_NEWBAR) {
if (vCCI != null) {
aCCI.pop();
aCCI.unshift(vCCI);
}
if (vK2 != null) {
aStochK2.pop();
aStochK2.unshift(vK2);
}
}
if (study == null) study = new CCIStudy(Math.round(nCCILength), nCCISource);
if (study == null) return;
vCCI = study.getValue(CCIStudy.CCI);
if (vCCI == null) return;
aCCI[0] = vCCI;
if (aCCI[Math.round(nKlength2) - 1] == null) return;
vK2 = StochK2(Math.round(nKlength2), Math.round(nKsmooth2));
if (vK2 == null) return;
aStochK2[0] = vK2;
if (aStochK2[Math.round(nDlength2) - 1] == null) return;
vD2 = StochD2(Math.round(nDlength2));
if (vD2 == null) return;
return new Array(vK2, vD2);
}
/*********************/
/***** Functions *****/
/*********************/
function StochHH(nInputOffset, nInputLength) {
var nOffset = nInputOffset;
var nLength = nInputLength;
var hh = 0;
var i = 0;
for(i = 0; i < nLength; i++) {
if(i == 0) {
hh = aCCI[i+nOffset];
} else {
hh = Math.max(hh, aCCI[i+nOffset]);
}
}
return hh;
}
function StochLL(nInputOffset, nInputLength) {
var nOffset = nInputOffset;
var nLength = nInputLength;
var ll = 0;
var i = 0;
for(i = 0; i < nLength; i++) {
if(i == 0) {
ll = aCCI[i+nOffset];
} else {
ll = Math.min(ll, aCCI[i+nOffset]);
}
}
return ll;
}
function StochK2(inputLength, inputSmoothing) {
var percentK;
var StochK;
var ll, hh;
var sum = 0;
var i = 0;
var nOffset = 0;
var nDO;
var nLength = inputLength;
var nSmoothing = inputSmoothing;
for(i = 0; i < nSmoothing; i++) {
nDO = i + nOffset;
StochK = aCCI[nDO];
ll = StochLL(nDO, nLength);
if(ll == null) return null;
hh = StochHH(nDO, nLength);
if(hh == null) return null;
percentK = ((StochK - ll) / (hh - ll)) * 100;
sum += percentK;
}
sum /= nSmoothing;
return sum;
}
function StochD2(nInputLength) {
var sum = 0;
var i = 0;
for (i = 0; i < nInputLength; ++i) {
sum += aStochK2[i];
}
sum /= nInputLength;
return sum;
}
TradeStation code for the "Fibonacci Swing Filter" by G. Vetrivel, p. 32:
if l>=h[1] then Sell Short Next Bar at l-.05 stop;
if l
h[1]-(h[1]-l[1])*.236 -.05 stop;
if l
Bar at h[1]-(h[1]-l[1])*.382-.05 stop;
if l
Bar at h[1]-(h[1]-l[1])*.5-.05 stop;
if l
Bar at h[1]-(h[1]-l[1])*.618-.05 stop;
if l
Bar at h[1]-(h[1]-l[1])*.786-.05 stop;
if l
Bar at h[1]-(h[1]-l[1])*.875-.05 stop;
if l
stop;
if l<=l[1] then Sell Short Next Bar at l-.05 stop;
if h<=l[1] then Buy Next Bar at h+.05 stop;
if h>l[1] and h<=l[1]+(h[1]-l[1])*.236 then Buy Next Bar at
l[1]+(h[1]-l[1])*.236+.05 stop;
if h>l[1]+(h[1]-l[1])*.236 and h<=l[1]+(h[1]-l[1])*.382 then Buy Next Bar
at l[1]+(h[1]-l[1])*.382+.05 stop;
if h>l[1]+(h[1]-l[1])*.382 and h<=l[1]+(h[1]-l[1])*.5 then Buy Next Bar at
l[1]+(h[1]-l[1])*.5+.05 stop;
if h>l[1]+(h[1]-l[1])*.5 and h<=l[1]+(h[1]-l[1])*.618 then Buy Next Bar at
l[1]+(h[1]-l[1])*.618+.05 stop;
if h>l[1]+(h[1]-l[1])*.618 and h<=l[1]+(h[1]-l[1])*.786 then Buy Next Bar
at l[1]+(h[1]-l[1])*.786+.05 stop;
if h>l[1]+(h[1]-l[1])*.786 and h<=l[1]+(h[1]-l[1])*.875 then Buy Next Bar
at l[1]+(h[1]-l[1])*.875+.05 stop;
if h>l[1]+(h[1]-l[1])*.875 and h
TradeStation code for "Volume Price Confirmation indicator (VPCI)" by G. Vetrivel, p. 38:
{*******************************************************************
Description : This Indicator plots VPCI, Volume Price Confirmation indicator
Developed by: Buff Dormeier, CMT
Marketguru@gmail.com or (800) 552-0774
********************************************************************}
Inputs:len2(10),VolToday(true), BBLength(3), StandardDev(2),
UpColor(DarkGreen), DnColor(Red);
;
variables:
VPCI(0),len(0),volumevolitility(0),vadjuster(0),vspread(0),smoothVPCI(0);
len=len2*4;
VPCI= (bd.vwma(l,len,voltoday) -
average(l,len))*(((bd.vwma(l,len,voltoday))/average(l,len))) *
((bd.vwma(l,len2,voltoday))/average(l,len2))
* ((AVERAGE(V,len2)/ AVERAGE(V,len)));
smoothVPCI= bd.vwma(VPCI,len,voltoday);
volumevolitility= (average (volume,5)/average(volume,15))*standardDev;
vspread= average(l,len)-(bd.vwma(l,len,voltoday));
vadjuster= vspread + average(l,len);
Plot1 (VPCI, "T");
Plot2 (smoothVPCI,"ST");
Some TradeStation users will need additional code for the VWMA (Volume Weighted Moving Average):
Function returns a Volume Weighted SMA
// futures volume is always reported 1-day late
// therefore, this function has the ability to calculate a MA with an offset of 1
// Date last changed: January 30, 2000
Inputs: price(numericSeries), { data to be averaged; e.g. close }
length(numericSimple), { length of moving average }
volToday(trueFalse); { true = volume is available for today (e.g. stocks)
false = volume is NOT available for today (e.g. futures) }
Vars: beg(0), { days back to begin working with for average }
sumOfVol(0), { sum of volume }
vwPx(0), { volume weighted price }
vwMa(0), { volume weighted moving average }
counter(0); { counter }
{ initialize/reset first 4 variables }
if currentBar = 1 then begin
if volToday = true then
beg = 0
else if volToday = false then
beg = 1;
end;
sumOfVol = 0;
vwPx = 0;
vwMa = 0;
{ update sumOfVol variable on each bar }
for counter = beg to (length-1+beg) begin
sumOfVol = sumOfVol + volume[counter];
end;
{ update vwPx and vwMa variables on each bar }
for counter = beg to (length-1+beg) begin
if sumOfVol > 0 then
vwPx = price[counter] * volume[counter] / sumOfVol;
vwMa = vwMa + vwPx;
end;
TradeStation (EasyLanguage) code for "Extreme Open-Close Days" by Xavier Maria Raj, p. 34:
Initial system test:
VAR:X(0),Y(0),R(0); R=RANGE
IF C>H-((R/10)) AND O
IF C
IF X=1 THEN Buy Next Bar AT H+.05 STOP;
IF Y=1 THEN Sell Short Next Bar AT L-.05 STOP;
Sell This Bar AT C;
Buy to Cover This Bar AT C;
Revised system test:
VAR:X(0),Y(0),R(0); R=RANGE
IF C>H-((R/10)) AND O
IF C
IF X=1 THEN Buy Next Bar AT H+.05 STOP;
IF Y=1 THEN Sell Short Next Bar AT L-.05 STOP;
Sell This Bar AT C;
Buy to Cover This Bar AT C;
Sell Next Bar AT MEDIANPRICE-.05 STOP;
Buy to Cover Newxt Bar AT MEDIANPRICE +.05 STOP;
Sell AT ("P1") Next Bar H+10 LIMIT;
Buy to Cover AT ("P2") Next Bar L-10 LIMIT;
TradeStation code for "Aggressive Gap Trading" by Tsutae Kamada, p. 37:
Entry rule:
inputs: Length( 20 );
if close > close[1] and
close[1] > close[2] and
close[2] > close[3] and
low[2] > close[3] and
open[2] > close[3] and
open[2] > average(close,Length)
then buy ("buy") next bar on open;
Exit rule:
if currentbar>1 and low < low [1]
then sell ("sell") this bar at close;
TradeStation code for "E-Mini Morning Reversal and Afternoon Breakout Patterns " by Tsutae Kamada, p. 26:
[LegacyColorValue = true];
var:x(0);
if entriestoday(d)<1 then begin
if t>830 and t<930 then begin
if highd(0)>highd(1) then Sell Short Next Bar at
minlist(highd(1), l) stop;
if lowd(0)
h) stop;
end;
if t>=1300 and t<1430 then begin
Buy Next Bar and maxlist(h,highd(0)) stop;
Sell Short Next Bar at minlist(l,lowd(0)) stop;
end;
end;
Sell Next Bar at lowd(0) stop;
Buy to Cover Next Bar at highd(0) stop:
if t=1500 then begin
Sell This Bar at c;
Buy to Cover This Bar at c;
end;
Traders' Studio code for "System Testing Redundancy" by Thomas Stridsman, p. 32:
Sub ChicagoLong (Contracts As Integer)
Dim TradeCont As Integer
Dim MinMove As Double
Dim ATR As BarArray(50)
MinMove = GetActiveMinMove()
'Calculate recent historical volatility using True Range:
ATR = Average(TrueRange, LookBack, 0)
If Contracts = 0 Then
'Calculate contracts to trade as a function of a constant risk to $100,000 over the dollar value of the volatility:
TradeCont = 100000 / ATR * GetActivePointValue() / MinMove)
Else
TradeCont = Contracts
End If
Back to top
Traders' Studio code for "Medians on the Move" by Thomas Stridsman, p. 28:
Sub AtmMarch (LookBack, DaysInTrade As Integer, LossMult As Double)
'Copyright (C), 2005: Thomas Stridsman
'Created with Traders' Studio, Version 1.3.4
Dim MyArray As Array
Dim Counter, ArraySize, ArrayMidPoint As Integer
Dim MinMove, EP, HC As Double
Dim ATR, MyTypical As BarArray(50)
MinMove = GetActiveMinMove()
ATR = Average(TrueRange, LookBack, 0)
ArraySize = LookBack * 2
ReDim(MyArray, ArraySize)
For Counter = 0 To (LookBack - 1) Step 1
MyArray[Counter * 2 + 0] = Close[Counter]
MyArray[Counter * 2 + 1] = Close[Counter]
Next
NumSort(MyArray)
ArrayMidPoint = ArraySize / 2
MyTypical = (MyArray[ArrayMidPoint-1] + MyArray[ArrayMidPoint]) /2
'SUBSTITUTE WITH THIS TO RUN MA SYSTEM: MyTypical = Average(Close, LookBack)
If Close < MyTypical Then
Buy("Buy", 1, MyTypical + MinMove, Stop, Day)
End If
If MarketPosition = +1 Then
EP = GetEntryPrice(0)
HC = Highest(Close, BarsSinceEntry, 0)
ExitLong("XL-L", "Buy", 1, Max(EP, HC) - LossMult * ATR - MinMove, Stop, Day)
If BarsSinceEntry >= DaysInTrade Then
ExitLong("XL-T", "Buy", 1, 0, Market, Day)
End If
End If
End Sub
Back to top
Spreadsheet for Small-trader money management, by Thomas Stridsman, p. 32
Back to top
May 2006
TradeStation code for "Using the TICK to identify the intraday trend," by David Bean, p. 32:
{Data1 is @ES.D or any of the following: @ER2.D, @YM.D, @NQ.D, @EMD.D
Data2 is $TICK. Both Data1 and Data2 are 15 minute charts - a custom session should be built for @YM.D to trade between 8:30 am CST and 3:15 pm CST instead of starting at 7:20 am CST.
*there are 27, 15 minute bars in the trading day}
Inputs: R(5), L1(27);
If Time=945 and H of data2 > 750 and L of data2 > -350 Then Buy Next Bar at market;
If Time=945 and C of data2 > 500 and L of data2 > -350 Then Buy Next Bar at market;
If Time=945 and Open > LowD(1) - 2*Average(Range,27) and L of data2 < -350 and H of data2 < 750 Then Sell Short Next Bar at OpenD(0) Limit;
If Time=945 and Open > LowD(1) - 2*Average(Range,27) and C of data2 < -100 and H of data2 < 750 Then Sell Short Next Bar at OpenD(0) Limit;
If Time=945 and C > C[1] and L of data2 < -350 and H of data2 < 750 Then Sell Short Next Bar at CloseD(1) Stop;
If Time=945 and C > C[1] and C of data2 < -100 and H of data2 < 750 Then Sell Short Next Bar at CloseD(1) Stop;
If Time=945 and C>(O + Average(Range,27)) and L of data2 > -350 Then Buy Next Bar at market;
If Time=945 and C<(O - Average(Range,27)) and H of data2 < 750 Then Sell Short Next Bar at market;
SetStopLoss(R*BigPointValue*Average(Range,L1));
SetExitonClose;
eSignal code for "Using the TICK to identify the intraday trend," by David Bean, p. 32:
/***************************************
Provided By : eSignal (c) Copyright 2006
Description: Using The TICK To Identify The Intraday Trend
by David Bean
Version 1.0 05/02/2006
Notes:
* May 2006 Issue of Active Trader Magazine
* Study requires version 7.9.1 or higher.
* Study must be used on a 15 minute or lower interval only.
* Study is configured for futures contracts only.
* If used in any time zone other than US Eastern Standard time, the
Start Time and End Time parameters need to be modified to local time.
* Study parameters are set for Emini S&P futures contract (ES #F=2) and
Eastern Standard time.
* Study is compatible for real time use and Back Testing with the
Strategy Analyzer.
* Study requires a time template that includes the bars based
on the specified Start Time and End Time parameters.
Formula Parameters: Defaults:
Local Start Time of Entry Bar 945
R Multiplier 5
Contract's Point Value 50
Local End Time of Trading Session 1615
***************************************/
function preMain() {
setPriceStudy(true);
setStudyTitle("Bean TICK Strategy ");
setCursorLabelName("Position", 0);
setCursorLabelName("Stop", 1);
setDefaultBarThickness(1, 0);
setDefaultBarThickness(2, 1);
setDefaultBarFgColor(Color.grey, 0);
setDefaultBarFgColor(Color.red, 1);
setPlotType(PLOTTYPE_DOT, 0);
setPlotType(PLOTTYPE_FLATLINES, 1);
setColorPriceBars(true);
setDefaultPriceBarColor(Color.grey);
setShowTitleParameters(false);
var fp1 = new FunctionParameter("nStart", FunctionParameter.NUMBER);
fp1.setName("Local Start Time of Entry Bar");
fp1.setDefault(945);
var fp2 = new FunctionParameter("nR", FunctionParameter.NUMBER);
fp2.setName("R Multiplier");
fp2.setLowerLimit(1);
fp2.setDefault(5);
var fp3 = new FunctionParameter("nPoints", FunctionParameter.NUMBER);
fp3.setName("Contract's Point Value");
fp3.setLowerLimit(0);
fp3.setDefault(50);
var fp5 = new FunctionParameter("nEnd", FunctionParameter.NUMBER);
fp5.setName("Local End Time of Trading Session");
fp5.setDefault(1615);
}
var bVersion = null;
var bInit = false;
var xAvgRange = null;
var sPosition = "Flat";
var nStop = null;
var bBT = true; // allow back testing
var bNewDay = false;
var bEntryBar = false;
function main(nStart, nR, nPoints, nEnd) {
if (bVersion == null) bVersion = verify();
if (bVersion == false) return;
if (getInterval() > 15) {
drawTextAbsolute(5, 35, "This study requires a chart interval of 15 minutes or lower.",
Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT,
null, 13, "error");
return;
}
var nState = getBarState();
if (bInit == false) {
xAvgRange = efsInternal("calcAR", inv(15));
bInit = true;
}
if (day(0) != day(-1)) {
bNewDay = true;
}
if (bNewDay == true) {
var nTime = (hour(0)*100) + minute(0);
if (nTime >= nStart) {
bEntryBar = true;
bNewDay = false;
}
}
if (isLastBarOnChart() == true) bBT = false;
// Exit
if (sPosition != "Flat") {
var nBarTime = (hour(0)*100) + minute(0);
var nO = open(0);
var nH = high(0);
var nL = low(0);
var nStopLimit = nStop;
if (sPosition == "Long" && nL <= nStop) { // Exit 1
if (nO < nStop) nStopLimit = nO;
if (bBT == true) Strategy.doSell("Long Stop", Strategy.STOP, Strategy.THISBAR, Strategy.ALL, nStopLimit);
doPriceBarColors();
sPosition = "Flat";
Alert.playSound("train.wav");
drawShape(Shape.DIAMOND, BelowBar1, Color.khaki, "exit"+rawtime(0));
} else if (sPosition == "Short" && nH >= nStop) { // Exit 1
if (nO > nStop) nStopLimit = nO;
if (bBT == true) Strategy.doCover("Short Stop", Strategy.STOP, Strategy.THISBAR, Strategy.ALL, nStopLimit);
doPriceBarColors();
sPosition = "Flat";
Alert.playSound("train.wav");
drawShape(Shape.DIAMOND, AboveBar1, Color.khaki, "exit"+rawtime(0));
} else if (nBarTime >= (nEnd-getInterval()) ) { // Exit 2
if (bBT == true) {
if (sPosition == "Long") Strategy.doSell("End of Day", Strategy.CLOSE, Strategy.THISBAR);
if (sPosition == "Short") Strategy.doCover("End of Day", Strategy.CLOSE, Strategy.THISBAR);
}
doPriceBarColors();
sPosition = "Flat";
Alert.playSound("train.wav");
drawShape(Shape.DIAMOND, AboveBar1, Color.khaki);
} else if (day(0) != day(-1) ) { // Exit 2 (lack of bars due to low volume)
if (bBT == true) {
if (sPosition == "Long") Strategy.doSell("End of Day", Strategy.MARKET, Strategy.THISBAR);
if (sPosition == "Short") Strategy.doCover("End of Day", Strategy.MARKET, Strategy.THISBAR);
}
doPriceBarColors();
sPosition = "Flat";
Alert.playSound("train.wav");
drawShape(Shape.DIAMOND, AboveBar1, Color.khaki);
}
} else {
if (nState == BARSTATE_NEWBAR) nStop = null;
}
// Entry
if (bEntryBar == true && sPosition == "Flat") {
var nTickHigh_1 = high( -1, sym("$TICK,15"));
var nTickLow_1 = low( -1, sym("$TICK,15"));
var nTickClose_1 = close( -1, sym("$TICK,15"));
var nOpen_1 = open( -1, inv(15));
var nHigh_1 = high( -1, inv(15));
var nLow_1 = low( -1, inv(15));
var nClose_1 = close( -1, inv(15));
var nAvgRange_1 = xAvgRange.getValue(-1);
var nDailyOpen = open( 0, inv("D"));
var nDailyLow_1 = low( -1, inv("D"));
var nDailyClose_1 = close( -1, inv("D"));
var sRule = 0;
if (nTickHigh_1 == null || nTickLow_1 == null || nAvgRange_1 == null) return;
// Long Entry
if (nTickLow_1 > -350) {
if (nTickHigh_1 > 750) { // Rule 1
sPosition = "Long";
sRule = 1;
} else if (nTickClose_1 > 500) { // Rule 2
sPosition = "Long";
sRule = 2;
} else if (nClose_1 > (nOpen_1 + nAvgRange_1) ) { // Rule 3
sPosition = "Long";
sRule = 3;
}
if (sPosition == "Long") {
if (bBT == true) Strategy.doLong("Rule " + sRule, Strategy.MARKET, Strategy.THISBAR);
drawShape(Shape.UPARROW, BelowBar2, Color.green, rawtime(0));
drawText(sRule, BelowBar4, Color.green, Text.CENTER|Text.BOLD, rawtime(0));
Alert.playSound("pop.wav");
}
}
// Short Entry
if (sPosition == "Flat" && nTickHigh_1 < 750) {
if (nDailyOpen > (nDailyLow_1 - (2*nAvgRange_1)) && nTickLow_1 < -350 &&
low(0) <= nDailyOpen && high(0) >= nDailyOpen) { // Rule 1
sPosition = "Short";
sRule = 1;
} else if (nDailyOpen > (nDailyLow_1 - (2*nAvgRange_1)) && nTickClose_1 < -100 &&
low(0) <= nDailyOpen && high(0) >= nDailyOpen) { // Rule 2
sPosition = "Short";
sRule = 2;
} else if (nClose_1 > nDailyClose_1 && nTickLow_1 < -350 &&
low(0) <= nDailyClose_1 && high(0) >= nDailyClose_1) { // Rule 3
sPosition = "Short";
sRule = 3;
} else if (nClose_1 > nDailyClose_1 && nTickClose_1 < -100 &&
low(0) <= nDailyClose_1 && high(0) >= nDailyClose_1) { // Rule 4
sPosition = "Short";
sRule = 4;
} else if (nClose_1 < (nOpen_1 - nAvgRange_1) ) { // Rule 5
sPosition = "Short";
sRule = 5;
}
if (sPosition == "Short") {
if (bBT == true) {
if (sRule == 1 || sRule == 2) {
Strategy.doShort("Rule " + sRule, Strategy.LIMIT, Strategy.THISBAR, Strategy.DEFAULT, nDailyOpen);
} else if (sRule == 3 || sRule == 4) {
Strategy.doShort("Rule " + sRule, Strategy.STOP, Strategy.THISBAR, Strategy.DEFAULT, nDailyClose_1);
} else if (sRule == 5) {
Strategy.doShort("Rule " + sRule, Strategy.MARKET, Strategy.THISBAR);
}
}
drawShape(Shape.DOWNARROW, AboveBar2, Color.red, rawtime(0));
drawText(sRule, AboveBar4, Color.red, Text.CENTER|Text.BOLD, rawtime(0));
Alert.playSound("ding.wav");
}
}
bEntryBar = false;
// Set Stop
if (sPosition != "Flat") {
nStop = (nR * nPoints * xAvgRange.getValue(0)) / nPoints;
if (sPosition == "Long") {
nStop = open(0) - nStop;
} else if (sPosition == "Short") {
if (sRule == 1 || sRule == 2) nStop = nDailyOpen + nStop;
else if (sRule == 3 || sRule == 4) nStop = nDailyClose_1 + nStop;
else if (sRule == 5) nStop = open(0) + nStop;
}
}
}
// Color Price Bars
doPriceBarColors();
return new Array(sPosition, nStop);
}
function doPriceBarColors() {
if (Strategy.isLong() || sPosition == "Long") setPriceBarColor(Color.green);
else if (Strategy.isShort() || sPosition == "Short") setPriceBarColor(Color.red);
return;
}
var xRange = null;
function calcAR(nInv) {
if (xRange == null) xRange = efsInternal("calcRange");
return sma(27, xRange);
}
function calcRange() {
return high(-1) - low(-1);
}
function verify() {
var b = false;
if (getBuildNumber() < 730) {
drawTextAbsolute(5, 35, "This study requires version 7.9.1 or later.",
Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT,
null, 13, "error");
drawTextAbsolute(5, 20, "Click HERE to upgrade.@URL=http://www.esignal.com/download/default.asp",
Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT,
null, 13, "upgrade");
return b;
} else {
b = true;
}
return b;
}
November 2006
From the article "The six signal composite indicator," by Art Collins.
Component formulas
Component 1: Close vs. 40-day average
inputs: x(40);
if c>average(c,x) then buy next bar at market;
if c
setexitonclose;
Component 2: Two-day/Five-day average fade
if average(c,2)
if average(c,2)>average(c,5) then sell short next bar at market;
setexitonclose;
Component 3: 50-day extreme highest/lowest close
Input: m(50);
if highestbar(c,m)>lowestbar(c,m) then buy next bar at market;
if highestbar(c,m)
setexitonclose;
Component 4: Go-with close direction following tight ranges, fade following wide ones
inputs:n(10);
if (range
at market;
if (range
next bar at market;
setexitonclose;
Component 5: Close vs. 15-day high-low averages
if c>(average(h,15)+average(l,15))/2 then buy next bar at market;
if c<(average(h,15)+average(l,15))/2 then sell short next bar at market;
setexitonclose;
Component 6: Fading two of the last three open-to-close moves
variables: e(0);
if c>o then e=1;
if c
if average(e,3)>0 then sell short next bar at market;
setexitonclose;
Six indicators combined
variables: e(0),aa(0),bb(0),cc(0),dd(0),ee(0),ff(0),gg(0);
if c>o then e=1;
if c
if c>average(c,40) then bb=1;
if c
if highestbar(c,50)
if c>(average(h,15)+average(l,15))/2 then ee=1;
if c<(average(h,15)+average(l,15))/2 then ee=-1;
if average(e,3)<0 then ff=1;
if average(e,3)>0 then ff=-1;
if aa+bb+cc+dd+ee+ff>0 then buy next bar at market;
if aa+bb+cc+dd+ee+ff<0 then sell short next bar at market;
setexitonclose;
Back to top
December 2006
eSignal code for Trading System Lab, "Trading the equity curve," p. 44
/***************************************
Provided By : eSignal (c) Copyright 2006
Description: Trading the equity curve
by Volker Knapp
Version 1.0 11/17/2006
Notes:
* Dec 2006 Issue of Active Trader Magazine
* Study requires version 8.0 or later.
Formula Parameters: Default:
KAMA Periods 10
KAMA Fast Length 2
KAMA Slow Length 30
Commission per Trade 8
Slippage per Trade 0.002 (0.2%)
Bollinger Band Periods 38
Bollinger Band Standard Deviations 3
*****************************************************************/
function preMain() {
setPriceStudy(true);
setStudyTitle("Equity Curve MA");
setShowTitleParameters(false);
setCursorLabelName("Upper BB", 0);
setCursorLabelName("Lower BB", 1);
setCursorLabelName("Equity Fast MA", 2);
setCursorLabelName("Equity Slow MA", 3);
setDefaultBarFgColor(Color.grey, 0);
setDefaultBarFgColor(Color.grey, 1);
setDefaultBarFgColor(Color.red, 2);
setDefaultBarFgColor(Color.green, 3);
setDefaultBarThickness(2, 0);
setDefaultBarThickness(2, 1);
// KAMA parameters
var fp1 = new FunctionParameter( "Period", FunctionParameter.NUMBER);
fp1.setName( "KAMA Periods" );
fp1.setLowerLimit( 5 );
fp1.setUpperLimit( 125 );
fp1.setDefault( 10 );
var fp2 = new FunctionParameter( "Fast", FunctionParameter.NUMBER);
fp2.setName( "KAMA Fast Length" );
fp2.setLowerLimit( 1 );
fp2.setUpperLimit( 125 );
fp2.setDefault( 2 );
var fp3 = new FunctionParameter( "Slow", FunctionParameter.NUMBER);
fp3.setName( "KAMA Slow Length" );
fp3.setLowerLimit( 1 );
fp3.setUpperLimit( 125 );
fp3.setDefault( 30 );
var fp4 = new FunctionParameter( "Commission", FunctionParameter.NUMBER);
fp4.setName( "Commission per Trade" );
fp4.setLowerLimit( 0 );
fp4.setDefault( 8 );
var fp5 = new FunctionParameter( "Slippage", FunctionParameter.NUMBER);
fp5.setName( "Slippage per Trade" );
fp5.setLowerLimit( 0 );
fp5.setDefault( 0.002 );
var fp5b = new FunctionParameter( "Lot", FunctionParameter.NUMBER);
fp5b.setName( "Lot Size" );
fp5b.setLowerLimit( 1 );
fp5b.setDefault( 100 );
var fp6 = new FunctionParameter( "BBPeriods", FunctionParameter.NUMBER);
fp6.setName( "Bollinger Band Periods" );
fp6.setLowerLimit( 1 );
fp6.setDefault( 38 );
var fp7 = new FunctionParameter( "BBStdv", FunctionParameter.NUMBER);
fp7.setName( "Bollinger Band Standard Deviations" );
fp7.setLowerLimit( 0 );
fp7.setDefault( 3 );
var fp8 = new FunctionParameter( "SMA_fast", FunctionParameter.NUMBER);
fp8.setName( "Fast SMA Length " );
fp8.setLowerLimit( 0 );
fp8.setDefault( 3 );
var fp9 = new FunctionParameter( "SMA_slow", FunctionParameter.NUMBER);
fp9.setName( "Slow SMA Length " );
fp9.setLowerLimit( 0 );
fp9.setDefault( 10 );
}
// Global Variables
var bVersion = null; // Version flag
var bInit = false; // Initialization flag
var bBT = true; // Back Testing flag
// Basis Strategy Variables
var xUpper = null;
var xLower = null;
var xEquity = null; // Equity Series
var nEquity = 100000;
var nLot = 100;
var nEntry = null;
var nExit = null;
var nCom = 8*2; // Commission per trade
var nSlip = 0.002; // 0.2% Slippage per trade
var vPosition = 0; // 1=long, 0=flat, -1=short
// Strategy of Basis (B)
var xSMA_fast = null;
var xSMA_slow = null;
var vPositionB = 0; // 1=long, 0=flat, -1=short
// KAMA globals
var xKamaH = null;
var xKamaL = null;
var nKama = 0; // Kama value
var nKama_1 = 0; // previous bar's Kama value
var nFast = 0;
var nSlow = 0;
function main(Period, Fast, Slow, Commission, Slippage, BBPeriods, BBStdv,
SMA_fast, SMA_slow) {
if (bVersion == null) bVersion = verify();
if (bVersion == false) return;
var nState = getBarState();
if(bInit == false) {
xKamaH = efsInternal("kama", Period, Fast, Slow, high());
xKamaL = efsInternal("kama", Period, Fast, Slow, low());
xUpper = upperBB(BBPeriods, BBStdv, xKamaH);
xLower = lowerBB(BBPeriods, BBStdv, xKamaL);
// Basis Strategy for Paper trading equity curve needs to go
// into the getBasisEquity series function. Any existing strategy
// may be used in place of the current strategy.
xEquity = efsInternal("getBasisEquity", xUpper, xLower);
xSMA_fast = sma(SMA_fast, xEquity);
xSMA_slow = sma(SMA_slow, xEquity);
nCom = Commission * 2;
nSlip = Slippage;
bInit = true;
}
if (nState == BARSTATE_NEWBAR) {
if (getCurrentBarIndex() == 0) bBT = false;
}
var nU = xUpper.getValue(-1);
var nL = xLower.getValue(-1);
var nSMA_fast_1 = xSMA_fast.getValue(-1);
var nSMA_slow_1 = xSMA_slow.getValue(-1);
if(nU == null || nL == null ||
nSMA_fast_1 == null || nSMA_slow_1 == null) return;
/***** Strategy of Basis (B) *****/
if (nState == BARSTATE_NEWBAR) {
if (nSMA_fast_1 > nSMA_slow_1) {
// Long Trade Signal
if (vPositionB != 1 && close(-1) > nU) {
drawShape(Shape.UPARROW, AboveBar1, Color.green, rawtime(0));
vPositionB = 1;
if (bBT == true) {
Strategy.doLong("Long", Strategy.MARKET, Strategy.THISBAR);
}
// Short Trade Signal
} else if (vPositionB != -1 && close(-1) < nL) {
drawShape(Shape.DOWNARROW, BelowBar1, Color.red, rawtime(0));
vPositionB = -1;
if (bBT == true) {
Strategy.doShort("Short", Strategy.MARKET, Strategy.THISBAR);
}
}
}
}
if(vPositionB == 1) {
setBarFgColor(Color.darkgreen, 0);
setBarFgColor(Color.darkgreen, 1);
} else if(vPositionB == -1) {
setBarFgColor(Color.red, 0);
setBarFgColor(Color.red, 1);
}
return new Array((xUpper.getValue(0)).toFixed(2)*1,
(xLower.getValue(0)).toFixed(2)*1,
(xSMA_fast.getValue(0)).toFixed(2),
(xSMA_slow.getValue(0)).toFixed(2));
}
function getBasisEquity(xU, xL) {
var nState = getBarState();
var nU = xU.getValue(-1);
var nL = xL.getValue(-1);
if (nState == BARSTATE_NEWBAR) {
// Long Trade Signal
if (vPosition != 1 && close(-1) > nU) {
nExit = open(0) + (nSlip * open(0));
if (vPosition == -1) {
nEquity += ((nEntry - nExit) * nLot) - nCom;
}
vPosition = 1;
nEntry = open(0) + (nSlip * open(0));
// Short Trade Signal
} else if (vPosition != -1 && close(-1) < nL) {
nExit = open(0) - (nSlip * open(0));
if (vPosition == 1) {
nEquity += ((nExit - nEntry) * nLot) - nCom;
}
vPosition = -1;
nEntry = open(0) - (nSlip * open(0));
}
}
return nEquity;
}
function kama(Period, Fast, Slow, xSource) {
/***************************************************
kama series modified from KAMA.efs by
Divergence Software, Inc.
http://share.esignal.com/groupgo.jsp?groupid=114
****************************************************/
var x = 0;
var nNoise;
var nSignal;
var nSmooth;
if (bInit == false) {
nFast = 2 / ( Fast + 1 );
nSlow = 2 / ( Slow + 1 );
bInit = true;
}
if (getBarState() == BARSTATE_NEWBAR) {
nKama_1 = nKama;
}
if (xSource.getValue(-(Period+1)) == null) return close(0);
nSignal = Math.abs( xSource.getValue(0) - xSource.getValue(-Period) );
nNoise = 0;
while( x
nNoise += Math.abs( xSource.getValue(-x)-xSource.getValue(-(x+1)) );
x++;
}
if ( nNoise==0 ) nNoise = 1.0;
nSmooth = Math.pow( ( nSignal/nNoise ) * ( nFast - nSlow ) + nSlow , 2 );
nKama = nKama_1 + nSmooth * ( xSource.getValue(0) - nKama_1 );
return nKama;
}
function verify() {
var b = false;
if (getBuildNumber() < 779) {
drawTextAbsolute(5, 35, "This study requires version 8.0 or later.",
Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT,
null, 13, "error");
drawTextAbsolute(5, 20, "Click HERE to upgrade.@URL=http://www.esignal.com/download/default.asp",
Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT,
null, 13, "upgrade");
return b;
} else {
b = true;
}
return b;
}
Back to top
January 2007
eSignal code for "Gauging gap opportunities," p. 14
/***************************************
Provided By : eSignal (c) Copyright 2006
Description: Gauging Gap Opportunities
by David Bukey
Version 1.0 11/10/2006
Notes:
* Jan 2007 Issue of Active Trader Magazine
* Study requires version 8.0 or later.
Formula Parameters: Default:
Filled Gap Price Bar Color lime
Fill Target Color blue
Fill Target Thickness 2
*****************************************************************/
function preMain() {
setPriceStudy(true);
setStudyTitle("Filled Gaps ");
setCursorLabelName("Fill Target", 0);
setShowTitleParameters(false);
setPlotType(PLOTTYPE_FLATLINES, 0);
setColorPriceBars(true);
setDefaultPriceBarColor(Color.grey);
var fp1 = new FunctionParameter("nFillColor", FunctionParameter.COLOR);
fp1.setName("Filled Gap Price Bar Color");
fp1.setDefault(Color.lime);
var fp2 = new FunctionParameter("nColor", FunctionParameter.COLOR);
fp2.setName("Fill Target Color");
fp2.setDefault(Color.blue);
var fp3 = new FunctionParameter("nThick", FunctionParameter.NUMBER);
fp3.setName("Fill Target Thickness");
fp3.setLowerLimit(1);
fp3.setDefault(2);
var fp4 = new FunctionParameter("nLimit", FunctionParameter.NUMBER);
fp4.setName("Limit for # of bars to fill gap.");
fp4.setLowerLimit(1);
fp4.setDefault(5);
}
// Global Variables
var bVersion = null; // Version flag
var bInit = false; // Initialization flag
var nFill = null;
var nCount = 0;
var nGap = 0;
function main(nFillColor, nColor, nThick, nLimit) {
if (bVersion == null) bVersion = verify();
if (bVersion == false) return;
var nState = getBarState();
//Initialization
if (bInit == false) {
setDefaultBarFgColor(nColor, 0);
setDefaultBarThickness(nThick, 0);
bInit = true;
}
var nH_2 = high(-2);
var nH_1 = high(-1);
var nH_0 = high(0);
var nL_2 = low(-2);
var nL_1 = low(-1);
var nL_0 = low(0);
if (nH_2 == null || nL_2 == null) return;
if (nState == BARSTATE_NEWBAR && nCount > 0) {
if (nGap != 0) {
nCount++;
if (nCount > nLimit) {
nCount = 0;
nGap = 0;
nFill = null;
}
} else {
nFill = null;
}
} else if (nCount <= 1) { // first gap bar
if (nL_0 > nH_1 ) {
nCount = 1
nFill = nH_1;
nGap = 1;
drawShapeRelative(0, (nFill+nL_0)/2, Shape.UPARROW,
null, Color.red, null, "gap"+rawtime(0));
}
if (nH_0 < nL_1 ) {
nCount = 1;
nFill = nL_1;
nGap = -1;
drawShapeRelative(0, (nFill+nH_0)/2, Shape.DOWNARROW,
null, Color.red, null, "gap"+rawtime(0));
}
if (nL_0 <= nH_1 && nH_0 >= nL_1) {
nCount = 0;
nFill = null;
nGap = 0;
removeShape("gap"+rawtime(0));
}
}
if (nCount > 1) { // Filled Gap check
if ( (nGap == 1 && nL_0 <= nFill) || (nGap == -1 && nH_0 >= nFill) ) {
setPriceBarColor(nFillColor);
nGap = 0;
nCount = 0;
}
}
return nFill;
}
function verify() {
var b = false;
if (getBuildNumber() < 779) {
drawTextAbsolute(5, 35, "This study requires version 8.0 or later.",
Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT,
null, 13, "error");
drawTextAbsolute(5, 20, "Click HERE to upgrade.@URL=http://www.esignal.com/download/default.asp",
Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT,
null, 13, "upgrade");
return b;
} else {
b = true;
}
return b;
}
eSignal code for Trading System Lab, "Exiting after profitable closes," p. 38
/***************************************
Provided By : eSignal (c) Copyright 2006
Description: Exiting after profitable closes
by Volker Knapp
Version 1.0 11/13/2006
Notes:
* Jan 2007 Issue of Active Trader Magazine
* Study requires version 8.0 or later.
* Long only system, compatible for Back Testing
and real time.
* Parameters optimized for Daily interval.
Formula Parameters: Default:
Number of days for Trend Entry 20
Number of days for Counter Trend Entry 10
Number of days for Trend Exit 20
Number of days for Counter Trend Exit 8
Fixed Stop Percent 0.10
*****************************************************************/
function preMain() {
setPriceStudy(true);
setStudyTitle("Highest High Trend System ");
setShowTitleParameters(false);
setCursorLabelName("HH", 0);
setCursorLabelName("LL", 1);
setCursorLabelName("Stop", 2);
setDefaultBarThickness(2, 0);
setDefaultBarThickness(2, 1);
setDefaultBarThickness(2, 2);
setDefaultBarFgColor(Color.blue, 0);
setDefaultBarFgColor(Color.blue, 1);
setDefaultBarFgColor(Color.red, 2);
setPlotType(PLOTTYPE_FLATLINES, 2);
var fp1 = new FunctionParameter("nTdays", FunctionParameter.NUMBER);
fp1.setName("Number of days for Trend Entry");
fp1.setLowerLimit(1);
fp1.setDefault(20);
var fp2 = new FunctionParameter("nCTdays", FunctionParameter.NUMBER);
fp2.setName("Number of days for Counter Trend Entry");
fp2.setLowerLimit(1);
fp2.setDefault(10);
var fp3 = new FunctionParameter("nTexit", FunctionParameter.NUMBER);
fp3.setName("Number of days for Trend Exit");
fp3.setLowerLimit(1);
fp3.setDefault(20);
var fp4 = new FunctionParameter("nCTexit", FunctionParameter.NUMBER);
fp4.setName("Number of days for Counter Trend Exit");
fp4.setLowerLimit(1);
fp4.setDefault(8);
var fp5 = new FunctionParameter("nStopPrct", FunctionParameter.NUMBER);
fp5.setName("Fixed Stop Percent");
fp5.setLowerLimit(0);
fp5.setUpperLimit(1);
fp5.setDefault(0.10);
}
// Global Variables
var bVersion = null; // Version flag
var bInit = false; // Initialization flag
var nCount = 0;
var xHH_Trend = null;
var xLL_CTrend = null;
var vPosition = 0; // 0 = flat, 1 = Trend long, 2 = Counter Trend Long
var nEntry = null; // entry price
var nStop = null; // stop price
var bExitTrade = false;
var bBT = true; // back test flag
function main(nTdays, nCTdays, nTexit, nCTexit, nStopPrct) {
if (bVersion == null) bVersion = verify();
if (bVersion == false) return;
var nState = getBarState();
//Initialization
if (bInit == false) {
xHH_Trend = upperDonchian(nTdays, high());
xLL_CTrend = lowerDonchian(nCTdays, low());
bInit = true;
}
var nH_0 = high(0);
var nL_0 = low(0);
var nC_1 = close(-1);
var nOpen = open(0);
var nHH = xHH_Trend.getValue(0);
var nLL = xLL_CTrend.getValue(0);
var nHH_1 = xHH_Trend.getValue(-1);
var nLL_1 = xLL_CTrend.getValue(-1);
if (nHH_1 == null || nLL_1 == null) return;
// Record Keeping
if (nState == BARSTATE_NEWBAR) {
bExitTrade = false;
if (vPosition == 0) {
nCount = 0;
nEntry = null;
nStop = null;
}
if (getCurrentBarIndex() == 0) bBT = false;
}
// Exit Conditions
if (vPosition != 0 && nState == BARSTATE_NEWBAR) {
var sText = "";
/*var sText = "Unprofitable Close";
if (nCount >= 1 && nC_1 < nEntry) {
// not a profitable close
// exit position
vPosition = 0;
bExitTrade = true;
}*/
nCount++;
// Trend Exit
if (vPosition == 1 && nCount >= nTexit) {
sText = "Counter Trend Exit";
bExitTrade = true;
}
// Counter Trend Exit
if (vPosition == 2 && nCount >= nCTexit) {
sText = "Counter Trend Exit";
bExitTrade = true;
}
if (bExitTrade == true) {
vPosition = 0;
drawShape(Shape.DIAMOND, AboveBar1, Color.red, "xtop"+rawtime(0));
drawShape(Shape.DIAMOND, BelowBar1, Color.red, "xbot"+rawtime(0));
Alert.playSound("train.wav");
if (bBT) {
Strategy.doSell(sText, Strategy.MARKET, Strategy.THISBAR);
}
}
}
// Fixed %Stop Exit
if (bExitTrade == false && vPosition != 0) {
if (nL_0 <= nStop) {
vPosition = 0;
bExitTrade = true;
drawShape(Shape.DIAMOND, AboveBar1, Color.red, "xtop"+rawtime(0));
drawShape(Shape.DIAMOND, BelowBar1, Color.red, "xbot"+rawtime(0));
Alert.playSound("train.wav");
if (bBT) {
Strategy.doSell("Stop Exit", Strategy.STOP, Strategy.THISBAR,
Strategy.DEFAULT, Math.min(nOpen, nStop));
}
}
}
// Entry Conditions
if (vPosition == 0 && bExitTrade == false) {
// Trend Entry
if (nH_0 > nHH_1) {
vPosition = 1;
nEntry = Math.max(nOpen, nHH_1);
nStop = nEntry * (1 - nStopPrct); // fixed stop
drawShape(Shape.UPARROW, AboveBar1, Color.green, rawtime(0));
Alert.playSound("ding.wav");
if (bBT) {
Strategy.doLong("Trend Signal", Strategy.STOP,
Strategy.THISBAR, Strategy.DEFAULT, nEntry);
}
} else if (nL_0 < nLL_1) { // Counter Trend Entry
vPosition = 2;
nEntry = Math.min(nOpen, nLL_1);
nStop = nEntry * (1 - nStopPrct); // fixed stop
drawShape(Shape.UPARROW, AboveBar1, Color.green, rawtime(0));
Alert.playSound("ding.wav");
if (bBT) {
Strategy.doLong("Counter Trend Signal", Strategy.LIMIT,
Strategy.THISBAR, Strategy.DEFAULT, nEntry);
}
}
}
return new Array(nHH, nLL, nStop);
}
function verify() {
var b = false;
if (getBuildNumber() < 779) {
drawTextAbsolute(5, 35, "This study requires version 8.0 or later.",
Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT,
null, 13, "error");
drawTextAbsolute(5, 20, "Click HERE to upgrade.@URL=http://www.esignal.com/download/default.asp",
Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT,
null, 13, "upgrade");
return b;
} else {
b = true;
}
return b;
Code for updated version of "The ultimate stop-loss equation," p. 20
Sub UnBiasedRange(LookBack As Integer)?'Copyright (C), 2006:Thomas Stridsman
Dim Typical, LatestMove, Target As BarArray(250)?Dim
TypicalMove, CloseVariation, TypicalBar, BarVariation As
Double
Typical = (O+H+L+C)/4?LatestMove = Typical - Typical[1]
TypicalMove = Average(LatestMove, LookBack,
0)?CloseVariation = StdDev(LatestMove, LookBack,
0)?TypicalBar = Average(TrueRange, LookBack,
0)?BarVariation = StdDev(TrueRange, LookBack, 0)
If TypicalMove > 0 Then? Target = Typical + TypicalMove
- CloseVariation - TypicalBar - BarVariation?Else If
TypicalMove < 0 Then? Target = Typical + TypicalMove +
CloseVariation + TypicalBar+ BarVariation?Else If
TypicalMove = 0 Then? Target = Typical?End If?End
If?End If
Plot1(Target)
End Sub
TradeStation code for the article “Turning systems upside down” by Art Collins (Active Trader), February 2007.
Nine-day reversal — first day follow-through
inputs: n(9);
if l[1]<lowest(l,n)[2]and l<l[1] and c>c[1] then buy this bar on close;
if barssinceentry=1 then setexitonclose;
if h[1]>highest(h,n)[2]and h>h[1] and c<c[1] then sell short this bar on close;
if barssinceentry=1 then setexitonclose;
Fading the reversal day signal
variables:hh(0),ll(0);
if marketposition=1 and barssinceentry=0 then hh=h;
if marketposition=-1 and barssinceentry=0 then ll=l;
if marketposition<1 and h>h[1] and c<c[1] then buy next bar at market;
if(h<=h[1] or c>=c[1]) then sell next bar at hh limit;
if barssinceentry>0 then sell next bar at ll-minmove/pricescale stop;
if marketposition>-1 and l<l[1] and c>c[1] then sell short next bar at market;
if (l>=l[1] or c<=c[1]) then buy to cover next bar at ll limit;
if barssinceentry>0 then buy to cover next bar at hh+minmove/pricescale stop;
Fading the RSI indicator
inputs: Length(9),n(15),b(9.15),x(14.45),z(15.1);
variables: e(0);
e = RSI( Close, Length ) ;
if time>=(b*100) and time<=(x*100) and e>(100-n) then buy next bar at market;
if time=(z*100) then sell next bar at market;
if time>=(b*100) and time<=(x*100) and e<n then sell short next bar at market;
if time=(z*100) then buy to cover next bar at market;
April 2007
eSignal code for "Closing Price Divergences, " p. 37
*************************************** Provided By : eSignal (c) Copyright 2007 Description: Closing-Price Divergences by Clive Corcoran Version 1.0 1/18/2007 Notes: * Study requires version 8.0 or later.
* This study is designed for back testing, not real time analysis.
* This study is intended for Equities only.
* The Starting Equity amount entered for the study will also need to be entered into the Strategy Analyzer settings.
Formula Parameters: Default:
Starting Equity 100000
Position Size (%of Equity) 2 *************************************************/
function preMain() {
setPriceStudy(true);
setStudyTitle("Price-Close Location Divergence");
setCursorLabelName("65th Percentile", 0);
setCursorLabelName("35th Percentile", 1);
setCursorLabelName("Closing Bias", 2);
setCursorLabelName("Close Stop 3%", 3);
setCursorLabelName("IntraBar Stop 5%", 4);
setCursorLabelName("Target1 5%", 5);
setCursorLabelName("Target2 7%", 6);
setCursorLabelName("long count", 7);
setCursorLabelName("short count", 8);
setDefaultBarFgColor(Color.blue, 0);
setDefaultBarFgColor(Color.blue, 1);
setDefaultBarFgColor(Color.magenta, 2);
setDefaultBarFgColor(Color.red, 3);
setDefaultBarFgColor(Color.red, 4);
setDefaultBarFgColor(Color.green, 5);
setDefaultBarFgColor(Color.green, 6);
//setDefaultBarThickness(2, 3);
setPlotType(PLOTTYPE_FLATLINES, 3);
setPlotType(PLOTTYPE_FLATLINES, 4);
setPlotType(PLOTTYPE_FLATLINES, 5);
setPlotType(PLOTTYPE_FLATLINES, 6);
setDefaultFont("Arial", 12, null, Text.BOLD|Text.FRAME|Text.CENTER);
var fp1 = new FunctionParameter("Equity", FunctionParameter.NUMBER);
fp1.setName("Starting Equity");
fp1.setLowerLimit(1);
fp1.setDefault(100000);
var fp2 = new FunctionParameter("PosSize", FunctionParameter.NUMBER);
fp2.setName("Position Size (%of Equity)");
fp2.setLowerLimit(0.1);
fp2.setDefault(2);
}
// Global Variables
var xRankC = null;
var xBiasC = null;
var aLongCount = new Array(21);
var aShortCount = new Array(21);
for (var i = 0; i < 21; i++) {
aLongCount[i] = 0;
aShortCount[i] = 0;
}
var nEquity = null; // Starting Equity
var nPS = null; // Position size as % of Equity
var vPosition = 0; // 0=flat, 1=long, -1=short
var nEntryPrice = null;
var nStop1 = null;
var nStop2 = null; var nTarget1 = null;
var nTarget2 = null;
var bTargetBreach = false;
var nLotSize = null;
var nLongCount = 0;
var nShortCount = 0;
var nLongCount_1 = 0;
var nShortCount_1 = 0;
var bInit = false; // initialization flag
var bBT = true;
function main(Equity, PosSize) {
var nState = getBarState();
if (getCurrentBarIndex() >= -1) bBT = false; // disable back testing functions
if (getCurrentBarIndex() == 0) return;
if(bInit == false) {
nEquity = Equity;
nPS = PosSize;
xRankC = efsInternal("calcPercentiles");
xBiasC = efsInternal("calcBias");
bInit = true; // Prevents this code block from executing again.
}
//if (getCurrentBarCount() < 21) return;
// Retrieve previous bar's values of Donchian Series for back testing conditions.
//var n = x.getValue(-1);
var x35th = getSeries(xRankC, 0);
var x65th = getSeries(xRankC, 1);
var nBias = xBiasC.getValue(0);
var nBias_1 = xBiasC.getValue(-1);
var n35th_1 = x35th.getValue(-1);
var n65th_1 = x65th.getValue(-1);
var bLong = false;
var bShort = false;
var bExitTrade = false;
var nExitPrice = null;
// Validate the study variables to ensure they contain valid data.
if(n35th_1 == null || n65th_1 == null || nBias_1 == null) {
return; // Exit the formula if variables contain invalid data.
}
// Record keeping
if (nState == BARSTATE_NEWBAR) {
nLongCount_1 = nLongCount;
nShortCount_1 = nShortCount;
aLongCount.pop();
aLongCount.unshift(0);
aShortCount.pop();
aShortCount.unshift(0);
// Long count
if (close(-1) <= n35th_1 && nBias_1 > 0.10) {
aLongCount[0] = 1;
}
// Short count
if (close(-1) >= n65th_1 && nBias_1 < -0.10) {
aShortCount[0] = 1;
}
nLongCount = 0;
nShortCount = 0;
for (var i = 0; i < 21; i++) {
nLongCount += aLongCount[i];
nShortCount += aShortCount[i];
if (i < 5) {
if (aLongCount[i] == 1) bLong = true;
if (aShortCount[i] == 1) bShort = true;
}
}
if (vPosition == 0) { nStop1 = null;
nStop2 = null;
nTarget1 = null;
nTarget2 = null;
bTargetBreach = false;
}
}
// Back Testing logic
if (getCurrentBarCount() > 21) { // study primed, begin evaluation
if (nState == BARSTATE_NEWBAR) {
// Exit Strategy
if (vPosition != 0) {
// Long Exit
if (vPosition == 1) {
if (bTargetBreach == false && high(0) > nTarget1) { // Profit Target1
bTargetBreach = true;
bExitTrade = true;
nExitPrice = Math.max(open(0), nTarget1);
drawShapeRelative(0, nExitPrice, Shape.DIAMOND, null, Color.green,
null, rawtime(0));
drawText("1", AboveBar2, Color.green, null, rawtime(0));
if (bBT == true) {
nEquity += (nExitPrice-nEntryPrice)*Math.round(nLotSize*.65);
Strategy.doSell("Target 1", Strategy.LIMIT, Strategy.THISBAR,
Math.round(nLotSize*.65), nExitPrice);
} } else if (bTargetBreach == true && high(0) > nTarget2) { // Profit Target2
vPosition = 0;
bExitTrade = true;
nExitPrice = Math.max(open(0), nTarget2);
drawShapeRelative(0, nExitPrice, Shape.DIAMOND, null, Color.green,
null, rawtime(0));
drawText("2", AboveBar2, Color.green, null, rawtime(0));
if (bBT == true) {
nEquity += (nExitPrice-nEntryPrice)*Strategy.getPositionSize();
Strategy.doSell("Target 2", Strategy.LIMIT, Strategy.THISBAR,
Strategy.getPositionSize(), nExitPrice);
}
}
} if (vPosition == 1 && bExitTrade == false) { // protective stops
if (close(-1) <= nStop1) {
vPosition = 0;
bExitTrade = true;
nExitPrice = open(0);
drawShapeRelative(0, nExitPrice, Shape.DIAMOND, null, Color.red,
null, rawtime(0));
drawText("1", BelowBar2, Color.red, null, rawtime(0));
if (bBT == true) {
nEquity += (nExitPrice-nEntryPrice)*Strategy.getPositionSize();
Strategy.doSell("Close Stop", Strategy.STOP, Strategy.THISBAR,
Strategy.getPositionSize(), nExitPrice);
}
} else if (low(0) <= nStop2) {
vPosition = 0;
bExitTrade = true;
nExitPrice = Math.min(open(0), nStop2);
drawShapeRelative(0, nExitPrice, Shape.DIAMOND, null, Color.red,
null, rawtime(0));
drawText("2", BelowBar2, Color.red, null, rawtime(0));
if (bBT == true) {
nEquity += (nExitPrice-nEntryPrice)*Strategy.getPositionSize();
Strategy.doSell("IntraBar Stop", Strategy.STOP, Strategy.THISBAR,
Strategy.getPositionSize(), nExitPrice);
}
}
}
// Short Exit
if (vPosition == -1) {
if (bTargetBreach == false && low(0) < nTarget1) { // Profit Target1
bTargetBreach = true;
bExitTrade = true;
nExitPrice = Math.min(open(0), nTarget1);
drawShapeRelative(0, nExitPrice, Shape.DIAMOND, null, Color.green,
null, rawtime(0));
drawText("1", BelowBar2, Color.green, null, rawtime(0));
if (bBT == true) {
nEquity += (nEntryPrice-nExitPrice)*Math.round(nLotSize*.65);
Strategy.doCover("Target 1", Strategy.LIMIT, Strategy.THISBAR,
Math.round(nLotSize*.65), nExitPrice);
}
} else if (bTargetBreach == true && low(0) < nTarget2) { // Profit Target2
vPosition = 0;
bExitTrade = true;
nExitPrice = Math.min(open(0), nTarget2);
drawShapeRelative(0, nExitPrice, Shape.DIAMOND, null, Color.green,
null, rawtime(0));
drawText("2", BelowBar2, Color.green, null, rawtime(0));
if (bBT == true) {
nEquity += (nEntryPrice-nExitPrice)*Math.abs(Strategy.getPositionSize());
Strategy.doCover("Target 2", Strategy.LIMIT, Strategy.THISBAR,
Math.abs(Strategy.getPositionSize()), nExitPrice);
}
}
}
if (vPosition == -1 && bExitTrade == false) { // protective stops
if (close(-1) >= nStop1) {
vPosition = 0;
bExitTrade = true;
nExitPrice = open(0);
drawShapeRelative(0, nExitPrice, Shape.DIAMOND, null, Color.red,
null, rawtime(0));
drawText("1", AboveBar2, Color.red, null, rawtime(0));
if (bBT == true) {
nEquity += (nEntryPrice-nExitPrice)*Math.abs(Strategy.getPositionSize());
Strategy.doCover("Close Stop", Strategy.STOP, Strategy.THISBAR,
Math.abs(Strategy.getPositionSize()), nExitPrice);
}
} else if (high(0) >= nStop2) {
vPosition = 0;
bExitTrade = true;
nExitPrice = Math.max(open(0), nStop2);
drawShapeRelative(0, nExitPrice, Shape.DIAMOND, null, Color.red,
null, rawtime(0));
drawText("2", AboveBar2, Color.red, null, rawtime(0));
if (bBT == true) {
nEquity += (nEntryPrice-nExitPrice)*Math.abs(Strategy.getPositionSize());
Strategy.doCover("IntraBar Stop", Strategy.STOP, Strategy.THISBAR,
Math.abs(Strategy.getPositionSize()), nExitPrice);
}
}
}
}
// Entry Strategy
if (vPosition == 0 && bExitTrade == false) {
// Long Signal
//if (bLong == true && aLongCount[0] > aLongCount[1]) {
if (bLong == true && nLongCount == 5 && nLongCount_1 == 4) {
vPosition = 1;
drawShape(Shape.UPARROW, BelowBar1, Color.green, rawtime(0));
if (bBT == true) {
nLotSize = getLotSize(open(0));
Strategy.doLong("Long Trigger", Strategy.MARKET, Strategy.THISBAR,
nLotSize);
}
nEntryPrice = open(0);
nStop1 = nEntryPrice - (0.03*nEntryPrice);
nStop2 = nEntryPrice - (0.05*nEntryPrice);
nTarget1 = nEntryPrice + (0.05*nEntryPrice);
nTarget2 = nEntryPrice + (0.07*nEntryPrice);
}
// Short Signal
//if (vPosition == 0 && bShort == true && aShortCount[0] > aShortCount[1]) {
if (vPosition == 0 && bShort == true && nShortCount == 5 && nShortCount_1 == 4) {
vPosition = -1;
drawShape(Shape.DOWNARROW, AboveBar1, Color.red, rawtime(0));
if (bBT == true) {
nLotSize = getLotSize(open(0));
Strategy.doShort("Short Trigger", Strategy.MARKET, Strategy.THISBAR,
nLotSize);
}
nEntryPrice = open(0);
nStop1 = nEntryPrice + (0.03*nEntryPrice);
nStop2 = nEntryPrice + (0.05*nEntryPrice);
nTarget1 = nEntryPrice - (0.05*nEntryPrice);
nTarget2 = nEntryPrice - (0.07*nEntryPrice);
}
}
}
}
return new Array(x65th, x35th, nBias.toFixed(2), nStop1, nStop2, nTarget1, nTarget2,
nLongCount+"", nShortCount+"");
}
var aClose = new Array(21);
function calcPercentiles() {
var nState = getBarState();
var n35 = null;
var n65 = null;
var aSort = new Array(21);
if (nState == BARSTATE_NEWBAR) {
aClose.pop();
aClose.unshift(close(0));
}
aClose[0] = close(0);
if (aClose[20] == null) return;
for (var i = 0; i < 21; i++) {
aSort[i] = aClose[i];
}
aSort.sort(compareNumbers);
n35 = aSort[7];
n65 = aSort[13];
return new Array(n35, n65);
}
function compareNumbers(a, b) {
return a - b;
}
function calcBias() {
var c_0 = close(0);
var c_1 = close(-1);
var nATR = atr(1, 0);
if (close(-1) == null || nATR == null) return;
return (c_0 - c_1) / nATR;
}
function getLotSize(Price) {
return ((nPS/100) * nEquity) / Price;
}
June 2007
TradeStation code for "Short-term, channel trading ," p. 29
The base strategy
inputs:length(10);
vars:lrgh(0),lrgl(0);
lrgh=linearregvalue(h,length,0);
lrgl=linearregvalue(l,length,0);
buy next bar at lrgh stop;
sell short next bar at lrgl stop;
The first filter
if (lrgh > lrgh[1] ) then buy next bar at lrgh stop;
if (lrgl < lrgl[1] ) then sell short next bar at lrgl stop;
The second filter
if (lrgh < lrgh[1] and c
if (lrgl > lrgl[1] and c>lrgl ) then sell short next bar at lrgl stop;
Behle-Conway modified exit strategy
Inputs: stopbars(3), exitfactor(0.25),
length(14), profitbars (3), profitfactor (0.9);
Vars: sellstop(0),Coverstop(0),ATR(0), selltarget1(0),covertarget1(0),selltarget2(0),covertarget2(0);
ATR=Avgtruerange(length);
Sellstop=lowest(low,stopbars)-(exitfactor*ATR);
Coverstop=highest(high,stopbars)=(exitfactor*ATR);
Selltarget1 =h+(profitfactor*atr);
Covertarget1=low - (profitfactor*atr):
Selltarget2=highest(h,profitbars)+(2*profitfactor*atr);
Covertarget2=lowest(l,profitbars)-(2*profitfactor*atr);
If marketposition<>0 then begin
Sell next bar at sellstop on stop;
Buy to cover next bar at coverstopon stop;
End;
If Marketposition<>0 then begin
Sell currentcontracts/2 contracts next bar at selltarget1 on stop;
Buy to cover currentcontracts/2 contracts next bar at covertarget1 on stop;
Sell next bar at selltarget2 on stop;
Buy to cover next bar at covertarget2 on stop;
End;
July 2007
TradeStation code for "Intraday hybrid strategy ," p. 22
// ================================
// Trend_Channel DT (Version 1.0)
// By: Lee Leibfarth
// 3-15-07
//
// TARGET : 610-Tick ER2
// ================================
inputs:
TradeSize(2),
Period(11),
Mult(3.5),
ProfitTargetAmount(250),
StopLossAmount(200),
IntradayStartTime(0940),
IntradayEndTime(1530);
variables:
RangeCalc(0),
StopLevel(0),
TradeDirection(0),
LStop(0),
SStop(0);
{========== Calculation Module ===========}
RangeCalc = xaverage((H - L), period);
LStop=maxlist(c[1] - RangeCalc * Mult, iff(l[1] < StopLevel[1], 0, StopLevel[1]) );
SStop=minlist(c[1] + RangeCalc * Mult, iff(h[1] > StopLevel[1], c*2, StopLevel[1]) );
if SStop > SStop[1] or h crosses over SStop then TradeDirection = 1;
if LStop < LStop[1] or l crosses under LStop then TradeDirection = -1;
if TradeDirection < 1 then StopLevel = SStop else StopLevel = LStop; {========== Entry Rules ===========}
if time > IntradayStartTime and time < IntradayEndTime and mp = 0 then begin
if TradeDirection[1] < 1 then buy ("ENTRY L") TradeSize contracts next bar at StopLevel stop;
if TradeDirection[1] > -1 then sellshort ("ENTRY S") TradeSize contracts next bar at StopLevel stop;
end;
{========== Exit Rules ===========}
if MP = 1 then begin
sell ("CHANNEL LS") TradeSize / 2 contracts next bar at entryprice - StopLossAmount / bigpointvalue stop;
if currentcontracts = TradeSize then begin
sell ("CHANNEL LX") TradeSize / 2 contracts next bar at entryprice + ProfitTargetAmount / bigpointvalue limit;
end;
sellshort ("TREND SE") TradeSize contracts next bar at Lstop stop;
end;
if MP = -1 then begin
buytocover ("CHANNEL SS") TradeSize / 2 contracts next bar at entryprice + StopLossAmount / bigpointvalue stop;
if currentcontracts = TradeSize then begin
buytocover ("CHANNEL SX") TradeSize / 2 contracts next bar at entryprice - ProfitTargetAmount / bigpointvalue limit;
end;
buy ("TREND LE") TradeSize contracts next bar at Sstop stop; end;
if marketposition <> 0 and time >=1600 then begin
- sell ("EOD SX")next bar at market;
buytocover ("EOD LX") next bar at market;
end;
setexitonclose;
TradeStation code for "Sharpening a countertrend strategy," p. 40
// ================================
// PP Stochastic (Version 1.0)
// By: Lee Leibfarth
// 6-23-07
//
// TARGET : Daily ER2
// ================================
inputs:
StochLength(8),
OverSoldLine(20),
OverBoughtLine(90),
StopLoss(800),
ProfitTarget(2200),
UsePositionSizing(true),
InitialAccount(40000),
InitMargin(4000),
RiskPercentage(.30);
variables:
TradeSize(1),
Balance(0),
oFastK(0),
oFastD(0),
oSlowK(0),
oSlowD(0);
value1 = Stochastic( h, l, c, StochLength, 3, 3, 1, oFastK, oFastD, oSlowK, oSlowD);
if UsePositionSizing then TradeSize = floor((InitialAccount + netprofit) * RiskPercentage / InitMargin);
if oFastK crosses over OverBoughtLine then sellshort ("ST_Sell") TradeSize contracts next bar at market ;
if oFastK crosses under OverSoldLine then buy ("ST_Buy") TradeSize contracts next bar at market ;
setstopcontract;
setstoploss(StopLoss);
setprofittarget(ProfitTarget);
AmiBroker code for "Testing the mean-reversion z-score system," p. 14.
Z-score system code:
// ZScore.afl
//
// z-score is a measure of the distance a single element
// of a data series is from the mean, measured in
// standard deviations.
function zscore(price,Length)
{
av = MA(price,Length);
st = StDev(price,Length);
zs = (price - av) / st;
return zs;
}
// The parameters that will be optimized
ZLength = Optimize("ZLen",4,2,50,2);
BuyLevel = Optimize("BuyLevel",-1.60,-3.00,0.00,0.02);
HoldDays = Optimize("HoldDays",5,1,10,1);
// Compute the z-score indicator
zz= zscore(C,ZLength);
// Enter the long position when the z-score rises
// through a specific level
Buy = Cross(zz,BuyLevel);
Sell = BarsSince(Buy)>=HoldDays;
Sell = ExRem(Sell,Buy);
// Plot the z-score and some reference levels
Plot(zz,"z-score",colorRed,styleLine|styleOwnScale,-2,2);
Plot(0,"0",colorRed,styleDots|styleOwnScale,-2,2);
Plot(1,"1",colorPink,styleDots|styleOwnScale,-2,2);
Plot(-1,"-1",colorPink,styleDots|styleOwnScale,-2,2);
Random entry code:
// RandomEntry.afl
//
// Example of a random entry trading system
//
// Be either Long or Flat.
// Generate signals after the close of daily bars.
//
// Take positions at the Close of the signal bar.
SetTradeDelays(0,0,0,0);
BuyPrice = Close;
SellPrice = Close;
dummy = Optimize("Dummy",1,1,100,1);
// Generate a random number, between 0.00 and 0.99
rn = Random();
// To be long 10% of the time, Buy if rn is <= 0.10
Buy = rn <= 0.10;
Sell = Ref(Buy,-1)==1;
// Compute the account equity.
e = Equity();
// Plot series of interest.
Plot(Close,"Close",colorBlack,styleCandle);
PlotShapes(shapeUpArrow*Buy+shapeDownArrow*Sell,
IIf(Buy,colorGreen,colorRed));
Plot(rn,"Random",colorBlue,styleLine|styleOwnScale);
Plot(e,"Equity",colorGreen,styleLine|styleOwnScale);
December 2007
Mechanica code for "Filtering Bollinger Band breakouts," p. 34.
'Resources
SYSTEM = 1
SLIPPAGE = 0
COL1 = CLOSE
COL2 = SMA[COL1,40]
COL3 = STD[COL1,40,0]
COL4 = 4 * COL3 / COL2
COL5 = SMA[LOW,20]
COL6 = SMA[HIGH,20]
COL7 = ATR[1]
COL8 = EMA[COL7,15]
SIZING[1] = POINTVALUE * COL8
'Trade Entry
STARTDATE = 19840101
IF HIGH[1] > COL2[1] + COL4[1] AND COL4[1] > 1.25 * COL4[5] THEN BUYOPEN
IF LOW[1] < COL2[1] - COL4[1] AND COL4[1] > 1.25 * COL4[5] THEN SELLOPEN
'Trade In Progress & Exit
SELLSTOP = COL5[1]
BUYSTOP = COL6[1]------NetAddressPart-00--=a8O4118S08475fd687
Content-Type: text/plain; name=OVOLEXP.siz..txt"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline; filename=OVOLEXP.siz..txt"
Money management code
STARTUPCASH = 1000000
NEWCONTRACTS = (.0075 * TOTALEQUITY) / SIZING[1]
AmiBroker code for "Designing and testing a pattern-based trading system," p. 22.
// ThreeDay.afl
//
// Buy when the low is lower than the
// lowest low of the previous three days.
// Short when the high is higher than the
// highest high of the previous three days.
//
// Long positions are entered using a
// limit order at the previous lowest low.
// Short positions are entered using a
// limit order at the previous highest high.
//
// Exit all positions at the Close after
// three days.
SetTradeDelays(0,0,0,0);
PriorLow = Ref(LLV(L,3),-1);
PriorHigh = Ref(HHV(H,3),-1);
BuyPrice = Min(PriorLow, Open);
SellPrice = Close;
ShortPrice = Max(PriorHigh, Open);
CoverPrice = Close;
FourDayLow = L
FourDayHigh = H>PriorHigh;
Buy = FourDayLow AND DayOfWeek()==3; // Wednesday
Sell = BarsSince(Buy)>=3;
Short = FourDayHigh AND DayOfWeek()==1; // Monday
Cover = BarsSince(Short)>=3;
**
// BuyMultiDayLow.afl
//
// AmiBroker code for a trading system
// that buys when the low of the day
// is lower than a multi-day low.
//
// BPSwitch chooses the BuyPrice to be either
// Close or PriorLow
// 0 == Prior Low; 1 == Close
BPSwitch = Optimize("BPSwitch",0,0,1,1);
// LLBBars determines how many days in the
// long multi-day look-back
LLBBars = Optimize("LLBBars",3,1,10,1);
// HoldDays determines how many days to
// hold the long position
LHoldDays = Optimize("LHoldDays",1,0,10,1);
// BuyDOW chooses which day of the week to buy.
// DayOfWeek() == 1 on Monday, 2 on Tuesday, ...
BuyDOW = Optimize("BuyDOW",2,1,5,1);
SetTradeDelays(0,0,0,0);
SellPrice = C;
PriorLow = Ref(LLV(L,LLBBars),-1);
BuyPrice = IIf(BPSwitch==1,C,PriorLow);
MultiDayLow = L
Buy = MultiDayLow AND DayOfWeek()==BuyDOW;
Sell = BarsSince(Buy)>=LHoldDays;
**
// SellMultiDayHigh.afl
//
// AmiBroker code for a trading system
// that sells when the high of the day
// is higher than a multi-day high.
//
// SPSwitch chooses the ShortPrice to be either
// Close or PriorHigh
// 0 == PriorHigh; 1 == Close
SPSwitch = Optimize("SPSwitch",1,0,1,1);
// SLBBars determines how many days in the
// short multi-day look-back
SLBBars = Optimize("SLBBars",10,1,10,1);
// SHoldDays determines how many days to
// hold the short position
SHoldDays = Optimize("SHoldDays",3,0,10,1);
// SellDOW chooses which day of the week to sell.
// DayOfWeek() == 1 on Monday, 2 on Tuesday, ...
SellDOW = Optimize("SellDOW",2,1,5,1);
SetTradeDelays(0,0,0,0);
CoverPrice = C;
PriorHigh = Ref(HHV(H,SLBBars),-1);
ShortPrice = IIf(SPSwitch==1,C,PriorHigh);
MultiDayHigh = H>PriorHigh;
Short = MultiDayHigh AND DayOfWeek()==SellDOW;
Cover = BarsSince(Short)>=SHoldDays;
Formulas for Symmetrical reversal bars, p. 30.
Symmetrical reversal up pattern (lower opens, higher closes):
1. ABS(H1 - H0) < 0.0625
2. ABS(L1 - L0) < 0.0625
3. (O1-L1)/(H1-L1) > 0.50
4. (C1-L1)/(H1-L1) < 0.50
5. (O0-L0)/(H0-L0) < 0.50
6. (C0-L0)/(H0-L0) > 0.50
where
O = open of the day
L = low of the day
H = high of the day
C = close of the day
ABS = absolute value
Subscripts0,1.., denote today, one day ago, etc.
Note: T-note prices trade in 32nds and halves of 32nds; prices have been converted to decimal equivalents for all the calculations.
Symmetrical reversal down pattern (higher opens, lower closes):
1. ABS(H1 - H0) < 0.0625
2. ABS(L1 - L0) < 0.0625
3. (O1-L1)/(H1-L1) < 0.50
4. (C1-L1)/(H1-L1) > 0.50
5. (O0-L0)/(H0-L0) > 0.50
6. (C0-L0)/(H0-L0) < 0.50
Treasury patterns
Bullish 1 (lower opens, higher closes):
1. ABS(H1 - H0) < 0.0625
2. ABS(L1 - L0) < 0.0625
3. (O1-L1)/(H1-L1) > 0.50
4. (C1-L1)/(H1-L1) < 0.50
5. (O0-L0)/(H0-L0) < 0.50
6. (C0-L0)/(H0-L0) > 0.50
where
O = open of the day
L = low of the day
H = high of the day
C = close of the day
ABS = absolute value
Subscripts0,1.., denote today, one day ago, etc.
Note: T-note prices trade in 32nds and halves of 32nds; prices have been converted to decimal equivalents for all the calculations.
Pattern definition 1 ("Bullish 2"):
1. ABS(H1 - H0) < 0.0625
2. ABS(L1 - L0) < 0.0625
3. (O1-L1)/(H1-L1) > 0.66
4. (C1-L1)/(H1-L1) < 0.33
5. (O0-L0)/(H0-L0) < 0.33
6. (C0-L0)/(H0-L0) > 0.66
Pattern definition 2 ("Bullish 3"):
1. ABS(H1 - H0) < 0.03125
2. ABS(L1 - L0) < 0.03125
3. (O1-L1)/(H1-L1) > 0.66
4. (C1-L1)/(H1-L1) < 0.33
5. (O0-L0)/(H0-L0) < 0.33
6. (C0-L0)/(H0-L0) > 0.66
Bearish patterns
Bearish 1 (higher opens, lower closes):
1. ABS(H1 - H0) < 0.0625
2. ABS(L1 - L0) < 0.0625
3. (O1-L1)/(H1-L1) < 0.50
4. (C1-L1)/(H1-L1) > 0.50
5. (O0-L0)/(H0-L0) > 0.50
6. (C0-L0)/(H0-L0) < 0.50
Pattern definition 1 ("Bearish 2"):
1. ABS(H1 - H0) < 0.0625
2. ABS(L1 - L0) < 0.0625
3. (O1-L1)/(H1-L1) < 0.66
4. (C1-L1)/(H1-L1) > 0.33
5. (O0-L0)/(H0-L0) > 0.33
6. (C0-L0)/(H0-L0) < 0.66
Pattern definition 2 ("Bearish 3"):
1. ABS(H1 - H0) < 0.03125
2. ABS(L1 - L0) < 0.03125
3. (O1-L1)/(H1-L1) < 0.66
4. (C1-L1)/(H1-L1) > 0.33
5. (O0-L0)/(H0-L0) > 0.33
6. (C0-L0)/(H0-L0) < 0.66
Euro/U.S. dollar currency pair (USD/EUR) patterns:
Bullish 1 (lower opens, higher closes):
1. ABS(H1 - H0) < 0.0002
2. ABS(L1 - L0) < 0.0002
3. (O1-L1)/(H1-L1) > 0.50
4. (C1-L1)/(H1-L1) < 0.50
5. (O0-L0)/(H0-L0) < 0.50
6. (C0-L0)/(H0-L0) > 0.50
Pattern definition 1 ("Bullish 2"):
1. ABS(H1 - H0) < 0.0002
2. ABS(L1 - L0) < 0.0002
3. (O1-L1)/(H1-L1) > 0.66
4. (C1-L1)/(H1-L1) < 0.33
5. (O0-L0)/(H0-L0) < 0.33
6. (C0-L0)/(H0-L0) > 0.66
Pattern definition 2 ("Bullish 3"):
1. ABS(H1 - H0) < 0.0001
2. ABS(L1 - L0) < 0.0001
3. (O1-L1)/(H1-L1) > 0.66
4. (C1-L1)/(H1-L1) < 0.33
5. (O0-L0)/(H0-L0) < 0.33
6. (C0-L0)/(H0-L0) > 0.66
Bearish patterns
Bearish 1 (higher opens, lower closes):
1. ABS(H1 - H0) < 0.0002
2. ABS(L1 - L0) < 0.0002
3. (O1-L1)/(H1-L1) < 0.50
4. (C1-L1)/(H1-L1) > 0.50
5. (O0-L0)/(H0-L0) > 0.50
6. (C0-L0)/(H0-L0) < 0.50
Pattern definition 1 ("Bearish 2"):
1. ABS(H1 - H0) < 0.0002
2. ABS(L1 - L0) < 0.0002
3. (O1-L1)/(H1-L1) < 0.66
4. (C1-L1)/(H1-L1) > 0.33
5. (O0-L0)/(H0-L0) > 0.33
6. (C0-L0)/(H0-L0) < 0.66
Pattern definition 2 ("Bearish 3"):
1. ABS(H1 - H0) < 0.0001
2. ABS(L1 - L0) < 0.0001
3. (O1-L1)/(H1-L1) < 0.66
4. (C1-L1)/(H1-L1) > 0.33
5. (O0-L0)/(H0-L0) > 0.33
6. (C0-L0)/(H0-L0) < 0.66
Mechanica code
Stop-and-reverse system (run using Simultest)
SYSTEM = 1
COL1 = MAX[H,80,1]
COL2 = MIN[L,80,1]
COL3 = ATR[20]
COL4 = CLOSE
SIZING[1] = COL3[1] * POINTVALUE[1]
STARTDATE = 19840101
'IF CLOSE[1] > COL1[1] THEN BUYOPEN
BUYSTOP = COL1[1]
'IF LONG > 0 AND CLOSE[1] < COL2[1] THEN SELLOPEN
IF LONG > 0 THEN SELLSTOP = COL2[1]
SYSTEM = 2
COL1 = MAX[H,80,1]
COL2 = MIN[L,80,1]
COL3 = ATR[20]
SIZING[1] = COL3[1] * POINTVALUE[1]
STARTDATE = 19840101
'IF CLOSE[1] < COL2[1] THEN SELLOPEN
SELLSTOP = COL2[1]
'IF SHORT > 0 AND CLOSE[1] > COL1[1] THEN BUYOPEN
IF SHORT > 0 THEN BUYSTOP = COL1[1]
Revised system
SYSTEM = 1
COL1 = MAX[H,80,1]
COL2 = MIN[L,80,1]
COL3 = MAX[H,20,1]
COL4 = MIN[L,20,1]
COL5 = ATR[20]
SIZING[1] = COL5[1] * POINTVALUE[1]
STARTDATE = 19840101
BUYSTOP = COL1[1]
SELLSTOP = COL2[1]
IF LONG > 0 THEN SELLSTOP = COL4[1]
IF SHORT > 0 THEN BUYSTOP = COL3[1]
Money management code (both systems)
STARTDATE = 19840101
STARTUPCASH = 1000000
NEWCONTRACTS = (TOTALEQUITY * .02) / NEWRISK
May 2008 "System death: When good systems go bad"
Mechanica code
55-21 breakout system
SYSTEM = 1
COL1 = HIGH[55]
COL2 = LOW[21]
COL3 = LOW[55]
COL4 = HIGH[21]
COL5 = CLOSE
COL6 = ATR[1]
COL7 = EMA[COL6,15]
SIZING[1] = POINTVALUE * COL7
'Entry Code
IF CLOSE[1] > COL1[1] THEN BUYOPEN
IF CLOSE[1] < COL3[1] THEN SELLOPEN
'Exit Code
IF LONG > 0 THEN SELLSTOP = COL2[1]
IF SHORT > 0 THEN BUYSTOP = COL4[1]
80-20 MA crossover system
SYSTEM = 2
COL1 = CLOSE
COL2 = EMA[COL1,20]
COL3 = EMA[COL1,80]
COL6 = ATR[1]
COL7 = EMA[COL6,15]
SIZING[1] = POINTVALUE * COL7
'Entry Code
IF COL2[1] > COL3[1] THEN BUYOPEN
'Exit Code
IF LONG > 0 AND DAYSINTRADE = 1 THEN MEMORY[1] = COL2[1] - 4 * COL7[1]
IF LONG > 0 AND DAYSINTRADE > 1 THEN SELLSTOP = MEMORY[1]
IF LONG > 0 AND COL2[1] < COL3[1] THEN SELLOPEN
SYSTEM = 1
COL1 = CLOSE
COL2 = EMA[COL1,20]
COL3 = EMA[COL1,80]
COL6 = ATR[1]
COL7 = EMA[COL6,15]
SIZING[1] = POINTVALUE * COL7
'Entry Code
IF COL2[1] < COL3[1] THEN SELLOPEN
'Exit Code
IF SHORT > 0 AND DAYSINTRADE = 1 THEN MEMORY[1] = COL2[1] + 4 * COL7[1]
IF SHORT > 0 AND DAYSINTRADE > 1 THEN BUYSTOP = MEMORY[1]
IF SHORT > 0 AND COL2[1] > COL3[1] THEN BUYOPEN
Money management code (both systems)
STARTDATE = 19860101
STARTUPCASH = 1500000
NEWCONTRACTS = (.005 * TOTALEQUITY) / SIZING[1]
February 2009
TradeStation code for Joe Krutsinger's "Trading late-day breakouts" in the February 2009 issue of Active Trader.
Inputs: StopLossAmt(500),Tim(1330);
June 2009
TradeStation code for “System design, part 5: Searching for the exit,”
in the June 2009 issue of Active Trader.
Entry rule
{Notes: The “L2Lmove” variable represents the difference between the
most recent low and the low two bars earlier.}
inputs: dropsize(.021);
if low < low[1]
and low[1] < low[2]
and high < high[1]
and high[1] < high[2]
and close < close[1]
and close[1] < close[2]
and close[2] < close[3]
and (low[2] - low)/low[2] > dropsize
then
sell next bar at the open;
Momentum indicator exit rule
{Notes: The “Length” input represents the look-back period for the
momentum calculation; the “SellThresh” input represents the level the momentum
calculation must meet or exceed to the upside to indicate an “overbought”
condition and a sell signal.}
inputs: Length(32), SellThresh(.62);
Value1 = (close
today-lowest(low,length))/(highest(high,length)-lowest(low,length));
If
BarsSinceEntry >1 and
Value1 >= OBThresh then
sell next bar at the open;
AmiBroker code
SetTradeDelays(
0, 0, 1, 1 );
Length = 7;
// this is the momentum lookback period.
SellThres =
0.75; //this is the overbought sell value for momentum
L2LMove =
-0.021; // this is the drop amount
Length =
Optimize( "length", 7, 5, 20, 5); // Optimizing Momentum lookback
period daf =7, min=5, max=20, step=1
SellThres =
Optimize( "sellthres", 0.75, 0.50, 1, 0.10); // Optimizing Mom Sell
Threshold def =0.75, min=0.50, max=1,step 0.10
//L2Lmove =
Optimize( "L2LMove", 0.021, 0.01, 0.04, 0.01); //Optimizing drop amount
def=2.1%, min 1%, max=4%, step =1%%
MyMomentum
= ( ( Close - LLV ( Low , Length ) ) / ( HHV ( High , Length )- LLV ( Low , Length ) ) ) ;
Buy = Low < Ref( Low , -1 )
SetOption(
"MaxOpenPositions", 5 );
SetOption(
"InitialEquity", 50000 );
PositionSize =
-100;
// removed
n-bar stop
Sell = MyMomentum
>= SellThres;
Short = 0;
Cover = 0;
July 2009
TradeStation code for “Trading
system design, part 6: Adjusting to reality,” in the July issue of Active
Trader
Entry rule
Trade entry initially occurred after
a series of three consecutive
lower closes, two consecutive lower
highs and lower lows and a
certain percentage-size
drop from the low two days ago to
the most recent low:
If low <
low[1]
and low[1]
< low[2]
and high
< high[1]
and high[1]
< high[2]
and close
< close[1]
and
close[1] < close[2]
and
close[2] < close[3]
and (low[2]
- low)/low[2] >= percent
then buy tomorrow at the open;
These rules were modified based on
the initial test results to:
if low < low[1]
and low[1] < low[2]
and high < high[1]
and high[1] < high[2]
and close < close[1]
and close[1] < close[2]
and close[2] < close[3]
and (low[2] - low)/low[2] >=
median(TrueRange(10))
Then buy today at the close
Momentum
indicator exit rule
{Notes: The
“Length” input represents the look-back period for the momentum calculation;
the “SellThresh” input represents the level the momentum calculation must meet
or exceed to the upside to indicate an “overbought” condition and a sell
signal.}
inputs:
Length(32), SellThresh(.62);
Value1
= (close
today-lowest(low,length))/(highest(high,length)-lowest(low,length));
If
BarsSinceEntry
>1 and
Value1
>= OBThresh then
sell next bar at the open;
TradeStation code for “Three-day pullback volatility setup,” by Johnan Prathap in the September issue of Active Trader