L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Données et recherche · SKILL.md

day-trading-patterns

day-trading-patterns

Use when implementing intraday trading strategies, scalping algorithms, VWAP/TWAP execution, candlestick pattern recognition, volume profile analysis, order flow interpretation, or time-of-day effect modelling

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

name: day-trading-patterns description: Use when implementing intraday trading strategies, scalping algorithms, VWAP/TWAP execution, candlestick pattern recognition, volume profile analysis, order flow interpretation, or time-of-day effect modelling

Day Trading Patterns

Overview

Day trading operates on minute-to-hour timeframes. Success depends on execution quality, time-of-day awareness, and pattern recognition in price/volume. Most retail patterns fail; focus on statistically validated ones with clear entry/exit rules.

Core principle: Most intraday edges are execution-dependent. A pattern profitable at market close may be unprofitable at market open spreads.

When to Use

  • Implementing scalping or intraday momentum strategies
  • Building VWAP/TWAP-anchored execution algorithms
  • Recognising candlestick patterns programmatically
  • Modelling volume profile (POC, VAH, VAL) for support/resistance
  • Understanding order flow imbalance signals

VWAP and TWAP Execution

import pandas as pd
import numpy as np

def calculate_vwap(ohlcv: pd.DataFrame, session_start: str = '09:30') -> pd.Series:
    """
    Volume-Weighted Average Price. Resets each session.
    Standard anchor for institutional execution benchmarking.
    """
    typical_price = (ohlcv['high'] + ohlcv['low'] + ohlcv['close']) / 3
    tp_volume = typical_price * ohlcv['volume']

    # Group by date for session reset
    vwap = (tp_volume.groupby(ohlcv.index.date).cumsum() /
            ohlcv['volume'].groupby(ohlcv.index.date).cumsum())
    return vwap


def vwap_signal(ohlcv: pd.DataFrame) -> pd.Series:
    """
    VWAP mean-reversion signal.
    Buy when price crosses below VWAP, sell when above.
    Only reliable during trending sessions; avoid in choppy markets.
    """
    vwap = calculate_vwap(ohlcv)
    close = ohlcv['close']

    signal = pd.Series(0, index=ohlcv.index)
    signal[close < vwap * 0.998] = 1   # 0.2% below VWAP = buy
    signal[close > vwap * 1.002] = -1  # 0.2% above VWAP = sell

    return signal


def twap_schedule(total_qty: float, start_time, end_time,
                   n_slices: int = 20) -> pd.DataFrame:
    """
    Generate TWAP order schedule.
    Splits total_qty into equal slices at regular intervals.
    """
    times = pd.date_range(start_time, end_time, periods=n_slices)
    slice_qty = total_qty / n_slices
    return pd.DataFrame({
        'time': times,
        'quantity': slice_qty,
        'type': 'limit',  # use limit orders for TWAP
    })

Candlestick Pattern Detection

def detect_candlestick_patterns(df: pd.DataFrame) -> pd.DataFrame:
    """
    Detect key candlestick reversal patterns.
    Returns dataframe with boolean columns for each pattern.
    """
    o, h, l, c = df['open'], df['high'], df['low'], df['close']
    body = (c - o).abs()
    total_range = h - l
    upper_wick = h - df[['open', 'close']].max(axis=1)
    lower_wick = df[['open', 'close']].min(axis=1) - l

    df = df.copy()

    # Doji: body < 10% of total range
    df['doji'] = body < (total_range * 0.1)

    # Hammer (bullish reversal): small body at top, long lower wick
    df['hammer'] = (
        (lower_wick > body * 2) &
        (upper_wick < body * 0.5) &
        (c > o)  # bullish close
    )

    # Shooting Star (bearish reversal): small body at bottom, long upper wick
    df['shooting_star'] = (
        (upper_wick > body * 2) &
        (lower_wick < body * 0.5) &
        (c < o)  # bearish close
    )

    # Engulfing (bullish): current bullish candle completely engulfs previous bearish
    prev_o, prev_c = o.shift(1), c.shift(1)
    df['bullish_engulfing'] = (
        (c > o) &           # current candle is bullish
        (prev_c < prev_o) & # previous candle is bearish
        (o < prev_c) &      # open below previous close
        (c > prev_o)        # close above previous open
    )

    # Bearish engulfing
    df['bearish_engulfing'] = (
        (c < o) &
        (prev_c > prev_o) &
        (o > prev_c) &
        (c < prev_o)
    )

    # Pinbar: rejection candle (long wick on one side)
    df['pinbar_bullish'] = (lower_wick > total_range * 0.6) & (body < total_range * 0.25)
    df['pinbar_bearish'] = (upper_wick > total_range * 0.6) & (body < total_range * 0.25)

    return df

Volume Profile (POC, VAH, VAL)

