> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reportify.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# 量化分析

> 技术指标、因子计算、行情数据和回测功能

# Quant Module

`quant` 模块提供量化分析工具，包括技术指标计算、因子分析、OHLCV 行情数据和策略回测。

公式语法基于 Mai-language，兼容通达信/同花顺。

## 快速开始

```typescript theme={null}
import { Reportify } from 'reportify-sdk';

const client = new Reportify({ apiKey: 'your-api-key' });

// 计算 RSI 指标
const data = await client.quant.indicatorsCompute({
  symbols: ['000001'],
  formula: 'RSI(14)'
});

// 因子选股
const stocks = await client.quant.factorsScreen({
  formula: 'RSI(14) < 30'
});

// 获取 OHLCV 数据
const ohlcv = await client.quant.ohlcv({ symbol: '000001' });

// 策略回测
const result = await client.quant.backtest({
  symbol: '000001',
  formula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 20))',
  startDate: '2023-01-01',
  endDate: '2024-01-01'
});
```

***

## 因子 (Factors)

### factors()

获取可用因子列表（变量和函数）。

```typescript theme={null}
const factors = await client.quant.factors();

factors.forEach(f => {
  console.log(`${f.name} (${f.type}, level ${f.level}): ${f.description}`);
});
```

**因子分级：**

* **Level 0 变量**: CLOSE, OPEN, HIGH, LOW, VOLUME, AMOUNT 及别名
* **Level 0 函数**: MA, EMA, REF, HHV, LLV, STD 等核心函数
* **Level 1 函数**: CROSS, COUNT, EVERY 等应用函数
* **Level 2 函数**: MACD, KDJ, RSI, BOLL 等技术指标

***

**市场状态函数：**

| 函数                   | 说明                  |
| -------------------- | ------------------- |
| `IS_LIMIT_UP()`      | 是否一字涨停（一字板封涨停）      |
| `IS_LIMIT_DOWN()`    | 是否一字跌停（一字板封跌停）      |
| `IS_ST()`            | 是否为 ST 股票           |
| `IS_CHAIN_MAIN()`    | 是否为中国主板股票（60/000开头） |
| `IS_CHAIN_STAR()`    | 是否为科创板股票（68开头）      |
| `IS_CHAIN_CHINEXT()` | 是否为创业板股票（30开头）      |

***

### factorsCompute()

计算因子值，使用 Mai-language 语法。

```typescript theme={null}
const data = await client.quant.factorsCompute({
  symbols: ['000001'],
  formula: 'RSI(14)',
  market: 'cn',
  startDate: '2024-01-01',
  endDate: '2024-06-01'
});
```

**公式示例：**

```typescript theme={null}
// 简单指标
const rsi = await client.quant.factorsCompute({
  symbols: ['000001'],
  formula: 'RSI(14)'
});

// 获取 MACD 的 DIF 线
const dif = await client.quant.factorsCompute({
  symbols: ['000001'],
  formula: 'MACD().dif'
});

// 收盘价是否高于 20 日均线（布尔值）
const aboveMA = await client.quant.factorsCompute({
  symbols: ['000001'],
  formula: 'CLOSE > MA(CLOSE, 20)'
});

// MA20 偏离度（百分比）
const deviation = await client.quant.factorsCompute({
  symbols: ['000001'],
  formula: '(CLOSE - MA(CLOSE, 20)) / MA(CLOSE, 20) * 100'
});
```

**支持的运算符：**

| 类型  | 运算符                              | 说明     |
| --- | -------------------------------- | ------ |
| 比较  | `>`, `<`, `>=`, `<=`, `==`, `!=` | 比较运算   |
| 逻辑与 | `&` 或 `AND`                      | 大小写不敏感 |
| 逻辑或 | `\|` 或 `OR`                      | 大小写不敏感 |
| 逻辑非 | `~` 或 `NOT`                      | 大小写不敏感 |
| 算术  | `+`, `-`, `*`, `/`               | 四则运算   |

***

### factorsScreen()

因子选股，筛选满足条件的股票。

```typescript theme={null}
const stocks = await client.quant.factorsScreen({
  formula: 'RSI(14) < 30',
  market: 'cn',             // 可选
  checkDate: '2024-06-01',  // 可选，默认最新交易日
  symbols: undefined        // 可选，undefined 表示当前市场
});
```

