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.
| Argument | Description |
|---|---|
frame | Source dataframe. |
timeframe | String such as 15m, 1h, 1d. |
expr | Callable or series expression evaluated on the resampled frame. |
fill_method | ffill (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.