Metadata-Version: 2.4
Name: atabet-trader
Version: 1.1.1
Summary: Atabet-Trader: Event-driven algorithmic trading engine for backtest, simulation, and live trading
Author: ATABET LIMITED
Author-email: ATABET LIMITED <info@atabet.com>
Maintainer: ATABET LIMITED
Maintainer-email: ATABET LIMITED <info@atabet.com>
License: Proprietary
Project-URL: Homepage, https://www.atabet.com
Project-URL: Repository, https://github.com/atabet-com/atabet-trader
Project-URL: Issues, https://github.com/atabet-com/atabet-trader/issues
Project-URL: Bug Tracker, https://github.com/atabet-com/atabet-trader/issues
Keywords: finance,trading,backtest,algorithmic-trading,futures,equity
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: pandas
Requires-Dist: numpy
Requires-Dist: pytz
Requires-Dist: PyYAML
Requires-Dist: matplotlib
Requires-Dist: plotly
Requires-Dist: func-timeout
Requires-Dist: python-dateutil
Provides-Extra: auth
Requires-Dist: atabet-token; extra == "auth"
Provides-Extra: futu
Requires-Dist: futu-api; extra == "futu"
Provides-Extra: ib
Requires-Dist: ibapi; extra == "ib"
Provides-Extra: qmt
Requires-Dist: redis; extra == "qmt"
Provides-Extra: clickhouse
Requires-Dist: clickhouse-driver; extra == "clickhouse"
Provides-Extra: telegram
Requires-Dist: python-telegram-bot; extra == "telegram"
Provides-Extra: monitor
Requires-Dist: dash; extra == "monitor"
Provides-Extra: analysis
Requires-Dist: pyautogui; extra == "analysis"
Provides-Extra: samples
Requires-Dist: finta; extra == "samples"
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: Cython; extra == "dev"
Provides-Extra: all
Requires-Dist: atabet-token; extra == "all"
Requires-Dist: futu-api; extra == "all"
Requires-Dist: ibapi; extra == "all"
Requires-Dist: redis; extra == "all"
Requires-Dist: clickhouse-driver; extra == "all"
Requires-Dist: python-telegram-bot; extra == "all"
Requires-Dist: dash; extra == "all"
Requires-Dist: pyautogui; extra == "all"
Requires-Dist: finta; extra == "all"
Requires-Dist: pytest; extra == "all"
Requires-Dist: Cython; extra == "all"
Dynamic: author
Dynamic: maintainer

# Atabet-Trader

Event-driven algorithmic trading engine for backtest, simulation, and live trading.

## Features

- Same strategy code for backtesting, simulation, and live trading
- Supports equity and futures
- Gateways: Backtest, Futu (securities / futures / crypto), Interactive Brokers (IB),
  QMT (Big QMT via Redis bridge)
  (CQG source is retained but disabled for public use)
- Plugins: analysis, live monitor (Dash), Telegram bot, SQLite, ClickHouse
- Token-based license checking via the Atabet licensing server (`com.atabet.trader`)
- N-minute bars (`5Min` / `15Min` / …) via shared 1Min→N-min aggregation
  (`atabet_trader.core.bar_aggregate`) for historical requests and backtest when
  only `K_1M` CSV data is available
- Daily backtest via `TIME_STEP = 86_400_000` + `K_1D/{code}/ohlcv.csv`
  (Yahoo sample equities: `AAPL` / `MSFT` / `GOOGL`)

## Authentication

`Engine` requires a valid authentication token. Install auth support with
`pip install atabet-trader[auth]` (requires **atabet-token** for licensing-server
session support).

### Token types

| Token source | Format | Usage |
|--------------|--------|-------|
| Licensing server (`/admin/generate_license`) | JWT (three dot-separated segments) | Default — `Engine(..., token=jwt)` uses `validation_method='licensing'` |
| Dev HMAC (`generate_secure_token` with `DEV_MODE=1`) | Hex string | Pass `validation_method='original'` |

```python
import os
import socket
from atabet_trader.core.engine import Engine

engine = Engine(
    gateways={gateway_name: gateway},
    token=os.environ["ATABET_TRADER_TOKEN"],
    licensing_server_url=os.environ.get(
        "LICENSING_SERVER_URL", "http://39.101.65.167:5001"
    ),
    device_name=os.environ.get(
        "ATABET_DEVICE_NAME",
        os.environ.get("ATABET_CLIENT_ID", socket.gethostname()),
    ),
)

# Dev HMAC token (offline / local testing)
engine = Engine(
    gateways={gateway_name: gateway},
    token=dev_token,
    validation_method="original",
)
```

Licenses must be issued with `application_id: "com.atabet.trader"`. Call
`engine.close()` (also invoked from `engine.stop()`) to free a licensing session
slot via `POST /logout`.

## Environment preparations

```bash
conda env create -f environment.yml
conda activate atabet_trader_env
pip install -e ".[auth,dev]"
```

Optional extras:

```bash
pip install -e ".[futu,ib,qmt,monitor,telegram,clickhouse]"
# or
pip install -e ".[all]"
```

