Skip to main content
Latest Crypto Fear & Greed Index


New Pine Script: Cosine Kernel Regression


 This pine script is adapted from Cosine Kernel Regression by QuantraSystems. Credit goes to this brilliant script writer. 

The Cosine Kernel Regressions indicator (CKR) uses mathematical concepts to offer a unique approach to market analysis. This indicator employs Kernel Regressions using bespoke tunable Cosine functions in order to smoothly interpret a variety of market data, providing traders with incredibly clean insights into market trends. Details here.. 

Strategy Description: This stratgey uses many indicators to combine into an indicator that minimizes noises to get as accurate as possible. Order Buy is placed on Oversold signal, and exits the order when Overbought signal.

Recommended Settings:

Pair: RNDRUSDT (Binance)

Time frame: 1 hour

Initial Capital: 100

Base Currency: Default

Order Size: 100% equity

Pyramiding: 1 order

Commission: 0.1 % 


// @version=5
strategy("CKR: capayam.com credit to QuantraSystems", overlay=false, initial_capital = 10, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent , commission_value=0.1)
import QuantraAI/QuantraMAs/2 as Dynamic

// Desc: refer to Cosine Kernel Regression by QuantraSystems for original pine script.
// Default setting is best with TF1hour

// Input Groups

GRP1          = "Display:"
GRP2          = "Indicator Setup:"
GRP3          = "Kernel Calibration:"

// Indicator Calibrations
src           = input.source(close,          "Source",                                          group = GRP2            )

bool_STOCH    = input.bool  (true,           "",                              inline = "STOCH", group = GRP2            )
bool_RSI      = input.bool  (true,           "",                              inline = "RSI",   group = GRP2            )      
bool_BBPCT    = input.bool  (true,           "",                              inline = "BBPCT", group = GRP2            )
bool_CMO      = input.bool  (true,           "",                              inline = "CMO",   group = GRP2            )
bool_CCI      = input.bool  (true,           "",                              inline = "CCI",   group = GRP2            )
bool_FISH     = input.bool  (true,           "",                              inline = "FISH",  group = GRP2            )
bool_VZO      = input.bool  (true,           "",                              inline = "VZO",   group = GRP2            )

length_STOCH  = input.int   (14,             "Stochastic Length",             inline = "STOCH", group = GRP2            )
length_RSI    = input.int   (14,             "RSI Length",                    inline = "RSI",   group = GRP2            )
length_BBPCT  = input.int   (20,             "BBPCT Length",                  inline = "BBPCT", group = GRP2            )
length_CMO    = input.int   (14,             "Chande Momentum Length",        inline = "CMO",   group = GRP2            )
length_CCI    = input.int   (20,             "CCI Length",                    inline = "CCI",   group = GRP2            )
length_FISH   = input.int   (9,              "Fisher Transform Length",       inline = "FISH",  group = GRP2            )
length_VZO    = input.int   (21,             "VZO Length",                    inline = "VZO",   group = GRP2            )


// Cosine Kernel Setup
varient       = input.string("Tuneable",     "Cosine Kernel Regression Type",                   group = GRP3, options = ["Tuneable", "Stepped"])
lookbackR     = input.int   (60,             "Regression Lookback",                             group = GRP3            )
tuning        = input.float (15.,            "Tuning Coefficient",                              group = GRP3            )


