Catalog PyPI
PACKAGE EXPLORERView in registry

agualphacn

PyPI

HTTP client for AGuAlpha Investment Platform (domestic China deployment)

Versions collected1
Direct dependencies6From release 0.2.1
Last observed21 Oct, 09:31 UTC

README

Version 0.2.1 documentation

AGuAlpha Python Client

Official Python library for accessing AGuAlpha Investment Platform data.

Installation

pip install agualphacn

For async support:

pip install agualphacn[async]

For pandas integration:

pip install agualphacn[pandas]

Quick Start

Synchronous Usage

from agualphacn import AGuAlphaClient

# Initialize client
client = AGuAlphaClient(api_key="sk-your-api-key-here")

# Get positions data
positions = client.get_positions()
print(f"Total positions: {positions.total}")

for position in positions.data:
    print(f"Date: {position.date}, Outstanding: {position.outstanding}")

# Get ideas data
ideas = client.get_ideas(status="active")
print(f"Total active ideas: {ideas.total}")

for idea in ideas.data:
    print(f"Symbol: {idea.ticker_symbol}, Status: {idea.status}")

# Close the connection
client.close()

Using Context Manager

from agualphacn import AGuAlphaClient

with AGuAlphaClient(api_key="sk-your-api-key-here") as client:
    positions = client.get_positions(
        start_date="2024-01-01",
        end_date="2024-12-31"
    )
    print(f"Found {positions.total} positions")

Asynchronous Usage

import asyncio
from agualphacn import AGuAlphaAsyncClient

async def main():
    async with AGuAlphaAsyncClient(api_key="sk-your-api-key-here") as client:
        # Fetch data concurrently
        positions, ideas = await asyncio.gather(
            client.get_positions(),
            client.get_ideas(status="active")
        )

        print(f"Positions: {positions.total}, Ideas: {ideas.total}")

asyncio.run(main())

Pandas Integration

from agualphacn import AGuAlphaClient
from agualphacn.utils import positions_to_dataframe, export_to_csv

client = AGuAlphaClient(api_key="sk-your-api-key-here")

# Get positions and convert to DataFrame
positions_response = client.get_positions()
df = positions_to_dataframe(positions_response.data)

# Export to CSV
export_to_csv(positions_response.data, "positions.csv")

CSI Weights

Read csi_weights rows from the prices database filtered by index. The index parameter is required and must be one of these semantic names:

ValueIndex
CSI300CSI 300
CSI500CSI 500
CSI1000CSI 1000
CSI2000CSI 2000

Numeric codes (e.g. 000300) are rejected with HTTP 400.

Three mutually-exclusive date filters are supported:

from agualphacn import AGuAlphaClient

with AGuAlphaClient(api_key="sk-your-api-key-here") as client:
    # 1) Single day
    df = client.get_csi_weights_dataframe(index="CSI300", date="2026-07-15")

    # 2) Inclusive range
    df = client.get_csi_weights_dataframe(
        index="CSI300",
        start_date="2026-07-01",
        end_date="2026-07-15",
    )

    # 3) Rolling window — last 30 days up to today
    df = client.get_csi_weights_dataframe(index="CSI300", days=30)

    print(df.head())
    print(f"Shape: {df.shape}")

If you don't need pandas, drop the _dataframe suffix to get a list of dicts:

with AGuAlphaClient(api_key="sk-your-api-key-here") as client:
    rows = client.get_csi_weights(index="CSI300", days=30)
    print(f"Total records: {len(rows)}")

Adjusted Close Prices

Read adj_close rows from the prices database. membership and a date filter are both required. The membership selects a universe of tickers; choose from:

ValueUniverse
csi300CSI 300 constituents
csi500CSI 500 constituents
csi1000CSI 1000 constituents
csi2000CSI 2000 constituents
csi800CSI 800 universe
csi1800CSI 1800 universe
csi2800CSI 2800 universe
x-csiCross-listed / uncategorized (NULL membership)
a-sharesAll A-shares (tickers ending .SZ, .SH, .BJ)
hkHong Kong listed (tickers ending .HK)
etfETFs
from agualphacn import AGuAlphaClient

with AGuAlphaClient(api_key="sk-your-api-key-here") as client:
    # Single day for CSI 300 constituents
    df = client.get_adj_close_dataframe(membership="csi300", date="2026-07-15")

    # Inclusive range for HK tickers
    df = client.get_adj_close_dataframe(
        membership="hk",
        start_date="2026-07-01",
        end_date="2026-07-15",
    )
    print(df.head())

P-CIES (HK / CN)

Read p_cies rows from the prices database filtered by zone. zone is required and must be exactly "hk" or "cn".

from agualphacn import AGuAlphaClient

with AGuAlphaClient(api_key="sk-your-api-key-here") as client:
    df_hk = client.get_p_cies_dataframe(zone="hk")
    df_cn = client.get_p_cies_dataframe(zone="cn")

SP Rolling Index (Commodities)

Read commodity rolling-index data from the sp_rolling_index table (prices database). At least one filter is required: a product and/or a date filter.

from agualphacn import AGuAlphaClient

with AGuAlphaClient(api_key="sk-your-api-key-here") as client:
    # List available product codes first (e.g. ["CU", "RB", ...])
    products = client.get_sp_rolling_index_products()

    # All rows for one product
    rows = client.get_sp_rolling_index(product="CU")

    # Multiple products at once (no count limit)
    rows = client.get_sp_rolling_index(products=["CU", "RB"])

    # All products in a date range (no product = all commodities)
    rows = client.get_sp_rolling_index(start_date="2025-06-01", end_date="2025-06-30")

    # Product + date range (intersection)
    df = client.get_sp_rolling_index_dataframe(
        product="CU", start_date="2025-06-01", end_date="2025-06-30",
    )

    # Single day
    rows = client.get_sp_rolling_index(date="2025-06-15")

date and start_date/end_date are mutually exclusive. With no product and no date filter, the server returns 400 Bad Request.

Limit Events

Read limit_evts rows (daily limit-up / limit-down events) from the prices database. A date filter is required — either a single day or an inclusive range.

from agualphacn import AGuAlphaClient

with AGuAlphaClient(api_key="sk-your-api-key-here") as client:
    # Single day
    rows = client.get_limit_evts(date="2024-06-15")

    # Inclusive range as a pandas DataFrame
    df = client.get_limit_evts_dataframe(
        start_date="2024-06-01",
        end_date="2024-06-30",
    )
    print(df.head())

date and start_date/end_date are mutually exclusive. With no date filter, the server returns 400 Bad Request.

API Reference

AGuAlphaClient

__init__(api_key: str, base_url: str = "https://www.agualpha.cn/api")

Initialize the client with your API key.

get_positions(start_date: Optional[str] = None, end_date: Optional[str] = None) -> PositionsResponse

Get position data from subscribed analysts.

Parameters:

  • start_date (str): Filter by start date (YYYY-MM-DD format)
  • end_date (str): Filter by end date (YYYY-MM-DD format)

Returns: PositionsResponse

get_ideas(status: Optional[str] = None, direction: Optional[str] = None) -> IdeasResponse

Get trade ideas from subscribed analysts.

Parameters:

  • status (str): Filter by status ("active", "closed")
  • direction (str): Filter by direction ("long", "short")

Returns: IdeasResponse

get_csi_weights(index: str, date=None, start_date=None, end_date=None, days=None, page=None, page_size=None) -> list

Get CSI weights data filtered by index. index is required and must be one of CSI1000, CSI2000, CSI300, CSI500. At most one of the date filters may be applied: date (single day), start_date+end_date (range), or days (rolling window). Auto-paginates unless page is given.

Returns: list of dicts, each representing a row from the csi_weights table.

get_csi_weights_dataframe(index: str, date=None, start_date=None, end_date=None, days=None, page=None, page_size=None) -> pandas.DataFrame

Same parameters as get_csi_weights. Returns a DataFrame. Requires the pandas extra (pip install agualphacn[pandas]).

Returns: pandas.DataFrame

get_revision_fy2(date=None, start_date=None, end_date=None, days=None, ticker=None, type=None, page=None, page_size=None) -> list

Get revision_fy2 data from the cn_af database. A date filter is required — exactly one of date (single day), start_date+end_date (range), or days (rolling window). Optional: ticker (e.g. "000009.SZ") and type ("eps"/"np"/"sales", no value = all types). Auto-paginates unless page is given.

Returns: list of dicts, each representing a row from the revision_fy2 table.

get_revision_fy2_dataframe(date=None, start_date=None, end_date=None, days=None, ticker=None, type=None, page=None, page_size=None) -> pandas.DataFrame

Same parameters as get_revision_fy2. A date filter is required. Requires the pandas extra (pip install agualphacn[pandas]).

Returns: pandas.DataFrame

get_adj_close(membership: str, date=None, start_date=None, end_date=None, page=None, page_size=None) -> list

Get adj_close data from the prices database. membership is required (universe selector — see the table above); a date filter is required — either date (single day) or start_date+end_date (inclusive range, either bound optional). Auto-paginates unless page is given.

Returns: list of dicts, each representing a row from adj_close.

