0% found this document useful (0 votes)
12 views4 pages

Funky EMA 2

This document contains a Pine Script™ code for a trading indicator called 'Trend Heuristics' that calculates a Rolling Volume Weighted Average Price (RVWAP) along with standard deviation bands. It includes customizable alert settings, breakout signals, and various input parameters for users to define their preferences. The code also features plotting functionalities for visual representation of buy/sell signals and breakout conditions on trading charts.

Uploaded by

darwincastrouk
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views4 pages

Funky EMA 2

This document contains a Pine Script™ code for a trading indicator called 'Trend Heuristics' that calculates a Rolling Volume Weighted Average Price (RVWAP) along with standard deviation bands. It includes customizable alert settings, breakout signals, and various input parameters for users to define their preferences. The code also features plotting functionalities for visual representation of buy/sell signals and breakout conditions on trading charts.

Uploaded by

darwincastrouk
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 4

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.

0
at https://mozilla.org/MPL/2.0/
// © mindyourbuisness

//@version=6
indicator("Trend Heuristics", "TH", overlay = true)
import mindyourbuisness/CustomAlertLib/2 as CAL

// Custom Alert Middleware Function


alertFormat = input.text_area('{default}', "Custom alert message format",
group="Alert Settings")

// Rolling VWAP
// v3, 2022.07.24

import PineCoders/ConditionalAverages/1 as pc

// Global scope variables for signals


var buySignalrvwap = false
var sellSignalrvwap = false
var bullishBreakout = false
var bearishBreakout = false

// ———————————————————— Constants and Inputs {

// ————— Constants
int MS_IN_MIN = 60 * 1000
int MS_IN_HOUR = MS_IN_MIN * 60
int MS_IN_DAY = MS_IN_HOUR * 24

string TT_SRC = "The source used to calculate the VWAP. The default is the
average of the high, low and close prices."
string TT_WINDOW = "By default, the time period used to calculate the RVWAP
automatically adjusts with the chart's timeframe.
Check this to use a fixed-size time period instead, which you define with the
following three values."
string TT_MINBARS = "The minimum number of last values to keep in the moving
window, even if these values are outside the time period.
This avoids situations where a large time gap between two bars would cause the
time window to be empty."
string TT_STDEV = "The multiplier for the standard deviation bands offset above
and below the RVWAP. Example: 1.0 is 100% of the offset value.
\n\nNOTE: A value of 0.0 will hide the bands."
string TT_TABLE = "Displays the time period of the rolling window."

// Inputs
string groupName = "Rolling VWAP"
float srcInput = input.source(hlc3, "Source", tooltip = TT_SRC, group = groupName)

// Time Period and Info Box


