Ever received a WebSocket tick stream for US stocks and wondered why your indicators behave oddly outside regular hours? The raw data doesn’t tell you which session a trade belongs to, but identifying the session is crucial for signal quality. Here’s a clean, no-dependency-heavy way to do it in Python.
Quick Session Reference
| Session | US Eastern Time | Data Characteristics |
|---|---|---|
| Pre-market | 04:00-09:30 | Sparse trades, choppy moves |
| Regular hours | 09:30-16:00 | Dense liquidity, smooth price action |
| After-hours | 16:00-20:00 | Volatility often triggered by news |
Method 1: Timestamp Conversion
Almost every API sends a UTC timestamp. Convert it to US/Eastern and classify.
from datetime import datetime
import pytz
# US Eastern timezone
et = pytz.timezone('US/Eastern')
def get_session(ts):
t = datetime.fromtimestamp(ts, et)
# Check pre-market window
if t.hour < 9 or (t.hour == 9 and t.minute < 30):
return "pre"
# Regular session
if t.hour < 16:
return "regular"
# After-hours
return "after"
Method 2: Use a Session Status Field
If your provider sends a field like sessionType, you can skip the timezone math. Just make sure to test edge cases at session boundaries.
Live Integration Example
Using a WebSocket feed (like AllTick’s market data stream) that includes a timestamp, I label ticks on the fly.
import websocket
import json
from datetime import datetime
import pytz
# US Eastern timezone
et = pytz.timezone('US/Eastern')
def session(ts):
t = datetime.fromtimestamp(ts, et)
if t.hour < 9 or (t.hour == 9 and t.minute < 30):
return "pre"
elif t.hour < 16:
return "regular"
else:
return "after"
def on_message(ws, message):
data = json.loads(message)
s = session(data["timestamp"])
print(f"{data['symbol']} | {s} | {data['price']} | {data['volume']}")
# Open WebSocket connection
ws = websocket.WebSocketApp("wss://ws.alltick.co/stock", on_message=on_message)
ws.run_forever()
Efficiency takeaway: Doing session classification at ingestion keeps the rest of your pipeline clean. Each downstream module simply filters by session == "regular" and ignores the noise. It’s a tiny compute cost that prevents huge modeling headaches down the line. Hope this helps your next real-time project!

Top comments (0)