# MA Crossover Cloud (Pine Script Conversion to ThinkScript)
# Based on the Pine Script "MA Crossover Cloud" indicator
declare lower; # Can be 'declare lower;' or 'declare upper;' or 'declare once_per_bar;'
declare once_per_bar;
# --- 1. Define Inputs ---
input priceSource = close;
input length1 = 10;
input length2 = 20;
input averageType = {default "EMA", "SMA", "WMA", "WildersMA", "HullMA", "HWEMA"};
input hwemaAlpha = 1.0; # Alpha parameter for HWEMA smoothing
# --- 2. Moving Average Custom Functions / Logic ---
# Hull Weighted Exponential Moving Average (HWEMA) Logic
# This requires a variable to persist state, we'll use a compound assignment for the EMA part
def wmaVal = WMA(priceSource, length1); # WMA for MA1
def wmaVal2 = WMA(priceSource, length2); # WMA for MA2
def wemaMA1;
if IsNaN(wemaMA1[1]) {
# Initialize the first bar with WMA value
wemaMA1 = wmaVal;
} else {
# The EMA part: Alpha * WMA + (1 - Alpha) * Previous WEMA
wemaMA1 = hwemaAlpha * wmaVal + (1 - hwemaAlpha) * wemaMA1[1];
}
def wemaMA2;
if IsNaN(wemaMA2[1]) {
wemaMA2 = wmaVal2;
} else {
wemaMA2 = hwemaAlpha * wmaVal2 + (1 - hwemaAlpha) * wemaMA2[1];
}
# The final HWEMA is the HMA of the WEMA
# HMA is calculated as: WMA(2*WMA(src, len/2) - WMA(src, len), Sqrt(len))
# This is an approximation since ThinkScript doesn't have a built-in HMA function.
# For simplicity and direct translation, we'll use a common HMA formula:
def hmaMA1 = WMA(2 * WMA(wemaMA1, length1 / 2) - WMA(wemaMA1, length1), Round(Sqrt(length1)));
def hmaMA2 = WMA(2 * WMA(wemaMA2, length2 / 2) - WMA(wemaMA2, length2), Round(Sqrt(length2)));
# --- 3. Universal MA Selector Logic (getMA) ---
def ma1;
switch (averageType) {
case "SMA":
ma1 = Average(priceSource, length1);
case "WMA":
ma1 = WMA(priceSource, length1);
case "WildersMA":
ma1 = WildersAvg(priceSource, length1);
case "HullMA":
# Simplified HMA calculation for MA1
ma1 = WMA(2 * WMA(priceSource, length1 / 2) - WMA(priceSource, length1), Round(Sqrt(length1)));
case "HWEMA":
ma1 = hmaMA1; # Use the custom calculated HWEMA
default: # EMA
ma1 = ExpAverage(priceSource, length1);
}
def ma2;
switch (averageType) {
case "SMA":
ma2 = Average(priceSource, length2);
case "WMA":
ma2 = WMA(priceSource, length2);
case "WildersMA":
ma2 = WildersAvg(priceSource, length2);
case "HullMA":
# Simplified HMA calculation for MA2
ma2 = WMA(2 * WMA(priceSource, length2 / 2) - WMA(priceSource, length2), Round(Sqrt(length2)));
case "HWEMA":
ma2 = hmaMA2; # Use the custom calculated HWEMA
default: # EMA
ma2 = ExpAverage(priceSource, length2);
}
# --- 4. Define Colors and Plotting (Slope-Based Colors) ---
# Define Colors
DefineColor("LineUp", Color.LIME);
DefineColor("LineDown", Color.RED);
DefineColor("LineNeutral", Color.GRAY);
# Determine MA1 Color based on Slope (ma1 > ma1[1])
def ma1Up = ma1 > ma1[1];
def ma1Down = ma1 < ma1[1];
plot PlotMA1 = ma1;
PlotMA1.SetLineWeight(2);
PlotMA1.DefineColor("LineUp", Color.LIME);
PlotMA1.DefineColor("LineDown", Color.RED);
PlotMA1.DefineColor("LineNeutral", Color.GRAY);
PlotMA1.AssignValueColor(if ma1Up then Color.LIME else if ma1Down then Color.RED else Color.GRAY);
# Determine MA2 Color based on Slope (ma2 > ma2[1])
def ma2Up = ma2 > ma2[1];
def ma2Down = ma2 < ma2[1];
plot PlotMA2 = ma2;
PlotMA2.SetLineWeight(2);
PlotMA2.DefineColor("LineUp", Color.LIME);
PlotMA2.DefineColor("LineDown", Color.RED);
PlotMA2.DefineColor("LineNeutral", Color.GRAY);
PlotMA2.AssignValueColor(if ma2Up then Color.LIME else if ma2Down then Color.RED else Color.GRAY);
# --- 5. Cloud Plotting (Crossover Logic) ---
# Define Cloud Colors (using semi-transparent colors)
# ThinkScript doesn't have a direct 'color.new(color, transparency)' like Pine Script.
# We define colors with a custom transparency property.
# The cloud remains based on the crossover relationship (MA1 > MA2)
def ma1Greater = ma1 > ma2;
# Assign the cloud fill between the two plots
AddCloud(PlotMA1, PlotMA2,
if ma1Greater then Color.GREEN else Color.RED,
if ma1Greater then Color.GREEN else Color.RED
);