pine script
This commit is contained in:
222
Niki/GPT/pine/swing.pine
Normal file
222
Niki/GPT/pine/swing.pine
Normal file
@ -0,0 +1,222 @@
|
||||
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
|
||||
// © d_popov
|
||||
|
||||
//Larry Williams inspired multi-trend analysis strategy
|
||||
// This script implements a multi-trend analysis strategy based on the concepts discussed in the transcript.
|
||||
|
||||
//@version=6
|
||||
strategy("Multi-Trend Analysis Strategy", overlay=true, fill_orders_on_standard_ohlc = true)
|
||||
|
||||
// Input parameters for swing detection and trend analysis
|
||||
swingLookback = input.int(5, "Swing Point Lookback", minval=1, tooltip="Number of bars to look back for swing highs/lows")
|
||||
blueRangeBars = input.int(13, "Blue Trend (Short-term) Range Bars", minval=1)
|
||||
purpleRangeBars = input.int(21, "Purple Trend Range Bars", minval=1)
|
||||
orangeRangeBars = input.int(34, "Orange Trend Range Bars", minval=1)
|
||||
yellowRangeBars = input.int(55, "Yellow Trend (Long-term) Range Bars", minval=1)
|
||||
magentaRangeBars = input.int(89, "Magenta Trend Range Bars", minval=1)
|
||||
|
||||
// Detect base swing highs and lows
|
||||
baseSwingHigh = ta.pivothigh(high, swingLookback, swingLookback)
|
||||
baseSwingLow = ta.pivotlow(low, swingLookback, swingLookback)
|
||||
|
||||
// Store base swing points
|
||||
var float[] baseHighs = array.new_float(0)
|
||||
var float[] baseLows = array.new_float(0)
|
||||
|
||||
// Store trend swing points
|
||||
var float[] blueHighs = array.new_float(0)
|
||||
var float[] blueLows = array.new_float(0)
|
||||
var float[] purpleHighs = array.new_float(0)
|
||||
var float[] purpleLows = array.new_float(0)
|
||||
var float[] orangeHighs = array.new_float(0)
|
||||
var float[] orangeLows = array.new_float(0)
|
||||
var float[] yellowHighs = array.new_float(0)
|
||||
var float[] yellowLows = array.new_float(0)
|
||||
var float[] magentaHighs = array.new_float(0)
|
||||
var float[] magentaLows = array.new_float(0)
|
||||
|
||||
// Update base swing points
|
||||
if not na(baseSwingHigh)
|
||||
array.push(baseHighs, baseSwingHigh)
|
||||
if array.size(baseHighs) > blueRangeBars * 2 // Keep enough history
|
||||
array.shift(baseHighs)
|
||||
|
||||
if not na(baseSwingLow)
|
||||
array.push(baseLows, baseSwingLow)
|
||||
if array.size(baseLows) > blueRangeBars * 2
|
||||
array.shift(baseLows)
|
||||
|
||||
// Hierarchical trend extraction
|
||||
// Blue trend (directly from base points but filtered)
|
||||
blueExtractInterval = 2
|
||||
if array.size(baseHighs) >= 3 and bar_index % blueExtractInterval == 0
|
||||
float lastHigh = array.get(baseHighs, array.size(baseHighs) - 1)
|
||||
// Only add if it's a significant swing
|
||||
if array.size(blueHighs) == 0 or math.abs(lastHigh - array.get(blueHighs, array.size(blueHighs) - 1)) > ta.atr(14) * 0.5
|
||||
array.push(blueHighs, lastHigh)
|
||||
if array.size(blueHighs) > blueRangeBars
|
||||
array.shift(blueHighs)
|
||||
|
||||
if array.size(baseLows) >= 3 and bar_index % blueExtractInterval == 0
|
||||
float lastLow = array.get(baseLows, array.size(baseLows) - 1)
|
||||
// Only add if it's a significant swing
|
||||
if array.size(blueLows) == 0 or math.abs(lastLow - array.get(blueLows, array.size(blueLows) - 1)) > ta.atr(14) * 0.5
|
||||
array.push(blueLows, lastLow)
|
||||
if array.size(blueLows) > blueRangeBars
|
||||
array.shift(blueLows)
|
||||
|
||||
// Purple trend (from blue)
|
||||
purpleExtractInterval = 3
|
||||
if array.size(blueHighs) >= 3 and bar_index % purpleExtractInterval == 0
|
||||
float lastHigh = array.get(blueHighs, array.size(blueHighs) - 1)
|
||||
if array.size(purpleHighs) == 0 or math.abs(lastHigh - array.get(purpleHighs, array.size(purpleHighs) - 1)) > ta.atr(14) * 0.8
|
||||
array.push(purpleHighs, lastHigh)
|
||||
if array.size(purpleHighs) > purpleRangeBars
|
||||
array.shift(purpleHighs)
|
||||
|
||||
if array.size(blueLows) >= 3 and bar_index % purpleExtractInterval == 0
|
||||
float lastLow = array.get(blueLows, array.size(blueLows) - 1)
|
||||
if array.size(purpleLows) == 0 or math.abs(lastLow - array.get(purpleLows, array.size(purpleLows) - 1)) > ta.atr(14) * 0.8
|
||||
array.push(purpleLows, lastLow)
|
||||
if array.size(purpleLows) > purpleRangeBars
|
||||
array.shift(purpleLows)
|
||||
|
||||
// Orange trend (from purple)
|
||||
orangeExtractInterval = 5
|
||||
if array.size(purpleHighs) >= 3 and bar_index % orangeExtractInterval == 0
|
||||
float lastHigh = array.get(purpleHighs, array.size(purpleHighs) - 1)
|
||||
if array.size(orangeHighs) == 0 or math.abs(lastHigh - array.get(orangeHighs, array.size(orangeHighs) - 1)) > ta.atr(14) * 1.2
|
||||
array.push(orangeHighs, lastHigh)
|
||||
if array.size(orangeHighs) > orangeRangeBars
|
||||
array.shift(orangeHighs)
|
||||
|
||||
if array.size(purpleLows) >= 3 and bar_index % orangeExtractInterval == 0
|
||||
float lastLow = array.get(purpleLows, array.size(purpleLows) - 1)
|
||||
if array.size(orangeLows) == 0 or math.abs(lastLow - array.get(orangeLows, array.size(orangeLows) - 1)) > ta.atr(14) * 1.2
|
||||
array.push(orangeLows, lastLow)
|
||||
if array.size(orangeLows) > orangeRangeBars
|
||||
array.shift(orangeLows)
|
||||
|
||||
// Yellow trend (from orange)
|
||||
yellowExtractInterval = 8
|
||||
if array.size(orangeHighs) >= 3 and bar_index % yellowExtractInterval == 0
|
||||
float lastHigh = array.get(orangeHighs, array.size(orangeHighs) - 1)
|
||||
if array.size(yellowHighs) == 0 or math.abs(lastHigh - array.get(yellowHighs, array.size(yellowHighs) - 1)) > ta.atr(14) * 1.5
|
||||
array.push(yellowHighs, lastHigh)
|
||||
if array.size(yellowHighs) > yellowRangeBars
|
||||
array.shift(yellowHighs)
|
||||
|
||||
if array.size(orangeLows) >= 3 and bar_index % yellowExtractInterval == 0
|
||||
float lastLow = array.get(orangeLows, array.size(orangeLows) - 1)
|
||||
if array.size(yellowLows) == 0 or math.abs(lastLow - array.get(yellowLows, array.size(yellowLows) - 1)) > ta.atr(14) * 1.5
|
||||
array.push(yellowLows, lastLow)
|
||||
if array.size(yellowLows) > yellowRangeBars
|
||||
array.shift(yellowLows)
|
||||
|
||||
// Magenta trend (from yellow)
|
||||
magentaExtractInterval = 13
|
||||
if array.size(yellowHighs) >= 3 and bar_index % magentaExtractInterval == 0
|
||||
float lastHigh = array.get(yellowHighs, array.size(yellowHighs) - 1)
|
||||
if array.size(magentaHighs) == 0 or math.abs(lastHigh - array.get(magentaHighs, array.size(magentaHighs) - 1)) > ta.atr(14) * 2.0
|
||||
array.push(magentaHighs, lastHigh)
|
||||
if array.size(magentaHighs) > magentaRangeBars
|
||||
array.shift(magentaHighs)
|
||||
|
||||
if array.size(yellowLows) >= 3 and bar_index % magentaExtractInterval == 0
|
||||
float lastLow = array.get(yellowLows, array.size(yellowLows) - 1)
|
||||
if array.size(magentaLows) == 0 or math.abs(lastLow - array.get(magentaLows, array.size(magentaLows) - 1)) > ta.atr(14) * 2.0
|
||||
array.push(magentaLows, lastLow)
|
||||
if array.size(magentaLows) > magentaRangeBars
|
||||
array.shift(magentaLows)
|
||||
|
||||
// Determine trend directions
|
||||
blueTrendUp = array.size(blueLows) >= 2 and array.get(blueLows, array.size(blueLows) - 1) > array.get(blueLows, array.size(blueLows) - 2)
|
||||
blueTrendDown = array.size(blueHighs) >= 2 and array.get(blueHighs, array.size(blueHighs) - 1) < array.get(blueHighs, array.size(blueHighs) - 2)
|
||||
|
||||
purpleTrendUp = array.size(purpleLows) >= 2 and array.get(purpleLows, array.size(purpleLows) - 1) > array.get(purpleLows, array.size(purpleLows) - 2)
|
||||
purpleTrendDown = array.size(purpleHighs) >= 2 and array.get(purpleHighs, array.size(purpleHighs) - 1) < array.get(purpleHighs, array.size(purpleHighs) - 2)
|
||||
|
||||
orangeTrendUp = array.size(orangeLows) >= 2 and array.get(orangeLows, array.size(orangeLows) - 1) > array.get(orangeLows, array.size(orangeLows) - 2)
|
||||
orangeTrendDown = array.size(orangeHighs) >= 2 and array.get(orangeHighs, array.size(orangeHighs) - 1) < array.get(orangeHighs, array.size(orangeHighs) - 2)
|
||||
|
||||
yellowTrendUp = array.size(yellowLows) >= 2 and array.get(yellowLows, array.size(yellowLows) - 1) > array.get(yellowLows, array.size(yellowLows) - 2)
|
||||
yellowTrendDown = array.size(yellowHighs) >= 2 and array.get(yellowHighs, array.size(yellowHighs) - 1) < array.get(yellowHighs, array.size(yellowHighs) - 2)
|
||||
|
||||
magentaTrendUp = array.size(magentaLows) >= 2 and array.get(magentaLows, array.size(magentaLows) - 1) > array.get(magentaLows, array.size(magentaLows) - 2)
|
||||
magentaTrendDown = array.size(magentaHighs) >= 2 and array.get(magentaHighs, array.size(magentaHighs) - 1) < array.get(magentaHighs, array.size(magentaHighs) - 2)
|
||||
|
||||
// Imbalance detection (simplified)
|
||||
highImbalance = high > high[1] and high[1] > high[2] and low < low[1]
|
||||
lowImbalance = low < low[1] and low[1] < low[2] and high > high[1]
|
||||
|
||||
// Calculate trend strengths (weighted by timeframe importance)
|
||||
bullishStrength = (blueTrendUp ? 1 : 0) + (purpleTrendUp ? 2 : 0) + (orangeTrendUp ? 3 : 0) + (yellowTrendUp ? 5 : 0) + (magentaTrendUp ? 4 : 0)
|
||||
bearishStrength = (blueTrendDown ? 1 : 0) + (purpleTrendDown ? 2 : 0) + (orangeTrendDown ? 3 : 0) + (yellowTrendDown ? 5 : 0) + (magentaTrendDown ? 4 : 0)
|
||||
|
||||
// Entry conditions based on multi-trend alignment
|
||||
longCondition = blueTrendUp and orangeTrendUp and not magentaTrendDown and bullishStrength > bearishStrength and lowImbalance
|
||||
varip shortConditionBase = blueTrendDown and orangeTrendDown and not magentaTrendUp and bearishStrength > bullishStrength and highImbalance
|
||||
|
||||
// Add preference for shorting when there's weakness as mentioned in the transcript
|
||||
weaknessDetected = orangeTrendDown and magentaTrendDown and not yellowTrendUp
|
||||
shortBias = input.bool(true, "Bearish Bias (Short Preference)", tooltip="Prefer short positions when market shows weakness")
|
||||
|
||||
// Determine final short condition
|
||||
shortCondition = shortBias and weaknessDetected or shortConditionBase
|
||||
|
||||
// Market open condition
|
||||
marketSession = "0930-1030"
|
||||
marketTimezone = "America/New_York"
|
||||
isMarketOpen = not na(time(timeframe.period, marketSession, marketTimezone))
|
||||
|
||||
// Entry points
|
||||
if longCondition and (not shortBias or isMarketOpen)
|
||||
strategy.entry("Long", strategy.long)
|
||||
|
||||
if shortCondition
|
||||
strategy.entry("Short", strategy.short)
|
||||
|
||||
// Exit based on trend reversal
|
||||
if strategy.position_size > 0 and (blueTrendDown or orangeTrendDown)
|
||||
strategy.close("Long", comment="Exit Long")
|
||||
|
||||
if strategy.position_size < 0 and (blueTrendUp or orangeTrendUp)
|
||||
strategy.close("Short", comment="Exit Short")
|
||||
|
||||
// Visualize base swing points
|
||||
plotshape(baseSwingHigh, title="Swing High", style=shape.triangledown, location=location.abovebar, color=color.red, size=size.tiny)
|
||||
plotshape(baseSwingLow, title="Swing Low", style=shape.triangleup, location=location.belowbar, color=color.green, size=size.tiny)
|
||||
|
||||
// Visualize trend directions with shapes instead of characters
|
||||
// Blue trend
|
||||
plotshape(blueTrendUp and not blueTrendUp[1], title="Blue Trend Up Start", style=shape.arrowup, location=location.belowbar, color=color.blue, size=size.small)
|
||||
plotshape(blueTrendDown and not blueTrendDown[1], title="Blue Trend Down Start", style=shape.arrowdown, location=location.abovebar, color=color.blue, size=size.small)
|
||||
|
||||
// Purple trend
|
||||
plotshape(purpleTrendUp and not purpleTrendUp[1], title="Purple Trend Up Start", style=shape.arrowup, location=location.belowbar, color=color.purple, size=size.small)
|
||||
plotshape(purpleTrendDown and not purpleTrendDown[1], title="Purple Trend Down Start", style=shape.arrowdown, location=location.abovebar, color=color.purple, size=size.small)
|
||||
|
||||
// Orange trend
|
||||
plotshape(orangeTrendUp and not orangeTrendUp[1], title="Orange Trend Up Start", style=shape.arrowup, location=location.belowbar, color=color.orange, size=size.small)
|
||||
plotshape(orangeTrendDown and not orangeTrendDown[1], title="Orange Trend Down Start", style=shape.arrowdown, location=location.abovebar, color=color.orange, size=size.small)
|
||||
|
||||
// Yellow trend
|
||||
plotshape(yellowTrendUp and not yellowTrendUp[1], title="Yellow Trend Up Start", style=shape.arrowup, location=location.belowbar, color=color.yellow, size=size.small)
|
||||
plotshape(yellowTrendDown and not yellowTrendDown[1], title="Yellow Trend Down Start", style=shape.arrowdown, location=location.abovebar, color=color.yellow, size=size.small)
|
||||
|
||||
// Magenta trend
|
||||
plotshape(magentaTrendUp and not magentaTrendUp[1], title="Magenta Trend Up Start", style=shape.arrowup, location=location.belowbar, color=color.fuchsia, size=size.small)
|
||||
plotshape(magentaTrendDown and not magentaTrendDown[1], title="Magenta Trend Down Start", style=shape.arrowdown, location=location.abovebar, color=color.fuchsia, size=size.small)
|
||||
|
||||
// Display current trend status using table
|
||||
var table trendTable = table.new(position.top_right, 5, 2, color.black, color.white, 2, color.gray, 2)
|
||||
if barstate.islast
|
||||
table.cell(trendTable, 0, 0, "Trend", text_color=color.white, bgcolor=color.gray)
|
||||
table.cell(trendTable, 1, 0, "Direction", text_color=color.white, bgcolor=color.gray)
|
||||
|
||||
table.cell(trendTable, 0, 1, "Blue", text_color=color.blue, bgcolor=color.black)
|
||||
table.cell(trendTable, 1, 1, blueTrendUp ? "UP" : blueTrendDown ? "DOWN" : "FLAT",
|
||||
text_color=blueTrendUp ? color.green : blueTrendDown ? color.red : color.gray, bgcolor=color.black)
|
||||
|
||||
// Highlight imbalance areas
|
||||
bgcolor(highImbalance ? color.new(color.red, 90) : lowImbalance ? color.new(color.green, 90) : na, title="Imbalance Background")
|
Reference in New Issue
Block a user