Skip to main content

TradingViewClient

Struct TradingViewClient 

Source
pub struct TradingViewClient { /* private fields */ }
Expand description

High-level entry point for TradingView screener, search, quote, and history data.

Most consumers should start with TradingViewClient::builder and then use one of the product-oriented facades such as TradingViewClient::equity, TradingViewClient::crypto, or TradingViewClient::forex.

§Examples

use tvdata_rs::{Result, TradingViewClient};

#[tokio::main]
async fn main() -> Result<()> {
    let client = TradingViewClient::builder().build()?;

    let quote = client.equity().quote("NASDAQ:AAPL").await?;
    println!("{:?}", quote.close);

    Ok(())
}

Implementations§

Source§

impl TradingViewClient

Source

pub fn endpoints(&self) -> &Endpoints

Source

pub async fn scan(&self, query: &ScanQuery) -> Result<ScanResponse>

Executes a low-level TradingView screener query.

This is the most flexible API in the crate and is useful when you need fields or filters that are not covered by the higher-level market facades.

§Examples
use tvdata_rs::scanner::fields::{core, price};
use tvdata_rs::scanner::ScanQuery;
use tvdata_rs::{Result, TradingViewClient};

#[tokio::main]
async fn main() -> Result<()> {
    let client = TradingViewClient::builder().build()?;
    let query = ScanQuery::new()
        .market("america")
        .select([core::NAME, price::CLOSE])
        .page(0, 10)?;

    let response = client.scan(&query).await?;
    println!("rows: {}", response.rows.len());

    Ok(())
}
Source

pub async fn validate_scan_query( &self, query: &ScanQuery, ) -> Result<ScanValidationReport>

Validates a scan query against live TradingView metainfo before execution.

Validation currently requires the query to specify one or more markets so the client can resolve the corresponding /{market}/metainfo endpoints.

§Examples
use tvdata_rs::scanner::fields::{core, price};
use tvdata_rs::scanner::ScanQuery;
use tvdata_rs::{Result, TradingViewClient};

#[tokio::main]
async fn main() -> Result<()> {
    let client = TradingViewClient::builder().build()?;
    let query = ScanQuery::new()
        .market("america")
        .select([core::NAME, price::CLOSE]);

    let report = client.validate_scan_query(&query).await?;
    assert!(report.is_strictly_supported());
    Ok(())
}
Source

pub async fn scan_validated(&self, query: &ScanQuery) -> Result<ScanResponse>

Executes a scan only after validating all requested fields against live TradingView metainfo for the selected markets.

§Examples
use tvdata_rs::scanner::fields::{core, price};
use tvdata_rs::scanner::ScanQuery;
use tvdata_rs::{Result, TradingViewClient};

#[tokio::main]
async fn main() -> Result<()> {
    let client = TradingViewClient::builder().build()?;
    let query = ScanQuery::new()
        .market("america")
        .select([core::NAME, price::CLOSE]);

    let response = client.scan_validated(&query).await?;
    println!("rows: {}", response.rows.len());
    Ok(())
}
Source

pub async fn filter_scan_query( &self, query: &ScanQuery, ) -> Result<(ScanQuery, ScanValidationReport)>

Filters a scan query down to columns that are fully supported across the selected markets according to live TradingView metainfo plus the embedded registry fallback.

Partially supported columns are removed from the filtered query to keep the result safe across all requested markets.

§Examples
use tvdata_rs::scanner::fields::{fundamentals, price};
use tvdata_rs::scanner::ScanQuery;
use tvdata_rs::{Result, TradingViewClient};

#[tokio::main]
async fn main() -> Result<()> {
    let client = TradingViewClient::builder().build()?;
    let query = ScanQuery::new()
        .markets(["america", "crypto"])
        .select([price::CLOSE, fundamentals::MARKET_CAP_BASIC]);

    let (filtered, report) = client.filter_scan_query(&query).await?;
    println!("filtered columns: {:?}", report.filtered_column_names());
    assert!(!filtered.columns.is_empty());
    Ok(())
}
Source

pub async fn scan_supported(&self, query: &ScanQuery) -> Result<ScanResponse>

Executes a scan after dropping columns that are not fully supported across all selected markets.

§Examples
use tvdata_rs::scanner::fields::{fundamentals, price};
use tvdata_rs::scanner::ScanQuery;
use tvdata_rs::{Result, TradingViewClient};

#[tokio::main]
async fn main() -> Result<()> {
    let client = TradingViewClient::builder().build()?;
    let query = ScanQuery::new()
        .markets(["america", "crypto"])
        .select([price::CLOSE, fundamentals::MARKET_CAP_BASIC]);

    let response = client.scan_supported(&query).await?;
    println!("rows: {}", response.rows.len());
    Ok(())
}
Source

pub async fn metainfo( &self, market: impl Into<Market>, ) -> Result<ScannerMetainfo>

