고래 추적기


생성 날짜: 2026-01-13 15:51:03 마지막으로 수정됨: 2026-01-13 15:51:03
복사: 6 클릭수: 261
avatar of ianzeng123 ianzeng123
2
집중하다
413
수행원

고래 추적기 고래 추적기

VS, ATR, MA200, HTF

이것은 일반적인 해킹 전략이 아니라, 거액의 자금의 움직임을 추적하는 독수리 추적기입니다.

재검토 자료에 따르면, 시장에서 볼륨 스파이크 (VS) 신호가 발생했을 때, 다중 MA 필터링과 함께, 승률은 전통적인 돌파 전략보다 훨씬 우수합니다. 핵심 논리는 간단하고 거친 거액의 자본이 들어오는 것은 반드시 흔적을 남길 것입니다.

21주기 VS 검출 + 2.3배 확대 계수, 진정한 이진 신호를 포착

전통적인 전략은 가격을 보고, 이 시스템은 거래량 변동을 보고 있다. 21주기 내에 2개의 극한값을 제거한 후 계산된 평균 변동, 현재 K선 변동이 평균값의 2.3배 이상이고, 매장값의 0.7% 이상을 차지할 때 신호를 트리거한다. 더욱 중요한 것은, 매장값이 현재 K선 상위 65%의 위치에 있어야 하며, 이것이 다목적 지배적인 방전임을 확인한다.

자료가 말하고 있습니다.이 VS 탐지 메커니즘은 90% 이상의 가짜 돌파구를 필터링하여 실제 큰 자본이 참여한 사례만을 잡습니다.

MA200 4중 필터링 메커니즘, 곰 시장에서 더 많은 것을 거부

모든 덩어리가 추구할 가치가 있는 것은 아니며, 시장의 추세가 모든 것을 결정한다. 전략은 네 가지 MA200 방어선을 설정한다:

  • 현재 가격은 MA200보다 높아야 합니다.
  • MA200은 상승세를 보아야 한다 (이하 20주기 경사율이 긍정)
  • 4시간 레벨 MA200도 확인
  • 입지 지점 MA200에서 6%를 넘지 않는다.

이것은 무엇을 의미합니까?하지만, 이 모든 것은, 당신이 그 어떤 신호를 제공하지 않을 것이기 때문에, 명백한 하향 추세에서 결코 잡히지 않을 것입니다.

2.7배의 ATR 중지 + 동적 추적, 당신이 생각하는 것보다 더 엄격한 위험 관리

각 거래의 위험은 100달러로 고정되어 있으며, ATR를 통해 역동적으로 계산되는 포지션 크기가 있다. 14주기 ATR을 2.7배로 곱하여 초기 스톱로 삼고, 이 파라미트는 많은 재검토를 거쳐 최적화되어, 정상적인 변동 스톱을 피하고, 실제 반전 시에는 시점에 퇴출할 수 있다.

핵심 혁신: 새로운 VS 신호가 출현할 때마다, 스톱로스 가격은 자동으로 최신 하위점으로 이동하여, 이미 이윤을 확보한 상태에서 트렌드에 공간을 남겨줍니다.

피라미드 상장 논리, 수익을 더 멀리 달릴 수 있게 해준다

첫 번째 VS 신호는 포지션을 열고, 두 번째 VS 신호는 포지션을 올리고, 세 번째 VS 신호는 스톱로스가 비용으로 이동한다. 이것은 맹목적으로 포지션을 올리는 것이 아니라, 시장의 지속적인 변동성에 대한 논리적인 판단에 따라 연속적으로 큰 자본의 유입은 일반적으로 더 큰 것을 의미한다.

데이터 지원: 역사적인 회견은 3번 이상의 연속 VS 신호가 발생하는 경우의 평균 상승이 단일 VS 신호의 2.8배인 것을 보여줍니다.

을 막기 위한 배열 장치, 안보 트렌드를 따르는 완벽한 균형

4번째 VS 신호가 터졌을 때, 자동으로 33%의 포지션을 중지하고, 5번째 VS 신호가 터졌을 때, 나머지 포지션의 50%를 중지한다. 이러한 설계의 논리는: 이전 VS 신호는 트렌드를 확인하고, 후기 VS 신호는 상위 영역에 가깝게 된다.

실전 효과“엘리베이터”를 타는 불편함을 피하면서도, 몇몇 포지션을 유지하면서도, 가능한 초월적인 상황을 포착할 수 있습니다.

