Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,13 @@ PostgreSQL migration guidance, see
[Installation troubleshooting](docs/deployment/INSTALL_TROUBLESHOOTING.md) and the
[cloud deployment guide](docs/deployment/CLOUD_DEPLOYMENT_EN.md).

### Optional Qveris data source

QuantDinger can use Qveris as an opt-in unified market-data layer while keeping
the existing market providers as automatic fallbacks. See the
[Qveris data-source guide](docs/integrations/QVERIS_DATA_SOURCE.md) for setup,
supported markets, safety behavior, and verification.

## Production deployment

Validate secrets before starting a production stack:
Expand Down
25 changes: 18 additions & 7 deletions backend_api_python/app/data_sources/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,27 +187,38 @@ def _create_source(cls, market: str) -> BaseDataSource:
"""创建数据源实例"""
if market == 'Crypto':
from app.data_sources.crypto import CryptoDataSource
return CryptoDataSource()
source = CryptoDataSource()
elif market == 'CNStock':
from app.data_sources.cn_stock import CNStockDataSource
return CNStockDataSource()
source = CNStockDataSource()
elif market == 'HKStock':
from app.data_sources.hk_stock import HKStockDataSource
return HKStockDataSource()
source = HKStockDataSource()
elif market == 'USStock':
from app.data_sources.us_stock import USStockDataSource
return USStockDataSource()
source = USStockDataSource()
elif market == 'Forex':
from app.data_sources.forex import ForexDataSource
return ForexDataSource()
source = ForexDataSource()
elif market == 'Futures':
from app.data_sources.futures import FuturesDataSource
return FuturesDataSource()
source = FuturesDataSource()
elif market == 'MOEX':
from app.data_sources.moex import MOEXDataSource
return MOEXDataSource()
source = MOEXDataSource()
else:
raise UnsupportedMarketError(market)
return cls._wrap_optional_source(market, source)

@staticmethod
def _wrap_optional_source(market: str, source: BaseDataSource) -> BaseDataSource:
"""Wrap an existing source with Qveris only when explicitly enabled."""
from app.data_sources.qveris import QverisDataSource

if QverisDataSource.is_enabled_for(market):
logger.info("Qveris data source enabled for %s with %s fallback", market, source.name)
return QverisDataSource(market, source)
return source

@classmethod
def get_kline(
Expand Down
Loading