# Ultimate ATR Combo
# Investing to Give
declare upper;
input averageType = AverageType.EXPONENTIAL;
# Fast ATR TS
input trailType = {default modified, unmodified};
input ATRPeriod = 10;
input ATRFactor = 3.0;
input firstTrade = {default long, short};
Assert(ATRFactor > 0, "'atr factor' must be positive: " + ATRFactor);
def HiLo = Min(high - low, 1.5 * Average(high - low, ATRPeriod));
def HRef = if low <= high[1]
then high - close[1]
else (high - close[1]) - 0.5 * (low - high[1]);
def LRef = if high >= low[1]
then close[1] - low
else (close[1] - low) - 0.5 * (low[1] - high);
def trueRange;
switch (trailType) {
case modified:
trueRange = Max(HiLo, Max(HRef, LRef));
case unmodified:
trueRange = TrueRange(high, close, low);
}
def loss = ATRFactor * MovingAverage(averageType, trueRange, ATRPeriod);
def state = {default init, long, short};
def trail;
switch (state[1]) {
case init:
if (!IsNaN(loss)) {
switch (firstTrade) {
case long:
state = state.long;
trail = close - loss;
case short:
state = state.short;
trail = close + loss;
}
} else {
state = state.init;
trail = Double.NaN;
}
case long:
if (close > trail[1]) {
state = state.long;
trail = Max(trail[1], close - loss);
} else {
state = state.short;
trail = close + loss;
}
case short:
if (close < trail[1]) {
state = state.short;
trail = Min(trail[1], close + loss);
} else {
state = state.long;
trail = close - loss;
}
}
def BuySignal = Crosses(state == state.long, 0, CrossingDirection.ABOVE);
def SellSignal = Crosses(state == state.short, 0, CrossingDirection.ABOVE);
def Buy_Zone = state == state.long;
def Sell_Zone = state == state.short;
# plot Buy = Buy_Zone[1] == 0 and Buy_Zone;
# plot Sell = Sell_Zone[1] == 0 and Sell_Zone;
plot TrailingStop = trail;
TrailingStop.SetPaintingStrategy(PaintingStrategy.Line);
TrailingStop.DefineColor("Buy", GetColor(5));
TrailingStop.DefineColor("Sell", GetColor(6));
TrailingStop.SetLineWeight(3);
TrailingStop.AssignValueColor(if state == state.long
then TrailingStop.Color("Sell")
else TrailingStop.Color("Buy"));
# Slow ATR TS
input trailType_Slow = {default modified_Slow, unmodified_Slow};
input ATRPeriod_Slow = 30;
input ATRFactor_Slow = 10.0;
input firstTrade_Slow = {default long_Slow, short_Slow};
Assert(ATRFactor_Slow > 0, "'atr factor' must be positive: " + ATRFactor_Slow);
def HiLo_Slow = Min(high - low, 1.5 * Average(high - low, ATRPeriod_Slow));
def HRef_Slow = if low <= high[1]
then high - close[1]
else (high - close[1]) - 0.5 * (low - high[1]);
def LRef_Slow = if high >= low[1]
then close[1] - low
else (close[1] - low) - 0.5 * (low[1] - high);
def trueRange_Slow;
switch (trailType_Slow) {
case modified_Slow:
trueRange_Slow = Max(HiLo_Slow, Max(HRef_Slow, LRef_Slow));
case unmodified_Slow:
trueRange_Slow = TrueRange(high, close, low);
}
def loss_Slow = ATRFactor_Slow * MovingAverage(averageType, trueRange_Slow, ATRPeriod_Slow);
def state_Slow = {default init_Slow, long_Slow, short_Slow};
def trail_Slow;
switch (state_Slow[1]) {
case init_Slow:
if (!IsNaN(loss_Slow)) {
switch (firstTrade_Slow) {
case long_Slow:
state_Slow = state_Slow.long_Slow;
trail_Slow = close - loss_Slow;
case short_Slow:
state_Slow = state_Slow.short_Slow;
trail_Slow = close + loss_Slow;
}
} else {
state_Slow = state_Slow.init_Slow;
trail_Slow = Double.NaN;
}
case long_Slow:
if (close > trail_Slow[1]) {
state_Slow = state_Slow.long_Slow;
trail_Slow = Max(trail_Slow[1], close - loss_Slow);
} else {
state_Slow = state_Slow.short_Slow;
trail_Slow = close + loss_Slow;
}
case short_Slow:
if (close < trail_Slow[1]) {
state_Slow = state_Slow.short_Slow;
trail_Slow = Min(trail_Slow[1], close + loss_Slow);
} else {
state_Slow = state_Slow.long_Slow;
trail_Slow = close - loss_Slow;
}
}
def BuySignal_Slow = Crosses(state_Slow == state_Slow.long_Slow, 0, CrossingDirection.ABOVE);
def SellSignal_Slow = Crosses(state_Slow == state_Slow.short_Slow, 0, CrossingDirection.ABOVE);
def Buy_Zone_Slow = state_Slow == state_Slow.long_Slow;
def Sell_Zone_Slow = state_Slow == state_Slow.short_Slow;
plot TrailingStop_Slow = trail_Slow;
TrailingStop_Slow.SetPaintingStrategy(PaintingStrategy.Line);
TrailingStop_Slow.DefineColor("Buy", GetColor(5));
TrailingStop_Slow.DefineColor("Sell", GetColor(6));
TrailingStop_Slow.SetLineWeight(3);
TrailingStop_Slow.AssignValueColor(if state_Slow == state_Slow.long_Slow
then TrailingStop_Slow.Color("Sell")
else TrailingStop_Slow.Color("Buy"));
def Buy = Buy_Zone and Buy_Zone_Slow;
def Sell = Sell_Zone and Sell_Zone_Slow;
AssignPriceColor (if Buy then Color.GREEN else if Sell then Color.RED else Color.YELLOW);
# End