**参数：**

| 参数          | 类型         | 必填 | 说明                   |
| ----------- | ---------- | -- | -------------------- |
| `formula`   | `string`   | 是  | 选股公式                 |
| `market`    | `string`   | 否  | 市场，默认 cn             |
| `checkDate` | `string`   | 否  | 检查日期，默认最新交易日         |
| `symbols`   | `string[]` | 否  | 股票池，undefined 表示当前市场 |

**选股示例：**

```typescript theme={null}
// RSI 超卖
const oversold = await client.quant.factorsScreen({
  formula: 'RSI(14) < 30'
});

// 金叉
const goldenCross = await client.quant.factorsScreen({
  formula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 10))'
});

// 上升趋势
const uptrend = await client.quant.factorsScreen({
  formula: '(CLOSE > MA(CLOSE, 20)) & (MA(CLOSE, 20) > MA(CLOSE, 60))'
});

// 行业筛选（申万行业）
const banks = await client.quant.factorsScreen({
  formula: 'INDUSTRY("银行") & (PE_TTM() < 10)'
});

// 在指定股票池中筛选
const filtered = await client.quant.factorsScreen({
  formula: 'RSI(14) < 30',
  symbols: ['000001', '600519', '000002']
});
```

***

## 行情 (Quotes)

### ohlcv()

获取单个股票的 OHLCV 日线数据。

`market` 可选 `cn`/`hk`/`us`/`global`（默认 `cn`）。获取指数行情（`stockType=index`）时，除 A 股（`cn`）、港股（`hk`）、美股（`us`）外，其余指数统一通过 `global` 查询。

```typescript theme={null}
const data = await client.quant.ohlcv({
  symbol: '000001',
  market: 'cn',
  startDate: '2024-01-01',
  endDate: '2024-06-01'
});

data.forEach(d => {
  console.log(`${d.date}: O=${d.open} H=${d.high} L=${d.low} C=${d.close} V=${d.volume}`);
});
```

**返回类型：**

```typescript theme={null}
interface OHLCVData {
  symbol: string;
  date: string;
  open: number;
  high: number;
  low: number;
  close: number;
  volume: number;
}
```

***

### ohlcvBatch()

批量获取多个股票的 OHLCV 数据。

`market` 可选 `cn`/`hk`/`us`/`global`（默认 `cn`）。获取指数行情（`stockType=index`）时，除 A 股（`cn`）、港股（`hk`）、美股（`us`）外，其余指数统一通过 `global` 查询。

```typescript theme={null}
const data = await client.quant.ohlcvBatch({
  symbols: ['000001', '600519', '000002'],
  market: 'cn',
  startDate: '2024-01-01',
  endDate: '2024-06-01'
});
```

数据按日期（降序）、股票代码排序。

***

### kline()

获取单个股票的 K 线数据，支持多种周期。

```typescript theme={null}
const data = await client.quant.kline({
  symbol: '000001',
  klineType: '5M',
  startDateTime: '2024-01-01 09:30:00',
  endDateTime: '2024-01-01 15:00:00',
  market: 'cn'
});

data.forEach(d => {
  console.log(`${d.datetime}: O=${d.open} H=${d.high} L=${d.low} C=${d.close} V=${d.volume}`);
});
```

**参数：**

| 参数              | 类型       | 必填 | 说明                                                           |
| --------------- | -------- | -- | ------------------------------------------------------------ |
| `symbol`        | `string` | 是  | 股票代码                                                         |
| `klineType`     | `string` | 否  | K 线类型，默认 `1D`，支持 `1M`/`5M`/`15M`/`30M`/`60M`/`1D`/`1W`/`1MO` |
| `market`        | `string` | 否  | 市场，默认 cn                                                     |
| `stockType`     | `string` | 否  | 品种类型，默认 `stock`，支持 `stock`/`etf`/`index`/`sw`                |
| `startDateTime` | `string` | 否  | 开始时间（YYYY-MM-DD HH:MM:SS），未指定时自动推算                           |
| `endDateTime`   | `string` | 否  | 结束时间（YYYY-MM-DD HH:MM:SS）                                    |

**返回类型：**

```typescript theme={null}
interface OHLCVData {
  symbol: string;
  datetime: string;
  open: number;
  high: number;
  low: number;
  close: number;
  volume: number;
}
```

***

### klineBatch()

批量获取多个股票的 K 线数据。

```typescript theme={null}
const data = await client.quant.klineBatch({
  symbols: ['000001', '600519', '000002'],
  klineType: '1D',
  market: 'cn'
});
```

数据按日期（升序）、股票代码排序。

***

### minute()

获取单个股票的分钟数据。

```typescript theme={null}
const data = await client.quant.minute({
  symbol: '000001',
  startDateTime: '2024-01-01 09:30:00',
  endDateTime: '2024-01-01 15:00:00',
  market: 'cn'
});

data.forEach(d => {
  console.log(`${d.datetime}: O=${d.open} H=${d.high} L=${d.low} C=${d.close} V=${d.volume}`);
});
```

**参数：**

| 参数              | 类型       | 必填 | 说明                        |
| --------------- | -------- | -- | ------------------------- |
| `symbol`        | `string` | 是  | 股票代码                      |
| `startDateTime` | `string` | 是  | 开始时间（YYYY-MM-DD HH:MM:SS） |
| `endDateTime`   | `string` | 是  | 结束时间（YYYY-MM-DD HH:MM:SS） |
| `market`        | `string` | 否  | 市场，默认 cn                  |

**返回类型：**

```typescript theme={null}
interface OHLCVData {
  symbol: string;
  datetime: string;
  open: number;
  high: number;
  low: number;
  close: number;
  volume: number;
}
```

***

### minuteBatch()

批量获取多个股票的分钟数据。

```typescript theme={null}
const data = await client.quant.minuteBatch({
  symbols: ['000001', '600519', '000002'],
  startDateTime: '2024-01-01 09:30:00',
  endDateTime: '2024-01-01 15:00:00',
  market: 'cn'
});
```

数据按日期（升序）、股票代码排序。

***

## 交易日历 (Trading Calendar)

<Note>
  支持的市场：`cn`（A 股，含 `sh`/`sz`/`bj`）、`hk`（港股）、`us`（美股）。`global` 无日历源，传入会抛出错误。
</Note>

### calendar()

获取指定区间内的 A 股交易日列表，返回 `{ date }` 数组（按日期升序）。

```typescript theme={null}
const days = await client.quant.calendar({
  startDate: '2026-01-01',
  endDate: '2026-01-31'
});

console.log(days.map((d) => d.date));
// ['2026-01-05', '2026-01-06', ...]
```

| 参数          | 类型       | 必填 | 描述                                                                     |
| ----------- | -------- | -- | ---------------------------------------------------------------------- |
| `startDate` | `string` | 否  | 开始日期 `YYYY-MM-DD`，默认当年 1 月 1 日                                         |
| `endDate`   | `string` | 否  | 结束日期 `YYYY-MM-DD`，默认当年 12 月 31 日                                       |
| `market`    | `string` | 否  | 市场，默认 `cn`，可选 `cn`/`hk`/`us`                                           |
| `exchange`  | `string` | 否  | 交易所（`cn`: `sh`/`sz`/`bj`，`hk`: `hk`，`us`: `us`），默认市场对应交易所（`cn` 为 `sh`） |

***

### calendarCheck()

判断某一天是否为交易日，并返回上一/下一交易日。

```typescript theme={null}
const info = await client.quant.calendarCheck({ target: '2026-01-01' });

console.log(info?.is_trading_day);        // false
console.log(info?.previous_trading_day);  // '2025-12-31'
console.log(info?.next_trading_day);      // '2026-01-05'
```

| 参数         | 类型       | 必填 | 描述                                                                     |
| ---------- | -------- | -- | ---------------------------------------------------------------------- |
| `target`   | `string` | 否  | 待判断日期 `YYYY-MM-DD`，默认今天                                                |
| `market`   | `string` | 否  | 市场，默认 `cn`，可选 `cn`/`hk`/`us`                                           |
| `exchange` | `string` | 否  | 交易所（`cn`: `sh`/`sz`/`bj`，`hk`: `hk`，`us`: `us`），默认市场对应交易所（`cn` 为 `sh`） |

返回字段：`date`、`is_trading_day`、`previous_trading_day`、`next_trading_day`。

***

