Jack Sprat
New member
Hi everyone~
I've been trying to write a strategy combining the PSAR and the MA Crossover indicators listed below. For the past week I've been trying to write a way to place an order when :
1. PSAR is bullish and fast MA has crossed over slow MA
2. PSAR is bearish and slow MA has crossed over fast MA
but for the life of me I can't seem to get agreement when both occur on one chart versus plotting each on separate charts. Any help would be greatly greatly appreciated. I have been able to get the first condition but still no luck on the second.
# This study looks for a PSAR state transition (either from bullish to bearish
# or vice versa) and plots a horizontal price line into the expansion area. If
# the state transition already triggered, it calculates the number of bars ago
# the event happened. I've included labels, alerts as well as chart bubbles
input accelerationFactor = 0.02;
input accelerationLimit = 0.2;
input offSet = 2;
Assert(accelerationFactor > 0, "'acceleration factor' must be positive: " + accelerationFactor);
Assert(accelerationLimit >= accelerationFactor, "'acceleration limit' (" + accelerationLimit + ") must be greater than or equal to 'acceleration factor' (" + accelerationFactor + ")");
def bar = BarNumber();
def state = {default init, long, short};
def extreme;
def SAR;
def acc;
switch (state[1]) {
case init:
state = state.long;
acc = accelerationFactor;
extreme = high;
SAR = low;
case short:
if (SAR[1] < high)
then {
state = state.long;
acc = accelerationFactor;
extreme = high;
SAR = extreme[1];
} else {
state = state.short;
if (low < extreme[1])
then {
acc = Min(acc[1] + accelerationFactor, accelerationLimit);
extreme = low;
} else {
acc = acc[1];
extreme = extreme[1];
}
SAR = Max(Max(high, high[1]), SAR[1] + acc * (extreme - SAR[1]));
}
case long:
if (SAR[1] > low)
then {
state = state.short;
acc = accelerationFactor;
extreme = low;
SAR = extreme[1];
} else {
state = state.long;
if (high > extreme[1])
then {
acc = Min(acc[1] + accelerationFactor, accelerationLimit);
extreme = high;
} else {
acc = acc[1];
extreme = extreme[1];
}
SAR = Min(Min(low, low[1]), SAR[1] + acc * (extreme - SAR[1]));
}
}
plot parSAR = SAR;
parSAR.SetPaintingStrategy(PaintingStrategy.POINTS);
parSAR.SetDefaultColor(GetColor(5));
def transitionBull = state[1] == state.short and state == state.long;
def transitionBear = state[1] == state.long and state == state.short;
def transitionBar = if transitionBull or transitionBear
then bar
else transitionBar[1];
def transitionPrice = if bar == (transitionBar)
then close
else transitionPrice[1];
def transitionBarsAgo = if bar != transitionBar
then bar - transitionBar
else if bar == transitionBar
then Double.NaN
else transitionBarsAgo[1];
def timeAxis = if IsNaN(close[-1]) and !IsNaN(close) then bar else timeAxis[1];
def hline = if GetTime() <= RegularTradingEnd(GetYYYYMMDD()) and
transitionBar == (transitionBar)
then transitionPrice
else hline[1];
plot horizLine = hline;
horizLine.SetLineWeight(2);
horizLine.SetDefaultColor(Color.YELLOW);
AddLabel(transitionBull or transitionBear, "PSAR Transition Detected Now!", Color.YELLOW);
AddLabel(!(transitionBull or transitionBear), "PSAR Transition " + transitionBarsAgo + " bars ago", Color.CYAN);
Alert(transitionBull, "PSAR Transition Bull", Alert.BAR, Sound.Ding);
Alert(transitionBear, "PSAR Transition Bear", Alert.BAR, Sound.Ring);
AddChartBubble(bar == HighestAll(timeAxis + offSet), transitionPrice, "PSAR\nTransitioned", Color.WHITE);
input showpricecolor = yes;
def bull = if transitionBull then 1 else if bull[1] == 1 and !transitionBear then 1 else 0;
AssignPriceColor(if !showpricecolor then Color.CURRENT else if bull and close > hline then Color.WHITE else if !bull and close < hline then Color.RED else Color.BLACK);
def cond11 = if bull and close > hline then 1 else 0;
def cond22 = if !bull and close < hline then 1 else 0;
#addverticalline( cond11, "UP", color.green, curve.firm );
#addverticalline( cond22, "DOWN", color.red, curve.firm );
#AssignBackgroundColor(if cond11 then color.light_green else if cond22 then color.light_red else Color.BLACK);
input EMAPeriod = 10;
input EMAPeriod2 = 21;
input price = close;
def na = Double.NaN;
plot fastema = ExpAverage(price, EMAPeriod);
plot slowema = ExpAverage(price, EMAPeriod2);
def crossover = if fastema > slowema and fastema[1] <= slowema[1] then 1 else 0;
def crossunder = if fastema < slowema and fastema[1] >= slowema[1] then 1 else 0;
#Plot arrows
plot up = if crossover then low - TickSize() else na;
plot down = if crossunder then high + TickSize() else na;
up.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
down.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
#Trigger alerts
Alert(crossover[1], "Crossover", Alert.BAR, Sound.Bell);
Alert(crossunder[1], "Crossunder", Alert.BAR, Sound.Bell);
#BUY
plot sma1 = cond11;
plot sma2 = crossover;
def cond1 = cond11 and crossover;
def close1 = if cond1 then close else close1[1];
plot cond2 = if cond1 and close > close1[1] then 1 else 0;
cond2.setpaintingstrategy(paintingstrategy.boolean_arrow_up);
input debug = yes;
addchartbubble(debug and cond1, high, close1, color.white);
#SELL
plot sma11 = cond22;
plot sma22 = crossunder;
def cond3 = cond22 and crossunder;
def close2 = if cond3 then close else close2[1];
plot cond4 = if cond3 and close > close2[1] then 1 else 0;
cond4.setpaintingstrategy(paintingstrategy.boolean_arrow_down);
addchartbubble(debug and cond3, low, close2, color.red);
#addorder(ordertype.buy_TO_CLOSE, cond2);
#AddOrder(OrderType.BUY_AUTO, cond2);
#addOrder(OrderType.SELL_TO_CLOSE, cond4);
#addOrder(OrderType.SELL_AUTO, cond4);
I've been trying to write a strategy combining the PSAR and the MA Crossover indicators listed below. For the past week I've been trying to write a way to place an order when :
1. PSAR is bullish and fast MA has crossed over slow MA
2. PSAR is bearish and slow MA has crossed over fast MA
but for the life of me I can't seem to get agreement when both occur on one chart versus plotting each on separate charts. Any help would be greatly greatly appreciated. I have been able to get the first condition but still no luck on the second.
# This study looks for a PSAR state transition (either from bullish to bearish
# or vice versa) and plots a horizontal price line into the expansion area. If
# the state transition already triggered, it calculates the number of bars ago
# the event happened. I've included labels, alerts as well as chart bubbles
input accelerationFactor = 0.02;
input accelerationLimit = 0.2;
input offSet = 2;
Assert(accelerationFactor > 0, "'acceleration factor' must be positive: " + accelerationFactor);
Assert(accelerationLimit >= accelerationFactor, "'acceleration limit' (" + accelerationLimit + ") must be greater than or equal to 'acceleration factor' (" + accelerationFactor + ")");
def bar = BarNumber();
def state = {default init, long, short};
def extreme;
def SAR;
def acc;
switch (state[1]) {
case init:
state = state.long;
acc = accelerationFactor;
extreme = high;
SAR = low;
case short:
if (SAR[1] < high)
then {
state = state.long;
acc = accelerationFactor;
extreme = high;
SAR = extreme[1];
} else {
state = state.short;
if (low < extreme[1])
then {
acc = Min(acc[1] + accelerationFactor, accelerationLimit);
extreme = low;
} else {
acc = acc[1];
extreme = extreme[1];
}
SAR = Max(Max(high, high[1]), SAR[1] + acc * (extreme - SAR[1]));
}
case long:
if (SAR[1] > low)
then {
state = state.short;
acc = accelerationFactor;
extreme = low;
SAR = extreme[1];
} else {
state = state.long;
if (high > extreme[1])
then {
acc = Min(acc[1] + accelerationFactor, accelerationLimit);
extreme = high;
} else {
acc = acc[1];
extreme = extreme[1];
}
SAR = Min(Min(low, low[1]), SAR[1] + acc * (extreme - SAR[1]));
}
}
plot parSAR = SAR;
parSAR.SetPaintingStrategy(PaintingStrategy.POINTS);
parSAR.SetDefaultColor(GetColor(5));
def transitionBull = state[1] == state.short and state == state.long;
def transitionBear = state[1] == state.long and state == state.short;
def transitionBar = if transitionBull or transitionBear
then bar
else transitionBar[1];
def transitionPrice = if bar == (transitionBar)
then close
else transitionPrice[1];
def transitionBarsAgo = if bar != transitionBar
then bar - transitionBar
else if bar == transitionBar
then Double.NaN
else transitionBarsAgo[1];
def timeAxis = if IsNaN(close[-1]) and !IsNaN(close) then bar else timeAxis[1];
def hline = if GetTime() <= RegularTradingEnd(GetYYYYMMDD()) and
transitionBar == (transitionBar)
then transitionPrice
else hline[1];
plot horizLine = hline;
horizLine.SetLineWeight(2);
horizLine.SetDefaultColor(Color.YELLOW);
AddLabel(transitionBull or transitionBear, "PSAR Transition Detected Now!", Color.YELLOW);
AddLabel(!(transitionBull or transitionBear), "PSAR Transition " + transitionBarsAgo + " bars ago", Color.CYAN);
Alert(transitionBull, "PSAR Transition Bull", Alert.BAR, Sound.Ding);
Alert(transitionBear, "PSAR Transition Bear", Alert.BAR, Sound.Ring);
AddChartBubble(bar == HighestAll(timeAxis + offSet), transitionPrice, "PSAR\nTransitioned", Color.WHITE);
input showpricecolor = yes;
def bull = if transitionBull then 1 else if bull[1] == 1 and !transitionBear then 1 else 0;
AssignPriceColor(if !showpricecolor then Color.CURRENT else if bull and close > hline then Color.WHITE else if !bull and close < hline then Color.RED else Color.BLACK);
def cond11 = if bull and close > hline then 1 else 0;
def cond22 = if !bull and close < hline then 1 else 0;
#addverticalline( cond11, "UP", color.green, curve.firm );
#addverticalline( cond22, "DOWN", color.red, curve.firm );
#AssignBackgroundColor(if cond11 then color.light_green else if cond22 then color.light_red else Color.BLACK);
input EMAPeriod = 10;
input EMAPeriod2 = 21;
input price = close;
def na = Double.NaN;
plot fastema = ExpAverage(price, EMAPeriod);
plot slowema = ExpAverage(price, EMAPeriod2);
def crossover = if fastema > slowema and fastema[1] <= slowema[1] then 1 else 0;
def crossunder = if fastema < slowema and fastema[1] >= slowema[1] then 1 else 0;
#Plot arrows
plot up = if crossover then low - TickSize() else na;
plot down = if crossunder then high + TickSize() else na;
up.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
down.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
#Trigger alerts
Alert(crossover[1], "Crossover", Alert.BAR, Sound.Bell);
Alert(crossunder[1], "Crossunder", Alert.BAR, Sound.Bell);
#BUY
plot sma1 = cond11;
plot sma2 = crossover;
def cond1 = cond11 and crossover;
def close1 = if cond1 then close else close1[1];
plot cond2 = if cond1 and close > close1[1] then 1 else 0;
cond2.setpaintingstrategy(paintingstrategy.boolean_arrow_up);
input debug = yes;
addchartbubble(debug and cond1, high, close1, color.white);
#SELL
plot sma11 = cond22;
plot sma22 = crossunder;
def cond3 = cond22 and crossunder;
def close2 = if cond3 then close else close2[1];
plot cond4 = if cond3 and close > close2[1] then 1 else 0;
cond4.setpaintingstrategy(paintingstrategy.boolean_arrow_down);
addchartbubble(debug and cond3, low, close2, color.red);
#addorder(ordertype.buy_TO_CLOSE, cond2);
#AddOrder(OrderType.BUY_AUTO, cond2);
#addOrder(OrderType.SELL_TO_CLOSE, cond4);
#addOrder(OrderType.SELL_AUTO, cond4);
Last edited: