Created
May 21, 2025 07:46
-
-
Save ExploiTR/60d3d32da4eed0b5511feb196a5af229 to your computer and use it in GitHub Desktop.
Drop Zone Scanner
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ | |
// © ExploiTR | |
//@version=6 | |
indicator("Drop Zone Highlighter", overlay=true) | |
// --- User Inputs --- | |
var group_inputs = "Settings" | |
var float drop_threshold_input = input.float(1.5, title="Drop Threshold (%)", minval=0.01, step=0.1, group=group_inputs) / 100.0 | |
var float gain_threshold_input = input.float(1.0, title="Gain Threshold (%)", minval=0.01, step=0.1, group=group_inputs) / 100.0 | |
var color box_bg_color_input = input.color(color.new(color.red, 85), title="Box Fill Color", group=group_inputs, inline="boxcolors") | |
var color box_border_color_input = input.color(color.new(color.red, 50), title="Box Border Color", group=group_inputs, inline="boxcolors") | |
// --- State Variables --- | |
// These variables maintain their values across bars. | |
var bool s_in_drop_zone = false // True if we are currently in a drop zone | |
var int s_box_start_bar_index = na // Bar index where the drop zone started | |
var float s_price_at_drop_trigger = na // The high price from which the drop was measured (top of the box) | |
var float s_lowest_price_in_zone = na // The lowest price recorded during the current drop zone (bottom of the box) | |
// Tracks the highest price observed since the last drop zone ended or since the script began. | |
var float s_high_since_last_event = high // Initialized with the high of the first bar | |
// --- Main Logic (executes on each bar) --- | |
if not s_in_drop_zone | |
// --- State: Not in a Drop Zone --- | |
// Check if the price has dropped significantly from the last recorded high (s_high_since_last_event). | |
// A drop is considered significant if the current close is below s_high_since_last_event by more than the drop_threshold_input. | |
if close < s_high_since_last_event * (1 - drop_threshold_input) | |
// Drop condition met: Transition to 'in_drop_zone' state. | |
s_in_drop_zone := true | |
s_box_start_bar_index := bar_index // Mark the start bar of the box. | |
s_price_at_drop_trigger := s_high_since_last_event // The top of the box will be this high. | |
s_lowest_price_in_zone := low // Initialize the lowest price in this new zone with the current bar's low. | |
else | |
// No drop condition met: Update s_high_since_last_event if a new high is made. | |
// This ensures s_high_since_last_event always holds the peak since the last zone ended or the script started. | |
s_high_since_last_event := math.max(s_high_since_last_event, high) | |
else | |
// --- State: Currently in a Drop Zone --- | |
// Update the lowest price encountered so far in this zone. | |
s_lowest_price_in_zone := math.min(s_lowest_price_in_zone, low) | |
// Check if the price has gained sufficiently from the lowest point (s_lowest_price_in_zone) of the current drop zone. | |
// A gain is considered significant if the current close is above s_lowest_price_in_zone by more than gain_threshold_input. | |
if close > s_lowest_price_in_zone * (1 + gain_threshold_input) | |
// Gain condition met: The drop zone ends. Draw the box. | |
box.new(left = s_box_start_bar_index, top = s_price_at_drop_trigger, right = bar_index, bottom = s_lowest_price_in_zone,bgcolor = box_bg_color_input, border_color = box_border_color_input) | |
// Reset state variables to exit 'in_drop_zone' state and prepare for the next cycle. | |
s_in_drop_zone := false | |
s_high_since_last_event := high // Reset the high tracking, starting from the current bar's high. | |
// Explicitly reset other state variables for clarity (they are re-assigned when a new zone starts). | |
s_box_start_bar_index := na | |
s_price_at_drop_trigger := na | |
s_lowest_price_in_zone := na | |
// Safety check: Ensure s_high_since_last_event has a valid value. | |
// Given the initialization `var float s_high_since_last_event = high`, this is mostly a safeguard. | |
if na(s_high_since_last_event) | |
s_high_since_last_event := high |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment