forked from itay1542/brokers-mcp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added ibkr support and trading view scanners
- Loading branch information
1 parent
6b094d8
commit eecf2f4
Showing
22 changed files
with
844 additions
and
102 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,81 +1,200 @@ | ||
# portfolio_service MCP server | ||
# Portfolio Service MCP Server | ||
|
||
A comprehensive Model Context Protocol (MCP) server that integrates popular brokerage APIs for portfolio management, market data access, and trading operations. | ||
|
||
## Features | ||
|
||
- **Multi-Broker Support**: Seamlessly integrate with multiple brokers | ||
- Interactive Brokers (IBKR) | ||
- TradeStation | ||
- **Comprehensive Market Data**: Access to real-time and historical market data | ||
- **Advanced Trading Capabilities**: Execute and manage trades programmatically | ||
- **News Integration**: Get real-time market news and full articles | ||
- **Options Trading Support**: Access options chains and manage options positions | ||
- **TradingView Integration**: Built-in market scanning capabilities | ||
|
||
## TradingView Integration | ||
|
||
### Market Scanning Tools | ||
|
||
1. **tradingview_scan_for_stocks** | ||
- Execute custom stock screening queries using TradingView's extensive database | ||
- Access to over 3000 technical and fundamental indicators | ||
- Flexible query building with SQL-like syntax | ||
- Example queries: | ||
```python | ||
# Basic stock screening | ||
Query().select('open', 'high', 'low', 'VWAP', 'MACD.macd', 'RSI') | ||
|
||
# Advanced filtering | ||
Query().select('close', 'volume', 'EMA5', 'EMA20').where( | ||
Column('close').between(Column('EMA5'), Column('EMA20')), | ||
Column('type').isin(['stock', 'fund']) | ||
) | ||
|
||
# Complex market scanning | ||
Query().select('name', 'close', 'volume').where( | ||
Column('market_cap_basic').between(1_000_000, 50_000_000), | ||
Column('relative_volume_10d_calc') > 1.2, | ||
Column('MACD.macd') >= Column('MACD.signal') | ||
).order_by('volume', ascending=False) | ||
``` | ||
|
||
2. **tradingview_scan_from_scanner** | ||
- Use pre-built market scanners | ||
- Available scanners: | ||
- premarket_gainers | ||
- premarket_losers | ||
- premarket_most_active | ||
- premarket_gappers | ||
- postmarket_gainers | ||
- postmarket_losers | ||
- postmarket_most_active | ||
|
||
## Interactive Brokers (IBKR) Integration | ||
|
||
> note: you need to have a running IBKR TWS instance to use these endpoints | ||
### Market Data Tools | ||
|
||
1. **ibkr_get_bars** | ||
- Get OHLCV (Open, High, Low, Close, Volume) data for stocks and indices | ||
- Supports multiple timeframes from 1 second to monthly bars | ||
- Configurable for regular trading hours or extended hours | ||
- Customizable date ranges and bar sizes | ||
```python | ||
# Example timeframes | ||
- Bar sizes: "1 min", "5 mins", "1 hour", "1 day", "1 week", "1 month" | ||
- Durations: "60 S", "30 D", "13 W", "6 M", "10 Y" | ||
``` | ||
|
||
### Order Management Tools | ||
|
||
1. **ibkr_place_new_order** | ||
- Place market or limit orders for stocks | ||
- Support for both buy and sell orders | ||
- Optional take profit and stop loss parameters | ||
- Bracket order capability | ||
|
||
2. **ibkr_modify_order** | ||
- Modify existing orders | ||
- Update order prices and other parameters | ||
- Real-time order status tracking | ||
|
||
### News Integration | ||
|
||
1. **ibkr_get_news_headlines** | ||
- Fetch recent news headlines for any symbol | ||
- Configurable time range | ||
- Multiple news providers support (Dow Jones, Reuters, etc.) | ||
|
||
2. **ibkr_get_news_article** | ||
- Retrieve full article content | ||
- Direct access to news sources | ||
- Historical news archive access | ||
|
||
### Options Trading Support | ||
|
||
1. **ibkr_get_option_expirations** | ||
- List all available expiration dates for options | ||
- Support for stock, index, and futures options | ||
|
||
2. **ibkr_read_option_chain** | ||
- Access complete option chains | ||
- View all strikes and expiration dates | ||
- Real-time options data | ||
|
||
### Account Resources | ||
|
||
Access key account information through these endpoints: | ||
|
||
1. **brokerage://ibkr/account_summary** | ||
- Complete account overview | ||
- Key metrics: Net Liquidation Value, Buying Power, etc. | ||
- Real-time account updates | ||
|
||
2. **brokerage://ibkr/portfolio** | ||
- Current positions and holdings | ||
- Real-time position updates | ||
- Detailed position information | ||
|
||
3. **brokerage://ibkr/orders** | ||
- All trades from current session | ||
- Comprehensive order history | ||
- Order status tracking | ||
|
||
4. **brokerage://ibkr/open_orders** | ||
- Active order monitoring | ||
- Real-time order status | ||
- Open order management | ||
|
||
A Model Context Protocol server implementing popular broker api's | ||
|
||
## Supported APIs | ||
|
||
- Currently only TradeStation API is supported *(partially)* | ||
|
||
## Components | ||
|
||
### Tools | ||
|
||
The server implements five tools that are based on TradeStation API: | ||
1. tradestation_get_bars - wraps the output of [TradeStation GetBars](https://api.tradestation.com/docs/specification#tag/MarketData/operation/GetBars) in a dataframe and returns it's `__str__` | ||
2. tradestation_place_buy_order - Same as [TradeStation PlaceOrder](https://api.tradestation.com/docs/specification#tag/Order-Execution/operation/PlaceOrder) but only for buy orders | ||
3. tradestation_place_sell_order - Same as [TradeStation PlaceOrder](https://api.tradestation.com/docs/specification#tag/Order-Execution/operation/PlaceOrder) but only for sell orders | ||
4. tradestation_get_positions - Same as [TradeStation GetPositions](https://api.tradestation.com/docs/specification/#tag/Brokerage/operation/GetPositions) | ||
5. tradestation_get_balances - Same as [TradeStation GetBalances](https://api.tradestation.com/docs/specification/#tag/Brokerage/operation/GetBalances) | ||
|
||
see the exact schemas in the definition file [here](./portfolio_service/brokers/tradestation/tools.py) | ||
## Configuration | ||
|
||
The server is configured via environment variables: | ||
Configure the server using environment variables: | ||
|
||
```bash | ||
```bash | ||
# TradeStation Configuration | ||
TRADESTATION_API_KEY="your_api_key" | ||
TRADESTATION_API_SECRET="your_api_secret" | ||
TS_REFRESH_TOKEN="your_refresh_token" | ||
TS_ACCOUNT_ID="your_account_id" | ||
|
||
# Interactive Brokers Configuration | ||
IBKR_ACCOUNT_ID="your_account_id" | ||
``` | ||
If you are unsure about how to get the values of the environment variables, | ||
I have a blog post that explains it [here](https://medium.com/@itay1542/how-to-get-free-historical-intraday-equity-prices-with-code-examples-8f36fc57e1aa) | ||
|
||
## Quickstart | ||
For detailed instructions on obtaining API credentials, visit our [setup guide](https://medium.com/@itay1542/how-to-get-free-historical-intraday-equity-prices-with-code-examples-8f36fc57e1aa). | ||
|
||
### Install | ||
## Installation | ||
|
||
#### Claude Desktop | ||
### Claude Desktop Integration | ||
|
||
On MacOS: `~/Library/Application\ Support/Claude/claude_desktop_config.json` | ||
#### MacOS | ||
Configure in: `~/Library/Application\ Support/Claude/claude_desktop_config.json` | ||
|
||
On Windows: `%APPDATA%/Claude/claude_desktop_config.json` | ||
#### Windows | ||
Configure in: `%APPDATA%/Claude/claude_desktop_config.json` | ||
|
||
``` | ||
"mcpServers": { | ||
"portfolio_service": { | ||
"command": "uv", | ||
"args": [ | ||
"--directory", | ||
"<path_to_project>/portfolio_service", | ||
"run", | ||
"portfolio_service" | ||
] | ||
```json | ||
{ | ||
"mcpServers": { | ||
"portfolio_service": { | ||
"command": "uv", | ||
"args": [ | ||
"--directory", | ||
"<path_to_project>/portfolio_service", | ||
"run", | ||
"portfolio_service" | ||
] | ||
} | ||
} | ||
} | ||
``` | ||
|
||
## Development | ||
|
||
### Building and Publishing | ||
|
||
### Dependencies Management | ||
|
||
1. Sync dependencies and update lockfile: | ||
```bash | ||
# Sync dependencies and update lockfile | ||
uv sync | ||
``` | ||
|
||
### Debugging | ||
|
||
Since MCP servers run over stdio, debugging can be challenging. For the best debugging | ||
experience, we strongly recommend using the [MCP Inspector](https://github.com/modelcontextprotocol/inspector). | ||
|
||
|
||
You can launch the MCP Inspector via [`npm`](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) with this command: | ||
For optimal debugging experience, use the [MCP Inspector](https://github.com/modelcontextprotocol/inspector): | ||
|
||
```bash | ||
# Launch MCP Inspector | ||
npx @modelcontextprotocol/inspector uv --directory <path_to_project>/portfolio_service run portfolio-service | ||
``` | ||
|
||
The Inspector provides a web interface for real-time debugging and monitoring of the MCP server. | ||
|
||
## Contributing | ||
|
||
Contributions are welcome! Please feel free to submit pull requests or create issues for bugs and feature requests. | ||
|
||
## License | ||
|
||
Upon launching, the Inspector will display a URL that you can access in your browser to begin debugging. | ||
This project is open-source and available under the MIT license. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,11 @@ | ||
import anyio | ||
import asyncio | ||
|
||
from . import server | ||
|
||
|
||
def main(): | ||
"""Main entry point for the package.""" | ||
anyio.run(server.main) | ||
asyncio.run(server.main()) | ||
|
||
# Optionally expose other important items at package level | ||
__all__ = ['main', 'server'] |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from .resources import resources | ||
from .tools import tools | ||
from .client import ib |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import os | ||
|
||
import pytz | ||
from ib_insync import IB | ||
|
||
ib = IB() | ||
ib.TimezoneTWS = pytz.timezone("US/Eastern") | ||
ib.connect('127.0.0.1', 7496, clientId=0, account=os.getenv("IBKR_ACCOUNT"), timeout=30) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
ibkr_tool_prefix = "ibkr" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import asyncio | ||
|
||
from ib_insync import Contract | ||
|
||
from .client import ib | ||
|
||
orders = {} | ||
|
||
class ContractCache(dict): | ||
def __init__(self, ib_client): | ||
super().__init__() | ||
self.contracts = {} | ||
self.ib_client = ib_client | ||
|
||
async def get(self, contract: Contract) -> Contract: | ||
if contract.conId in self.contracts: | ||
return self.contracts[contract.conId] | ||
else: | ||
self.contracts[contract.conId] = (await self.ib_client.qualifyContractsAsync(contract))[0] | ||
return self.contracts[contract.conId] | ||
|
||
cache = ContractCache(ib) | ||
|
||
async def qualify_contracts(*contracts: Contract) -> list[Contract]: | ||
return await asyncio.gather(*[cache.get(c) for c in contracts]) | ||
|
||
news_providers: list[str] = [] |
Oops, something went wrong.