| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [View Raw Code] [Original HTTPS Page] |
This service provides access to real-time and historical market data, including quotes, price bars, options data, and symbol information.
First, ensure you have an initialized TradeStationClient:
import asyncio
from dotenv import load_dotenv
from tradestation.client import TradeStationClient
# Load environment variables
load_dotenv()
# Create the client
client = TradeStationClient()
# Access the market data service
market_data = client.market_data
# --- Your code using market_data methods goes here ---
# Remember to close the client when finished
async def main():
# ... use market_data methods ...
await client.close()
if __name__ == "__main__":
asyncio.run(main())Gets detailed information about one or more symbols.
details = await market_data.get_symbol_details(["AAPL", "MSFT", "INVALID"])
for symbol_info in details.Symbols:
print(f"Symbol: {symbol_info.Name}, Description: {symbol_info.Description}, Type: {symbol_info.AssetType}")
for error in details.Errors:
print(f"Error getting details for {error.Symbol}: {error.Error}")Fetches crypto Symbol Names for all available symbols (e.g., BTCUSD, ETHUSD). Note: These symbols cannot be traded via this API.
crypto_names = await market_data.get_crypto_symbol_names()
print("Available Crypto Symbols:")
for symbol in crypto_names.SymbolNames:
print(f"- {symbol}")Fetches a full snapshot of the latest Quote for the given Symbols (up to 100). For realtime updates, use stream_quotes.
snapshot = await market_data.get_quote_snapshots(["MSFT", "BTCUSD"])
for quote in snapshot.Quotes:
print(f"{quote.Symbol}: Last={quote.Last}, Bid={quote.Bid}, Ask={quote.Ask}, Volume={quote.Volume}")
for error in snapshot.Errors:
print(f"Error getting quote for {error.Symbol}: {error.Error}")Get the available expiration dates for option contracts on the specified underlying symbol.
expirations = await market_data.get_option_expirations("AAPL")
print(f"Expirations for AAPL: {expirations.Expirations}")
expirations_at_strike = await market_data.get_option_expirations("MSFT", strike_price=300.0)
print(f"Expirations for MSFT at $300 strike: {expirations_at_strike.Expirations}")Fetches all valid spread types for complex option orders.
spread_types = await market_data.get_option_spread_types()
print("Available Option Spread Types:")
for spread_type in spread_types.SpreadTypes:
print(f"- {spread_type}")Get the available strike prices for option contracts on the specified underlying symbol.
# Get all strikes for AAPL
all_strikes = await market_data.get_option_strikes("AAPL")
print(f"First 10 strikes for AAPL: {all_strikes.Strikes[:10]}")
# Get strikes for a specific expiration
expiration_date = "2025-06-20" # Find a valid date first using get_option_expirations
strikes_for_expiry = await market_data.get_option_strikes("AAPL", expiration=expiration_date)
print(f"Strikes for AAPL expiring {expiration_date}: {strikes_for_expiry.Strikes}")Provides risk/reward analysis for one or more options legs.
# Define the analysis input (e.g., a single call option leg)
analysis_input = {
"Legs": [
{
"Symbol": "AAPL", # Replace with a specific option symbol if needed
"BuyOrSell": "BUY",
"Quantity": 1,
"ExpirationDate": "2025-12-19", # Use valid expiration
"StrikePrice": 200,
"OptionType": "CALL"
}
]
}
risk_reward = await market_data.get_option_risk_reward(analysis_input)
print("Risk/Reward Analysis:")
# Process risk_reward.Profiles, risk_reward.Greeks, etc.
if risk_reward.Profiles:
print(f"- Max Profit: {risk_reward.Profiles[0].MaxProfit}")
print(f"- Max Loss: {risk_reward.Profiles[0].MaxLoss}")
if risk_reward.Greeks:
print(f"- Delta: {risk_reward.Greeks[0].Delta}")
print(f"- Gamma: {risk_reward.Greeks[0].Gamma}")Fetches historical price bars for a specified symbol.
# Get last 5 daily bars for SPY
daily_params = {"interval": "1", "unit": "Daily", "barsback": 5}
daily_bars = await market_data.get_bar_history("SPY", daily_params)
print("SPY Daily Bars:")
for bar in daily_bars.Bars:
print(f" {bar.TimeStamp}: O={bar.Open} H={bar.High} L={bar.Low} C={bar.Close} V={bar.TotalVolume}")
# Get 1-minute bars for MSFT for a specific period (adjust dates/times)
# minute_params = {
# "interval": "1", "unit": "Minute",
# "firstdate": "2024-04-20T13:30:00Z", # UTC time
# "lastdate": "2024-04-20T13:35:00Z"
# }
# minute_bars = await market_data.get_bar_history("MSFT", minute_params)
# print("\nMSFT 1-Minute Bars:")
# for bar in minute_bars.Bars:
# print(f" {bar.TimeStamp}: Close={bar.Close}")These methods provide real-time data updates via Server-Sent Events (SSE). You receive an aiohttp.StreamReader object to process the incoming data.
General Streaming Example:
import asyncio
import json
import signal
# --- Signal Handling (for stopping gently) ---
running = True
def stop_running(sig, frame):
global running
print("\nSignal caught! Telling the stream to stop...")
running = False
signal.signal(signal.SIGINT, stop_running) # Catch Ctrl+C
signal.signal(signal.SIGTERM, stop_running)
# ---------------------------------------------
async def process_stream(stream_reader):
global running
print("Starting stream processing. Press Ctrl+C to stop.")
while running:
try:
# Wait for a new line from the stream (max 1 second)
line = await asyncio.wait_for(stream_reader.readline(), timeout=1.0)
if not line: # Stream ended
if running: print("Stream closed unexpectedly.")
break
# Decode and try to parse the line as JSON
line_str = line.strip().decode("utf-8")
if not line_str: continue # Skip empty lines
try:
data = json.loads(line_str)
# --- Process different message types ---
if "Symbol" in data and "Last" in data: # Likely a Quote
print(f"Quote {data.get('Symbol')}: Last={data.get('Last')}, Bid={data.get('Bid')}, Ask={data.get('Ask')}")
elif "Timestamp" in data and "Close" in data: # Likely a Bar
print(f"Bar {data.get('Symbol')} ({data.get('Interval')}{data.get('Unit')}): Time={data.get('Timestamp')}, Close={data.get('Close')}")
elif "Heartbeat" in data:
print(f"Heartbeat at {data.get('Timestamp')}")
elif "Error" in data:
print(f"Stream Error: {data.get('Message')}")
# Add more checks for Market Depth, Option Chain data etc.
else:
print(f"Unknown data: {data}") # Log other messages
except json.JSONDecodeError:
# print(f"Non-JSON line: {line_str}") # Optional: Log non-JSON
pass # Ignore non-JSON lines
except asyncio.TimeoutError:
continue # No data in the last second, check 'running' again
except Exception as e:
if running: print(f"Error during stream: {e}")
running = False # Stop on errors
async def main_stream():
client = TradeStationClient()
stream_reader = None
try:
# --- Replace with specific stream method call ---
# Example: stream_reader = await client.market_data.stream_quotes("AAPL,MSFT")
stream_reader = await client.market_data.stream_bars("SPY", {"interval": "1", "unit": "Minute"})
# -----------------------------------------------
if stream_reader:
await process_stream(stream_reader)
else:
print("Failed to get stream reader.")
except Exception as e:
print(f"Error setting up stream: {e}")
finally:
print("\nCleaning up stream resources...")
if client:
await client.close() # Closes client and associated stream
print("Stream stopped.")
# if __name__ == "__main__":
# load_dotenv()
# asyncio.run(main_stream())Streams Quote changes for one or more symbols (up to 100).
Streams Bar updates for a specified symbol.
Streams Market Depth quote updates (Level II) for a specified symbol.
Streams aggregated Market Depth updates for a specified symbol. Provides summed volume at price levels.
Streams real-time updates for an entire option chain based on the underlying symbol.
Streams Quote changes for specific option contracts defined by legs.
| Back | FazBrowse Home | New Git URL |