Financial Calculations & Valuation Intermediate

Automated 9-Point Piotroski F-Score Fundamental Value Screener in Python

Calculate Joseph Piotroski's 9-point F-Score in Python across Profitability, Leverage/Liquidity, and Operating Efficiency to separate value traps from winners.

#pandas

Problem Statement

Buying low P/B or low P/E stocks blindly often traps investors in dying companies. Piotroski's 9 binary accounting tests score financial health from 0 to 9 (8–9 = Strong Value).

Formula / Core Logic

Profitability (4 pts): ROA>0, OCF>0, Delta_ROA>0, OCF>Net_Income Leverage (3 pts): Delta_Debt<0, Delta_Current_Ratio>0, No_Dilution Efficiency (2 pts): Delta_Gross_Margin>0, Delta_Asset_Turnover>0

Installation

pip install pandas
piotroski-f-score-9-point-value-screener-python.py
def calculate_piotroski_fscore(curr, prev):
    # curr and prev are dicts with keys: roa, ocf, net_income, lt_debt_ratio, current_ratio, shares, gross_margin, asset_turnover
    score = 0
    score += int(curr['roa'] > 0)
    score += int(curr['ocf'] > 0)
    score += int(curr['roa'] > prev['roa'])
    score += int(curr['ocf'] > curr['net_income'])  # Accrual quality
    score += int(curr['lt_debt_ratio'] < prev['lt_debt_ratio'])
    score += int(curr['current_ratio'] > prev['current_ratio'])
    score += int(curr['shares'] <= prev['shares'])
    score += int(curr['gross_margin'] > prev['gross_margin'])
    score += int(curr['asset_turnover'] > prev['asset_turnover'])
    rating = 'STRONG_VALUE' if score >= 8 else ('WEAK_TRAP' if score <= 3 else 'MODERATE')
    return {'Piotroski_F_Score': score, 'Rating': rating}

Get the Complete 100+ Python Quant & Automation Bundle

Instant lifetime access to all production-ready scripts, valuation models, and trading bots ($19).

Buy Full Bundle on Gumroad ($19) →

Frequently Asked Questions

Q: Why is `OCF > Net_Income` one of the most important checks?

It verifies that accounting profits are backed by real operating cash inflow rather than aggressive revenue accruals.