Why Faster Code Does Not Fix Slow Triangular Arbitrage Data
Summary
The discussion evaluates whether rewriting a polling-based triangular arbitrage monitor in C++ could uncover profitable opportunities across three crypto markets. The example queries each market sequentially over HTTP, applies bid or ask prices and a fee assumption, and reports simulated balances below the starting amount. The accepted response argues that local computation speed is only one part of the latency problem: periodic polling can leave quotes stale before an opportunity is observed, and network distance and connection variability can put a trader behind competitors.
A more responsive design would consume exchange updates through a persistent socket and process quote changes as they arrive, if the venue supports that interface. Another reply suggests parallelizing the three requests, since network waits and response decoding may dominate the arithmetic. The thread offers no measured language benchmark or live execution evidence, and the displayed calculation uses quotes gathered at different times, so it does not establish whether an executable arbitrage exists. Fees, available depth, and execution risk also matter beyond the hypothetical balance calculation.
Key ideas
- A faster programming language cannot eliminate exchange, network, or polling delays.
- Sequential HTTP requests can produce a slow and time-inconsistent view of the three markets.
- Real-time quote streams and parallel requests can reduce data acquisition delays.
- Network latency and competitors’ proximity to the venue affect whether fleeting opportunities are actionable.
- A simulated price loop does not establish executable profitability without accounting for depth and execution.
Tags
Full text
# Would C++'s speed over Python make it a more applicable language for scalping arbitrage opportunities?
# Would C++'s speed over Python make it a more applicable language for scalping arbitrage opportunities?
I am using the Bittrex exchange API to ping markets to poll whether there are triangular arbitrage opportunities available for USD/BTC/LTC/USD. Note that I am not trading but rather synthesising them by using the API to collect bid and ask data for each of the 3 markets. My test polls also account for fees too. My current code base that uses the API is as follows
```
import requests as rq
import json
from CONSTANTS import API_PUBLIC, API_SECRET
import time
import hmac
import hashlib
def arbitrage():
nonce = time.time()
#Defines the API call that gets the price data
usd_btc_market = 'https://api.bittrex.com/api/v1.1/public/getticker?market=USD-BTC&apikey={0}&nonce={1}'.format(API_PUBLIC, nonce)
btc_ltc_market = 'https://api.bittrex.com/api/v1.1/public/getticker?market=BTC-LTC&apikey={0}&nonce={1}'.format(API_PUBLIC, nonce)
usd_ltc_market = 'https://api.bittrex.com/api/v1.1/public/getticker?market=USD-LTC&apikey={0}&nonce={1}'.format(API_PUBLIC, nonce)
#Ensures connections are secured through hashing
usd_btc_signature = hmac.new(API_SECRET.encode(), usd_btc_market.encode(), hashlib.sha512).hexdigest()
btc_ltc_signature = hmac.new(API_SECRET.encode(), btc_ltc_market.encode(), hashlib.sha512).hexdigest()
usd_ltc_signature = hmac.new(API_SECRET.encode(), usd_ltc_market.encode(), hashlib.sha512).hexdigest()
#Conducts the hypothetical trades using the API bid/ask prices from each market.
#Assumes a starting capital value of $1
btc_balance = (1 / json.loads(rq.get(usd_btc_market, headers = {'apisign': usd_btc_signature}).content.decode('utf-8'))['result']['Ask']) * 0.998
ltc_balance = (btc_balance / json.loads(rq.get(btc_ltc_market, headers = {'apisign': btc_ltc_signature}).content.decode('utf-8'))['result']['Ask']) * 0.998
usd_balance = (ltc_balance * json.loads(rq.get(usd_ltc_market, headers = {'apisign': usd_ltc_signature}).content.decode('utf-8'))['result']['Bid'])* 0.998
print(usd_balance)
while True:
arbitrage()
time.sleep(3) #Limited to 60 API calls per minute, ensures not too many calls are made
```
The hypothetical trade results appear nearly profitable. Note that if we started with $1, then the final balance at the end of the arbitrage loop are as follows (code ran every 3 seconds):
```
#Time span of over a 5 minute period
#Each arbitrage loop takes on average 0.48 seconds to run
0.9915490241394859
0.9915511459969782
0.9915511459969782
...
0.9901270999326443
0.9901250816417339
0.9901269101525229
```
I am using Python to run this bot, however I am wondering if the 'so close yet so far' conundrum could be rectified by switching to a faster language such as c++? According to this post, c++ is atleast 10 times faster than python. My thinking is, could this language, with its faster runtime, overcome the minutely small time increments between each API market call? Could this be the reason why such opportunities aren't being found, that Python is simply to slow to take advantage of fleeting arbitrage opportunities? Or, is it just the case that the Cryptocurrency market is more efficient than I thought and arbitrage opportunities don't persist. Looking forward to hearing back what you think.
## Answer by chrisaycock (score 1, accepted)
https://quant.stackexchange.com/a/54522
To expand on what others have said, C++ is only faster on your machine; it's not going to help your counterparty.
Polling over HTTP is the slowest imaginable way to get data, but if that's all Bittrex provides, then perhaps an alternative venue is needed. You are literally waiting three seconds to sample the data; by that point, the market has likely moved to a more efficient price.
Ideally you'd have an open socket with a callback mechanism. The venue should alert you in realtime whenever a new quote appears. Then, at least, the performance of your machine becomes a factor because you'll have to consume the data fast enough to keep up.
Beyond that, there is another issue: the speed of light. I assume you are not colocated with the venue. And in fact, if you're running over the Internet, then your latency is completely at the whim of your connection. If it takes you 40 ms to get the data and your competitors only 20 ms, then no amount of code will make-up for that. It is extremely difficult to comparatively measure this, and almost impossible to control.
## Answer by C8H10N4O2 (score 3)
https://quant.stackexchange.com/a/53996
It’s likely the gets and decoding are where the time is spent. If you want to speed this up, run the three gets in parallel instead of in serial, then make that calculation.
C or C++ can be faster, but here it’s more about the code than the language.Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.