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
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
Spreadsheet for Small-trader money management, by Thomas Stridsman, p. 32
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;
}
From the article "The six signal composite indicator," by Art Collins.
Component formulas
This code can be copied at www.activetradermag.com/code.htm. (Or, select "Strategy code" from the "Tools and resources" menu on the left side of the page.)
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
if (range
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 buy next bar at market;
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 average(c,2)
if average(c,2)>average(c,5)then aa=-1;
if c>average(c,40) then bb=1;
if c
if highestbar(c,50)>lowestbar(c,50) then cc=1;
if highestbar(c,50)
if (range
if (range
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;
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++