Pay-Self 메커니즘, 2% 상승 후 자동으로 0.15%의 수익을 보호

이것은 리스크 관리의 핵심입니다. 파동이 2%에 도달하면 스톱 스로프는 자동으로 비용 가격보다 0.15% 상승합니다. 보수적으로 보이지만 실제로는 전략의 장기적인 안정성을 보장하는 전제 조건으로 큰 추세에 충분한 공간을 남깁니다.

왜 2%가 트리거일까요?왜냐하면, 재검토 자료에 따르면, 2%의 유동성 거래가 가능하고, 최종 수익률은 78% 이상이기 때문입니다.

적용 가능한 시장: BTC 1 시간 수준, 황소 시장 환경에서 가장 잘 수행

이 전략은 BTC 1시간 차트 최적화를 위해 고안된 것으로, 트렌디한 상황에서는 두드러지게 나타난다. 주의할 점은, 흔들리는 시장에서 VS 신호가 자주 발생하지만, 폭이 제한되어, 연속적으로 작은 손실이 발생할 수 있다는 것이다.

위험 경고: 역사 회전은 미래의 수익을 나타내지 않으며, 전략에 연속적인 손실 위험이 있습니다. 단일 위험을 엄격히 제어하여 1-2%의 계정을 초과하지 않는 것이 좋습니다. 시장 환경이 변화하면 전략의 성능이 크게 달라질 수 있습니다.

아래쪽: 전체적인 트렌드 추적 시스템입니다. 단선 투기 도구가 아닙니다.

매일 신호를 기대한다면, 이 전략은 당신에게 적합하지 않습니다. 당신이 진정한 트렌드 상황을 잡고 고품질의 진입 기회를 기다린다면, 이 상어 추적기는 깊이 연구할 가치가 있습니다.

전략 소스 코드
/*backtest
start: 2025-01-13 00:00:00
end: 2026-01-11 00:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_OKX","currency":"ETH_USDT","balance":500000}]
*/

//@version=5
strategy("BULL Whale Finder + BTC 1h",
     overlay=true,
     pyramiding=4,
     calc_on_every_tick=true,
     process_orders_on_close=false)

// =====================================================
// INPUTS (SOLO 1)
// =====================================================
float MLPT_USD = input.float(100, "MLPT USD (riesgo por trade)", minval=1, step=1)

// =====================================================
// HARD CODED (NO TOCAR)
// =====================================================
// Execution
string POINTER = ""
bool allowBacktestNoPointer = true

// SL (ATR)
int   atrLen  = 14
float atrMult = 2.7

// Pay-Self
bool  usePaySelf    = true
float payTriggerPct = 2.0  / 100.0
float payLockPct    = 0.15 / 100.0

// MA200 Filter
bool useMA200Filter = true
bool useMA200Slope  = true
int  ma200Len       = 200
int  ma200SlopeLen  = 20

// MA200 HTF
bool   useMA200HTF   = true
string ma200HTF_tf   = "240" // 4H

// VS Params
int   vsLen      = 21
int   vsOut      = 2
float vsMult     = 2.3
float vsMinPct   = 0.7  / 100.0
float vsClosePct = 35.0 / 100.0

// Exchange / rounding
float SL_BUFFER        = 0.01
float qtyFixed         = 0.001
float stepQty          = 0.001
float MIN_NOTIONAL_USD = 20.0

// TP
bool  tpFromVS3 = false
float tp1Pct    = 33.0
float tp2Pct    = 50.0

// Visual
bool  showSL       = true
bool  showShade    = true
bool  showEntryDot = true
color cSL      = color.new(color.green, 0)
color cShade   = color.new(color.green, 85)
color cVSentry = color.lime
color cVStp    = color.orange

// Proximidad MA1/MA2 (tal cual tus valores)
bool useMA1Filter      = true        // exigir close > MA20
bool useEntryNearMA2   = true        // VS#1 cerca MA200 desde LOW
float entryNearMA2Pct  = 6.0 / 100.0 // 6%
bool useEntryNearMA1   = false       // desactivado (tu screenshot)
float entryNearMA1Pct  = 6.0 / 100.0 // queda fijo aunque no se use
bool useMA1MA2Near     = true        // MA20 y MA200 cerca
float ma1ma2NearPct    = 6.0 / 100.0 // 6%

