Closed GonzRon closed 3 weeks ago
Hi @GonzRon many thanks for sharing your idea and your code 👏
Just to start:
Hi @GonzRon many thanks for sharing your idea and your code 👏
Just to start:
- You mention you've tried looking through the WebAPI docs. By that I assume you looked through the WebAPI V1.0 (CP Web API) and not the new Web API.
Incorrect assumption, although that would have been the smart thing to do. I looked through the new webApi docs. Though the API 1.0 docs also do not feature this capability. So it's a nill point anyways.
Seeing that you didn't find it there, did you try contacting IBKR to find out if they provide an API to query this? If not, it could be a good idea to check with them first.
I did not, and I probably don't plan on doing so any time soon. After all, this is not that important to me if we're being honest, and I am busy with more important tasks ATM. However, I did not want to hold the functionality back on the off-chance that it was of interest to the project.
- Could I ask you to reformat the code you've shared? The indentation seems to be all off.
Yes, absolutely, of course, here's a more complete solution:
import requests
from bs4 import BeautifulSoup
import pandas as pd
URL = "https://www.interactivebrokers.com/en/trading/margin-futures-fops.php"
def extract_futures_margin_tables(URL=URL):
response = requests.get(URL)
response.raise_for_status() # Check if the request was successful
soup = BeautifulSoup(response.text, 'html.parser')
# Dictionary to store all tables
margin_tables = {}
# Find all table sections with headings
table_sections = soup.find_all('div', {'class': 'table-responsive'})
for section in table_sections:
# Try to find the closest heading above the table
header = None
current = section
while current and not header:
# Look for h5 (exchange names are in h5 tags)
header_elem = current.find_previous_sibling('h5')
if header_elem:
header = header_elem.text.strip()
break
current = current.parent
if not header:
continue
# Find the table in this section
table = section.find('table')
if not table:
continue
# Extract table headers
headers = []
for th in table.find_all('th'):
headers.append(th.text.strip())
# Extract table rows
rows = []
for tr in table.find_all('tr')[1:]: # Skip header row
row = []
for td in tr.find_all('td'):
row.append(td.text.strip())
if row: # Only add non-empty rows
rows.append(row)
# Convert to DataFrame for easier handling
df = pd.DataFrame(rows, columns=headers)
# Store in dictionary
margin_tables[header] = df
return margin_tables
# Function to display table info
def print_table_summary(tables_dict):
print(f"Found {len(tables_dict)} tables:")
for exchange, df in tables_dict.items():
print(f"\n{exchange}")
print(f"Dimensions: {df.shape}")
print("Columns:", list(df.columns))
print("First few rows:")
print(df.head(2))
print("-" * 80)
if __name__ == "__main__":
tables = extract_futures_margin_tables(URL)
print_table_summary(tables)
Since I wrote my comment, I ran into other limitations with the Client Portal (web) API - totally understand not wanting to add screen scraping code as a backend, feel free to close this ticket.
Hey @GonzRon I think I understand what you were trying to do here. Thanks for expanding on your answers. And I'm sorry to see that you found some other limitations that prohibited you from going forward. Would you be able to share what these are?
Specifically the inability to retrieve historical data for continuous futures symbols.
Thanks for sharing and I'm sorry to hear that. Best of luck! Feel free to close this issue when ready
Thanks for sharing and I'm sorry to hear that. Best of luck! Feel free to close this issue when ready
hey @GonzRon not sure how to interpret that screenshot - is that a good thing or a bad thing?
I dont know @Voyz you tell me?
Describe the feature If you trade futures, you know the margin required may often change. It’s particularly true for IB: being a rather conservative broker, they apply an extra margin required on any contract on top of what is typically dictated by the exchange. Keeping up to date with their latest margins required is a bit of a pain. You’d need to look on their webpage and scroll between dozens and dozens of contracts, at least weekly if you run multiple algos.
https://www.interactivebrokers.com/en/trading/margin-futures-fops.php
I did take a look at the official WebApi Documentation, specifically: WebApi Querying Equity and Margin. However, this seems to be related to the account's usage of margin, rather than the margin requirements for a symbol in particular. Perhaps the webApi supports this already on instruments, i.e. you can get a ‘live quote’ on the required margin for a given product, however I did not find that capability in their API Docs, so I am not aware of this in webApi, and did not bother looking at TWSAPI documentation.
If the IB webApi does not currently support this, this sample code below can potentially serve as the backend for a new IBeam API call. It could be configured to scrape the site periodically, and maintain a local cache with this information that can be easily queried. Or perhaps, the data could simply be added as a new field to the existing symbol lookup data return object? (i.e. the margin required for the symbol).
Here’s the script:
Thanks to a fellow trader Davide for the write up and the code!