top of page

Free indicators

Public·5 members

Mid-Day Volume Spikes - with trail




# ─────────────────────────────────────────────

# │ MarketFragments.com | DNA & Market │

# │ info@marketfragments.com │

# │ www.marketfragments.com │

# ─────────────────────────────────────────────

# Time →

# │

# █ █ █│ █

# █ █ █ │ █ █

# █ █ █ │ █ █ █ ╭─╮

# █ █ █ │ █ █ █ █ ╭─╯ ╰─╮

# █ █ █ │ █ █ █ █ █ █ ╭─╯ ╰─╮

# █ █ █ │ █ █ █ █ █ █ █ █ ╭─╯ ╰─╮

# █ █ █ │ █ █ █ █ █ █ █ █ █ █╭─╯ ╰─╮

# █ █ █ │ █ █ █ █ █ █ █ █ ╰─╮ ╭─╯

# █ █ █ │ █ █ █ █ █ █ ╰─╮ ╭─╯

# █ █ █ │ █ █ █ █ ╰─╮ ╭─╯

# █ █ █ │ █ █ ╰─╮ ╭─╯

# █ █ █ │ █ ╰─────╯

# ──────┴──────────────────────────────────────────────────────────────

# T1 T2 T3 T4 T5 T6

#

# =============================================================================

# Free Open Source ThinkScript Study for ThinkOrSwim

#

# This code is provided free of charge and is open source under the MIT License.

# You are free to use, copy, modify, merge, publish, distribute, sublicense,

# and/or sell copies of this software for any purpose, with or without

# modification, subject to the following conditions:

#

# The above copyright notice and this permission notice shall be included in all

# copies or substantial portions of the Software.

#

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE

# SOFTWARE.

#

# Name: Mid day volume spikes with trail

# Author: Market Fragments team/mcdon

# Description: Intraday trading strategy with Heikin Ashi, ATR trailing stops,

# Kase deviation lines, midday pullback entries, and RVOL spike

# detection for signal confirmation.

# Inputs

input TrailType = { "Simple", default "Kase" }; # Hint: Type of trailing stop method

input KaseLine = { "Warning", default "StdDev1", "StdDev2", "StdDev3" }; # Hint: Kase deviation line selection

input AtrMult = 2.2; # Hint: ATR multiplier for simple trail (unused in current logic)

input PaintBars = yes; # Hint: Enable/disable bar coloring based on trade direction

input ShowBubbles = no; # Hint: Show bubbles on chart (unused in current code)

input AtrAvgType = AverageType.WILDERS; # Hint: Averaging type for ATR calculation

input AtrLength = 7; # Hint: Length for ATR moving average

input AtrMultiple = 1.9; # Hint: Multiplier for adjusted ATR in trailing stops

input offset = 0; # Hint: Offset for volume calculations (unused in signals)

input TimeBasedNumDays = 10; # Hint: Number of days for relative volume calculation

input threshold3 = 200; # Hint: Threshold for relative volume spike detection

input tckPadding = 1; # Hint: Padding in ticks for loss calculations


# Constants

def nan = Double.NaN; # Hint: Not a Number value for invalid or missing data


# Basic price and bar data

def h = high; # Hint: Current bar high price

def l = low; # Hint: Current bar low price

def c = close; # Hint: Current bar close price

def o = open; # Hint: Current bar open price

def v = volume; # Hint: Current bar volume

def tcnt = tick_count; # Hint: Tick count for the bar (for volume weighting)

def bn = BarNumber(); # Hint: Sequential bar number for indexing


# Volume-weighted calculations (simplified to typical price)

def isValue = v / tcnt; # Hint: Volume per tick (simplified, often 1)

def issvwap = (((h + l + c) / 3) * v) / v; # Hint: Session VWAP using typical price (h+l+c)/3

def isvwap2 = (((h + l + c) / 3) * isValue) / isValue; # Hint: Alternative VWAP using tick-adjusted volume (simplified to typical price)


# Heikin Ashi calculations (non-standard variant with VWAP offset)

def HAopen; # Hint: Heikin Ashi open price

def HAhigh; # Hint: Heikin Ashi high price

def HAlow; # Hint: Heikin Ashi low price

def HAclose; # Hint: Heikin Ashi close price

def HAclosevwap; # Hint: VWAP-adjusted Heikin Ashi close

HAopen = CompoundValue(1, (HAopen[1] + HAclosevwap[1]) / 2, (o[1] + c) / 2);

HAhigh = Max(h, c[1]); # Hint: Max of current high and previous close

HAlow = Min(l, c[1]); # Hint: Min of current low and previous close