get_adj_close_dataframe(membership: str, date=None, start_date=None, end_date=None, page=None, page_size=None) -> pandas.DataFrame

Same parameters as get_adj_close. membership and a date filter are required. Requires the pandas extra (pip install agualphacn[pandas]).

Returns: pandas.DataFrame

get_p_cies(zone: str, page=None, page_size=None) -> list

Get p_cies data from the prices database. zone is required and must be "hk" or "cn". Auto-paginates unless page is given.

Returns: list of dicts, each representing a row from p_cies.

get_p_cies_dataframe(zone: str, page=None, page_size=None) -> pandas.DataFrame

Same parameters as get_p_cies. zone is required. Requires the pandas extra (pip install agualphacn[pandas]).

get_sp_rolling_index(product=None, products=None, date=None, start_date=None, end_date=None, page=None, page_size=None) -> list

Get commodity rolling-index rows from the prices database. At least one of product(s) or a date filter is required. date and start_date/end_date are mutually exclusive.

  • product (single string) and products (list) are merged; you can pass either or both.
  • With no product(s) and no date filter, the server returns 400.

Returns: list of dicts, each representing a row from sp_rolling_index.

get_sp_rolling_index_dataframe(product=None, products=None, date=None, start_date=None, end_date=None, page=None, page_size=None) -> pandas.DataFrame

Same parameters as get_sp_rolling_index. Requires the pandas extra.

get_sp_rolling_index_products() -> list

Return all distinct product codes available in sp_rolling_index, sorted ascending. Useful for discovering which values are valid for the product(s) parameter.

Returns: pandas.DataFrame

get_limit_evts(date=None, start_date=None, end_date=None, page=None, page_size=None) -> list

Get limit_evts rows (daily limit-up / limit-down events) from the prices database. A date filter is required: either date (single day) or start_date/end_date (inclusive range). date and start_date/end_date are mutually exclusive.

Returns: list of dicts, each representing a row from limit_evts.

get_limit_evts_dataframe(date=None, start_date=None, end_date=None, page=None, page_size=None) -> pandas.DataFrame

Same parameters as get_limit_evts. Requires the pandas extra.

Response Models

PositionsResponse

  • success (bool): Request success status
  • total (int): Total number of records
  • data (List[Position]): List of position objects
  • error (str, optional): Error message if failed

IdeasResponse

  • success (bool): Request success status
  • total (int): Total number of records
  • data (List[Idea]): List of idea objects
  • error (str, optional): Error message if failed

Error Handling

from agualphacn import AGuAlphaClient
from agualphacn.exceptions import APIError, AuthenticationError, RateLimitError

try:
    client = AGuAlphaClient(api_key="invalid-key")
    positions = client.get_positions()
except AuthenticationError:
    print("Invalid API key")
except RateLimitError as e:
    print(f"Too many requests: {e}")
except APIError as e:
    print(f"API error: {e}")

Rate Limiting

The data API limits each API key to 4 requests per second (sliding 1-second window). When the limit is exceeded, the server returns HTTP 429 Too Many Requests with a Retry-After header indicating how many seconds to wait. The SDK surfaces this as a RateLimitError (subclass of APIError), so you can catch it and back off:

import time
from agualphacn import AGuAlphaClient
from agualphacn.exceptions import RateLimitError

client = AGuAlphaClient(api_key="your-api-key")
while True:
    try:
        data = client.get_positions()
        break
    except RateLimitError as e:
        time.sleep(1)

Pagination

The server caps each request at 2000 rows. By default, the SDK auto-paginates — calling get_positions(), get_ideas(), get_csi_weights(index=...), or get_revision_fy2(date=...) with no page argument walks every page and returns the full result set in one call. Each underlying page request counts against your rate limit (2 req/s standard, 10 req/s VIP; 429 responses are retried automatically), so large tables cost multiple requests.

If you want a single page, pass page (1-indexed) and optionally page_size (server caps at 2000):

# Fetch only the first 500 rows of revision_fy2 in the last 30 days
rows = client.get_revision_fy2(days=30, page=1, page_size=500)

When paginating manually, the response object exposes page, page_size, total_pages, and has_more so you can loop pages yourself:

page = 1
all_rows = []
while True:
    resp = client.get_positions(page=page, page_size=1000)
    all_rows.extend(resp.data)
    if not resp.has_more:
        break
    page += 1

Requirements

  • Python 3.8+
  • requests 2.28.0+

License

MIT License

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
0.2.116 Sept 20266

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
agualpha/agualpha-python

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 21 Oct, 09:31 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:106f060bf85a3faa1a0e6a7dd23e1f0a39ff14317a109884f4cd398b6989cbac