Fetches TradingView scanner metainfo for a specific market or screener.

This endpoint returns the currently supported field names and their value types as exposed by TradingView for the selected screener route.

§Examples
use tvdata_rs::{Result, TradingViewClient};

#[tokio::main]
async fn main() -> Result<()> {
    let client = TradingViewClient::builder().build()?;
    let metainfo = client.metainfo("america").await?;

    println!("fields: {}", metainfo.fields.len());
    Ok(())
}
Source

pub async fn search(&self, request: &SearchRequest) -> Result<Vec<SearchHit>>

Searches TradingView symbol metadata using the symbol search endpoint.

§Examples
use tvdata_rs::{Result, SearchRequest, TradingViewClient};

#[tokio::main]
async fn main() -> Result<()> {
    let client = TradingViewClient::builder().build()?;
    let hits = client
        .search(&SearchRequest::builder().text("AAPL").build())
        .await?;

    println!("matches: {}", hits.len());
    Ok(())
}
Source

pub async fn search_equities( &self, text: impl Into<String>, ) -> Result<Vec<SearchHit>>

Searches equities using TradingView’s current search_type=stock filter.

Source

pub async fn search_equities_response( &self, text: impl Into<String>, ) -> Result<SearchResponse>

Searches equities and returns the richer v3 response envelope.

Source

pub async fn search_forex( &self, text: impl Into<String>, ) -> Result<Vec<SearchHit>>

Searches forex instruments using TradingView’s current search_type=forex filter.

Source

pub async fn search_forex_response( &self, text: impl Into<String>, ) -> Result<SearchResponse>

Searches forex instruments and returns the richer v3 response envelope.

Source

pub async fn search_crypto( &self, text: impl Into<String>, ) -> Result<Vec<SearchHit>>

Searches crypto instruments using TradingView’s current search_type=crypto filter.

Source

pub async fn search_crypto_response( &self, text: impl Into<String>, ) -> Result<SearchResponse>

Searches crypto instruments and returns the richer v3 response envelope.

Source

pub async fn search_options( &self, text: impl Into<String>, ) -> Result<Vec<SearchHit>>

Searches option-like instruments.

As of March 22, 2026, TradingView’s live symbol_search/v3 endpoint rejects search_type=option, so this method performs a broader search and then keeps hits that look option-related based on the returned payload.

Source

pub async fn search_options_response( &self, text: impl Into<String>, ) -> Result<SearchResponse>

Searches option-like instruments and returns the filtered v3 response envelope.

Source

pub async fn search_response( &self, request: &SearchRequest, ) -> Result<SearchResponse>

Searches TradingView symbol metadata and returns the richer v3 search envelope.

This includes the remaining symbol count reported by TradingView, plus richer instrument metadata such as identifiers and listing/source information.

§Examples
use tvdata_rs::{Result, SearchRequest, TradingViewClient};

#[tokio::main]
async fn main() -> Result<()> {
    let client = TradingViewClient::builder().build()?;
    let response = client
        .search_response(&SearchRequest::builder().text("AAPL").build())
        .await?;

    println!("hits: {}", response.hits.len());
    println!("remaining: {}", response.symbols_remaining);
    Ok(())
}
Source

pub async fn economic_calendar( &self, request: &EconomicCalendarRequest, ) -> Result<EconomicCalendarResponse>

Fetches economic calendar events from TradingView’s Reuters-backed calendar feed.

§Examples
use tvdata_rs::{EconomicCalendarRequest, Result, TradingViewClient};

#[tokio::main]
async fn main() -> Result<()> {
    let client = TradingViewClient::builder().build()?;
    let response = client
        .economic_calendar(&EconomicCalendarRequest::upcoming(7))
        .await?;

    println!("events: {}", response.events.len());
    Ok(())
}
Source

pub async fn earnings_calendar( &self, request: &CalendarWindowRequest, ) -> Result<Vec<EarningsCalendarEntry>>

Fetches an earnings calendar window from TradingView scanner fields.

This is a market-wide calendar product, distinct from client.equity().earnings_calendar("NASDAQ:AAPL"), which returns single-symbol analyst earnings metadata.

§Examples
use tvdata_rs::{CalendarWindowRequest, Result, TradingViewClient};

#[tokio::main]
async fn main() -> Result<()> {
    let client = TradingViewClient::builder().build()?;
    let events = client
        .earnings_calendar(&CalendarWindowRequest::upcoming("america", 7))
        .await?;

    println!("events: {}", events.len());
    Ok(())
}
Source

pub async fn dividend_calendar( &self, request: &DividendCalendarRequest, ) -> Result<Vec<DividendCalendarEntry>>

Fetches a dividend calendar window from TradingView scanner fields.

The request can be anchored either on upcoming ex-dates or upcoming payment dates through DividendCalendarRequest::date_kind.

§Examples
use tvdata_rs::{DividendCalendarRequest, Result, TradingViewClient};

