Skip to main content
ATK Pine Script®

request.* Namespace

Multi-timeframe data access via request.security and request.security_lower_tf — when to use it and how to avoid alignment complexity.

request.* Namespace#

Use only when needed — Reach for request.* only when the script truly depends on higher-timeframe or alternate-frame data. It adds state and alignment complexity quickly.

Keep it in signal or indicator builders — Do all request work in build_indicator_frame or build_signal_frame, never in build_trade_frame or build_visuals.

request.security(frame, timeframe, expr, fill_method="ffill")#

Resamples the source frame to the requested timeframe, evaluates expr on the resampled frame, and aligns the result back to the base frame.

ArgumentDescription
frameSource dataframe.
timeframeString such as 15m, 1h, 1d.
exprCallable or series expression evaluated on the resampled frame.
fill_methodffill (default) or bfill.

request.security_lower_tf(...)#

Currently partial. It caches by request signature and falls back when the lower timeframe cannot be meaningfully derived from the base frame.

MTF confirmation strategy example#

# @name: pynescript_mtf_confirmation_strategy
import numpy as np
import pandas as pd

from source import strategy, input, ta, request, build_mapped_trade_frame

strategy("Pyne MTF Confirmation Strategy", overlay=True, process_orders_on_close=True, max_bars_back=180)
fast_period = input.int(10, title="Fast EMA", key="fast_period")
slow_period = input.int(24, title="Slow EMA", key="slow_period")
trend_length = input.int(34, title="HTF Trend EMA", key="trend_length")
confirm_tf = input.timeframe("15m", title="Confirm TF", key="confirm_tf")
trade_qty = input.float(1.0, title="Trade Qty", key="trade_qty")


def build_signal_frame(df: pd.DataFrame, params: dict | None = None) -> pd.DataFrame:
    frame = df.copy().reset_index(drop=True)
    p = {
        "fast_period": int(fast_period),
        "slow_period": int(slow_period),
        "trend_length": int(trend_length),
        "confirm_tf": str(confirm_tf),
    } | dict(params or {})
    ema_fast = ta.ema(frame["close"], int(p["fast_period"]))
    ema_slow = ta.ema(frame["close"], int(p["slow_period"]))
    htf_trend = request.security(
        frame,
        str(p["confirm_tf"]),
        lambda x: ta.ema(x["close"], int(p["trend_length"])),
    )
    frame["buy_signal"] = (
        ta.crossover(ema_fast, ema_slow).fillna(False)
        & (frame["close"] >= htf_trend.fillna(frame["close"]))
    )
    frame["sell_signal"] = (
        ta.crossunder(ema_fast, ema_slow).fillna(False)
        & (frame["close"] <= htf_trend.fillna(frame["close"]))
    )
    frame["entry_side"] = np.where(frame["buy_signal"], "BUY", np.where(frame["sell_signal"], "SELL", ""))
    frame["entry_price"] = frame["open"]
    frame["quantity"] = float(trade_qty)
    frame["size_pct"] = 0.0
    return frame


def build_trade_frame(signal_df: pd.DataFrame, params: dict | None = None, styles: dict | None = None) -> pd.DataFrame:
    return build_mapped_trade_frame(signal_df)

If this is your first multi-timeframe script, copy the confirmation strategy pattern above before trying to improvise resampling logic.