HAclose = (HAopen + HAclose[1] + HAlow + c) / 4; # Hint: Average of HA open, previous HA close, HA low, and current close

HAclosevwap = (((HAhigh + HAlow + HAclose) / 3) * isValue) / isValue; # Hint: VWAP using HA typical price (simplified)


# Tick-related constants

def tickSize = if !IsNaN(TickSize()) then TickSize() else .01; # Hint: Instrument tick size, default 0.01

def tickValue = if !IsNaN(TickValue()) then TickValue() else .01; # Hint: Tick value in dollars, default 0.01 (unused)

def isTickpad = (tckPadding * tickSize); # Hint: Padded tick size for stop adjustments


# True Range and ATR (using HA values)

def tra = TrueRange(HAhigh, HAclose, HAlow); # Hint: True Range based on Heikin Ashi values

def atr = Round(MovingAverage(AtrAvgType, tra, AtrLength) / tickSize, 0) * tickSize; # Hint: ATR rounded to tick size

def adjustedATR = Round((atr * AtrMultiple) / tickSize, 0) * tickSize; # Hint: ATR scaled by multiple, rounded to ticks

def HAHL2 = (HAhigh + HAlow) / 2; # Hint: Heikin Ashi midpoint (HL/2)

def loss = adjustedATR; # Hint: Base loss distance (unused directly)


declare upper;


# Time-based definitions (RTH, sessions) - Intraday only

def RTH = GetTime() >= RegularTradingStart(GetYYYYMMDD()) &&

GetTime() <= RegularTradingEnd(GetYYYYMMDD()); # Hint: Regular Trading Hours flag

def OpeningBell = GetTime()[1] < RegularTradingStart(GetYYYYMMDD()) &&

GetTime() > RegularTradingStart(GetYYYYMMDD()); # Hint: First RTH bar after pre-market

def start = GetTime() >= OpeningBell &&

GetTime() <= RegularTradingStart(GetYYYYMMDD()) + 7000000 && RTH; # Hint: Morning session start (~11:30 AM from open)

def end = GetTime() >= OpeningBell &&

GetTime() <= RegularTradingStart(GetYYYYMMDD()) + 18300000 && RTH; # Hint: Midday session end (~2:30 PM from open)


def time330 = GetTime() >= OpeningBell &&

GetTime() <= RegularTradingStart(GetYYYYMMDD()) + 21600000 && RTH; # Hint: Midday session end (~3:30 PM from open)


def trigger330 = if RTH && !RTH[1] then 0 else if !time330 && time330[1] then 1 else trigger330[1];


def midday = if bn == 1 then 0

else if midday[1] == 0 && !start && start[1] then 1

else if midday[1] == 1 && !end && end[1] then 0

else midday[1]; # Hint: Flag for midday trading window (after morning, before afternoon)



def tr = Max(TrueRange(hahigh, haClose, halow), tickSize);

### RVOL

input threshold4 = 200;

def isOpen = GetTime() >= RegularTradingStart(GetYYYYMMDD()) and GetTime() < RegularTradingEnd(GetYYYYMMDD());

def bars = if bn == 1 then 1 else if isOpen then bars[1] + 1 else 0;

def bnx = HighestAll(bars);


## 1.

def up = haClose[offset] >= haOpen[offset];

def dn = !up[offset];

def v1 = v / tr;

def vSum = CompoundValue( 1, fold index = 1 to TimeBasedNumDays + 1 with a = 0 do a + GetValue(v1, index * bnx), 1);

def relvol1 = (v1[offset] / (vSum[offset] / TimeBasedNumDays)) * 100;

def curVol1;

if up {

curVol1 = Min(threshold4, relvol1);

} else {

curVol1 = Round(Max(-threshold4, -relvol1));

}

def RvolSTate1 = if curVol1 >= 200 then 100 else if curVol1 <= -200 then -200 else 0;


## 2.

def vSum2 = CompoundValue( 1, fold index2 = 1 to TimeBasedNumDays + 1 with b = 0 do b + GetValue(v, index2 * bnx), 1);

def relvol2 = (v[offset] / (vSum2[offset] / TimeBasedNumDays)) * 100;

#def curVol2 = if up2 then Min(threshold4, relvol2) else Round(Max(-threshold4, -relvol2));

def curVol2;

if up {

curVol2 = Min(threshold4, relvol2);

} else {

curVol2 = Round(Max(-threshold4, -relvol2));

}

def RvolSTate2 = if curVol2 >= 189 then 200 else if curVol2 <= -200 then -200 else 0;


### 3 Tick

def vtk = v /tcnt/ tr;

