DEV Community

William Wang
William Wang

Posted on

Rules-Based Investing for Developers: How I Automated My Investment Decisions

Last year, I merged a PR that cost me $4,200.

Not at work — in my brokerage account. I'd been so deep in a sprint that I forgot to check on a position that had hit my mental stop-loss two weeks earlier. By the time I remembered, the damage was done.

The irony hit me hard: I would never deploy code without automated tests, but I was managing my life savings with "I'll remember to check it later."

That night, I started building a rules-based investment system using the same engineering principles I apply to software every day. And honestly, it's been one of the most impactful side projects I've ever done — not because it made me rich, but because it made me consistent.

Developers Already Think Like Investors (They Just Don't Know It)

Consider how similar these mindsets are:

Software Engineering Investing
Don't ship without tests Don't buy without due diligence
Avoid premature optimization Avoid market timing
Reduce technical debt Avoid excessive financial leverage
Code review before merge Checklist before purchase
Automated CI/CD pipeline Systematic investment process
Rollback strategy Stop-loss / exit criteria
Single responsibility principle Circle of competence

If you can architect a distributed system, you can absolutely architect an investment framework. The mental models transfer directly.

My Investment Rules as Code

Here's how I translated my investment principles into something that feels familiar to a developer's brain:

class InvestmentDecision:
    """
    A rules-based investment evaluation system.
    Every potential investment must pass ALL checks before capital is allocated.
    """

    def __init__(self, ticker: str, analysis: dict):
        self.ticker = ticker
        self.analysis = analysis
        self.passed_checks = []
        self.failed_checks = []

    def check_circle_of_competence(self) -> bool:
        """Can I explain this business to a 10-year-old?"""
        return self.analysis.get("business_understood", False)

    def check_competitive_moat(self) -> bool:
        """Does this company have a durable competitive advantage?"""
        moat_signals = [
            self.analysis.get("high_switching_costs", False),
            self.analysis.get("network_effects", False),
            self.analysis.get("brand_power", False),
            self.analysis.get("cost_advantage", False),
            self.analysis.get("regulatory_barrier", False)
        ]
        return sum(moat_signals) >= 2  # At least 2 moat sources

    def check_financial_health(self) -> bool:
        """Is the balance sheet strong enough to survive a recession?"""
        return (
            self.analysis.get("debt_to_equity", 999) < 0.5 and
            self.analysis.get("current_ratio", 0) > 1.5 and
            self.analysis.get("free_cash_flow_positive_years", 0) >= 3
        )

    def check_valuation(self) -> bool:
        """Am I paying a reasonable price?"""
        intrinsic_value = self.analysis.get("estimated_intrinsic_value", 0)
        current_price = self.analysis.get("current_price", float('inf'))
        margin_of_safety = 1 - (current_price / intrinsic_value)
        return margin_of_safety >= 0.25  # At least 25% discount

    def check_position_sizing(self, portfolio_value: float) -> bool:
        """Does this fit within my risk management rules?"""
        proposed_size = self.analysis.get("proposed_investment", 0)
        max_position = portfolio_value * 0.05  # 5% max per position
        return proposed_size <= max_position

    def evaluate(self, portfolio_value: float) -> dict:
        """Run all checks and return a go/no-go decision."""
        checks = {
            "circle_of_competence": self.check_circle_of_competence(),
            "competitive_moat": self.check_competitive_moat(),
            "financial_health": self.check_financial_health(),
            "valuation": self.check_valuation(),
            "position_sizing": self.check_position_sizing(portfolio_value)
        }

        all_passed = all(checks.values())

        return {
            "ticker": self.ticker,
            "decision": "BUY" if all_passed else "PASS",
            "checks": checks,
            "failed": [k for k, v in checks.items() if not v]
        }
Enter fullscreen mode Exit fullscreen mode

When I look at a potential investment now, I literally run it through this mental framework. Every check must pass. No exceptions, no "I'll make an exception this time because the stock is hot."

The If-Then Rules That Changed Everything

The most powerful concept I borrowed from programming is the if-then rule. In code, we don't leave decisions to feelings. We define conditions and actions.

Here are my actual investment if-then rules:

IF market drops > 20% AND watchlist stock hits target price
THEN deploy up to 3% of cash reserves into that position

IF any single position grows to > 8% of portfolio
THEN trim back to 5% regardless of conviction

IF original investment thesis breaks (moat erodes, management changes)
THEN sell entire position within 5 trading days

IF I feel "urgent" about any trade
THEN wait 48 hours before acting (the FOMO circuit breaker)

IF a stock I own drops > 30% from my purchase price
THEN re-evaluate thesis — if thesis intact, do nothing; if broken, sell

IF I haven't reviewed a position in > 90 days
THEN schedule review before any new purchases
Enter fullscreen mode Exit fullscreen mode

Notice something? These rules are completely mechanical. They don't care about my mood, the latest headline, or what some influencer said on social media. They're my personal CI/CD pipeline for investment decisions.

Why I Built KeepRule

As I developed this system for myself, I realized the hardest part wasn't writing the rules — it was sticking to them and having them accessible when I needed them most.

My rules started in a Notion doc, then moved to a spreadsheet, then to sticky notes on my monitor. None of these worked consistently. I'd forget to check them, or I'd be on my phone at night and not have access.

That frustration led me to build KeepRule. The core idea: a platform where you can organize investment principles from master investors (Buffett, Munger, Howard Marks, Peter Lynch) alongside your own personal rules, accessible anytime.

But the feature that surprised me most was how many users wanted to start with established principles before creating their own. It turns out most people don't know where to begin when building an investment framework. Having a curated library of battle-tested principles from investors with 50+ year track records gives you a foundation to build on.

The Portfolio Monitoring Script

Beyond the buy/sell framework, I wrote a simple monitoring system:

def weekly_portfolio_review(portfolio: list, rules: dict) -> list:
    """
    Sunday evening portfolio health check.
    Returns a list of actions needed.
    """
    actions = []

    for position in portfolio:
        # Check concentration risk
        if position["weight"] > rules["max_position_weight"]:
            actions.append({
                "type": "TRIM",
                "ticker": position["ticker"],
                "reason": f"Position weight {position['weight']:.1%} exceeds "
                          f"max {rules['max_position_weight']:.1%}",
                "target_weight": rules["max_position_weight"]
            })

        # Check thesis freshness
        days_since_review = (today() - position["last_review"]).days
        if days_since_review > rules["max_days_without_review"]:
            actions.append({
                "type": "REVIEW",
                "ticker": position["ticker"],
                "reason": f"Last reviewed {days_since_review} days ago",
                "deadline": today() + timedelta(days=7)
            })

        # Check if original thesis still holds
        if position.get("thesis_broken"):
            actions.append({
                "type": "SELL",
                "ticker": position["ticker"],
                "reason": "Original investment thesis no longer valid",
                "urgency": "HIGH"
            })

    return actions
Enter fullscreen mode Exit fullscreen mode

Every Sunday evening, I spend 30 minutes running through this review. It's not automated trading — it's automated discipline. The script tells me what to look at; I make the decisions.

What I Learned: The Parallels Are Deeper Than You Think

After a year of rules-based investing, here are the insights that surprised me:

1. Tests Prevent Regressions — In Code and In Portfolios

In software, tests catch regressions before they reach production. In investing, rules catch emotional decisions before they reach your brokerage account. My 48-hour FOMO rule alone has saved me from at least five bad trades.

2. Premature Optimization Is the Root of All Evil

Knuth said it about code. It's equally true for investing. Trying to time the market perfectly is premature optimization. Dollar-cost averaging is the O(n) solution that beats the O(1) solution you'll never actually find.

3. Code Review Makes Everything Better

I started sharing my investment theses with two friends — essentially "code review" for investment decisions. The quality of my analysis improved dramatically. When you know someone will read your reasoning, you think harder.

4. Refactoring Is Necessary

My investment rules from two years ago were too complex — 23 rules that overlapped and sometimes contradicted each other. I refactored them down to 12 clear, non-overlapping rules. Just like code, simpler is better.

Getting Started: Your First Investment Rules

If you're a developer who invests (or wants to start), here's my suggested starter framework:

STARTER_RULES = {
    # Entry rules
    "understand_business": True,        # Can you explain it simply?
    "positive_free_cash_flow": True,    # Is it actually making money?
    "reasonable_debt": True,            # Debt/equity < 0.5
    "max_position_size": 0.05,          # Never more than 5% in one stock

    # Exit rules
    "thesis_break_sell": True,          # Sell if your reason for buying breaks
    "max_loss_review": 0.30,            # Review at 30% loss (don't auto-sell)

    # Behavioral rules
    "fomo_cooldown_hours": 48,          # Wait 48h on any "urgent" trade
    "review_frequency_days": 90,        # Review each position quarterly
    "max_trades_per_month": 4           # Limit activity to prevent overtrading
}
Enter fullscreen mode Exit fullscreen mode

Start with these nine rules. Follow them for three months. Then refine based on what you learn about yourself. The best system is one you'll actually follow.

You can also explore proven investment frameworks on KeepRule — it's built specifically to help investors organize and follow principles from master investors and their own experience.

The Bottom Line

We'd never write production code without version control, tests, and review processes. Why do we manage our financial futures with gut feelings and hot tips?

Rules-based investing isn't about removing human judgment — it's about channeling it. You still decide which rules to follow. You still make the final call. But you make that call within a framework that protects you from your worst impulses.

The code we write at work follows a process. The decisions we make with our money deserve the same rigor.

Start with your rules. Write them down. Follow them consistently. Debug when something goes wrong. Iterate and improve.

You already know how to do this. You've been doing it in your IDE every day. Now apply it where it matters most.


William Wang is the founder of KeepRule, helping investors build systematic, rules-based investment frameworks. He's been writing code for over a decade and investing for almost as long — and finds the overlap between the two more useful every year.

Top comments (0)