# Tradepose Python Client

易於使用的 Tradepose API 客戶端和數據分析工具，專為 Jupyter Notebook 互動式開發設計。

## 特點

✅ **易於導入** - 簡潔的 Python API
✅ **無需 PostgreSQL** - 純 API + Redis 模式
✅ **Parquet 下載** - 直接下載並讀取 Parquet 文件
✅ **Jupyter 友好** - 專為 notebook 環境優化
✅ **自動等待** - 自動監控任務完成
✅ **Polars 支援** - 高效數據處理
✅ **Schema 驗證** - 完整的 schema 處理工具
✅ **可視化** - 內建 Plotly 圖表支援
✅ **分析工具** - 豐富的技術分析函數

## 安裝依賴

```bash
cd tradepose-client

# 核心依賴
uv add polars redis plotly hvplot

# Jupyter 環境
uv add jupyterlab ipykernel ipywidgets

# 可選：金融數據視覺化
uv add mplfinance matplotlib
```

## 快速開始

### 🚀 推薦方式：使用 Parquet 下載（無需 PostgreSQL）

```python
from tradepose_client import TradeposeClient

client = TradeposeClient()

# 完整工作流程：創建任務 -> 下載 Parquet -> 讀取
df = client.quick_workflow(
    strategy_name="txf_1h_sma30_50",
    start_date="2020-01-01T00:00:00",
    save_path="./data/my_data.parquet"
)

# 開始分析
print(df.describe())
```

### 方法一：最簡單（一行搞定）

```python
from tradepose_client import quick_export

# 一行代碼導出數據（下載 Parquet）
df = quick_export(
    strategy_name="txf_1h_sma30_50",
    start_date="2020-01-01T00:00:00",
    end_date="2024-12-31T23:59:59",
    save_path="./data/my_data.parquet"
)

# 開始分析
print(df.describe())
```

### 方法二：使用客戶端（更多控制）

```python
from tradepose_client import TradeposeClient

# 初始化
client = TradeposeClient()

# 列出策略
strategies = client.list_strategies()
print(strategies)

# 創建 export 任務
task_id = client.create_export(
    strategy_name="txf_1h_sma30_50",
    blueprint_name="txf_base_trend",
    start_date="2020-01-01T00:00:00"
)

# 等待並下載 Parquet
df = client.wait_and_download(task_id, output_path="./data/output.parquet")
```

### 方法三：分步驟執行（Parquet 下載）

```python
# 1. 創建任務
task_id = client.create_export(
    strategy_name="txf_1h_sma30_50",
    blueprint_name="txf_base_trend",
    start_date="2020-01-01T00:00:00"
)

# 2. 等待完成
client.wait_for_export(task_id)

# 3. 下載 Parquet 文件
parquet_path = client.download_parquet(task_id, "./data/output.parquet")

# 4. 讀取並應用 schema
df = client.load_parquet_with_schema(parquet_path)
```

### 方法四：使用 Parquet 工具模組

```python
from parquet_utils import (
    read_enhanced_ohlcv,
    extract_all_trading_contexts,
    validate_schema,
    print_validation_report,
    get_column_info
)

# 讀取 Parquet
df = read_enhanced_ohlcv("./data/output.parquet")

# 驗證 schema
report = validate_schema(df)
print_validation_report(report)

# 展開 trading context
df = extract_all_trading_contexts(df)

# 查看列分類
col_info = get_column_info(df)
```

## 數據分析工具

```python
from analysis_utils import *

# 計算收益率
df = calculate_returns(df)

# 計算波動率
df = calculate_volatility(df, window=20)

# 重採樣為日線
daily_df = resample_to_daily(df)

# 計算回撤
df = calculate_drawdown(df)
max_dd = get_max_drawdown(df)

# 打印統計摘要
print_summary(df)

# 查找技術指標
indicators = find_indicator_columns(df)
print(indicators)

# 按日期過濾
df_2023 = filter_by_date_range(df, "2023-01-01", "2023-12-31")

# 分割訓練/測試集
train, test = split_train_test(df, train_ratio=0.8)
```

## Jupyter Notebook 示例

項目包含兩個示例 notebook：

### 1. 快速開始 (`examples/01_quick_start.ipynb`)

