Files
Grid_Trading/docs/superpowers/plans/2026-07-08-tencent-quotes.md
2026-07-08 21:57:05 +08:00

7.1 KiB

Tencent Quotes Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Display Tencent realtime A-share prices in the holdings table and account summary after a manual quote refresh.

Architecture: Add a focused market quote client that parses Tencent responses and returns typed quote snapshots. Keep quotes in TradingService as an in-memory cache, then pass quote prices into the existing pure position calculations so GUI display updates without writing realtime prices into SQLite.

Tech Stack: Python 3.11, urllib.request, Decimal, PySide6, pytest.


File Structure

  • Create src/grid_trading/market/__init__.py: market package marker.
  • Create src/grid_trading/market/tencent.py: Tencent symbol inference, response parsing, and HTTP quote provider.
  • Modify src/grid_trading/domain/models.py: add QuoteSnapshot.
  • Modify src/grid_trading/domain/calculations.py: let quote snapshots override manual price when computing positions.
  • Modify src/grid_trading/services/trading_service.py: add quote provider injection, refresh_quotes, and quote cache use in summaries.
  • Modify src/grid_trading/ui/main_window.py: make the toolbar refresh action fetch Tencent quotes and display quote refresh errors.
  • Create tests/test_tencent_quotes.py: parser and symbol inference tests.
  • Modify tests/test_calculations.py: verify quote price overrides manual price.
  • Modify tests/test_services.py: verify service refresh uses fake quote provider and summaries use realtime price.

Tasks

Task 1: Tencent Quote Parser

Files:

  • Create: src/grid_trading/market/__init__.py

  • Create: src/grid_trading/market/tencent.py

  • Test: tests/test_tencent_quotes.py

  • Step 1: Write failing parser tests

from decimal import Decimal

from grid_trading.market.tencent import infer_tencent_symbol, parse_tencent_response


def test_infer_tencent_symbol_from_a_share_code():
    assert infer_tencent_symbol("000001") == "sz000001"
    assert infer_tencent_symbol("600000") == "sh600000"
    assert infer_tencent_symbol("sz000001") == "sz000001"


def test_parse_tencent_response_extracts_realtime_fields():
    raw = (
        'v_sz000001="51~平安银行~000001~10.60~10.47~10.44~0~0~0~'
        '10.60~0~10.59~0~10.58~0~10.57~0~10.56~0~10.61~0~10.62~0~'
        '10.63~0~10.64~0~10.65~0~~20260708161430~0.13~1.24~10.63~10.34";'
    ).encode("gbk")

    [quote] = parse_tencent_response(raw)

    assert quote.symbol == "sz000001"
    assert quote.code == "000001"
    assert quote.name == "平安银行"
    assert quote.price == Decimal("10.60")
    assert quote.previous_close == Decimal("10.47")
    assert quote.open_price == Decimal("10.44")
    assert quote.change == Decimal("0.13")
    assert quote.change_percent == Decimal("1.24")
    assert quote.high == Decimal("10.63")
    assert quote.low == Decimal("10.34")
  • Step 2: Run parser tests and verify they fail

Run: pytest tests/test_tencent_quotes.py -v Expected: FAIL because grid_trading.market does not exist.

  • Step 3: Implement parser and provider

Define QuoteFetchError, infer_tencent_symbol, parse_tencent_response, and TencentQuoteProvider.fetch_quotes(instruments).

  • Step 4: Run parser tests and verify they pass

Run: pytest tests/test_tencent_quotes.py -v Expected: PASS.

  • Step 5: Commit
git add src/grid_trading/market tests/test_tencent_quotes.py
git commit -m "feat: add Tencent quote parser"

Task 2: Quote Prices In Calculations And Service

Files:

  • Modify: src/grid_trading/domain/models.py

  • Modify: src/grid_trading/domain/calculations.py

  • Modify: src/grid_trading/services/trading_service.py

  • Test: tests/test_calculations.py

  • Test: tests/test_services.py

  • Step 1: Write failing calculation and service tests

Add a calculation test where an Instrument has manual_price=Decimal("9"), a QuoteSnapshot(price=Decimal("10")) is passed, and PositionSummary.current_price becomes 10 with price_source == "tencent".

Add a service test with a fake provider:

class FakeQuoteProvider:
    def fetch_quotes(self, instruments):
        return {
            "510300": QuoteSnapshot(
                symbol="sh510300",
                code="510300",
                name="沪深300ETF",
                price=Decimal("4.12"),
                source="tencent",
            )
        }

The test should call service.refresh_quotes() and assert get_position_summaries()[0].current_price == Decimal("4.12").

  • Step 2: Run tests and verify they fail

Run: pytest tests/test_calculations.py tests/test_services.py -v Expected: FAIL because QuoteSnapshot and service quote cache are not implemented.

  • Step 3: Implement quote snapshot flow

Add QuoteSnapshot to models. Add quote_snapshots argument to calculate_positions. Add quote_provider injection, _quote_cache, and refresh_quotes to TradingService.

  • Step 4: Run tests and verify they pass

Run: pytest tests/test_calculations.py tests/test_services.py -v Expected: PASS.

  • Step 5: Commit
git add src/grid_trading/domain src/grid_trading/services tests/test_calculations.py tests/test_services.py
git commit -m "feat: use realtime quotes in summaries"

Task 3: GUI Refresh Wiring

Files:

  • Modify: src/grid_trading/ui/main_window.py

  • Test: tests/test_ui.py

  • Step 1: Update GUI smoke expectation

Extend the existing main window smoke test to assert a refresh button exists with text containing 行情.

  • Step 2: Run UI test and verify it fails

Run: pytest tests/test_ui.py -v Expected: FAIL because the toolbar still uses the old generic refresh text.

  • Step 3: Implement GUI quote refresh

Change the toolbar button to 刷新行情. Wire it to call service.refresh_quotes() before refresh_all(). Keep post-save refreshes as local recalculation without forcing network calls.

  • Step 4: Run UI test and verify it passes

Run: pytest tests/test_ui.py -v Expected: PASS.

  • Step 5: Commit
git add src/grid_trading/ui/main_window.py tests/test_ui.py
git commit -m "feat: refresh Tencent quotes from GUI"

Task 4: Verification

Files:

  • Modify: README.md

  • Step 1: Run all tests

Run: pytest -v Expected: all tests pass.

  • Step 2: Run CLI smoke

Run: python -m grid_trading.app --help Expected: help text prints normally.

  • Step 3: Update README

Document that the 刷新行情 button fetches Tencent quotes from http://qt.gtimg.cn/q=<symbol> and that realtime quotes are not persisted.

  • Step 4: Commit
git add README.md
git commit -m "docs: document Tencent quote refresh"

Self-Review

  • Spec coverage: parser, symbol inference, realtime price priority, service cache, manual GUI refresh, and tests are covered.
  • Scope check: no auto-refresh, no grid order suggestions, and no quote persistence are included.
  • Placeholder scan: no unresolved placeholders or ambiguous steps remain.