#[tokio::main]
async fn main() -> Result<()> {
    let client = TradingViewClient::builder().build()?;
    let events = client
        .dividend_calendar(&DividendCalendarRequest::upcoming("america", 14))
        .await?;

    println!("events: {}", events.len());
    Ok(())
}
Source

pub async fn ipo_calendar( &self, request: &CalendarWindowRequest, ) -> Result<Vec<IpoCalendarEntry>>

Fetches an IPO calendar window from TradingView scanner fields.

§Examples
use tvdata_rs::{CalendarWindowRequest, Result, TradingViewClient};

#[tokio::main]
async fn main() -> Result<()> {
    let client = TradingViewClient::builder().build()?;
    let events = client
        .ipo_calendar(&CalendarWindowRequest::trailing("america", 30))
        .await?;

    println!("events: {}", events.len());
    Ok(())
}
Source

pub async fn history(&self, request: &HistoryRequest) -> Result<HistorySeries>

Downloads a single OHLCV history series over TradingView’s chart websocket.

§Examples
use tvdata_rs::{HistoryRequest, Interval, Result, TradingViewClient};

#[tokio::main]
async fn main() -> Result<()> {
    let client = TradingViewClient::builder().build()?;
    let request = HistoryRequest::new("NASDAQ:AAPL", Interval::Day1, 30);
    let series = client.history(&request).await?;

    println!("bars: {}", series.bars.len());
    Ok(())
}

To fetch the maximum history currently available, construct the request with HistoryRequest::max("NASDAQ:AAPL", Interval::Day1).

Source

pub fn builder() -> TradingViewClientBuilder

Builds a TradingViewClient with validated endpoint configuration and retry settings.

Source§

impl TradingViewClient

Source

pub fn crypto(&self) -> CryptoClient<'_>

Returns the high-level crypto facade.

Source§

impl TradingViewClient

Source

pub fn equity(&self) -> EquityClient<'_>

Returns the high-level equity facade.

§Examples
use tvdata_rs::{Result, TradingViewClient};

#[tokio::main]
async fn main() -> Result<()> {
    let client = TradingViewClient::builder().build()?;
    let movers = client.equity().top_gainers("america", 5).await?;

    println!("movers: {}", movers.len());
    Ok(())
}
Source§

impl TradingViewClient

Source

pub fn forex(&self) -> ForexClient<'_>

Returns the high-level FX facade.

Source§

impl TradingViewClient

Source

pub async fn history_batch( &self, request: &HistoryBatchRequest, ) -> Result<Vec<HistorySeries>>

Downloads multiple OHLCV history series with bounded concurrency.

§Examples
use tvdata_rs::{HistoryBatchRequest, Interval, Result, TradingViewClient};

#[tokio::main]
async fn main() -> Result<()> {
    let client = TradingViewClient::builder().build()?;
    let request = HistoryBatchRequest::new(["NASDAQ:AAPL", "NASDAQ:MSFT"], Interval::Day1, 30);
    let series = client.history_batch(&request).await?;

    println!("series: {}", series.len());
    Ok(())
}
Source

pub async fn download_history_max<I, T>( &self, symbols: I, interval: Interval, ) -> Result<Vec<HistorySeries>>
where I: IntoIterator<Item = T>, T: Into<Ticker>,

Downloads the maximum history currently available for multiple symbols.

The crate keeps requesting older bars over the chart websocket until TradingView stops returning new history.

§Examples
use tvdata_rs::{Interval, Result, TradingViewClient};

#[tokio::main]
async fn main() -> Result<()> {
    let client = TradingViewClient::builder().build()?;
    let series = client
        .download_history_max(["NASDAQ:AAPL", "NASDAQ:MSFT"], Interval::Day1)
        .await?;

    println!("series: {}", series.len());
    Ok(())
}
Source

pub async fn download_history<I, T>( &self, symbols: I, interval: Interval, bars: u32, ) -> Result<Vec<HistorySeries>>
where I: IntoIterator<Item = T>, T: Into<Ticker>,

Convenience wrapper around TradingViewClient::history_batch for a list of symbols.

Source

pub async fn download_history_map<I, T>( &self, symbols: I, interval: Interval, bars: u32, ) -> Result<BTreeMap<Ticker, HistorySeries>>
where I: IntoIterator<Item = T>, T: Into<Ticker>,

Downloads multiple history series and returns them keyed by symbol.

Source

pub async fn download_history_map_max<I, T>( &self, symbols: I, interval: Interval, ) -> Result<BTreeMap<Ticker, HistorySeries>>
where I: IntoIterator<Item = T>, T: Into<Ticker>,

Downloads the maximum history available and returns it keyed by symbol.

Trait Implementations§

Source§

impl Clone for TradingViewClient

Source§

fn clone(&self) -> TradingViewClient

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for TradingViewClient

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more