Whale Tracker


Date de création: 2026-01-13 15:51:03 Dernière modification: 2026-01-13 15:51:03
Copier: 6 Nombre de clics: 261
2
Suivre
413
Abonnés

Whale Tracker Whale Tracker

VS, ATR, MA200, HTF

Ce n’est pas une tactique de piratage ordinaire, c’est un traqueur de requins spécialement conçu pour détecter les mouvements de capitaux importants.

Les données de retracement montrent que lorsque le marché émet des signaux de Volume Spike ((VS), le taux de victoire est nettement supérieur à celui des stratégies de rupture traditionnelles. La logique de base est simple.

21 cycles de détection VS + 2,3 fois le coefficient d’amplification pour capturer le véritable signal isotherme

Les stratégies traditionnelles regardent le prix, ce système regarde les fluctuations de la quantité de transaction. La fluctuation moyenne est calculée en éliminant les 2 extrêmes en 21 cycles, et le signal est déclenché lorsque la ligne K actuelle fluctue plus de 2,3 fois la moyenne et représente plus de 0,7% du prix du comptoir. Plus important encore, le prix du comptoir doit être situé à 65% au-dessus de la ligne K actuelle, pour s’assurer qu’il s’agit d’une amplitude dominée par plusieurs têtes.

Les données parlentLe système de détection VS filtre plus de 90% des fausses percées et ne prend en compte que les entreprises qui ont réellement participé à de grosses sommes.

MA200, un système à quatre filtres qui refuse de faire plus dans un marché baissier

La stratégie définit quatre lignes de défense MA200:

  • Le prix actuel doit être supérieur à MA200
  • La MA200 doit être à la hausse ((la pente de 20 cycles est positive))
  • 4 heures niveau MA200 confirme également plusieurs têtes
  • Point d’entrée situé à moins de 6% de la MA200

Qu’est-ce que cela signifie ?Vous ne serez jamais pris au piège d’une tendance baissière évidente, car le système ne donnera aucun signal.

2,7 fois le stop ATR + suivi dynamique, plus de contrôle des risques que vous ne le pensez

Le risque par transaction est fixé à 100 $ (modifiable) et la taille de la position est calculée dynamiquement par l’ATR. Le 14 cycles ATR est multiplié par 2,7 fois le stop initial. Ce paramètre a été optimisé après un grand nombre de tests de rétroaction, ce qui permet d’éviter les stops de fluctuation normaux et de quitter la position en temps opportun lors d’une véritable inversion.

Les innovations clés: Chaque fois qu’un nouveau signal VS apparaît, le prix stop-loss se déplace automatiquement vers le dernier bas, en bloquant les gains déjà réalisés et en laissant de la place à la tendance.

La logique de la pyramide pour faire courir les profits plus loin

Le premier signal VS ouvre la position, le deuxième signal VS augmente la position, le troisième signal VS est suivi d’un stop loss qui se déplace vers le prix de revient. Il ne s’agit pas d’une prise de position aveugle, mais d’un jugement logique basé sur la dynamique continue du marché.

Soutenue par les données: Les relevés historiques montrent que les signaux VS successifs de plus de 3 fois ont augmenté en moyenne de 2,8 fois par rapport aux signaux VS simples.

Le système de blocage des lots, le parfait équilibre entre les sacs de déchargement et les tendances

Lors du déclenchement du quatrième signal VS, il s’arrête automatiquement à 33% de la position; lors du cinquième signal VS, il s’arrête à 50% de la position restante. La logique de cette conception est la suivante: les signaux VS antérieurs confirment la tendance, les signaux VS postérieurs se rapprochent souvent de la zone supérieure.

Les effets de la guerreLe film a été réalisé par un groupe de cinéastes de l’Université du Michigan, qui a été créé pour diffuser des films de cinéma et d’animation.

Mécanisme Pay-Self, protection automatique de 0,15% des bénéfices après une hausse de 2%

C’est l’essence même de la gestion des risques: lorsque la volatilité atteint 2%, le prix stop-loss est automatiquement porté à 0,15% au-dessus du prix de revient. En apparence conservateur, il est en fait suffisamment large pour laisser place à une grande tendance, à condition de garantir la stabilité à long terme de la stratégie.

Pourquoi 2% de déclenchement ?Les données de retracement ont montré que les transactions pouvant atteindre une volatilité de 2% ont une probabilité de profit de plus de 78%.

Marché applicable: niveau horaire de 1 BTC, le meilleur rendement dans un environnement de marché haussier

La stratégie est spécifiquement conçue pour optimiser le graphique horaire de 1 heure de BTC, qui se démarque dans les tendances. Il convient de noter que les signaux VS sont fréquents mais limités dans les marchés en mouvement, ce qui peut entraîner de petites pertes successives.

Conseils à la prudence: la rétroaction historique ne représente pas les gains futurs, la stratégie présente un risque de perte continue. Il est recommandé de contrôler strictement le risque individuel et de ne pas dépasser 1 à 2% du compte. La performance de la stratégie peut être significativement différente lorsque les conditions du marché changent.

Bottom line: C’est un système complet de suivi des tendances, pas un outil de spéculation à courte ligne

Si vous vous attendez à des signaux tous les jours, cette stratégie ne vous convient pas. Si vous voulez capturer de vraies tendances et que vous êtes prêt à attendre des opportunités d’entrée de qualité, alors ce traqueur de requins vaut la peine d’être étudié en profondeur.

Code source de la stratégie
/*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))