## 回测 (Backtest)

### backtest()

执行策略回测。

```typescript theme={null}
const result = await client.quant.backtest({
  startDate: '2023-01-01',
  endDate: '2024-01-01',
  symbols: ['000001'],
  market: 'cn',
  entryFormula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 20))',  // 买入信号：MA5 上穿 MA20
  exitFormula: 'CROSSDOWN(MA(CLOSE, 5), MA(CLOSE, 20))',  // 卖出信号（可选）
  initialCash: 100000,  // 初始资金
  commission: 0.0003,   // 佣金费率
  positionSize: 0.2,    // 单个股票最大仓位 20%
  maxPositions: 5,      // 最大持仓股票数量
  cheatOnOpen: false,   // 是否启用 T 日信号当日开盘成交
  autoClose: true,      // 自动平仓
  signalFactors: { rsi: 'RSI(14)', ma20: 'MA(CLOSE, 20)' }  // 额外指标（可选）
});
```

**参数：**

| 参数                    | 类型                       | 必填 | 默认值       | 说明                                                            |
| --------------------- | ------------------------ | -- | --------- | ------------------------------------------------------------- |
| `startDate`           | `string`                 | 是  | -         | 回测开始日期（YYYY-MM-DD）                                            |
| `endDate`             | `string`                 | 是  | -         | 回测结束日期（YYYY-MM-DD）                                            |
| `symbols`             | `string[]`               | 否  | -         | 股票代码列表（不传则需传 filterFormula）                                   |
| `filterFormula`       | `string`                 | 否  | -         | 前置过滤公式                                                        |
| `market`              | `string`                 | 否  | cn        | 市场（cn/hk/us）                                                  |
| `entryFormula`        | `string`                 | 否  | -         | 买入/开仓公式（不传则需传 strategyCode）                                   |
| `strategyCode`        | `string`                 | 否  | -         | 自定义回测策略 Python 源码代码。代码中必须定义 `handle_data(context, datas)` 函数。 |
| `exitFormula`         | `string`                 | 否  | -         | 卖出/平仓公式（结果 > 0 触发卖出）                                          |
| `initialCash`         | `number`                 | 否  | 100000    | 初始资金（元）                                                       |
| `commission`          | `number`                 | 否  | 0         | 佣金费率（如 0.0003 表示万三）                                           |
| `buyCommission`       | `number`                 | 否  | 0         | 买入手续费率（优先于 commission）                                        |
| `sellCommission`      | `number`                 | 否  | 0         | 卖出手续费率（优先于 commission）                                        |
| `minCommissionAmount` | `number`                 | 否  | 0         | 单笔最低手续费金额（元）                                                  |
| `slippage`            | `number`                 | 否  | 0         | 滑点比例（买入价上浮、卖出价下浮）                                             |
| `positionSize`        | `number \| null`         | 否  | 不传/`null` | 单只股票最大仓位比例。不传或传 `null` 表示不限制                                  |
| `maxPositions`        | `number \| null`         | 否  | 不传/`null` | 最大持仓股票数量。不传或传 `null` 表示不限制                                    |
| `minVolume`           | `number`                 | 否  | 100       | 最小买入股数                                                        |
| `autoClose`           | `boolean`                | 否  | true      | 是否在回测结束时自动平仓                                                  |
| `cheatOnOpen`         | `boolean`                | 否  | false     | `true` 时 T 日信号在 T 日开盘成交，`false` 时在 T+1 开盘成交                   |
| `signalFactors`       | `Record<string, string>` | 否  | -         | 指标与因子字典，用于策略计算或返回                                             |

**返回类型：**

```typescript theme={null}
interface BacktestResult {
  success: boolean;
  initial_cash: number;
  final_cash: number;
  total_return: number;
  total_return_pct: number;
  max_drawdown: number;
  profit_factor: number;
  win_rate: number;
  total_trades: number;
  winning_trades: number;
  losing_trades: number;
  trades: Array<{
    id: number;
    symbol: string | null;
    type: string;
    entry_date: string;
    exit_date: string;
    entry_price: number;
    exit_price: number;
    size: number;
    net_pnl: number;
    return_pct: number;
    cumulative_pnl: number;
  }>;
  portfolio_value: Record<string, number>;
  benchmark_value: Record<string, number>;
  benchmark_return_pct: number;
  sharpe_ratio: number;
  alpha: number;
  beta: number;
  max_drawdown_start: string | null;
  max_drawdown_end: string | null;
  daily_returns: Record<string, number>;
  drawdown_series: Record<string, number>;
  error_msg: string | null;
}
```

**使用示例：**

```typescript theme={null}
// 1. 简单金叉策略（只有买入信号）
const result = await client.quant.backtest({
  startDate: '2023-01-01',
  endDate: '2024-01-01',
  symbols: ['000001'],
  entryFormula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 20))'
});

console.log(`总收益: ${result.total_return.toFixed(2)}`);
console.log(`收益率: ${(result.total_return_pct * 100).toFixed(2)}%`);
console.log(`最大回撤: ${(result.max_drawdown * 100).toFixed(2)}%`);
console.log(`胜率: ${(result.win_rate * 100).toFixed(2)}%`);
console.log(`盈亏比: ${result.profit_factor.toFixed(2)}`);
console.log(`交易次数: ${result.total_trades}`);

// 2. 买入和卖出信号都指定
const result2 = await client.quant.backtest({
  startDate: '2023-01-01',
  endDate: '2024-01-01',
  symbols: ['000001'],
  entryFormula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 20))',      // 金叉买入
  exitFormula: 'CROSSDOWN(MA(CLOSE, 5), MA(CLOSE, 20))'    // 死叉卖出
});

// 3. RSI 超卖超买策略
const result3 = await client.quant.backtest({
  startDate: '2023-01-01',
  endDate: '2024-01-01',
  symbols: ['000001'],
  entryFormula: 'RSI(14) < 30',   // RSI 低于 30 买入
  exitFormula: 'RSI(14) > 70'     // RSI 高于 70 卖出
});

// 4. 使用 signalFactors 记录额外指标
const resultIndicator = await client.quant.backtest({
  startDate: '2023-01-01',
  endDate: '2024-01-01',
  symbols: ['000001'],
  entryFormula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 10))',
  exitFormula: 'CROSS(MA(CLOSE, 10), MA(CLOSE, 5))',
  signalFactors: {
    ma5: 'MA(CLOSE, 5)',
    ma10: 'MA(CLOSE, 10)'
  }
});

// 5. 自定义策略
const customCode = `
def handle_data(context, datas):
    for data in datas:
        symbol = data.name
        position = context.portfolio.get_position(symbol)

        if position is None:
            if data.close > data.open:  # 阳线买入
                context.order_target_percent(symbol, 0.2)
        else:
            if data.close < data.open:  # 阴线卖出
                context.order_target_percent(symbol, 0)
`;

const resultCustom = await client.quant.backtest({
  startDate: '2023-01-01',
  endDate: '2024-01-01',
  symbols: ['000001'],
  strategyCode: customCode
});
```

### backtestUpload()

上传 Excel 文件进行回测。使用自己的行情数据（而非系统内置数据源）。

```typescript theme={null}
const result = await client.quant.backtestUpload({
  file: myFile,  // File 对象
  startDate: '2023-06-01',
  endDate: '2024-01-01',
  entryFormula: 'CROSS(MA(CLOSE, 5), MA(CLOSE, 10))',
  exitFormula: 'CROSS(MA(CLOSE, 10), MA(CLOSE, 5))',
  initialCash: 100000,
  commission: 0.0003
});
```

**参数：**

