Factor expression syntax & the 85-factor dictionary
The previous guide covered how to screen; this one covers how to write conditions: expression structure, operators, unit traps, and a lookup-ready 85-factor dictionary. Written to be copied and run.
1. There is only one expression shape
A factor expression is an `intersect([...])` call whose brackets hold a comma-separated list of conditions, meaning all must hold (AND logic):
intersect([factor1 op value, factor2 op value, ...])
# Example: PE between 0 and 20, ROE above 15%, dividend yield above 2%
intersect([PE_TTM > 0, PE_TTM < 20, ROETTM > 15, DividendRatioTTM > 2])- Only `intersect` (AND) — there is no `union` / `or`
- No `between` / `in` / nested brackets — express ranges with two comparisons
- A factor may appear twice (as with `PE_TTM > 0` and `PE_TTM < 20`) — the standard way to exclude negative PE
2. Six comparison operators (that is all)
| Operator | Meaning | Example |
|---|---|---|
| > | greater than | PE_TTM > 0 |
| < | less than | PE_TTM < 20 |
| >= | greater or equal | ROETTM >= 15 |
| <= | less or equal | TotalMV <= 5000000000 |
| = | equal (rare) | — |
| != | not equal (rare) | — |
Simple expressions are allowed: measured support for `factorA > factorB * k`, e.g. the cash-collection template `GoodsSaleServiceRenderCash > OperatingRevenue * 0.9`.
3. Unit rules (the two that bite)
# OK: ROE > 15%, market cap < 5 bn CNY, dividend yield > 2%
intersect([ROETTM > 15, TotalMV < 5000000000, DividendRatioTTM > 2])
# WRONG: percentage written as a decimal (read as 0.15%)
intersect([ROETTM > 0.15])- Percentages take plain numbers: `ROETTM > 15` means "ROE above 15%" (not `0.15`); `DividendRatioTTM > 2` means yield above 2%
- Money is in CNY: `TotalMV` is in CNY — 5 bn CNY is `5000000000`
- Ratios are plain multiples: `PE_TTM` / `PB` / `PS_TTM` / `CurrentRatio` take the number directly
4. All 85 verified factors (grouped)
Listed by group; the "note" column marks verified fields.
4.1 Valuation (6)
| Factor | Meaning | Unit | Note |
|---|---|---|---|
| PE_TTM | Price/earnings TTM | x | Always guard with > 0 |
| PB | Price/book | x | No PB_TTM — writing it errors out |
| PS_TTM | Price/sales TTM | x | Market cap / revenue TTM |
| TotalMV | Total market value | CNY | The only market-cap factor |
| DividendRatioTTM | Dividend yield TTM | % | Plain number (> 3 means 3%) |
| DividendTTM | Total dividend TTM | CNY | Amount, not yield |
4.2 Profitability (most used)
| Factor | Meaning |
|---|---|
| ROETTM | Return on equity TTM (most used) |
| ROE | Return on equity (current basis) |
| ROECut | Ex-non-recurring ROE (health check) |
| ROEWeighted | Weighted ROE |
| ROIC | Return on invested capital |
| GrossIncomeRatioTTM | Gross margin TTM |
| NetProfitRatioTTM | Net margin TTM |
| NPParentCompanyOwners | Net profit attributable (current) |
| NPParentCompanyOwnersTTM | Net profit attributable TTM |
| OperatingRevenue | Total operating revenue |
| GrossProfitTTM | Gross profit TTM |
| NPDeductNonRecurringPL | Net profit ex-non-recurring (health check) |
38 profitability factors in total, including expenses, EBIT, per-share metrics and 3-year CAGR.
4.3 Growth (partial)
| Factor | Meaning | Unit |
|---|---|---|
| NPParentCompanyYOY | Net profit YoY | % |
| OperatingRevenueGrowRate | Revenue growth | % |
| TotalAssetGrowRate | Total asset growth | % |
| NPPCCGrowRate3Y | Net profit 3-yr CAGR | % |
| ORComGrowRate3Y | Revenue 3-yr CAGR | % |
| NetAssetGrowRate | Net asset growth | % |
4.4 Balance sheet (partial)
| Factor | Meaning | Unit | Use |
|---|---|---|---|
| DebtAssetsRatio | Debt-to-assets | % | Health check: > 70% is leveraged |
| DebtEquityRatio | Debt-to-equity | % | Leverage inflates ROE |
| CurrentRatio | Current ratio | x | Short-term solvency |
| QuickRatio | Quick ratio | x | Stricter solvency |
| TotalShareholderEquity | Total shareholders equity | CNY | ROE denominator |
| InterestBearDebt | Interest-bearing debt | CNY | Real debt pressure |
| Goodwill | Goodwill | CNY | Impairment risk |
| BillAccReceivable | Notes & accounts receivable | CNY | Common blow-up area |
| ARTDays | Receivable turnover days | days | > 180 means slow collection |
| Inventories | Inventory | CNY |
32 balance-sheet factors in total, including turnover ratios, working capital and contract liabilities.
4.5 Cash flow (partial)
| Factor | Meaning | Unit |
|---|---|---|
| NetOperateCashFlowTTM | Operating cash flow TTM | CNY |
| NetOperateCashFlow | Net operating cash flow | CNY |
| NetOperateCashFlowYOY | Operating cash flow YoY | % |
| FCFF | Free cash flow to firm | CNY |
| FCFE | Free cash flow to equity | CNY |
| GoodsSaleServiceRenderCash | Cash received from sales | CNY |
14 cash-flow factors in total.
4.6 Market (2)
| Factor | Meaning | Unit |
|---|---|---|
| ClosePrice | Close price | CNY |
| TurnoverRate | Turnover rate | % |
5. Fourteen copy-paste templates
From the in-project factor dictionary measured record (verified 2026-08-31).
# 1) Low valuation + high profitability + dividend
intersect([PE_TTM > 0, PE_TTM < 20, ROETTM > 15, DividendRatioTTM > 2])
--limit 20 --orderby ROETTM --desc
# 2) Graham-style (conservative)
intersect([PE_TTM > 0, PE_TTM < 15, PB < 1.5, DebtAssetsRatio < 50, CurrentRatio > 1.5])
--limit 20 --orderby PE_TTM --asc
# 3) Growth (double-high)
intersect([PE_TTM > 0, PE_TTM < 25, NPParentCompanyYOY > 25,
OperatingRevenueGrowRate > 20, ROETTM > 12])
--limit 20 --orderby NPParentCompanyYOY- Healthy cash flow: `intersect([PE_TTM > 0, NetOperateCashFlowTTM > 0, ROETTM > 10, DebtAssetsRatio < 60])`
- Low leverage: `intersect([PE_TTM > 0, DebtAssetsRatio < 30, InterestBearDebt < 1000000000, ROETTM > 10])`
- Small-cap value: `intersect([PE_TTM > 0, PE_TTM < 25, TotalMV < 5000000000, ROETTM > 10])` + `--orderby TotalMV --asc`
- Large-cap quality: `intersect([PE_TTM > 0, TotalMV > 100000000000, ROETTM > 12, DividendRatioTTM > 2])`
- Below-book recovery: `intersect([PB > 0, PB < 1, ROETTM > 5, NetOperateCashFlowTTM > 0])` + `--orderby PB --asc`
- High gross margin: `intersect([PE_TTM > 0, GrossIncomeRatioTTM > 50, ROETTM > 15])`
- Receivable risk scan (reverse use): `intersect([BillAccReceivable > 0, ARTDays > 180, ROETTM < 5])`
Combination principle: always include at least one "quality" factor (`ROETTM` or `NetOperateCashFlowTTM`), otherwise pure low-valuation screening tends to surface cheap-but-poor companies.
6. Eight pitfalls (measured, from the official dictionary)
| # | Pitfall | Detail |
|---|---|---|
| 1 | PE_TTM needs > 0 | Loss-makers have negative PE and appear as "low PE" |
| 2 | Case sensitive | A-shares use PE_TTM; HK uses PeTTM — a wrong case errors out |
| 3 | No PB_TTM | Writing PB_TTM is not available |
| 4 | Market cap in CNY | TotalMV 5 bn CNY is 5000000000 |
| 5 | Only TotalMV | TotalMarketCap / MarketCap / MV are unavailable |
| 6 | Yield = DividendRatioTTM | DividendTTM is the amount; DivTTM is the HK spelling |
| 7 | Percentages take numbers | ROETTM > 15 means 15%, not 0.15 |
| 8 | Filings lag | TTM uses the latest disclosed report — mind the disclosure date |
7. Code formats (prefix selects the market)
| Prefix | Market | Example |
|---|---|---|
| sh | Shanghai | sh600519 |
| sz | Shenzhen (incl. ChiNext) | sz300750 |
| bj | Beijing Stock Exchange | bj430047 |
| hk | Hong Kong | hk00700 |
| us | United States | usAAPL |
Combine with `--market`: hs (A-shares) / hk / us.
FAQ
No. The only form is intersect([...]) and everything inside is AND. For OR-like behaviour, issue several requests and merge the results.
Use two conditions: intersect([PE_TTM > 10, PE_TTM < 20]). between is not supported.
Percentage factors use the percentage number directly. Writing 0.15 is read as 0.15%, which returns almost nothing.
Extremes can come from basis issues (TTM vs current, non-recurring items, leverage). Cross-check with ROECut, other ROE bases and DebtEquityRatio — see guide "Factor screening basics", sections 4-5.
Last updated: 2026-09-29
Factor list, 8 pitfalls and 14 templates from measured verification notes (85 factors, verified by live runs on 2026-08-31); expression structure and strategies cross-checked against ashareapi /v1/screen live responses (2026-09-29).