// Display
ColType       = input.string("Fast Trend",   "Choose Mode",                                     group = GRP1, options = ["None",    "Fast Trend", "Slow Trend"], tooltip = "Signal Mode - Barcolor")
ColMode       = input.string("Modern",       "Color Palette Choice",          inline = "Drop",  group = GRP1, options = ["Classic", "Modern", "Robust", "Accented", "Monochrome"])
man           = input.bool  (false,          "Custom Palette",                inline = "Drop",  group = GRP1            )
manUpC        = input.color (#00ff00,      "Custom Up",                     inline = "Man",   group = GRP1            )
manDnC        = input.color (#ff0000,      "Custom Down",                   inline = "Man",   group = GRP1            )


// Color assignment based on the selected palette
[UpC, DnC]       =   switch     ColMode
    "Classic"    => [#00E676, #880E4F]
    "Modern"     => [#5ffae0, #c22ed0]
    "Robust"     => [#ffbb00, #770737]
    "Accented"   => [#9618f7, #ff0078]
    "Monochrome" => [#dee2e6, #495057]


// Override with custom colors if manual palette is selected
[UpCol, DnCol]   =   switch      man
    false        => [UpC,        DnC     ]
    true         => [manUpC,     manDnC  ]



// Define a function to compute the cosine of an input scaled by a frequency tuner
cosine(x, z) =>
    // Where x = source input
    //       y = function output
    //       z = frequency tuner
    var y = 0.
    y := math.cos(z * x)
    y


// Define a kernel that utilizes the cosine function
kernel(x, z) =>
    var y = 0.
    y := cosine(x, z)
    math.abs(x) <= math.pi/(2 * z) ? math.abs(y) : 0.    //    cos(zx) = 0
//  The above restricts the wave to positive values      //     when x = π / 2z


// Kernel Regression                                                      
kernelRegression(src, lookback, tuning) =>                                
                                                                         
    currentWeight = 0.                                                    
    totalWeight   = 0.                                                    
    for i = 0 to math.min(lookback - 1, bar_index)                        
        y = src[i]                                                        
        w = kernel(i / lookback, tuning)                                  
        currentWeight += y * w                                            
        totalWeight   += w                                                
    currentWeight / totalWeight                                          
                                                                         



// Multi Cosine                                                          
multicosine(src, lookback, steps) =>                                      
                                                                         
    regression = 0.                                                      
    for i = 1 to math.min(steps - 1, bar_index)                          
        regression += kernelRegression(src, lookback, i)                  
    regression / steps                                                    
                                                                         


RSI_ReScale   (_res      ) => (      _res - 50   ) * 2.8
STOCH_ReScale (_stoch    ) => (    _stoch - 50   ) * 2
BBPCT_ReScale (_bbpct    ) => (    _bbpct - 0.5  ) * 120
CMO_ReScale   (_chandeMO ) => ( _chandeMO * 1.15 )
CCI_ReScale   (_cci      ) => (      _cci / 2    )
FISH_ReScale  (_fish1    ) => (    _fish1 * 30   )
VZO_ReScale   (_VP, _TV  ) => (_VP / _TV) * 110


DynamicStdev(src, length) =>
    actualLength =    math.min(length, bar_index + 1)
    mean         = Dynamic.SMA(src,     actualLength)
    sumSquares   = 0.0
    for i = 0 to actualLength - 1
        sumSquares := sumSquares + math.pow(nz(src[i]) - mean, 2)
    stdev = math.sqrt(sumSquares / actualLength)
    stdev


DynamicDev(source, length) =>
    mean  = Dynamic.SMA(source, length)
    sum   = 0.0
    for i = 0 to length - 1
        val  = source[i]
        sum := sum + math.abs(val - mean)
    dev = sum / length
   

DynamicRMA(src, length) =>
    srcx = src * 100
    var float rma = na
    rma := length == 1 ?
           Dynamic.SMA(srcx, length) :
           ((rma[1] * (length - 1) ) + srcx) / length
    rma


DynamicRSI(src, length) =>
    var float res = na
    len  =     math.min(length,   bar_index        )
    u    =     math.max(src     - src[1], 0        )
    d    =     math.max(src[1]  - src,     0       )
    rs   =   DynamicRMA(u, len) / DynamicRMA(d, len)
    res := 100 - 100 / (1 + rs)
    RSI_ReScale(res)


DynamicSTOCH(source, hi, lo, length) =>
    len         =    math.min(length,   1 + bar_index)
    lowestLow   =   ta.lowest(lo,           len      )
    highestHigh =  ta.highest(hi,           len      )
    stochastic  =      100 * (source      - lowestLow) /
                             (highestHigh - lowestLow)
    STOCH_ReScale(stochastic)


DynamicBBPCT(length, multi) =>
    basis =   Dynamic.SMA(src, length)
    dev   =   multi * DynamicStdev(src, length)
    upper =   basis + dev
    lower =   basis - dev
    bbpct =  (src   - lower) /
             (upper - lower)
    BBPCT_ReScale(bbpct)

 
DynamicCMO(length) =>
    len  = math.min(length, bar_index + 1)            
    momm = ta.change(src)                            
    m1   = momm >= 0 ?  momm : 0.0                    
    m2   = momm <  0 ? -momm : 0.0                    
    sm1  = math.sum(m1, len)                          
    sm2  = math.sum(m2, len)                          
    div  = sm1 + sm2                                  
    chandeMO = div != 0 ? 100 * (sm1 - sm2) / div : 0
    CMO_ReScale(chandeMO)                            


DynamicCCI(length) =>
    len = math.min(length, bar_index + 1)
    ma  = Dynamic.SMA(src, len)
    cci = (src - ma) / (0.015 * DynamicDev(src, len))
    CCI_ReScale(cci)


DynamicFisher(length) =>
    len     =   math.min(length, 1 + bar_index)
    high_   = ta.highest(hl2,        len      )
    low_    =  ta.lowest(hl2,        len      )
    value1  = 0.0
    value2  = 0.0
    value1 := 0.66 * ((hl2 - low_)  / (high_ - low_) - 0.5)  + 0.67 * nz(value1[1])
    value2 := value1 > 0.99 ? 0.999 : value1 < -.99  ? -.999 : value1
    fish1   = 0.0
    fish1  := 0.5 * math.log((1 + value2) / (1 - value2)) + 0.5 * nz(fish1[1])
    FISH_ReScale(fish1)


DynamicVZO(length) =>
    VP = Dynamic.EMA(math.sign(ta.change(hlc3)) * volume, length / 3)
    TV = Dynamic.EMA(volume, length / 3)
    VZO_ReScale(VP, TV)


// Function to check the status of user-bools
booleanCheck(condition, func) => condition ? func : na


// Function to count active indicators
countCondition(condition)     => condition ? 1 : 0


// Pull all standardized base indicator values
val_RSI   = booleanCheck(bool_RSI,   DynamicRSI    (src, length_RSI)              )
val_STOCH = booleanCheck(bool_STOCH, DynamicSTOCH  (src, high, low, length_STOCH) )
val_BBPCT = booleanCheck(bool_BBPCT, DynamicBBPCT  (length_BBPCT, 2)              )
val_CMO   = booleanCheck(bool_CMO,   DynamicCMO    (length_CMO     )              )
val_CCI   = booleanCheck(bool_CCI,   DynamicCCI    (length_CCI     )              )
val_FISH  = booleanCheck(bool_FISH,  DynamicFisher (length_FISH    )              )
val_VZO   = booleanCheck(bool_VZO,   DynamicVZO    (length_VZO     )              )


// Count the number of active indicators
activeIndicators =
          countCondition(bool_RSI  ) +
          countCondition(bool_STOCH) +
          countCondition(bool_BBPCT) +
          countCondition(bool_CMO  ) +
          countCondition(bool_CCI  ) +
          countCondition(bool_FISH ) +
          countCondition(bool_VZO  )


// Calculate the average only with active indicators
value = activeIndicators > 0 ? (
          nz(val_RSI,   0) +
          nz(val_STOCH, 0) +
          nz(val_BBPCT, 0) +
          nz(val_CMO,   0) +
          nz(val_CCI,   0) +
          nz(val_FISH,  0) +
          nz(val_VZO,   0)
          ) / activeIndicators : na

// Gentle ALMA smoothing
value := Dynamic.ALMA(value, 9, 0, 6)


// Calulate the Output - Depending on the method of Cosine Regression Selected
out  = switch varient
    "Tuneable" => kernelRegression(value, lookbackR, tuning)
    "Stepped"  =>      multicosine(value, lookbackR, tuning)

out2 = switch varient
    "Tuneable" => kernelRegression(value, lookbackR, math.round(tuning / 5))
    "Stepped"  =>      multicosine(value, lookbackR, math.round(tuning / 5))


// Define Alert Conditions
fastTrend_up  = out  > out[1]  and not (out[1]  > out[2])
fastTrend_dn  = out  < out[1]  and not (out[1]  < out[2])
slowTrend_up  = out2 >     0   and not (out2[1] >     0 )
slowTrend_dn  = out2 <     0   and not (out2[1] <     0 )
overbought    = out  >    50   and not (out[1]  >    50 )
oversold      = out  <   -50   and not (out[1]  <   -50 )

fastTrend     = fastTrend_up or fastTrend_dn
slowTrend     = slowTrend_up or slowTrend_dn


                                                                                                           
                                                                                                           
barcol = switch ColType                                                                                    
    "None"                   => na                                                                        
    "Fast Trend"             => out  > out[1]       ?      UpCol : DnCol                                  
    "Slow Trend"             => out2 > 0            ?      UpCol : DnCol                                  
col                          =  out  > out[1]       ?      UpCol : DnCol                                  
col2                         =  color.new((out2 > 0 ?      UpCol : DnCol), 80)                            
                                                                                                           
mid  = plot(  0, "Midline",   color.gray ,               display = display.all         )                
                                                                                                           
                                                                                                           
sig  = plot(out,  "Fast Signal",          col,       3,    display = display.all         ),                
       plot(out,  "",           color.new(col, 85), 10,    display = display.pane        ),                
       plot(out,  "",           color.new(col, 98), 25,    display = display.pane        )                
sig2 = plot(out2, "Slow Signal",          col2,      3,    display = display.all, style = plot.style_area)
                                                                                                           
                                                                                                           
l1   = plot( 100, "",                     na,              display = display.data_window )                
l2   = plot(  50, "",           color.new(DnCol, 50),      display = display.data_window )                
l3   = plot( -50, "",           color.new(UpCol, 50),      display = display.data_window )                
l4   = plot(-100, "",                     na,              display = display.data_window )                
                                                                                                           
                                                                                                           
plotshape  (out, "",  shape.xcross,      color = fastTrend_dn ? color.new(DnCol, 15) : na,                
           location = location.absolute, size  = size.small                              )                
plotshape  (out, "",  shape.circle,      color = fastTrend_up ? color.new(UpCol, 15) : na,                
           location = location.absolute, size  = size.small                              )                
                                                                                                           
fill(l1, l2, 100,   50,         color.new(DnCol, 60),           color.new(chart.bg_color, 30))            
fill(l4, l3, -50, -100,         color.new(chart.bg_color, 30),  color.new(UpCol, 60)     )                
                                                                                                           
barcolor(barcol)                                                                                          
                                                                                                           

symbol = "CKR [QuantraSystems] >>> {{exchange}}:{{ticker}}"

// Fast Trend Alerts
alertcondition(fastTrend_up, "Fast Positive Trend",  symbol + " - Fast Positive Trend!" )
alertcondition(fastTrend_dn, "Fast Negative Trend",  symbol + " - Fast Negative Trend!" )

// Slow Trend Alerts  
alertcondition(slowTrend_up, "Slow Positive Trend",  symbol + " - Slow Positive Trend!" )
alertcondition(slowTrend_dn, "Slow Negative Trend",  symbol + " - Slow Negative Trend!" )

// Combined Alerts
alertcondition(fastTrend,    "Fast Trend Shift",     symbol + " - Fast Trend Shift!"    )
alertcondition(slowTrend,    "Slow Trend Shift",     symbol + " - Slow Trend Shift!"    )

    // Define Buy Exit condition
uptrend_condition = oversold
downtrend_condition = overbought


// Strategy entry and exit conditions
if (uptrend_condition)
    strategy.entry("Buy", strategy.long)
   
if (downtrend_condition)
    strategy.close("Buy")


*Feel free to share your different settings in the comment section


Comments

Popular posts from this blog

New Pine Script Stratgey: Buy on Whale Signal

This strategy is adapted from an indicator Whale detector, which is thanks to BLACKCAT1404, the curator of the indicator.  Startegy Description: It places buy order when then whale detector bar reaches certain threshold level which you can adjust as well as the Take Profit and Stop Loss. Recommended Settings: Pair: BTCUSDT (Binance) Time frame: 7min Initial Capital: 10 Base Currency: Default Order Size: 10 USDT Pyramiding: 1 order Commission: 0.1 % Each pair of token has different threshold, suitable time frame, TP and SL. Aa a matter of fact, Even different CEX may produce result for the same coin. You have to test one by one to get the best result. Do share your best strategy setting in the comment.  *credit to  BLACKCAT1404     // @version= 4 strategy ( "WHALE pump signal [www.capayam.com, credit to Blackcat1404]" , overlay =false, commission_type = strategy.commission.percent , commission_value = 0.1 ) // Desc: Best setting ETH TF7min Thres 30 TP6 SL3 Sc...

New Script: VWAP strategy

This strategy uses VWAP with period 7. The success rate about 50%, and one huge drawback is the huge drawdown. I do not set up stop loss for this strategy. Strategy Description: It buys when the price crosses up VWAP line. Exit when EMA50 crosses down SMA100. Potential ROI Monthly (in bullish trend): 0-10% Recommended Settings: Pair: BTCUSDT, TIAUSDT Time frame: 5mins Initial Capital: 100 Base Currency: Default Order Size: 98% of equity Pyramiding: 1 order Commission: 0.1 % // @version= 4 strategy ( "VWAP+MA[www.capayam.com]" , overlay =true ) // Input for the VWAP period cumulativePeriod = input ( 7 , title = "VWAP Period" ) // Calculate VWAP typicalPrice = ( high + low + close ) / 3 typicalPriceVolume = typicalPrice * volume cumulativeTypicalPriceVolume = sum ( typicalPriceVolume , cumulativePeriod ) cumulativeVolume = sum ( volume , cumulativePeriod ) vwapValue = cumulativeTypicalPriceVolume / cumulativeVolume // Plot VWAP plot ( vwapValu...

New script published: EMA-SMA cross

This strategy is pretty simple actually, based on ride trend principle. It exits when trend started to go down. During bearish, it will stay in cash. Strategy Description: It buys when the EMA50 line crosses up SMA2000 line. Exit when EMA50 crosses down SMA100 . Potential ROI Monthly (in bullish trend): 0-5% Recommended Settings: Pair: BTCUSDT, MATICUSDT, TIAUSDT Time frame: 5mins Initial Capital: 100 Base Currency: Default Order Size: 100% of equity Pyramiding: 1 order Commission: 0.1 % // @version= 4 strategy ( "EMA-SMA Crossover [www.capayam.com]" , overlay = true ) // Define input parameters emaLength = input ( 50 , title = "EMA Length" ) smaShortLength = input ( 100 , title = "SMA Short Length" ) smaLongLength = input ( 2000 , title = "SMA Long Length" ) // Calculate EMA and SMA values ema50 = ema ( open , emaLength ) sma100 = sma ( open , smaShortLength ) sma2000 = sma ( open , smaLongLength ) // Plot EMA and SMA on th...