// =====================================================
// JSON (ALERTS) — hardcode pointer vacío
// =====================================================
f_json(_event, _reduce) =>
    "{" + "\"ticker\":\"{{ticker}}\"," + "\"action\":\"{{strategy.order.action}}\"," + "\"quantity\":\"{{strategy.order.contracts}}\"," + "\"pointer\":\"" + POINTER + "\"," + "\"reduce_only\":" + (_reduce ? "true" : "false") + "," + "\"event\":\"" + _event + "\"}"

// =====================================================
// HELPERS
// =====================================================
f_round_step_floor(_x, _step) => _step > 0 ? math.floor(_x / _step) * _step : _x
f_round_step_ceil(_x, _step)  => _step > 0 ? math.ceil(_x / _step)  * _step : _x

f_qty_min_notional(_qty, _px) =>
    need = (MIN_NOTIONAL_USD > 0) ? (MIN_NOTIONAL_USD / _px) : 0.0
    qRaw = math.max(_qty, need)
    f_round_step_ceil(qRaw, stepQty)

f_qty_mlpt_long(_entry, _sl) =>
    risk = _entry - _sl
    qRaw = (risk > 0) ? (MLPT_USD / risk) : 0.0
    f_round_step_floor(qRaw, stepQty)

// =====================================================
// MA200 / MA20
// =====================================================
ma200 = ta.sma(close, ma200Len)
plot(ma200, "MA200", color=color.red, linewidth=2)

ma1 = ta.sma(close, 20)
plot(ma1, "MA20", color=color.blue, linewidth=2)

ma200Slope   = ma200 - ma200[ma200SlopeLen]
ma200SlopeOK = (not useMA200Slope) or (not na(ma200Slope) and ma200Slope > 0)
ma200FilterOK = (not useMA200Filter) or (close > ma200 and ma200SlopeOK)

// HTF MA200
ma200HTF = request.security(syminfo.tickerid, ma200HTF_tf, ta.sma(close, ma200Len))
ma200HTFFilterOK = (not useMA200HTF) or (not na(ma200HTF) and close > ma200HTF)

// Proximidad (medido desde LOW)
ma1FilterOK = (not useMA1Filter) or (close > ma1)

distLowMA2 = (not na(ma200) and low > 0) ? math.abs(low - ma200) / low : na
entryNearMA2OK = (not useEntryNearMA2) or (not na(distLowMA2) and distLowMA2 <= entryNearMA2Pct)

distLowMA1 = (not na(ma1) and low > 0) ? math.abs(low - ma1) / low : na
entryNearMA1OK = (not useEntryNearMA1) or (not na(distLowMA1) and distLowMA1 <= entryNearMA1Pct)

distMA1MA2 = (not na(ma1) and not na(ma200) and ma1 != 0) ? math.abs(ma1 - ma200) / ma1 : na
ma1ma2NearOK = (not useMA1MA2Near) or (not na(distMA1MA2) and distMA1MA2 <= ma1ma2NearPct)

// =====================================================
// VS DETECTION — LONG
// =====================================================
rng = high - low

f_avg_no_out(_len, _k) =>
    float result = na
    if bar_index >= _len
        arr = array.new_float(0)
        for i = 0 to _len - 1
            array.push(arr, high[i] - low[i])
        array.sort(arr, order.ascending)
        n = array.size(arr)
        kk = math.min(_k, math.floor((n - 1) / 2))
        start = kk
        stop  = n - kk - 1
        sum = 0.0
        count = 0
        if stop >= start
            for j = start to stop
                sum += array.get(arr, j)
                count += 1
            result := count > 0 ? sum / count : na
    result

avgRng = f_avg_no_out(vsLen, vsOut)
okRange   = not na(avgRng) and rng >= avgRng * vsMult
okMinPct  = rng >= close * vsMinPct
strongBull = rng > 0 and (high - close) / rng <= vsClosePct
isVS = okRange and okMinPct and strongBull

// =====================================================
// EXEC FLAGS (hardcoded)
// =====================================================
hasPointer = str.length(POINTER) > 0
canTrade   = allowBacktestNoPointer or hasPointer

// =====================================================
// VARS
// =====================================================
var float slPrice = na
var float entryPx = na
var float initQty = na
var float mfePct  = 0.0
var bool  payArmed = false

var int   vsCount = 0
var float vs2Low  = na
var bool  tp1     = false
var bool  tp2     = false

// RESET
if strategy.position_size == 0
    slPrice := na
    entryPx := na
    initQty := na
    mfePct  := 0.0
    payArmed := false
    vsCount := 0
    vs2Low  := na
    tp1 := false
    tp2 := false