bool fixedTfInput = input.bool(false, "Use a fixed time period", tooltip =
TT_WINDOW, group = groupName, inline = "1")
bool showInfoBoxInput = input.bool(true, "Show time period", group = groupName,
inline = "1")
int daysInput = input.int(1, "Days", minval = 0, maxval = 90, group = groupName,
inline = "2") * MS_IN_DAY
int hoursInput = input.int(0, "Hours", minval = 0, maxval = 23, group = groupName,
inline = "2") * MS_IN_HOUR
int minsInput = input.int(0, "Minutes", minval = 0, maxval = 59, group = groupName,
inline = "2") * MS_IN_MIN
string infoBoxSizeInput = input.string("small", "Size", options = ["tiny", "small",
"normal", "large", "huge", "auto"], group = groupName, inline = "3")
string infoBoxYPosInput = input.string("bottom", "Vertical Position", options =
["top", "middle", "bottom"], group = groupName, inline = "3")
string infoBoxXPosInput = input.string("left", "Horizontal Position", options =
["left", "center", "right"], group = groupName, inline = "3")
color infoBoxColorInput = input.color(color.gray, "Info Box Color", group =
groupName, inline = "4")
color infoBoxTxtColorInput = input.color(color.white, "Text Color", group =
groupName, inline = "4")
bool showSignalInputrVwap = input.bool(true, "Show Signal", group = groupName,
inline = "5")
// Define colors
var color BULL_COLOR = color.new(#A8D5BA, 0)
var color BEAR_COLOR = color.new(#F4A7A3, 0)
var color NEUTRAL_COLOR = color.new(#808080, 100)

// RVWAP and Deviation Bands


bool showRVWAPInput = input.bool(true, "Show RVWAP", group = groupName, inline =
"5")
color rvwapColorInput = input.color(#eaeaea, "RVWAP Color", group = groupName,
inline = "5")
color fillColorInput = input.color(color.new(BULL_COLOR, 95), "Band Fill Color",
group = groupName, inline = "5")
float stdevMult1 = input.float(0.386, "Bands Multiplier", minval = 0.0, step = 0.1,
group = groupName, inline = "6")
color stdevColor1 = input.color(color.new(#eaeaea, 100), "Deviation Band Color",
group = groupName, inline = "6")

// Minimum Window Size


int minBarsInput = input.int(10, "Minimum Bars", tooltip = TT_MINBARS, group =
groupName)

// In the inputs section, add new input for breakout signals


bool showBreakoutSignals = input.bool(true, "Show Breakout Signals", group =
groupName, inline = "7")

// ———————————————————— Functions {

// @function Determines a time period from the chart's timeframe.


// @returns (int) A value of time in milliseconds that is appropriate for the
current chart timeframe. To be used in the RVWAP calculation.
timeStep() =>
int tfInMs = timeframe.in_seconds() * 1000
float step =
switch
tfInMs <= MS_IN_MIN => MS_IN_HOUR
tfInMs <= MS_IN_MIN * 5 => MS_IN_HOUR * 4
tfInMs <= MS_IN_HOUR => MS_IN_DAY * 1
tfInMs <= MS_IN_HOUR * 4 => MS_IN_DAY * 3
tfInMs <= MS_IN_HOUR * 12 => MS_IN_DAY * 7
tfInMs <= MS_IN_DAY => MS_IN_DAY * 30.4375
tfInMs <= MS_IN_DAY * 7 => MS_IN_DAY * 90
=> MS_IN_DAY * 365
int result = int(step)
// @function Produces a string corresponding to the input time in days, hours,
and minutes.
// @param (series int) A time value in milliseconds to be converted to a
string variable.
// @returns (string) A string variable reflecting the amount of time from the
input time.
tfString(int timeInMs) =>
int s = timeInMs / 1000
int m = s / 60
int h = m / 60
int tm = math.floor(m % 60)
int th = math.floor(h % 24)
int d = math.floor(h / 24)
string result = switch
d == 30 and th == 10 and tm == 30 => '1M'
d == 7 and th == 0 and tm == 0 => '1W'
=>
string dStr = bool(d) ? str.tostring(d) + 'D ' : ''
string hStr = bool(th) ? str.tostring(th) + 'H ' : ''
string mStr = bool(tm) ? str.tostring(tm) + 'min' : ''
dStr + hStr + mStr
result
// }

// ———————————————————— Calculations and Plots {

// Stop the indicator on charts with no volume.


if barstate.islast and ta.cum(nz(volume)) == 0
runtime.error("No volume is provided by the data vendor.")

// RVWAP + stdev bands


int timeInMs = fixedTfInput ? minsInput + hoursInput + daysInput : timeStep()

float sumSrcVol = pc.totalForTimeWhen(srcInput * volume, timeInMs, true,


minBarsInput)
float sumVol = pc.totalForTimeWhen(volume, timeInMs, true, minBarsInput)
float sumSrcSrcVol = pc.totalForTimeWhen(volume * math.pow(srcInput, 2), timeInMs,
true, minBarsInput)

float rollingVWAP = sumSrcVol / sumVol

float variance = sumSrcSrcVol / sumVol - math.pow(rollingVWAP, 2)


variance := math.max(0, variance)

float stDev = math.sqrt(variance)

float upperBand1 = rollingVWAP + stDev * stdevMult1


float lowerBand1 = rollingVWAP - stDev * stdevMult1

// Signal calculations
float bodyRange = high - low
float closePosition = (close - low) / bodyRange

// Calculate wick sizes


float upperWick = high - math.max(open, close)
float lowerWick = math.min(open, close) - low

buySignalrvwap := open > upperBand1 and low < upperBand1 and close > upperBand1 and
closePosition >= 0.5 and lowerWick > upperWick and close > high[1]
sellSignalrvwap := open < lowerBand1 and high > lowerBand1 and close < lowerBand1
and closePosition <= 0.5 and upperWick > lowerWick and close < low [1]

// Add breakout signals


bullishBreakout := open < rollingVWAP and close > upperBand1
bearishBreakout := open > rollingVWAP and close < lowerBand1

// Plots
plot(showRVWAPInput ? rollingVWAP : na, "Rolling VWAP", rvwapColorInput)

p1rvwap = plot(showRVWAPInput and stdevMult1 != 0 ? upperBand1 : na, "Upper Band


1", stdevColor1)
p2rvwap = plot(showRVWAPInput and stdevMult1 != 0 ? lowerBand1 : na, "Lower Band
1", stdevColor1)

color fillColor = showRVWAPInput ? fillColorInput : color.new(fillColorInput, 100)


fill(p1rvwap, p2rvwap, fillColor, "Bands Fill")

// Signal plots
plotshape(showSignalInputrVwap and buySignalrvwap, "Buy Signal",
style=shape.triangleup, location=location.belowbar, color=BULL_COLOR,
size=size.tiny)
plotshape(showSignalInputrVwap and sellSignalrvwap, "Sell Signal",
style=shape.triangledown, location=location.abovebar, color=BEAR_COLOR,
size=size.tiny)
plotshape(showBreakoutSignals and bullishBreakout, "Bullish Breakout",
style=shape.circle, location=location.belowbar, color=BULL_COLOR, size=size.tiny)
plotshape(showBreakoutSignals and bearishBreakout, "Bearish Breakout",
style=shape.circle, location=location.abovebar, color=BEAR_COLOR, size=size.tiny)

// Alerts
if buySignalrvwap and showSignalInputrVwap
CAL.customAlert(alertFormat, str.tostring(syminfo.ticker) + ": Bullish sweep of
rolling VWAP")
if sellSignalrvwap and showSignalInputrVwap
CAL.customAlert(alertFormat, str.tostring(syminfo.ticker) + ": Bearish sweep of
rolling VWAP")
if bullishBreakout and showBreakoutSignals
CAL.customAlert(alertFormat, str.tostring(syminfo.ticker) + ": Bullish breakout
above VWAP")
if bearishBreakout and showBreakoutSignals
CAL.customAlert(alertFormat, str.tostring(syminfo.ticker) + ": Bearish breakout
below VWAP")

You might also like