def vSumtk = CompoundValue( 1, fold index3 = 1 to TimeBasedNumDays + 1 with cx = 0 do cx + GetValue(vtk, index3 * bnx), 1);

def relvoltk = (v1[offset] / (vSum[offset] / TimeBasedNumDays)) * 100;

#def curVoltk = if up then Min(threshold4, relvoltk) else Round(Max(-threshold4, -relvoltk));

def curVoltk;

if up {

curVoltk = Min(threshold4, relvoltk);

} else {

curVoltk = Round(Max(-threshold4, -relvoltk));

}

def RvolSTate3 = if curVoltk >= 200 then 200 else if curVoltk <= -200 then -200 else 0;


### 4 shares

def vsh = v /tcnt;

def vSumsh = CompoundValue( 1, fold index4 = 1 to TimeBasedNumDays + 1 with d = 0 do d + GetValue(vsh, index4 * bnx), 1);

def relvolsh = (vsh[offset] / (vSumsh[offset] / TimeBasedNumDays)) * 100;

#def curVolsh = if up then Min(threshold4, relvolsh) else Round(Max(-threshold4, -relvolsh));

def curVolsh;

if up {

curVolsh = Min(threshold4, relvolsh);

} else {

curVolsh = Round(Max(-threshold4, -relvolsh));

}

def RvolSTate4 = if curVolsh >= 200 then 200 else if curVolsh <= -200 then -200 else 0;


## 5 v spikes RTH

def start5 = RTH && !RTH[1];

def cnt = if start5 then 1 else cnt[1] + 1;

def SumV = CompoundValue(1, if start5 then v else SumV [1] + v, 0);

def RTHAvVol = SumV / cnt;

def RvolSTate5 = if (Average(v, 1) - RTHAvVol) / RTHAvVol > 1 then 100 else 0;



## 6 AL Relavitive StandardD

input length = 14;

input numDev = 2.0;

input allowNegativeValues = no;

def rawRelVol = (v - Average(v, length)) / StDev(v, length);

def RelVol = if allowNegativeValues then rawRelVol else Max(0, rawRelVol);

def RvolSTate6 = if c >= o && RelVol > numDev then 100 else if c < o && RelVol > numDev then -100 else 0;


## 7 vspikes

def VolumeOsc1 = if (Average(v, 1) - Average(v, 9)) / Average(v, 9) > 1 then 100 else 0;

def VolumeOsc2 = if (Average(v, 1) - Average(v, 11)) / Average(v, 11) > 1 then 100 else 0;

def VolumeOsc3 = if (Average(v, 1) - Average(v, 13)) / Average(v, 13) > 1 then 100 else 0;

def VolumeOsc4 = if (Average(v, 1) - Average(v, 15)) / Average(v, 15) > 1 then 100 else 0;

def VolumeOsc5 = if (Average(v, 1) - Average(v, 17)) / Average(v, 17) > 1 then 100 else 0;


def VolumeOscSum = VolumeOsc1 + VolumeOsc2 + VolumeOsc3 + VolumeOsc4 + VolumeOsc5 ;


def RvolSTate7 = if VolumeOscSum>99 then 100 else 0;



def signal;


if (RvolSTate1!=0 or RvolSTate2!=0 or RvolSTate3!=0 or RvolSTate4!=0

or RvolSTate5!=0 or RvolSTate6!=0 or RvolSTate7!=0){


signal = 1;

} else {

signal = nan;

}


# Daily High/Low tracking (RTH) - Hint: Tracks session highs/lows for pullback detection

def TodayH = if RTH && !RTH[1] then h else if h > TodayH[1] then h else TodayH[1]; # Hint: Running session high

def TodayL = if RTH && !RTH[1] then l else if l < TodayL[1] then l else TodayL[1]; # Hint: Running session low

def isdayH = if h == TodayH then 100 else 0; # Hint: Flag for new session high

def isdayL = if l == TodayL then 100 else 0; # Hint: Flag for new session low

def isdayh15 = h == Highest(h, 20); # Hint: 20-bar high (recent swing high)

def isdayl15 = l == Lowest(l, 20); # Hint: 20-bar low (recent swing low)


# Entry conditions (midday pullbacks to recent lows/highs) - Hint: Enters on pullbacks during midday

def longentry = if !isnan(signal) && midday && (100 == Highest(isdayL, 3) or isdayl15) then 1 else 0; # Hint: Long on recent low during midday

def shortentry = if !isnan(signal) && midday && (100 == Highest(isdayH, 3) or isdayh15) then 1 else 0; # Hint: Short on recent high during midday


# Kase-specific standard deviation level - Hint: Selects deviation multiplier for Kase stops

