ftgo


Nameftgo JSON
Version 1.0.0 PyPI version JSON
download
home_pagehttps://github.com/gohibiki/ftgo
SummaryA Python library for fetching financial data from FT Markets
upload_time2025-09-09 01:53:16
maintainerNone
docs_urlNone
authorgohibiki
requires_python>=3.7
licenseNone
keywords finance stocks etf historical-data financial-analysis market-data ft-markets financial-times
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # FTMarkets

[![PyPI version](https://badge.fury.io/py/ftgo.svg)](https://badge.fury.io/py/ftgo)
[![Python 3.7+](https://img.shields.io/badge/python-3.7+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

A Python library for fetching financial data from Financial Times Markets, including historical stock prices, ETF holdings, fund profiles, and allocation breakdowns.

## Features

- **Historical Data**: Fetch historical OHLCV data for stocks and ETFs
- **Holdings Data**: Get ETF/fund holdings, asset allocation, and sector breakdowns
- **Fund Profiles**: Access fund information, statistics, and investment details
- **Symbol Search**: Find FT Markets XIDs by ticker symbols
- **Concurrent Processing**: Fast data retrieval using multithreading
- **Pandas Integration**: Returns data as pandas DataFrames for easy analysis

## Installation

```bash
pip install ftgo
```

## Quick Start

```python
from ftgo import search_securities, get_xid, get_historical_prices, get_holdings

# Search for a security
results = search_securities('AAPL')
print(results)

# Get XID for a ticker
xid = get_xid('AAPL')

# Fetch historical data
df = get_historical_prices(xid, "01012024", "31012024")
print(df.head())

# Get ETF holdings
spy_xid = get_xid('SPY')
holdings = get_holdings(spy_xid, "top_holdings")
print(holdings)
```

## API Reference

### Search Functions

#### `search_securities(query)`

Search for securities on FT Markets.

**Parameters:**
- `query` (str): Search term for securities (ticker symbol or company name)

**Returns:** pandas.DataFrame with search results containing xid, name, symbol, asset_class, url

```python
# Search for Apple
results = search_securities('Apple')
print(results)

# Search by ticker
results = search_securities('AAPL')
```

#### `get_xid(ticker, display_mode="first")`

Get FT Markets XID for given ticker symbol.

**Parameters:**
- `ticker` (str): Ticker symbol
- `display_mode` (str): "first" to return first match XID, "all" to return all matches

**Returns:** String XID (if display_mode="first") or DataFrame (if display_mode="all")

```python
# Get XID for Apple
xid = get_xid('AAPL')
print(xid)  # Returns XID string

# Get all matches
all_results = get_xid('AAPL', display_mode='all')
print(all_results)
```

### Historical Data

#### `get_historical_prices(xid, date_from, date_to)`

Get historical price data for a security with full OHLCV data.

**Parameters:**
- `xid` (str): The FT Markets XID
- `date_from` (str): Start date in DDMMYYYY format (e.g., "01012024")
- `date_to` (str): End date in DDMMYYYY format (e.g., "31122024")

**Returns:** pandas.DataFrame with columns: date, open, high, low, close, volume

```python
xid = get_xid('AAPL')
df = get_historical_prices(xid, "01012024", "31012024")
print(df.head())
```

#### `get_multiple_historical_prices(xids, date_from, date_to)`

Get historical data for multiple securities concurrently.

**Parameters:**
- `xids` (list): List of FT Markets XIDs
- `date_from` (str): Start date in DDMMYYYY format
- `date_to` (str): End date in DDMMYYYY format

**Returns:** pandas.DataFrame with concatenated data for all securities

```python
xids = [get_xid('AAPL'), get_xid('MSFT')]
df = get_multiple_historical_prices(xids, "01012024", "31012024")
```

### Holdings Data

#### `get_holdings(xid, holdings_type="all")`

Get holdings and allocation data for ETFs and funds.

**Parameters:**
- `xid` (str): The FT Markets XID
- `holdings_type` (str): Type of holdings data:
  - `"asset_allocation"`: Asset class breakdown (stocks, bonds, cash)
  - `"sector_weights"`: Sector allocation
  - `"geographic_allocation"`: Geographic allocation
  - `"top_holdings"`: Top holdings by weight
  - `"all"`: All holdings data types as a tuple

**Returns:** pandas.DataFrame or tuple of DataFrames

```python
# Get top holdings for SPY ETF
spy_xid = get_xid('SPY')
top_holdings = get_holdings(spy_xid, "top_holdings")

# Get asset allocation
allocation = get_holdings(spy_xid, "asset_allocation")

# Get all holdings data
all_data = get_holdings(spy_xid, "all")
asset_alloc, sectors, regions, holdings = all_data
```

#### `get_fund_breakdown(xid)`

Get complete fund breakdown with all allocation data.

**Parameters:**
- `xid` (str): The FT Markets XID

**Returns:** Dictionary with all DataFrames

```python
qqq_xid = get_xid('QQQ')
breakdown = get_fund_breakdown(qqq_xid)
print(breakdown['asset_allocation'])
print(breakdown['top_holdings'])
```

### Fund Profile Data

#### `get_fund_profile(xid)`

Get profile and investment information for ETFs and funds.

**Parameters:**
- `xid` (str): The FT Markets XID

**Returns:** pandas.DataFrame with Field and Value columns

```python
xid = get_xid('SPY')
profile = get_fund_profile(xid)
print(profile)

# Filter for specific information
fees = profile[profile['Field'].str.contains('fee', case=False)]
```

#### `get_fund_stats(xid)`

Get fund profile data as a dictionary for easy access.

**Parameters:**
- `xid` (str): The FT Markets XID

**Returns:** Dictionary with all available fund fields and values

```python
xid = get_xid('QQQ')
stats = get_fund_stats(xid)

# Access any available field safely
inception = stats.get('Inception date', 'Not available')
fees = stats.get('Ongoing charge', 'Not available')
```

#### `get_available_fields(xid)`

Get list of all available profile fields for a fund.

**Parameters:**
- `xid` (str): The FT Markets XID

**Returns:** List of all field names available

```python
xid = get_xid('SPY')
fields = get_available_fields(xid)
print("Available fields:")
for field in fields:
    print(f"  - {field}")
```

#### `search_profile_field(xid, search_term)`

Search for specific fields in the fund profile data.

**Parameters:**
- `xid` (str): The FT Markets XID
- `search_term` (str): Term to search for in field names (case-insensitive)

**Returns:** pandas.DataFrame with matching fields and values

```python
xid = get_xid('SPY')
fees = search_profile_field(xid, 'fee')
inception = search_profile_field(xid, 'inception')
```

## Complete Example

```python
from ftgo import get_xid, get_historical_prices, get_holdings, get_fund_profile
import matplotlib.pyplot as plt

# Search for QQQ ETF
qqq_xid = get_xid('QQQ')

# Get 1 year of historical data
historical_data = get_historical_prices(qqq_xid, "01012023", "31122023")

# Get fund information
profile = get_fund_profile(qqq_xid)
top_holdings = get_holdings(qqq_xid, "top_holdings")
asset_allocation = get_holdings(qqq_xid, "asset_allocation")

# Plot price chart
historical_data.set_index('date')['close'].plot(title='QQQ Price History')
plt.show()

# Display fund information
print("Fund Profile:")
print(profile.head(10))

print("\nTop 10 Holdings:")
print(top_holdings.head(10))

print("\nAsset Allocation:")
print(asset_allocation)
```

## Error Handling

The library includes logging and error handling, but you should wrap calls in try-except blocks for production use:

```python
try:
    xid = get_xid('INVALID_TICKER')
    data = get_historical_prices(xid, "01012024", "31012024")
except ValueError as e:
    print(f"Error: {e}")
except Exception as e:
    print(f"Unexpected error: {e}")
```

## Requirements

- Python 3.7+
- cloudscraper >= 1.2.68
- pandas >= 1.3.0
- beautifulsoup4 >= 4.11.0

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Disclaimer

This library is for educational and research purposes.

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/gohibiki/ftgo",
    "name": "ftgo",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "gohibiki <gohibiki@protonmail.com>",
    "keywords": "finance, stocks, etf, historical-data, financial-analysis, market-data, ft-markets, financial-times",
    "author": "gohibiki",
    "author_email": "gohibiki <gohibiki@protonmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/98/d8/06ab954883963cd3c922f699d9ee4f43bf1766344d93a42bb21b0724d245/ftgo-1.0.0.tar.gz",
    "platform": null,
    "description": "# FTMarkets\n\n[![PyPI version](https://badge.fury.io/py/ftgo.svg)](https://badge.fury.io/py/ftgo)\n[![Python 3.7+](https://img.shields.io/badge/python-3.7+-blue.svg)](https://www.python.org/downloads/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nA Python library for fetching financial data from Financial Times Markets, including historical stock prices, ETF holdings, fund profiles, and allocation breakdowns.\n\n## Features\n\n- **Historical Data**: Fetch historical OHLCV data for stocks and ETFs\n- **Holdings Data**: Get ETF/fund holdings, asset allocation, and sector breakdowns\n- **Fund Profiles**: Access fund information, statistics, and investment details\n- **Symbol Search**: Find FT Markets XIDs by ticker symbols\n- **Concurrent Processing**: Fast data retrieval using multithreading\n- **Pandas Integration**: Returns data as pandas DataFrames for easy analysis\n\n## Installation\n\n```bash\npip install ftgo\n```\n\n## Quick Start\n\n```python\nfrom ftgo import search_securities, get_xid, get_historical_prices, get_holdings\n\n# Search for a security\nresults = search_securities('AAPL')\nprint(results)\n\n# Get XID for a ticker\nxid = get_xid('AAPL')\n\n# Fetch historical data\ndf = get_historical_prices(xid, \"01012024\", \"31012024\")\nprint(df.head())\n\n# Get ETF holdings\nspy_xid = get_xid('SPY')\nholdings = get_holdings(spy_xid, \"top_holdings\")\nprint(holdings)\n```\n\n## API Reference\n\n### Search Functions\n\n#### `search_securities(query)`\n\nSearch for securities on FT Markets.\n\n**Parameters:**\n- `query` (str): Search term for securities (ticker symbol or company name)\n\n**Returns:** pandas.DataFrame with search results containing xid, name, symbol, asset_class, url\n\n```python\n# Search for Apple\nresults = search_securities('Apple')\nprint(results)\n\n# Search by ticker\nresults = search_securities('AAPL')\n```\n\n#### `get_xid(ticker, display_mode=\"first\")`\n\nGet FT Markets XID for given ticker symbol.\n\n**Parameters:**\n- `ticker` (str): Ticker symbol\n- `display_mode` (str): \"first\" to return first match XID, \"all\" to return all matches\n\n**Returns:** String XID (if display_mode=\"first\") or DataFrame (if display_mode=\"all\")\n\n```python\n# Get XID for Apple\nxid = get_xid('AAPL')\nprint(xid)  # Returns XID string\n\n# Get all matches\nall_results = get_xid('AAPL', display_mode='all')\nprint(all_results)\n```\n\n### Historical Data\n\n#### `get_historical_prices(xid, date_from, date_to)`\n\nGet historical price data for a security with full OHLCV data.\n\n**Parameters:**\n- `xid` (str): The FT Markets XID\n- `date_from` (str): Start date in DDMMYYYY format (e.g., \"01012024\")\n- `date_to` (str): End date in DDMMYYYY format (e.g., \"31122024\")\n\n**Returns:** pandas.DataFrame with columns: date, open, high, low, close, volume\n\n```python\nxid = get_xid('AAPL')\ndf = get_historical_prices(xid, \"01012024\", \"31012024\")\nprint(df.head())\n```\n\n#### `get_multiple_historical_prices(xids, date_from, date_to)`\n\nGet historical data for multiple securities concurrently.\n\n**Parameters:**\n- `xids` (list): List of FT Markets XIDs\n- `date_from` (str): Start date in DDMMYYYY format\n- `date_to` (str): End date in DDMMYYYY format\n\n**Returns:** pandas.DataFrame with concatenated data for all securities\n\n```python\nxids = [get_xid('AAPL'), get_xid('MSFT')]\ndf = get_multiple_historical_prices(xids, \"01012024\", \"31012024\")\n```\n\n### Holdings Data\n\n#### `get_holdings(xid, holdings_type=\"all\")`\n\nGet holdings and allocation data for ETFs and funds.\n\n**Parameters:**\n- `xid` (str): The FT Markets XID\n- `holdings_type` (str): Type of holdings data:\n  - `\"asset_allocation\"`: Asset class breakdown (stocks, bonds, cash)\n  - `\"sector_weights\"`: Sector allocation\n  - `\"geographic_allocation\"`: Geographic allocation\n  - `\"top_holdings\"`: Top holdings by weight\n  - `\"all\"`: All holdings data types as a tuple\n\n**Returns:** pandas.DataFrame or tuple of DataFrames\n\n```python\n# Get top holdings for SPY ETF\nspy_xid = get_xid('SPY')\ntop_holdings = get_holdings(spy_xid, \"top_holdings\")\n\n# Get asset allocation\nallocation = get_holdings(spy_xid, \"asset_allocation\")\n\n# Get all holdings data\nall_data = get_holdings(spy_xid, \"all\")\nasset_alloc, sectors, regions, holdings = all_data\n```\n\n#### `get_fund_breakdown(xid)`\n\nGet complete fund breakdown with all allocation data.\n\n**Parameters:**\n- `xid` (str): The FT Markets XID\n\n**Returns:** Dictionary with all DataFrames\n\n```python\nqqq_xid = get_xid('QQQ')\nbreakdown = get_fund_breakdown(qqq_xid)\nprint(breakdown['asset_allocation'])\nprint(breakdown['top_holdings'])\n```\n\n### Fund Profile Data\n\n#### `get_fund_profile(xid)`\n\nGet profile and investment information for ETFs and funds.\n\n**Parameters:**\n- `xid` (str): The FT Markets XID\n\n**Returns:** pandas.DataFrame with Field and Value columns\n\n```python\nxid = get_xid('SPY')\nprofile = get_fund_profile(xid)\nprint(profile)\n\n# Filter for specific information\nfees = profile[profile['Field'].str.contains('fee', case=False)]\n```\n\n#### `get_fund_stats(xid)`\n\nGet fund profile data as a dictionary for easy access.\n\n**Parameters:**\n- `xid` (str): The FT Markets XID\n\n**Returns:** Dictionary with all available fund fields and values\n\n```python\nxid = get_xid('QQQ')\nstats = get_fund_stats(xid)\n\n# Access any available field safely\ninception = stats.get('Inception date', 'Not available')\nfees = stats.get('Ongoing charge', 'Not available')\n```\n\n#### `get_available_fields(xid)`\n\nGet list of all available profile fields for a fund.\n\n**Parameters:**\n- `xid` (str): The FT Markets XID\n\n**Returns:** List of all field names available\n\n```python\nxid = get_xid('SPY')\nfields = get_available_fields(xid)\nprint(\"Available fields:\")\nfor field in fields:\n    print(f\"  - {field}\")\n```\n\n#### `search_profile_field(xid, search_term)`\n\nSearch for specific fields in the fund profile data.\n\n**Parameters:**\n- `xid` (str): The FT Markets XID\n- `search_term` (str): Term to search for in field names (case-insensitive)\n\n**Returns:** pandas.DataFrame with matching fields and values\n\n```python\nxid = get_xid('SPY')\nfees = search_profile_field(xid, 'fee')\ninception = search_profile_field(xid, 'inception')\n```\n\n## Complete Example\n\n```python\nfrom ftgo import get_xid, get_historical_prices, get_holdings, get_fund_profile\nimport matplotlib.pyplot as plt\n\n# Search for QQQ ETF\nqqq_xid = get_xid('QQQ')\n\n# Get 1 year of historical data\nhistorical_data = get_historical_prices(qqq_xid, \"01012023\", \"31122023\")\n\n# Get fund information\nprofile = get_fund_profile(qqq_xid)\ntop_holdings = get_holdings(qqq_xid, \"top_holdings\")\nasset_allocation = get_holdings(qqq_xid, \"asset_allocation\")\n\n# Plot price chart\nhistorical_data.set_index('date')['close'].plot(title='QQQ Price History')\nplt.show()\n\n# Display fund information\nprint(\"Fund Profile:\")\nprint(profile.head(10))\n\nprint(\"\\nTop 10 Holdings:\")\nprint(top_holdings.head(10))\n\nprint(\"\\nAsset Allocation:\")\nprint(asset_allocation)\n```\n\n## Error Handling\n\nThe library includes logging and error handling, but you should wrap calls in try-except blocks for production use:\n\n```python\ntry:\n    xid = get_xid('INVALID_TICKER')\n    data = get_historical_prices(xid, \"01012024\", \"31012024\")\nexcept ValueError as e:\n    print(f\"Error: {e}\")\nexcept Exception as e:\n    print(f\"Unexpected error: {e}\")\n```\n\n## Requirements\n\n- Python 3.7+\n- cloudscraper >= 1.2.68\n- pandas >= 1.3.0\n- beautifulsoup4 >= 4.11.0\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## Disclaimer\n\nThis library is for educational and research purposes.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A Python library for fetching financial data from FT Markets",
    "version": "1.0.0",
    "project_urls": {
        "Bug Reports": "https://github.com/gohibiki/ftgo/issues",
        "Changelog": "https://github.com/gohibiki/ftgo/blob/main/CHANGELOG.md",
        "Documentation": "https://github.com/gohibiki/ftgo#readme",
        "Homepage": "https://github.com/gohibiki/ftgo",
        "Repository": "https://github.com/gohibiki/ftgo"
    },
    "split_keywords": [
        "finance",
        " stocks",
        " etf",
        " historical-data",
        " financial-analysis",
        " market-data",
        " ft-markets",
        " financial-times"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "90d997ca37c1b12ff8f7d156bd10c6faa4d4b0845b49f140b64a0d1b29b3a00d",
                "md5": "1add449dfb53138132fe975792510a5b",
                "sha256": "465d515f73161c41cde3de9174fc1fc31773c3f0ae05b01086ddc457d9d0aae9"
            },
            "downloads": -1,
            "filename": "ftgo-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "1add449dfb53138132fe975792510a5b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 14638,
            "upload_time": "2025-09-09T01:53:15",
            "upload_time_iso_8601": "2025-09-09T01:53:15.266860Z",
            "url": "https://files.pythonhosted.org/packages/90/d9/97ca37c1b12ff8f7d156bd10c6faa4d4b0845b49f140b64a0d1b29b3a00d/ftgo-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "98d806ab954883963cd3c922f699d9ee4f43bf1766344d93a42bb21b0724d245",
                "md5": "3b0d09fb77743e66c534cce780b04f40",
                "sha256": "5f6da93f3e672f661c3a134948f92c8ddb9be0cbe125c740eee1095acadbb469"
            },
            "downloads": -1,
            "filename": "ftgo-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "3b0d09fb77743e66c534cce780b04f40",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 15206,
            "upload_time": "2025-09-09T01:53:16",
            "upload_time_iso_8601": "2025-09-09T01:53:16.712041Z",
            "url": "https://files.pythonhosted.org/packages/98/d8/06ab954883963cd3c922f699d9ee4f43bf1766344d93a42bb21b0724d245/ftgo-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-09 01:53:16",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "gohibiki",
    "github_project": "ftgo",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "lcname": "ftgo"
}
        
Elapsed time: 0.49625s