## Configuration

At the working directory (or on `PYTHONPATH`), create `atabet_trader_config.py`.
Use [`atabet_trader_config_sample.py`](atabet_trader_config_sample.py) as a template.

```python
DATA_PATH = {
    "kline": "sample_data/k_line",
}
ACTIVATED_PLUGINS = ["analysis"]
```

**Backtest data (CSV-on-disk only)** — illustrated cookbook:
[`samples/LLM_DATA_PATH_GUIDE.md`](samples/LLM_DATA_PATH_GUIDE.md).

```text
{DATA_PATH["kline"]}/K_1M/{security.code}/YYYY-MM-DD.csv   # TIME_STEP=60000
{DATA_PATH["kline"]}/K_1D/{security.code}/ohlcv.csv        # TIME_STEP=86400000
# DATA_PATH["kline"] = parent of K_1M / K_1D (not the symbol folder)
```

CSV header: `time_key,open,high,low,close,volume` (time column first; no extra
broker export columns). Native `K_5M` / `K_15M` are used when present; otherwise
aggregatable `TIME_STEP` values build N-min bars from `K_1M`.

Repo sample equities under `K_1D/` (`AAPL` / `MSFT` / `GOOGL`) were downloaded
via the atabet-data Yahoo channel (`samples/download_yahoo_k1d.py`).

```bash
cd samples
python prepare_backtest_data.py --out /tmp/my_kline --code FUT.GC
python prepare_backtest_data.py --validate /tmp/my_kline --code FUT.GC
python prepare_backtest_data.py --validate ../sample_data/k_line --code AAPL --freq K_1D
python download_yahoo_k1d.py   # optional refresh of K_1D from Yahoo
```

LLM / onboarding docs under [`samples/`](samples/):

| Doc | Topic |
|-----|--------|
| [`samples/LLM_DATA_PATH_GUIDE.md`](samples/LLM_DATA_PATH_GUIDE.md) | **`DATA_PATH` + local CSV folder structure** |
| [`samples/LLM_PROJECT_STRUCTURE.md`](samples/LLM_PROJECT_STRUCTURE.md) | Layout + config contract |
| [`samples/LLM_BACKTEST_GUIDE.md`](samples/LLM_BACKTEST_GUIDE.md) | Backtest wiring, gotchas |
| [`samples/LLM_API_REFERENCE.md`](samples/LLM_API_REFERENCE.md) | Engine / Strategy / types / enums |
| [`samples/LLM_LIVE_GUIDE.md`](samples/LLM_LIVE_GUIDE.md) | SIMULATE / LIVETRADE gateways |
| [`samples/LLM_PLUGINS_GUIDE.md`](samples/LLM_PLUGINS_GUIDE.md) | analysis / monitor / telegram / sqlite |

## Quick start (backtest)

```python
from datetime import datetime
from atabet_trader.core.constants import TradeMode, Exchange
from atabet_trader.core.event_engine import BarEventEngineRecorder, BarEventEngine
from atabet_trader.core.security import Stock
from atabet_trader.core.engine import Engine
from atabet_trader.core.strategy import BaseStrategy
from atabet_trader.gateways import BacktestGateway

class MyStrategy(BaseStrategy):
    def init_strategy(self):
        pass

    def on_bar(self, cur_data):
        print(cur_data)

stock_list = [
    Stock(code="HK.01157", lot_size=100, security_name="example", exchange=Exchange.SEHK),
]
gateway_name = "Backtest"
gateway = BacktestGateway(
    securities=stock_list,
    start=datetime(2021, 3, 15, 9, 30, 0, 0),
    end=datetime(2021, 3, 17, 16, 0, 0, 0),
    gateway_name=gateway_name,
)
gateway.SHORT_INTEREST_RATE = 0.0
gateway.set_trade_mode(TradeMode.BACKTEST)

engine = Engine(gateways={gateway_name: gateway}, token=your_token)
# ... init strategy, recorder, BarEventEngine, then event_engine.run()
```

Full runnable demo:

```bash
export ATABET_TRADER_TOKEN='...'
cd samples
python main_demo.py
```

## Simulation / live trading

Replace the backtest gateway with `FutuGateway`, `FutuFuturesGateway`, `FutuCryptoGateway`, `IbGateway`, or `QmtGateway` and set `TradeMode.SIMULATE` or `TradeMode.LIVETRADE`. Install the matching optional extra first. List currently importable gateways with `from atabet_trader.gateways import list_available_gateways`.