| 参数                    | 类型                       | 必填 | 默认值       | 说明                                          |
| --------------------- | ------------------------ | -- | --------- | ------------------------------------------- |
| `file`                | `File`                   | 是  | -         | Excel 文件（File 对象）                           |
| `startDate`           | `string`                 | 否  | -         | 回测开始日期(YYYY-MM-DD)，指标计算后按此过滤                |
| `endDate`             | `string`                 | 否  | -         | 回测结束日期(YYYY-MM-DD)，指标计算后按此过滤                |
| `entryFormula`        | `string`                 | 否  | -         | 买入/开仓公式（不传则需传 `strategyCode`）               |
| `strategyCode`        | `string`                 | 否  | -         | 自定义回测策略 Python 源码                           |
| `exitFormula`         | `string`                 | 否  | -         | 卖出/平仓公式                                     |
| `initialCash`         | `number`                 | 否  | 100000    | 初始资金（元）                                     |
| `commission`          | `number`                 | 否  | 0         | 佣金费率                                        |
| `buyCommission`       | `number`                 | 否  | 0         | 买入手续费率（优先于 commission）                      |
| `sellCommission`      | `number`                 | 否  | 0         | 卖出手续费率（优先于 commission）                      |
| `minCommissionAmount` | `number`                 | 否  | 0         | 单笔最低手续费金额（元）                                |
| `slippage`            | `number`                 | 否  | 0         | 滑点比例（买入价上浮、卖出价下浮）                           |
| `positionSize`        | `number \| null`         | 否  | 不传/`null` | 单只股票最大仓位比例。不传或传 `null` 表示不限制                |
| `maxPositions`        | `number \| null`         | 否  | 不传/`null` | 最大持仓股票数量。不传或传 `null` 表示不限制                  |
| `minVolume`           | `number`                 | 否  | 1         | 最小买入股数                                      |
| `autoClose`           | `boolean`                | 否  | true      | 是否自动平仓                                      |
| `cheatOnOpen`         | `boolean`                | 否  | false     | `true` 时 T 日信号在 T 日开盘成交，`false` 时在 T+1 开盘成交 |
| `signalFactors`       | `Record<string, string>` | 否  | -         | 指标与因子字典                                     |

**Excel 文件格式：**

| 列名       | 是否必须   | 说明   |
| -------- | ------ | ---- |
| `date`   | 必须     | 交易日期 |
| `open`   | 必须     | 开盘价  |
| `high`   | 必须     | 最高价  |
| `low`    | 必须     | 最低价  |
| `close`  | 必须     | 收盘价  |
| `symbol` | 多标的时必须 | 股票代码 |
| `volume` | 可选     | 成交量  |
| `amount` | 可选     | 成交额  |

支持中文列名自动映射：

| 中文列名                 | 映射到      |
| -------------------- | -------- |
| 日期 / 时间 / 交易日期 / 交易日 | `date`   |
| 开盘 / 开盘价             | `open`   |
| 最高 / 最高价             | `high`   |
| 最低 / 最低价             | `low`    |
| 收盘 / 收盘价             | `close`  |
| 成交量 / 交易量            | `volume` |
| 成交额 / 交易额            | `amount` |
| 代码 / 股票代码 / 证券代码     | `symbol` |

> 自定义字段列名仍须为 ASCII 字符（英文字母、数字、下划线）。

***

## 完整示例

### 技术分析工作流

```typescript theme={null}
import { Reportify } from 'reportify-sdk';

const client = new Reportify({ apiKey: 'your-api-key' });

async function technicalAnalysis() {
  // 1. 获取股票数据
  const ohlcv = await client.quant.ohlcv({
    symbol: '000001',
    startDate: '2024-01-01'
  });

  // 2. 计算多个指标
  const rsi = await client.quant.indicatorsCompute({
    symbols: ['000001'],
    formula: 'RSI(14)'
  });
  
  const macd = await client.quant.indicatorsCompute({
    symbols: ['000001'],
    formula: 'MACD()'
  });

  // 3. 分析最新数据
  const latestRSI = rsi[0]?.rsi;
  const latestMACD = macd[0]?.macd;
  
  console.log(`最新 RSI: ${latestRSI}`);
  console.log(`最新 MACD: ${latestMACD}`);
}

technicalAnalysis();
```

### 选股并回测

```typescript theme={null}
async function screenAndBacktest() {
  // 1. 选股：RSI 超卖
  const oversoldStocks = await client.quant.factorsScreen({
    formula: 'RSI(14) < 30'
  });
  
  console.log(`发现 ${oversoldStocks.length} 只超卖股票`);

  // 2. 对每只股票进行回测
  for (const stock of oversoldStocks.slice(0, 5)) {
    const result = await client.quant.backtest({
      startDate: '2023-01-01',
      endDate: '2024-01-01',
      symbols: [stock.symbol],
      entryFormula: 'CROSS(RSI(14), 30)'  // RSI 上穿 30 买入
    });
    
    console.log(`${stock.symbol}: 收益率 ${(result.total_return_pct * 100).toFixed(2)}%`);
  }
}

screenAndBacktest();
```