// =====================================================
// ENTRY (VS #1) + SL inicial ATR
// =====================================================
enterCond = barstate.isconfirmed and isVS and ma200FilterOK and ma200HTFFilterOK and ma1FilterOK and entryNearMA2OK and entryNearMA1OK and ma1ma2NearOK and strategy.position_size == 0 and canTrade
if enterCond
    atr   = ta.atr(atrLen)
    slInit = close - atr * atrMult
    qtyRisk = f_qty_mlpt_long(close, slInit)
    qtyFinal = f_qty_min_notional(qtyRisk, close)
    qtyFinal := f_round_step_floor(qtyFinal, stepQty)
    if qtyFinal > 0
        strategy.entry("L", strategy.long, qty=qtyFinal, alert_message=(hasPointer ? f_json("ENTRY_INIT", false) : ""))
        entryPx := close
        initQty := qtyFinal
        slPrice := slInit
        vsCount := 1

plotshape(showEntryDot and enterCond, title="Entry Dot", style=shape.circle, size=size.tiny, location=location.belowbar, color=color.new(color.green, 0))

// =====================================================
// PAY-SELF (MFE % -> SL piso a profit fijo, sin cerrar size)
// =====================================================
if usePaySelf and strategy.position_size > 0 and not na(entryPx) and entryPx > 0
    curMfePct = math.max(0.0, (high - entryPx) / entryPx)
    mfePct := math.max(mfePct, curMfePct)
    if not payArmed and mfePct >= payTriggerPct
        payArmed := true
    if payArmed and payLockPct > 0 and not na(initQty) and initQty > 0
        paySL = entryPx * (1.0 + payLockPct)
        slPrice := na(slPrice) ? paySL : math.max(slPrice, paySL)

// =====================================================
// VS SEQUENCE
// =====================================================
if barstate.isconfirmed and strategy.position_size > 0 and isVS
    vsCount += 1

    slTrail = low - SL_BUFFER
    slPrice := na(slPrice) ? slTrail : math.max(slPrice, slTrail)

    if vsCount == 2
        vs2Low := low - SL_BUFFER
        addQty = f_qty_mlpt_long(close, slPrice)
        addQty := f_qty_min_notional(addQty, close)
        addQty := f_round_step_floor(addQty, stepQty)
        if addQty > 0
            strategy.entry("L", strategy.long, qty=addQty, alert_message=(hasPointer ? f_json("ADD_VS2", false) : ""))

    if vsCount == 3
        slPrice := math.max(slPrice, entryPx)
        if not na(vs2Low)
            slPrice := math.max(slPrice, vs2Low)

    int tp1VS = tpFromVS3 ? 3 : 4
    int tp2VS = tpFromVS3 ? 4 : 5

    if vsCount == tp1VS and not tp1
        strategy.close("L", qty_percent=tp1Pct, alert_message=(hasPointer ? f_json("TP1_VS" + str.tostring(tp1VS), true) : ""))
        tp1 := true

    if vsCount == tp2VS and not tp2
        strategy.close("L", qty_percent=tp2Pct, alert_message=(hasPointer ? f_json("TP2_VS" + str.tostring(tp2VS), true) : ""))
        tp2 := true

// =====================================================
// EXIT (SL EVENT)
// =====================================================
if strategy.position_size > 0 and not na(slPrice)
    strategy.exit("XL", from_entry="L", stop=slPrice, alert_message=(hasPointer ? f_json("SL_EVENT", true) : ""))

// =====================================================
// BAR COLORS (VS entrada vs VS de TP)
// =====================================================
int tp1VS_now = tpFromVS3 ? 3 : 4
int tp2VS_now = tpFromVS3 ? 4 : 5
isTPvs = strategy.position_size > 0 and isVS and (vsCount == tp1VS_now or vsCount == tp2VS_now)
barcolor(isTPvs ? cVStp : (isVS ? cVSentry : na))

// =====================================================
// SL PLOT + SHADE
// =====================================================
pSL = plot(showSL ? slPrice : na, "SL", color=cSL, linewidth=2, style=plot.style_linebr)
pPx = plot(showShade and strategy.position_size > 0 ? close : na, "PX (fill)", color=color.new(color.white, 100), display=display.none)
fill(pSL, pPx, color=(showShade and strategy.position_size > 0 ? cShade : na))