Python - Poloniex Push API

Viewed 2243

I am trying to get live data in Python 2.7.13 from Poloniex through the push API. I read many posts (including How to connect to poloniex.com websocket api using a python library) and I arrived to the following code:

from autobahn.twisted.wamp import ApplicationSession
from autobahn.twisted.wamp import ApplicationRunner
from twisted.internet.defer import inlineCallbacks
import six


class PoloniexComponent(ApplicationSession):
    def onConnect(self):
        self.join(self.config.realm)

    @inlineCallbacks
    def onJoin(self, details):
        def onTicker(*args):
            print("Ticker event received:", args)

        try:
            yield self.subscribe(onTicker, 'ticker')
        except Exception as e:
            print("Could not subscribe to topic:", e)


def main():
    runner = ApplicationRunner(six.u("wss://api.poloniex.com"), six.u("realm1"))
    runner.run(PoloniexComponent)


if __name__ == "__main__":
    main()

Now, when I run the code, it looks like it's running successfully, but I don't know where I am getting the data. I have two questions:

  1. I would really appreciate if someone could walk me through the process of subscribing and getting ticker data, that I will elaborate in python, from step 0: I am running the program on Spyder on Windows. Am I supposed to activate somehow Crossbar?

  2. How do I quit the connection? I simply killed the process with Ctrl+c and now when I try to run it agan, I get the error: ReactorNonRestartable.

2 Answers

I ran into a lot of issues using Poloniex with Python2.7 but finally came to a solution that hopefully helps you.

I found that Poloniex has pulled support for the original WAMP socket endpoint so I would probably stray from this method altogether. Maybe this is the entirety of the answer you need but if not here is an alternate way to get ticker information.

The code that ended up working best for me is actually from the post you linked to above but there was some info regarding currency pair ids I found elsewhere.

import websocket
import thread
import time
import json

def on_message(ws, message):
    print(message)

def on_error(ws, error):
    print(error)

def on_close(ws):
    print("### closed ###")

def on_open(ws):
    print("ONOPEN")
    def run(*args):
        # ws.send(json.dumps({'command':'subscribe','channel':1001}))
        ws.send(json.dumps({'command':'subscribe','channel':1002}))
        # ws.send(json.dumps({'command':'subscribe','channel':1003}))
        # ws.send(json.dumps({'command':'subscribe','channel':'BTC_XMR'}))
        while True:
            time.sleep(1)
        ws.close()
        print("thread terminating...")
    thread.start_new_thread(run, ())


if __name__ == "__main__":
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp("wss://api2.poloniex.com/",
                              on_message = on_message,
                              on_error = on_error,
                              on_close = on_close)
    ws.on_open = on_open
    ws.run_forever()

I commented out the lines that pull data you don't seem to want, but for reference here is some more info from that previous post:

1001 = trollbox (you will get nothing but a heartbeat)
1002 = ticker
1003 = base coin 24h volume stats
1010 = heartbeat
'MARKET_PAIR' = market order books

Now you should get some data that looks something like this:

[121,"2759.99999999","2759.99999999","2758.000000‌​00","0.02184376","12‌​268375.01419869","44‌​95.18724321",0,"2767‌​.80020000","2680.100‌​00000"]]

This is also annoying because the "121" at the beginning is the currency pair id, and this is undocumented and also unanswered in the other stack overflow question referred to here.

However, if you visit this url: https://poloniex.com/public?command=returnTicker it seems the id is shown as the first field, so you could create your own mapping of id->currency pair or parse the data by the ids you want from this.

Alternatively, something as simple as:

import urllib
import urllib2
import json

ret = urllib2.urlopen(urllib2.Request('https://poloniex.com/public?command=returnTicker'))
print json.loads(ret.read())

will return to you the data that you want, but you'll have to put it in a loop to get constantly updating information. Not sure of your needs once the data is received so I will leave the rest up to you.

Hope this helps!

Related