def kasestd = if KaseLine == KaseLine."StdDev1" then 1

else if KaseLine == KaseLine."StdDev2" then 2

else 3;


# Loss calculations for trailing stops - Hint: Stop levels based on Kase deviation or warning line

def TRD = 2 * tra; # Hint: Doubled true range for Kase calculations

def longloss = if KaseLine == KaseLine."Warning" then c - Round(MovingAverage(AtrAvgType, TRD, AtrLength) / tickSize, 0) * tickSize

else Round(((c - Round(MovingAverage(AtrAvgType, TRD, AtrLength) / tickSize, 0) * tickSize) - kasestd * StDev(TRD, AtrLength)) / tickSize, 0) * tickSize - isTickpad; # Hint: Long stop: close - avg TRD - (std * kasestd), padded


def shortloss = if KaseLine == KaseLine."Warning" then c + Round(MovingAverage(AtrAvgType, TRD, AtrLength) / tickSize, 0) * tickSize

else Round(((c + Round(MovingAverage(AtrAvgType, TRD, AtrLength) / tickSize, 0) * tickSize) + kasestd * StDev(TRD, AtrLength)) / tickSize, 0) * tickSize - isTickpad; # Hint: Short stop: close + avg TRD + (std * kasestd), padded


# State machine for trailing stops - Hint: Manages long/short states and ratchets trail

def state = { default Inactive, long, short };

def trail;

switch (state[1]) {

case Inactive:

if longentry && state[1] == state.Inactive {

state = state.long;

trail = if TrailType == TrailType."Simple" then Round((HAHL2 - atr * AtrMultiple) / tickSize, 0) * tickSize # Hint: Simple trail: HA midpoint - adjusted ATR

else longloss;

} else if shortentry && state[1] == state.Inactive {

state = state.short;

trail = if TrailType == TrailType."Simple" then Round((HAHL2 + atr * AtrMultiple) / tickSize, 0) * tickSize # Hint: Simple trail: HA midpoint + adjusted ATR

else shortloss;

} else {

state = state.Inactive;

trail = nan;

}

case long:

if c > trail[1] && trigger330==0 {

state = state.long;

trail = Max(if TrailType == TrailType."Simple" then Round((HAHL2 - atr * AtrMultiple) / tickSize, 0) * tickSize else longloss, trail[1]); # Hint: Ratchet up if favorable

} else {

state = state.Inactive;

trail = nan; # Hint: Exit on stop hit

}

case short:

if c < trail[1] && trigger330==0 {

state = state.short;

trail = Min(if TrailType == TrailType."Simple" then Round((HAHL2 + atr * AtrMultiple) / tickSize, 0) * tickSize else shortloss, trail[1]); # Hint: Ratchet down if favorable

} else {

state = state.Inactive;

trail = nan; # Hint: Exit on stop hit

}

}


# Signal crossings (for orders) - Hint: Detects state changes for buy/sell/exit alerts

def buy = Crosses(state == state.long, 0, CrossingDirection.ABOVE);

def sell = Crosses(state == state.short, 0, CrossingDirection.ABOVE);

def out = Crosses(state == state.Inactive, 0, CrossingDirection.ABOVE);


# Plot trailing stop

plot trailstop = trail[1]; # Hint: Plots the trailing stop level (lagged by 1 bar)

trailstop.SetLineWeight(2);

trailstop.SetPaintingStrategy(PaintingStrategy.LINE);

trailstop.DefineColor("Buy", Color.GREEN);

trailstop.DefineColor("Sell", Color.RED);

trailstop.AssignValueColor(if state == state.long then trailstop.Color("Buy") else trailstop.Color("Sell"));


# Trade direction tracking - Hint: Maintains current direction until exit

def tradeDirection;

if buy {

tradeDirection = 1;

} else if tradeDirection[1] == 1 && out {

tradeDirection = 0;

} else if sell {

tradeDirection = -1;

} else if tradeDirection[1] == -1 && out {

tradeDirection = 0;

} else {

tradeDirection = tradeDirection[1];

}


# Bar coloring and label

AssignPriceColor(if PaintBars then

if tradeDirection == 1 then Color.GREEN # Hint: Green bars for long trades

else if tradeDirection == -1 then Color.RED # Hint: Red bars for short trades

else Color.GRAY # Hint: Gray for neutral/no trade

else Color.CURRENT);



69 Views
Brain with financial data analysis.

Inquiries at :

tel#: (843) 321-8514

Important Risk Notice: Trading involves substantial risk of loss. This is educational content only—not advice. Full details here  ------------>  

Proceed only if you're prepared.

bottom of page