Skip to content
Course contents
Talking to the broker

The live tick feed

A live strategy reacts to prices as they arrive, which means a streaming connection that pushes ticks rather than a request you repeat. This chapter explains subscribing to a data stream, handling the messages as they come, and the reality that streams drop and must be reconnected. The tested example replays a recorded tick stream through the simulated broker.

9 min readChapter 8 of 28
What you will learn
  • Explain a streaming (WebSocket) subscription and how it differs from polling
  • Handle incoming ticks in a callback loop
  • Reason about dropped connections and the need to reconnect

In the last chapter, getting a price meant asking for one. That works for a glance, but a live strategy watching the market cannot ask "what is the price" fifty times a second for fifty stocks. It needs the prices to come to it. That is what a streaming feed does: you subscribe once, and the broker pushes each new price to your program the instant it changes. A single tick, in this world, is one such update: a new price for one instrument at one moment.

Push, not pull

A live strategy uses a streaming connection that pushes ticks as they arrive, rather than polling the same request over and over.
A live strategy uses a streaming connection that pushes ticks as they arrive, rather than polling the same request over and over.

The difference from the last chapter is the direction. Reading a quote is pull: your program pulls an answer when it asks. A stream is push: after you subscribe, the broker pushes updates to you, and your program reacts to each as it lands. The connection stays open, often as a WebSocket, which is a kind of long-lived two-way link, so the prices flow without a fresh request each time. This is lighter on everyone and far faster than polling, and it is how any program that reacts to live prices is fed.

python
# A broker's live stream, shown generically and NOT run. You subscribe once and
# the broker calls your function on every tick.
def on_tick(tick):
    print(tick["symbol"], tick["last_price"])

ws = client.stream(on_tick=on_tick)
ws.subscribe(["NSE:RELIANCE", "NSE:INFY"])
ws.connect()          # stays open, pushing ticks to on_tick until you stop it

Reacting to the stream

The heart of stream handling is a callback: a function you hand to the broker's library, which it calls for you every time a tick arrives. Your job is to write what happens on each tick. Here is that pattern against the simulated broker, with a recorded list of ticks standing in for a live feed. A resting limit order waits, and the incoming ticks fill it when the price arrives.

ExampleHandling a stream of ticks in a callback, and filling a resting orderch08/replay_stream.py
# A live feed pushes prices to you, one tick at a time, and your code reacts in a
# callback. Here a recorded list of ticks stands in for a broker's live stream.
# We rest a limit order, then let the stream fill it when the price arrives.
from paper_broker import PaperBroker

broker = PaperBroker(cash=1_000_000, prices={"RELIANCE": 1400})

# We want in only if the price dips to 1395.
order = broker.place_order("RELIANCE", "BUY", 100, "LIMIT", price=1395)
print(f"Resting limit order {order.order_id}: {order.status} at {order.price}")

# A recorded stream of ticks, standing in for a live WebSocket feed.
ticks = [1401, 1399, 1400, 1396, 1394, 1398, 1402]


def on_tick(symbol, price):
    fills = broker.feed_price(symbol, price)     # move the market, fill resting orders
    note = ""
    for o in fills:
        note = f"   filled order {o.order_id}: {o.filled_quantity} @ {o.average_price}"
    print(f"tick {symbol} {price}{note}")


# The streaming loop. In real life the broker calls on_tick for you; here we
# replay the recorded ticks to imitate that.
for price in ticks:
    on_tick("RELIANCE", price)

print("Final position:", broker.get_positions())
Output
Resting limit order 1: OPEN at 1395
tick RELIANCE 1401
tick RELIANCE 1399
tick RELIANCE 1400
tick RELIANCE 1396
tick RELIANCE 1394   filled order 1: 100 @ 1395.0
tick RELIANCE 1398
tick RELIANCE 1402
Final position: [{'symbol': 'RELIANCE', 'quantity': 100, 'avg_price': 1395.0}]

Follow the flow. The order rests, wanting to buy only at 1,395. The ticks arrive one by one, and on_tick reacts to each. The prices at 1,401, 1,399, 1,400 and 1,396 pass without a fill, because none has reached the limit. When the tick at 1,394 arrives, the price has crossed the level, and the resting order fills, 100 shares. This is the shape of every live strategy: prices push in, a function reacts, and sometimes that reaction is a fill. The strategy you build later lives inside a callback just like this one.

Streams break, and your code must expect it

A stream is a live connection over the internet, and live connections drop. Your phone loses signal, a server restarts, a network hiccups. A stream that has silently died is dangerous, because your program thinks it is watching the market while the prices have frozen, and it may hold or place positions on stale information. So a real streaming system does two things. It notices when the stream has gone quiet or disconnected, and it reconnects and resubscribes automatically, ideally rechecking the account on return in case something changed while it was blind. You will meet this again in the reliability chapter. For now, hold the point that a live feed is never guaranteed, and code that trades on it must assume it can break.

What to carry forward

A live strategy is fed by a stream, not by repeated questions: you subscribe once and the broker pushes each tick to a callback function you write, which reacts as prices land. You saw that pattern fill a resting order the moment the price reached it, which is exactly how a live strategy will behave. And you saw the catch: streams drop, and a program trading on a frozen feed is trading blind, so real systems detect and recover from a lost connection. You can now read the account and take in a live feed. The next chapter completes the toolkit by doing the one thing that actually moves money: placing and managing an order from code.