Higher TimeFrame Smooth Moving Averages
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © EsIstTurnt

//@version=5
indicator("Higher TimeFrame Smooth Moving Averages",shorttitle="HTFSMA",overlay=true)
float src      = input.source(close)                                                                                            // Choose source
bool showZigZag= input.bool(false,"Show Higher TimeFrame ZigZag MA")                                                            // Show the Moving Average that is being smoothened out 
int len = input.int(8,"Moving Average Length")                                                                                  // Length of Higher timeframe Moving Avgerage 
string maType = input.string("SMA", "MA type", options = ["SMA","WMA","LRC","EMA","DEMA","TEMA","TRIMA","FRAMA"])               // Select Moving Average type to use
int targetTFmult= input.int(1,"TimeFrame Multiplier  ('X' Hours/Days/etc..., )")                                                // Select the timeFrame multiplier ( 4 for 4H timeframe, 1 for 1D , 1 for 1H)
string targetTFtype=input.string("Days","TimeFrame Denomination",options=["Seconds","Minutes","Hours","Days","Weeks","Months"])// Select the time denomination of the higher timeframe moving average
translate = switch targetTFtype                                                                                                 // \
    "Seconds"=>"S"                                                                                                              //  \
    "Minutes"=>""                                                                                                               //   \
    "Hours"=>""                                                                                                                 //    - Translating TimeFrame Denomination to a usable suffix
    "Days"=>"D"                                                                                                                 //   /
    "Weeks"=>"W"                                                                                                                //  /
    "Months"=>"M"                                                                                                               // /

string targetTF= targetTFtype=="Hours"? str.tostring(targetTFmult*60)+translate:str.tostring(targetTFmult)+translate            // Combine the Multiplier and Denomination selected above, but '3H' for example does not work so if Hours is selected, multiply multiplier by 60 for same result

import TradingView/ta/4 as f                                                                                                    // Importing ta library by TradingView for their moving averages that allow series as length - https://www.tradingview.com/script/BICzyhq0-ta/
sma(src,p) => a = ta.cum(src), (a - a[math.max(p,0)])/math.max(p,0)                                                             // SMA function from @author=alexgrover, for PineCoders - https://www.tradingview.com/script/kY5hhjA7-Functions-Allowing-Series-As-Length-PineCoders-FAQ/
//Script 
noZigZag(src)=>
    currentTF=timeframe.period                                                                                      //     Get chart timeframe
    q=0                                                                                                             //     Create a placeholder integer for future use
    target_s =timeframe.in_seconds(targetTF )                                                                       //  \
                                                                                                                    //   - Translate current And chosen timeframe into seconds So we can compare 
    current_s=timeframe.in_seconds(currentTF)                                                                       //  /


    if target_s<current_s                                                                                           //   \
        runtime.error("Check Settings and/or Chart Timeframe: Selected Timeframe Smaller than Chart Timeframe")     //    \
    else                                                                                                            //     \
        if target_s/current_s*len >=5000                                                                            //      -  Checks if selected timeframe is Larger than chart timeframe, but not so large that
            runtime.error("Check Settings and/or Chart Timeframe: Chart Timeframe Too Small for Selected Timeframe")//     /     too many bars would be necessary before a quotient is calculated by dividing
        else                                                                                                        //    /      the chosen TimeFrame by the chart timeframe (Values in Seconds for Common Denominator)
            q:=target_s/current_s// Replace placeholder integer "q" with quotient                                        /
    
    int candles = q*len //- Take Quotient from above ("q") and Multiply it by the Chosen length. This gives us how many Bars of the Chart's TimeFrame would be used in Calculating the Higher TimeFrame Moving Average
    
    float ma = switch maType                 // \
        "SMA"   => sma      (src,candles)    //  \
        "WMA"   => ta.wma   (src,candles)    //   \
        "LRC"   => ta.linreg(src,candles,0)  //    \
        "EMA"   => f.ema2   (src,candles)    //     - Get the higher timeframe moving average by using the value from above ("candles") as the length
        'DEMA'  => f.dema2  (src,candles)    //    /
        'TEMA'  => f.tema2  (src,candles)    //   / 
        'TRIMA' => f.trima2 (src,candles)    //  / 
        'FRAMA' => f.frama  (src,candles)    // / 
    ma


// Function to show what the script is attempting to smoothen out---------------------------------------------------------
ZigZag(src)=>                           //                                                                                |     
    float zigzag = switch maType        //   \                                                                            |
        "SMA"   => sma      (src,len)   //    \                                                                           |
        "WMA"   => ta.wma   (src,len)   //     \                                                                          |
        "LRC"   => ta.linreg(src,len,0) //      \                                                                         |
        "EMA"   => f.ema2   (src,len)   //        - Basic Moving Average calculation using same inputs from above         |
        'DEMA'  => f.dema2  (src,len)   //      /                                                                         |
        'TEMA'  => f.tema2  (src,len)   //     /                                                                          |
        'TRIMA' => f.trima2 (src,len)   //    /                                                                           |
        'FRAMA' => f.frama  (src,len)   //   /                                                                            |
                                                            //                                                            | 
    sym= request.security(syminfo.ticker,targetTF ,zigzag)  // using request.security to access the higher timeframe      |
    sym                                                     //   moving average. (produces an ugly zigzag line)           | 
//------------------------------------------------------------------------------------------------------------------------
//Calculate using functions above with selected source
ma=noZigZag(src)
zz=ZigZag(src)

//Plot 
plot(ma,color=color.new(input.color(#acfb00,"Color"),0))
plot(showZigZag?zz:na,color=#ffffff)