- 初始化客戶端
- 查看可用策略
- 三種導出方式
- 數據預覽和保存

### 2. 數據分析 (`examples/02_data_analysis.ipynb`)

- OHLCV 統計分析
- 技術指標分析
- K 線圖可視化
- 成交量分析
- 相關性分析

### 啟動 Jupyter Lab

```bash
cd tradepose-client
uv run jupyter lab
```

瀏覽器會自動打開，可以直接運行示例 notebook。

## API 參考

### TradeposeClient

#### `__init__(api_url, redis_url)`

初始化客戶端

#### `list_strategies() -> List[Dict]`

列出所有可用策略

#### `get_strategy_detail(strategy_name) -> Dict`

獲取策略詳情

#### `create_export(strategy_name, blueprint_name, export_type, start_date, end_date) -> str`

創建 export 任務，返回 task_id

**參數**：

- `strategy_name`: 策略名稱
- `blueprint_name`: 藍圖名稱
- `export_type`: 導出類型 (enhanced-ohlcv, backtest-results, latest-trades)
- `start_date`: 起始日期（ISO 8601 格式，如 "2020-01-01T00:00:00"）
- `end_date`: 終止日期（可選，默認當前時間）

#### `get_export_status(task_id) -> Dict`

查詢任務狀態

#### `wait_for_export(task_id, timeout, poll_interval) -> Dict`

等待任務完成

#### `get_metadata_from_redis(task_id) -> Dict`

從 Redis 讀取任務 metadata（注意：只有 metadata，實際數據在 Parquet 文件中）

#### `wait_and_download(task_id, output_path, timeout, verbose) -> pl.DataFrame`

等待並下載 Parquet（推薦方法）

#### `save_to_parquet(df, output_path) -> Path`

保存為 Parquet 文件

#### `download_parquet(task_id, output_path) -> Path`

直接從 API 下載 Parquet 文件

**參數**：

- `task_id`: Export task ID
- `output_path`: 輸出文件路徑（可選，自動生成）

#### `load_parquet_with_schema(file_path) -> pl.DataFrame`

讀取 Parquet 文件並應用正確的 schema

**參數**：

- `file_path`: Parquet 文件路徑

#### `quick_export(strategy_name, blueprint_name, start_date, end_date, save_path) -> pl.DataFrame`

一鍵導出（下載 Parquet）

**參數**：

- `save_path`: 保存路徑（如果為 None，自動生成臨時文件）

#### `quick_workflow(strategy_name, blueprint_name, start_date, end_date, save_path) -> pl.DataFrame`

完整工作流程（推薦使用，與 quick_export 相同）

**說明**：

- 完全不依賴 PostgreSQL 或 Redis 數據存儲
- 只需要 API server 運行即可

## 便捷函數

### `quick_export(...)`

全局便捷函數，無需創建客戶端實例

```python
df = quick_export("txf_1h_sma30_50", start_date="2020-01-01T00:00:00")
```

### `get_client(api_url, redis_url)`

獲取客戶端實例

## Parquet 工具 API

從 `parquet_utils` 模組導入:

### `read_enhanced_ohlcv(file_path, apply_schema=True) -> pl.DataFrame`

讀取並正確處理 enhanced OHLCV Parquet 文件

### `extract_struct_field(df, struct_col, field_name, new_col_name) -> pl.DataFrame`

從 Struct 欄位中提取單個字段

### `extract_all_struct_fields(df, struct_col) -> pl.DataFrame`

展開 Struct 欄位的所有字段為獨立列

### `extract_all_trading_contexts(df) -> pl.DataFrame`

展開所有 trading context Struct 欄位

### `validate_schema(df) -> Dict`

驗證 DataFrame schema 完整性

### `print_validation_report(report)`

打印 schema 驗證報告

### `get_column_info(df, verbose=True) -> Dict`

獲取列分類信息（ohlcv, signals, indicators 等）

### `filter_columns(df, include, exclude) -> pl.DataFrame`

根據模式過濾列

## 文件結構