**Big QMT (`QmtGateway`):** MiniQMT / external `xtquant` is being phased out; Big QMT has no XtQuantServer, so trading runs through a Redis bridge. Deploy [`atabet_trader/gateways/qmt/agent/atabet_qmt_bridge.py`](atabet_trader/gateways/qmt/agent/atabet_qmt_bridge.py) inside the Big QMT built-in strategy environment (see agent [README](atabet_trader/gateways/qmt/agent/README.md)), keep the QMT client logged in, and point `GATEWAYS["Qmt"]` at Redis (`redis_host` / `redis_port` / `redis_password` / `redis_db`). The **same** bridge is shared with **atabet-data** (`source='qmt'`) — do not run a second strategy on the same key prefix. Historical bars (`req_historical_bars` for native `1Day` / `1Min`, plus aggregatable N-min such as `5Min` / `15Min` built from `1Min` via `bar_aggregate`) use bridge op `get_market_data_ex` → Big QMT `ContextInfo.get_market_data_ex`. Financial datasets use `get_raw_financial_data` / `get_divid_factors` / `get_instrumentdetail`. QMT reads **local** history only — use 数据管理 → 补充数据 for each symbol/period you need; short lookbacks usually mean missing local data, not an RPC failure. Optional config: `hist_rpc_timeout` (default 30s), `hist_max_count`, `hist_fill_data` / `hist_subscribe` (default False). Install `pip install -e ".[qmt]"`. Keep `allow_orders=False` (and agent `ALLOW_ORDERS=False`) until `python samples/qmt_bridge_smoke.py` succeeds. Strategy hosts may be macOS/Linux; Big QMT itself remains Windows.

**Interactive Brokers (`IbGateway`):** install the official `ibapi` Python client from
[interactivebrokers.github.io](https://interactivebrokers.github.io/) and match
the API build to your TWS/Gateway (e.g. API **10.48** with TWS **1048**). The
`ib` extra expects the `ibapi` package; it is not reliably available on PyPI from IB.
Configure `GATEWAYS["Ib"]` in `atabet_trader_config.py` (`host`, `port` paper TWS
`7497`, `clientid`, `broker_account`). Close other live TWS/IBKR sessions on the
same account — competing sessions block market/historical data (IB errors 10197 / 162).
Crypto spot (e.g. `BTC.USD`) maps to IB `CRYPTO` on **PAXOS** and needs a PAXOS
crypto market-data subscription (`AGGTRADES`); without it you get IB error 162/354.
CME crypto futures (e.g. `MBT`) may have market data but still require Virtual Asset
trading permission to place orders. `IbGateway` disables ibapi 10.48 protobuf
encoding for place/cancel (classic socket) because protobuf placeOrder can fail silently.

**Important:** live mode can send real orders. Use simulation first and review risk controls. Futu crypto (`FutuCryptoGateway`) supports live trading only (no paper trading).

## Live monitoring and Telegram

Enable plugins in `atabet_trader_config.py`:

```python
ACTIVATED_PLUGINS = ["analysis", "monitor", "telegram"]
TELEGRAM_TOKEN = ""       # prefer env / secret store
TELEGRAM_CHAT_ID = 1
```

Monitor UI (when enabled): `http://127.0.0.1:8050`

## Packaging

Protected wheels are built with Cython (sources stripped; `__init__.pyc` kept for importability). `samples/` remain plain Python in the distribution.

```bash
python setup.py bdist_wheel
# or via cibuildwheel in CI
```

## Test

```bash
pip install -e ".[auth,dev]"
DEV_MODE=1 pytest tests/ -v
```

Integration / broker scripts live under `tests/manual_*.py` and are not run in default CI. Licensing-server integration tests are marked `@pytest.mark.integration`.

**Note:** Analysis / recorder / historical-data helpers avoid pandas in-place column writes (`df[col]=…`, `.T` then mutate). They use `DataFrame` rebuilds and `.assign` so Cython-built extensions stay compatible with pandas ≥3 Copy-on-Write.

## GitHub Actions

- **Test** workflow: every push and pull request (`pytest` with `.[auth,dev]`)
- **Build wheels** (`build-wheels.yml`): runs when the **tip** commit message contains `[build ci]`, `[pub pypi]`, or `[pub test.pypi]` (case variants allowed), or via `workflow_dispatch` (build only — no publish).
- **Publish**: tip commit must include `[pub pypi]` (PyPI) or `[pub test.pypi]` (TestPyPI). Requires Trusted Publishing on PyPI for workflow `build-wheels.yml` (no GitHub Environment), or an API token wired into the publish step.

## Project structure

```text
atabet-trader/
├── atabet_trader/          # library package
│   ├── core/                # Engine, Strategy, event loop, types
│   ├── gateways/            # Backtest, Futu, IB, QMT (+ disabled CQG)
│   │   └── qmt/agent/       # Big QMT Redis bridge
│   └── plugins/             # analysis, monitor, telegram, sqlite3, …
├── samples/                 # demos + LLM_* guides (plain .py in wheels)
├── sample_data/             # offline bar CSVs for demos/tests
├── tests/                   # pytest + manual broker scripts
├── atabet_trader_config_sample.py
├── pyproject.toml
├── environment.yml
├── setup.py
└── build_wheel.py
```

See [`samples/LLM_PROJECT_STRUCTURE.md`](samples/LLM_PROJECT_STRUCTURE.md) for the
config import contract (`atabet_trader_config` on CWD / `PYTHONPATH`).

## License

Proprietary — ATABET LIMITED. Contact: info@atabet.com
