{
 "title": "How to screen Japanese net-net stocks with SQL \u2014 StockQL",
 "description": "Screen Japan-listed stocks for NCAV, Graham-style, double-net, and triple-net thresholds with reproducible SQL and filing checks.",
 "url": "https://stockql.ai/blog/how-to-screen-japanese-net-net-stocks.html",
 "slug": "blog/how-to-screen-japanese-net-net-stocks",
 "published": "2026-09-12",
 "site": "StockQL",
 "contact": "hello@stockql.ai",
 "body_text": "Japanese stock screening\n\nHow to screen Japanese net-net stocks with SQL\n\nA reproducible JPX screen for below-NCAV, Graham-style, double-net, and triple-net candidates, with date-aware statements, current market capitalization, and liquidity checks.\n\nSeptember 12, 2026 \u00b7 15 minute read\n\nIn this guide\n\nDefine the valuation tiers\n\nSet the data contract\n\nRun the screen\n\nRead the live result\n\nUnderstand the Japan-specific data rules\n\nReview the filings\n\nA net-net screen asks whether the stock market values an entire company below the current assets left after every liability is deducted. The arithmetic is short. Building one comparable, current row per company is the real work.\n\nThis guide runs a current screen across StockQL\u2019s active JPX common-share universe. It keeps the financial-statement date, price date, market-cap source, yen units, and trading liquidity visible. The output is a review queue, not a buy list.\n\nEducational screen, not investment advice. A low market value can reflect dilution, restricted assets, weak receivables, obsolete inventory, contingent claims, governance problems, or a business that is consuming cash. Read the current filing before acting on any row.\n\n1. Define the valuation tiers\n\nThis screen uses a transparent NCAV proxy:\n\nNCAV proxy = current assets - total liabilities\nNCAV multiple = NCAV proxy / current market capitalization\n\nIt is a proxy because a strict claim available to common shareholders should also account for preferred equity and noncontrolling interests where they exist. Those fields are not consistently available across the provider\u2019s JPX statements. Missing claims remain unknown; the query never turns them into zero.\n\nLabel in this guide Minimum NCAV multiple Maximum market cap as a share of NCAV\n\nBelow NCAV 1.00\u00d7 100%\n\nGraham-style 1.50\u00d7 66.7%\n\nDouble-net 2.00\u00d7 50%\n\nTriple-net 3.00\u00d7 33.3%\n\nThe 1.50\u00d7 tier is equivalent to paying no more than two-thirds of NCAV, the familiar Graham valuation threshold. \u201cDouble-net\u201d and \u201ctriple-net\u201d are descriptive extensions used here, not standardized accounting terms. Triple-net in this article has nothing to do with a triple-net real-estate lease.\n\n2. Set the data contract before ranking anything\n\nThe screen admits a company only when all of these conditions are true:\n\nThe security is an active, unquarantined common share on JPX and is not marked delisted.\n\nA positive closing price is available.\n\nThe latest eligible annual balance sheet is denominated in JPY, was effective by the price date, and ended no more than 18 months earlier.\n\ncurrent_assets , total_liabilities , and a positive current market_cap are present.\n\nTwenty-session average traded value is calculated from observed closes and volume; it is reported for review, not used to hide illiquid results.\n\nThe date test matters. A fiscal period ending in March was not public in March. StockQL uses the provider\u2019s filing date when it is credible and a conservative lag when the provider merely repeats the period end as the filing date. The query then requires effective_date <= price_date .\n\nStockQL joins JPX prices, company profiles, normalized statements, filing dates, and issuer share counts on a common symbol-and-exchange key. The completeness rules above admit a company only when the accounting facts and current valuation needed by this screen are available together.\n\n3. Run the screen\n\nThe statement below ran unchanged against the live StockQL database. It creates a session-local view, so the filtered rows remain available for inspection and export without adding permanent database objects.\n\nCREATE OR REPLACE TEMP VIEW jpx_ncav_screen AS\nWITH universe AS (\nSELECT symbol, exchange_code, name\nFROM stocks\nWHERE exchange_code = 'JPX'\nAND security_class = 'common'\nAND is_active\nAND NOT is_delisted\nAND quarantined_since IS NULL\n)\nSELECT\nu.symbol,\nu.name,\npx.price_date,\npx.close,\nbal.period_end,\nbal.effective_date,\nbal.currency,\nbal.current_assets,\nbal.total_liabilities,\nmetrics.fetched_at::date AS metrics_fetched,\nmetrics.market_cap,\nbal.current_assets - bal.total_liabilities AS ncav,\n(bal.current_assets - bal.total_liabilities)::numeric\n/ metrics.market_cap::numeric AS ncav_multiple,\nliquidity.avg_traded_value_20d\nFROM universe u\nJOIN LATERAL (\nSELECT p.date AS price_date, p.close\nFROM stock_prices p\nWHERE p.exchange_code = u.exchange_code\nAND p.symbol = u.symbol\nORDER BY p.date DESC\nLIMIT 1\n) px ON px.close > 0\nJOIN LATERAL (\nSELECT\nf.period_end,\nf.effective_date,\nf.currency,\nf.current_assets,\nf.total_liabilities\nFROM stock_financial_periods f\nWHERE f.exchange_code = u.exchange_code\nAND f.symbol = u.symbol\nAND f.statement = 'balance'\nAND f.frequency = 'annual'\nAND f.effective_date <= px.price_date\nAND f.period_end >= px.price_date - INTERVAL '18 months'\nAND f.currency = 'JPY'\nAND f.current_assets IS NOT NULL\nAND f.total_liabilities IS NOT NULL\nORDER BY f.period_end DESC, f.effective_date DESC\nLIMIT 1\n) bal ON true\nJOIN stock_fundamental_metrics metrics\nON metrics.exchange_code = u.exchange_code\nAND metrics.symbol = u.symbol\nAND metrics.market_cap > 0\nLEFT JOIN LATERAL (\nSELECT AVG(recent.close * recent.volume) AS avg_traded_value_20d\nFROM (\nSELECT p.close, p.volume\nFROM stock_prices p\nWHERE p.exchange_code = u.exchange_code\nAND p.symbol = u.symbol\nAND p.date <= px.price_date\nORDER BY p.date DESC\nLIMIT 20\n) recent\n) liquidity ON true;\n\nThe two lateral joins select one price and one eligible balance per company through their indexed symbol and exchange keys. The balance must have been effective by that company\u2019s price date; changing the final threshold cannot bypass that rule.\n\nCount each tier from the unrounded ratio:\n\nSELECT\n(\nSELECT COUNT(*)\nFROM stocks\nWHERE exchange_code = 'JPX'\nAND security_class = 'common'\nAND is_active\nAND NOT is_delisted\nAND quarantined_since IS NULL\n) AS universe,\nCOUNT(*) AS complete_rows,\nCOUNT(*) FILTER (WHERE ncav_multiple >= 1.0) AS below_ncav,\nCOUNT(*) FILTER (WHERE ncav_multiple >= 1.5) AS graham_style,\nCOUNT(*) FILTER (WHERE ncav_multiple >= 2.0) AS double_net,\nCOUNT(*) FILTER (WHERE ncav_multiple >= 3.0) AS triple_net\nFROM jpx_ncav_screen;\n\nThen rank the review set while retaining its dates and liquidity:\n\nSELECT\nsymbol,\nname,\nROUND((market_cap / 1e6)::numeric) AS market_cap_jpym,\nROUND((ncav / 1e6)::numeric) AS ncav_jpym,\nROUND(ncav_multiple, 2) AS multiple,\nCASE\nWHEN ncav_multiple >= 3.0 THEN '3.0+'\nWHEN ncav_multiple >= 2.0 THEN '2.0+'\nWHEN ncav_multiple >= 1.5 THEN '1.5+'\nELSE '1.0+'\nEND AS tier,\nperiod_end,\neffective_date,\nprice_date,\nmetrics_fetched,\nROUND((avg_traded_value_20d / 1e6)::numeric, 1) AS adv20_jpym\nFROM jpx_ncav_screen\nWHERE ncav_multiple >= 1.0\nORDER BY ncav_multiple DESC, symbol\nLIMIT 20;\n\nFor the September 11 snapshot, creating the view took 11 ms, the count query 214 ms, and the ranked query 175 ms. Those timings describe one database snapshot, not a general benchmark.\n\nThe stored market_cap uses StockQL\u2019s current-share validation rather than a period-average diluted count. The query retains metrics_fetched so the valuation observation remains visible beside the price and statement dates.\n\n4. Read the live result\n\nThe snapshot used prices available through September 11, 2026. Current market capitalization was available for 3,749 of 3,776 active JPX common shares; 26 used issuer-filed EDINET share counts where provider data materially disagreed. Applying the price, eligible annual-balance, currency, and accounting-field rules left 3,639 complete rows.\n\nJPX common-share universe 3,776\n\nComplete screen rows 3,639\n\nBelow NCAV \u00b7 \u22651.0\u00d7 138\n\nGraham-style \u00b7 \u22651.5\u00d7 26\n\nDouble-net \u00b7 \u22652.0\u00d7 4\n\nTriple-net \u00b7 \u22653.0\u00d7 0\n\nThe honest triple-net result was zero. Four companies cleared 2\u00d7 and 26 cleared the Graham-style 1.5\u00d7 threshold. Every current share count below either comes from an issuer-filed EDINET count or passes StockQL\u2019s cross-source consistency checks:\n\nSymbol Company Market cap NCAV proxy Multiple Balance / effective Price date ADV20\n\n7034 Prored Partners \u00a53.56bn \u00a510.25bn 2.88\u00d7 2025-10-31 / 2026-01-29 2026-09-11 \u00a510.6m\n\n3189 ANAP Holdings \u00a54.68bn \u00a512.28bn 2.62\u00d7 2025-08-31 / 2025-11-29 2026-09-11 \u00a5183.8m\n\n2961 Nitcho \u00a51.73bn \u00a54.25bn 2.45\u00d7 2025-09-30 / 2025-12-29 2026-09-11 \u00a54.0m\n\n3600 FUJIX \u00a52.37bn \u00a54.76bn 2.01\u00d7 2026-03-31 / 2026-06-29 2026-09-07 \u00a50.5m\n\nMarket capitalization and NCAV are rounded JPY values; the tier uses the unrounded ratio. ADV20 is the mean of close \u00d7 volume over the latest 20 observed sessions. \u201cEffective\u201d is the first date StockQL allows the annual balance in an as-of query.\n\nStockQL uses EDINET , Japan\u2019s official disclosure system, as the issuer source for resolving material share-count disagreements. Unresolved discrepancies are excluded from the screen.\n\nANAP also demonstrates why NCAV is not a synonym for cash. Its fiscal 2025 securities report showed about \u00a517.95 billion of current assets and \u00a55.68 billion of liabilities, but digital assets accounted for roughly \u00a516.25 billion of current assets. A standardized balance-sheet field makes that row comparable enough to find; only the filing explains what the field contains.\n\n5. Understand the Japan-specific data rules\n\nSymbol mapping StockQL maps provider symbols such as 3189.T to symbol = '3189' and exchange_code = 'JPX' at ingestion, so queries use one consistent exchange-aware key.\nCurrency StockQL keeps JPX exchange currency and each normalized statement\u2019s reported currency distinct. The query explicitly requires f.currency = 'JPY' rather than inferring yen from the listing alone.\nStatement availability StockQL retains filing or conservative effective dates for normalized periods. The query rejects an annual statement until it was knowable on the selected price date.\nCurrent equity value StockQL calculates market capitalization from the latest close and current outstanding shares, cross-checks the share count against dated statement or issuer data, and excludes unresolved disagreements.\nTrading units and liquidity JPX standardized domestic common-stock trading units at 100 shares. A low quoted price can still require a meaningful lot, and a wide NCAV discount can coexist with very little daily traded value. The screen reports 20-session average traded value in yen for that reason.\n\nFor primary-source review, use the JPX listed-company search , the exchange\u2019s timely-disclosure resources , and the issuer\u2019s latest securities report. The JPX trading-unit guide documents the 100-share convention.\n\n6. Treat every result as the start of diligence\n\nFor each high-ranked row, reconcile the standardized numbers to the latest filing and ask:\n\nHow much of current assets is unrestricted cash rather than receivables, inventory, securities, or digital assets?\n\nWere there share issues, options, conversions, buybacks, or treasury-stock changes after the balance date?\n\nAre there lease obligations, guarantees, preferred claims, noncontrolling interests, or litigation outside the proxy?\n\nIs the company profitable, or how quickly is it consuming the reported surplus?\n\nCould a realistic position be entered and exited at the observed traded value?\n\nChange the threshold without changing the definition:\n\nSELECT *\nFROM jpx_ncav_screen\nWHERE ncav_multiple >= 2.0\nORDER BY ncav_multiple DESC, symbol;\n\nOr export the complete review set from the same PostgreSQL session:\n\n\\copy (SELECT * FROM jpx_ncav_screen ORDER BY ncav_multiple DESC, symbol) TO 'jpx-ncav-screen.csv' CSV HEADER\n\nA current screen is not a historical backtest. Moving the price date backward while keeping today\u2019s market cap, share count, classifications, or universe membership creates look-ahead. For the point-in-time rules a cross-sectional test requires, start with the StockQL backtesting guide and preserve every fact\u2019s effective date.\n\nWhat StockQL contributes\n\nThe formula in this guide is ordinary SQL. The durable work sits beneath it: provider-symbol mapping, normalized financial periods, explicit currencies, conservative effective dates, retained source facts, current valuation fields, and enough price history to expose liquidity.\n\nThat separation keeps the screen auditable. StockQL maintains the research database; PostgreSQL, a notebook, or your own agent can decide what to test next.\n\nSee how StockQL handles the data \u2192"
}