```
tradepose-client/
├── tradepose_client.py       # 主要客戶端模組
├── parquet_utils.py          # Parquet 工具模組（NEW）
├── pl_schema.py              # Enhanced OHLCV schema 定義
├── analysis_utils.py          # 數據分析工具函數
├── strategy_models.py         # 策略模型（Pydantic）
├── export_to_parquet.py       # CLI 工具（獨立使用）
├── example_no_postgres.py     # 無 PostgreSQL 示例（NEW）
├── example_usage.py           # 使用示例
├── workflow_example.sh        # Shell 腳本示例
├── examples/
│   ├── 01_quick_start.ipynb   # 快速開始
│   ├── 02_data_analysis.ipynb # 數據分析
│   └── 03_strategy_models.ipynb # 策略模型示例
├── README.md
└── pyproject.toml
```

## 使用場景

### 1. 無 PostgreSQL 完整工作流程（推薦）

```python
from tradepose_client import TradeposeClient
from parquet_utils import read_enhanced_ohlcv, extract_all_trading_contexts

# 1. 下載數據
client = TradeposeClient()
df = client.quick_workflow(
    strategy_name="txf_1h_sma30_50",
    download_parquet=True,
    save_path="./data/my_strategy.parquet"
)

# 2. 讀取並處理
df = read_enhanced_ohlcv("./data/my_strategy.parquet")
df = extract_all_trading_contexts(df)

# 3. 分析
from analysis_utils import print_summary
print_summary(df)
```

### 2. 快速探索數據

```python
# 一行導出
df = quick_export("txf_1h_sma30_50", start_date="2023-01-01T00:00:00")

# 快速統計
print_summary(df)

# 查看指標
indicators = find_indicator_columns(df)
df.select(indicators).describe()
```

### 2. 策略回測分析

```python
# 導出多個時間段
df_2023 = quick_export(..., start_date="2023-01-01", end_date="2023-12-31")
df_2024 = quick_export(..., start_date="2024-01-01", end_date="2024-12-31")

# 比較表現
print_summary(df_2023)
print_summary(df_2024)
```

### 3. 技術指標研究

```python
# 導出數據
df = quick_export(...)

# 找出所有 SMA
sma_cols = [col for col in df.columns if 'SMA' in col]

# 分析相關性
df.select(sma_cols).to_pandas().corr()
```

### 4. 可視化分析

```python
import plotly.graph_objects as go

# K線圖
fig = go.Figure(data=[go.Candlestick(
    x=df['ts'],
    open=df['open'],
    high=df['high'],
    low=df['low'],
    close=df['close']
)])
fig.show()
```

## 完整示例

查看 `example_no_postgres.py` 獲取完整的無 PostgreSQL 工作流程示例:

```bash
# 運行完整示例
uv run --python 3.13 example_no_postgres.py
```

示例包含:

1. Quick workflow - 一鍵下載並分析
2. 分步驟工作流程
3. Parquet 工具函數使用
4. 數據分析
5. 可視化

## CLI 工具

如果不需要 Jupyter，仍可使用命令行工具：

```bash
# 直接轉換
uv run --python 3.13 export_to_parquet.py --task-id <task-id>

# 完整工作流程
./workflow_example.sh
```

## 故障排除

### Redis 連接錯誤

```python
# 檢查密碼
# docker exec tradepose-api-dev env | grep REDIS_URL

# 使用正確的 URL
client = TradeposeClient(redis_url="redis://:tradepose_password@localhost:6379")
```

### 導入模組錯誤

```python
# 確保路徑正確
import sys
sys.path.append('..')  # 在 examples/ 目錄中時

# 或使用絕對導入
sys.path.append('/Users/ender/workspace/tradepose-rust/tradepose-client')
```

### Jupyter Kernel 問題

```bash
# 重新安裝 kernel
uv run python -m ipykernel install --user --name=tradepose

# 在 Jupyter 中選擇 tradepose kernel
```

## 最佳實踐

1. **使用 `quick_export()` 進行探索**
2. **保存中間結果為 Parquet**
3. **使用 `print_summary()` 快速檢查數據**
4. **利用 Polars 的惰性執行優化性能**
5. **在 notebook 中記錄分析思路**

## 依賴

- **Python 3.13+**
- **polars** - 高效數據處理
- **redis** - Redis 連接
- **plotly** - 互動式圖表
- **hvplot** - 高階可視化
- **ipykernel** - Jupyter kernel
- **ipywidgets** - 互動式小工具

## 授權

此工具是 Tradepose 項目的一部分。