def calculate_volume_profile(
    df: pd.DataFrame,
    n_bins: int = 50,
) -> dict:
    """
    Volume Profile: distribution of volume across price levels.
    POC = Point of Control (highest volume price)
    VAH = Value Area High (top of 70% value area)
    VAL = Value Area Low (bottom of 70% value area)
    """
    price_min, price_max = df['low'].min(), df['high'].max()
    price_bins = pd.cut(df['close'], bins=n_bins)

    # Volume per price bin
    vol_profile = df.groupby(price_bins, observed=True)['volume'].sum()
    vol_profile = vol_profile.sort_index()

    # POC: price level with highest volume
    poc_bin = vol_profile.idxmax()
    poc_price = poc_bin.mid

    # Value Area: 70% of total volume around POC
    total_vol = vol_profile.sum()
    target_vol = total_vol * 0.70

    # Expand outward from POC until 70% volume captured
    poc_idx = vol_profile.index.get_loc(poc_bin)
    lower_idx, upper_idx = poc_idx, poc_idx
    captured_vol = vol_profile.iloc[poc_idx]

    while captured_vol < target_vol:
        lower_can_expand = lower_idx > 0
        upper_can_expand = upper_idx < len(vol_profile) - 1

        lower_vol = vol_profile.iloc[lower_idx - 1] if lower_can_expand else 0
        upper_vol = vol_profile.iloc[upper_idx + 1] if upper_can_expand else 0

        if lower_vol >= upper_vol and lower_can_expand:
            lower_idx -= 1
            captured_vol += lower_vol
        elif upper_can_expand:
            upper_idx += 1
            captured_vol += upper_vol
        else:
            break

    return {
        'poc': poc_price,
        'vah': vol_profile.index[upper_idx].right,
        'val': vol_profile.index[lower_idx].left,
        'profile': vol_profile,
    }

Order Flow Imbalance

def order_flow_imbalance(trades: pd.DataFrame,
                          window: int = 100) -> pd.Series:
    """
    Order flow imbalance = (buy_volume - sell_volume) / total_volume.
    Positive = buying pressure, negative = selling pressure.
    Uses tick rule: price up = buy-initiated, price down = sell-initiated.
    """
    # Classify trades by tick rule
    price_change = trades['price'].diff()
    trades['side'] = 0
    trades.loc[price_change > 0, 'side'] = 1   # buy
    trades.loc[price_change < 0, 'side'] = -1  # sell
    # Carry forward for unchanged prices
    trades['side'] = trades['side'].replace(0, np.nan).ffill().fillna(0)

    buy_vol = (trades['size'] * (trades['side'] == 1)).rolling(window).sum()
    sell_vol = (trades['size'] * (trades['side'] == -1)).rolling(window).sum()
    total_vol = (buy_vol + sell_vol).clip(lower=1)

    return (buy_vol - sell_vol) / total_vol

Time-of-Day Effects

# Intraday patterns (equity markets, US Eastern Time)
TIME_OF_DAY_NOTES = {
    '09:30-10:00': 'Opening auction — highest volatility, wide spreads. Avoid unless breakout strategy.',
    '10:00-11:30': 'First trend window — most reliable intraday trends form here.',
    '11:30-14:00': 'Midday chop — range-bound, low momentum. Reduce position sizes.',
    '14:00-15:00': 'London close overlap — moderate volatility, directional moves.',
    '15:00-16:00': 'Power hour — second highest volume, trends often extend or reverse.',
    '15:50-16:00': 'MOC imbalances published — large institutional moves, avoid fade.',
}

# Crypto (24/7 markets — UTC)
CRYPTO_TIME_PATTERNS = {
    '00:00-04:00 UTC': 'Asian session — generally lower volatility for BTC/ETH.',
    '07:00-09:00 UTC': 'European open — increased EUR pairs activity.',
    '13:00-15:00 UTC': 'US/EU overlap — highest liquidity window for crypto.',
    '21:00-23:59 UTC': 'Low liquidity — wider spreads, avoid large orders.',
    'Funding (every 8h)': 'Funding payments at 00:00, 08:00, 16:00 UTC — brief price manipulation common.',
}

Quick Reference — Pattern Reliability

PatternWin Rate (backtest)Best TimeframeNotes
VWAP reversion52-58%5m-15mOnly in ranging markets
Bullish engulfing54-60%15m-1hRequires volume confirmation
Opening range breakout55-65%5m (first 30min)Direction of first 30min
Volume POC bounce55-62%1h+More reliable on higher timeframes
Hammer at support56-63%15m-4hNeeds identifiable support level

All win rates are indicative; verify on your specific instrument and timeframe.

Common Mistakes

  1. Trading the open — first 15 minutes have the widest spreads and most noise; wait for range to form
  2. Ignoring volume — a breakout without volume surge is 70% more likely to fail
  3. Over-trading midday — equities 11:30-14:00 and crypto low-liquidity windows are choppy; reduce size
  4. Pattern hunting without context — a hammer at a support level is a signal; a hammer in the middle of a range is noise
  5. Market orders for entries — use limit orders within the bid-ask for entries; market orders on exits only
  6. No daily bias — intraday direction should align with daily trend; fading a strong trend is low-probability

Anti-Patterns

Anti-PatternWhy It FailsCorrect Approach
Trading the first 15 minutes of market openWidest spreads, maximum noise, institutional order flow distortion — most retail losses happen hereWait for the opening range to form (first 15-30 min); trade the breakout or reversion, not the chaos
Entering breakouts without volume confirmationA breakout on low volume is 70% more likely to be a false breakout that reversesRequire volume surge (1.5x+ average) to confirm breakout; no volume = no entry
Over-trading during midday chop (11:30-14:00 equities)Low volume, tight ranges, mean-reversion dominates — directional strategies get whipsawedReduce position size or stop trading during low-liquidity windows; focus on open and close sessions
Using market orders for entriesSlippage on entries compounds over hundreds of trades; destroys edge on scalping strategiesUse limit orders within the bid-ask for entries; reserve market orders for stop-loss exits only
Fading a strong daily trend intradayCounter-trend scalps have 30-40% win rates against strong trends; losses are larger than winsAlign intraday direction with the daily trend bias; only fade at major support/resistance with volume divergence

See also: this skill works a symbol you already chose — for building the tradeable universe / pre-market watchlist, use equity-scanning-and-watchlists.

Skills enregistrées