akapur / pyiqfeed

Python LIbrary for reading DTN's IQFeed
GNU General Public License v2.0
172 stars 109 forks source link

Extracting and Parsing Data From a Numpy Array #70

Open futuristly opened 5 months ago

futuristly commented 5 months ago

I am seeking assistance with a problem I'm facing while working with the IQFeed API and the pyiqfeed library in Python. I'm trying to extract the ask and bid prices from the real-time market data provided by the API, but I'm encountering difficulties in accessing the nested data correctly. The data returned by the IQFeed API is in the form of numpy arrays or structured arrays, and it appears to be nested. I've been trying to modify the on_update method of a custom quote listener class to properly access and extract the ask and bid prices, but I haven't been successful so far. Here's a snippet of the code I'm working with:

import pyiqfeed as iq
import signal
import sys

class BidAskListener(iq.VerboseQuoteListener):
    def __init__(self, name, jupiter_instrument_codes):
        super().__init__(name)
        self.jupiter_instrument_codes = jupiter_instrument_codes

    def on_update(self, data: dict):
        if isinstance(data, iq.TimeStampMsg):
            print(f"Bid Ask Listener: Timestamp: {data.date} {data.time}")
        else:
            for quote in data:
                ticker = quote['Symbol'].decode()
                bid = quote.get('Bid')
                ask = quote.get('Ask')
                if bid is not None and ask is not None:
                    print(f"{bid}|{ask}")

def get_bid_and_ask(ticker: str):
    quote_conn = iq.QuoteConn(name="pyiqfeed-Example-lvl1")
    jupiter_instrument_codes = ["MNQ"]  
    quote_listener = BidAskListener("Bid Ask Listener", jupiter_instrument_codes)
    quote_conn.add_listener(quote_listener)
    with iq.ConnConnector([quote_conn]) as connector:
        all_fields = ["Bid", "Ask"]
        quote_conn.select_update_fieldnames(all_fields)
        quote_conn.watch(ticker)

        signal.signal(signal.SIGINT, signal_handler)
        try:
            while True:
                pass
        except KeyboardInterrupt:
            print("\nProgram interrupted. Stopping...")
            quote_conn.unwatch(ticker)
            quote_conn.remove_listener(quote_listener)
            sys.exit(0)

def signal_handler(sig, frame):
    print("\nReceived SIGINT signal. Stopping...")
    sys.exit(0)

if __name__ == "__main__":

    ticker = "@MNQ#"

    get_bid_and_ask(ticker)

In the on_update method, I'm iterating over the data dictionary and trying to access the ticker symbol, bid price, and ask price using quote['Symbol'], quote.get('Bid'), and quote.get('Ask'), respectively. However, I'm not getting the desired output, which should be in the format ask|bid. Instead, I'm getting output like this:

Bid Ask Listener: Data Update
[(b'@MNQ#', 17720.75, 17721.5)]
Bid Ask Listener: Data Update
[(b'@MNQ#', 17721., 17721.5)]