Prop firm consistency rule and news trading rule, explained

8 min readMetaKit

You hit the profit target on day six. Drawdown never got close. Then the review comes back: failed, because one day made up 45% of your profit. Or passed, but a payout is denied because a trade closed ninety seconds after a CPI print you didn't know was scheduled.

Drawdown rules get all the attention because they end accounts loudly. The prop firm consistency rule and the news trading rule end them quietly, after the hard part is done, and usually by post-hoc review rather than a live breach. Here's how each is measured and how to watch your own numbers before the firm does.

Usual disclaimer: "many firms" and "a common setup" throughout. Your firm's terms are the only version that counts.

The prop firm consistency rule

The rule: no single trading day may account for more than X% of your total profit at the time you're evaluated. A common range is 30% to 50%. Some firms apply it only during the evaluation, some only to payouts on the funded account, some to both.

The point of it, from the firm's side, is to stop one lucky oversized punt passing a challenge. The effect, from your side, is that it changes what a good day means.

A worked example

Say the target is $2,000 profit and the cap is 40%. You've made $1,100 over five ordinary days. On day six gold moves and you close $900.

Total: $2,000. Target hit. Best day: $900, which is 45% of $2,000. You've failed the consistency rule on the day you passed the target.

The only fix is to keep going. For a $900 best day to sit under 40%, total profit needs to reach at least $900 / 0.40 = $2,250. So you need another $250 of profit, spread across days that are each smaller than $900, without breaching drawdown along the way.

And note the trap inside the trap: a second big day doesn't help. If day seven is another $900, total is $2,900, best day is still $900, ratio is 31%. Fine. But if day seven is $1,200, best day is now $1,200 and the ratio is 37.5% of $3,200. Still fine, but you needed a bigger total to absorb it. The cap punishes the outlier, whichever day it lands on.

How it changes behaviour

Three practical consequences:

  1. You can't stop at the target. A big day extends the challenge instead of ending it. Budget for that.
  2. Position sizing has to be boring. Not because small size is virtuous, but because a consistent size produces consistent days, and the rule is literally measuring consistency of days.
  3. You need to know your ratio every day. It's arithmetic on your own history, so there's no excuse for finding out at review time. The script below does it.

Some firms also run a lot-size consistency rule: your largest position can't exceed some multiple of your average. Same idea, applied to volume instead of profit. If your firm has one, the script needs a second loop over volume.

The prop firm news trading rule

The rule: no opening or closing positions within N minutes before and after a high-impact news event. A common window is a few minutes each side; some firms go wider. Some only restrict opening, some restrict both, and some allow the trade but void any profit made inside the window.

Two things about this rule bite people who've read it carefully.

"High impact" is whatever the firm's calendar says. Not yours, not the one in your terminal. Firms typically publish which calendar they use and which impact tier counts. If they don't, ask, and keep the answer.

A copied or automated entry lands in the window without you noticing. Your EA sees a setup at 14:28 and fires. Your copier mirrors a master whose firm has no news rule (or who isn't on a prop account at all). Neither system knows there's a release at 14:30. The trade opens, the firm's review pulls the timestamp, and you're explaining a trade you never clicked. The copy trading and prop firms post covers the mitigation: put the copier into monitor state across the window so it closes with the master but opens nothing new.

Stop-loss and take-profit hits inside the window are a grey area. Many firms exempt them, since you didn't act. Some don't. This is a clause worth reading twice, because a stop that was placed hours earlier is exactly the kind of "close" a review might flag.

The rules nobody mentions until they matter

Minimum trading days. Many challenges require you to trade on at least a handful of distinct days before you can pass, regardless of profit. "Trade" usually means at least one position opened and closed that day. Combined with the consistency rule this is the firm saying, in two different ways, that one good day isn't a track record.

Weekend holding. Some firms forbid positions held over the weekend (commonly on the evaluation, sometimes on funded too). If your strategy holds swing trades, this rule alone decides which firm you pick.

Lot-size limits. A cap on lot size per position or per symbol, scaled to account size. Covered in the copy trading post, because copiers are the easiest way to break it.

Computing your consistency ratio from deal history

The ratio is best-day profit divided by total profit, where "day" is the firm's day. That last part is where DIY calculations go wrong.

The API returns deal timestamps in UTC. Most firms define a day by their broker's server time, which shifts with daylight saving, or by a stated timezone. A trade closed at 23:30 in one timezone is tomorrow in another, and moving one trade across a day boundary changes your best day. The server time post explains how to find the right offset; the script takes it as a parameter.

import os
from collections import defaultdict
from datetime import datetime, timedelta
 
import requests
 
BASE = "https://api.metakit.cloud"
HEADERS = {"Authorization": f"Bearer {os.environ['METAKIT_KEY']}"}
 
ACCOUNT_ID = 2
CHALLENGE_START = "2026-08-01"
CAP = 0.40                              # the firm's cap, as a fraction
FIRM_UTC_OFFSET = timedelta(hours=3)    # the firm's daily reset timezone
 
 
def fetch_deals(account_id: int, start: str) -> list[dict]:
    deals, page = [], 1
    while True:
        res = requests.get(
            f"{BASE}/v1/accounts/{account_id}/deals",
            params={"from": start, "page": page, "limit": 100},
            headers=HEADERS,
        ).json()
        deals.extend(res["data"])
        if page >= res["total_pages"]:
            return deals
        page += 1
 
 
def daily_pnl(deals: list[dict]) -> dict[str, float]:
    days: dict[str, float] = defaultdict(float)
    for d in deals:
        if d["type"] not in ("buy", "sell"):
            continue        # deposits, credits: not trading profit
        utc = datetime.fromisoformat(d["time"].replace("Z", "+00:00"))
        firm_day = (utc + FIRM_UTC_OFFSET).date().isoformat()
        days[firm_day] += d["profit"] + d["commission"] + d["swap"] + d["fee"]
    return days
 
 
days = daily_pnl(fetch_deals(ACCOUNT_ID, CHALLENGE_START))
total = sum(days.values())
best_day, best = max(days.items(), key=lambda kv: kv[1])
ratio = best / total if total > 0 else float("inf")
 
print(f"total profit: {total:,.2f}")
print(f"best day:     {best_day} {best:,.2f} ({ratio:.0%} of total, cap {CAP:.0%})")
 
if ratio > CAP:
    print(f"FAIL: total must reach {best / CAP:,.2f} before this passes")
else:
    room = CAP * total / (1 - CAP)
    print(f"largest single day you can add today: {room:,.2f}")

A few notes on what it's doing. Entry deals carry zero profit and exit deals carry the realised amount, so summing every deal's profit per day gives the right daily figure without needing to pair them up (the deals explainer covers why). Commission, swap, and fee are added because most firms measure net profit, and a day's swap on a held position can move the ratio. Balance deals are skipped: a deposit is not a profitable day, whatever the raw sum says.

The last line is the number you actually want each morning. If today's gain is g and total profit so far is T, the rule holds when g / (T + g) is at or under the cap, which rearranges to g at most cap × T / (1 − cap). With T at $1,500 and a 40% cap, that's $1,000: the largest day you can have today without needing to extend the challenge.

Deal history is cached for about a minute server-side, so run this once a day, not in a loop.

Alerting when a day approaches the cap

Once you know today's ceiling, the alert is an equity monitor that fires when the day's gain gets close to it. The equity_percent metric measures change from the equity captured when the monitor was armed, so arm it at the firm's daily reset and the baseline is that day's starting equity.

curl -X POST https://api.metakit.cloud/v1/monitors \
  -H "Authorization: Bearer $METAKIT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "account_id": 2,
        "name": "Consistency ceiling",
        "metric": "equity_percent",
        "comparator": "above",
        "threshold": 1.6,
        "rearm_mode": "once",
        "channel": "telegram",
        "channel_config": { "bot_token": "123456:ABC...", "chat_id": "-100123456789" }
      }'

Here 1.6 is 80% of a $1,000 ceiling on a $50k account, expressed as a percent. Recompute the threshold each morning from the script's output and PATCH it. When it fires, you've made most of what today can safely make; the choice is to stop or to accept that you're extending the challenge.

Pair it with the drawdown monitors you should already have. Full accounts get three monitors; a read-only account gets one, so if that's what you've connected, the daily drawdown alert wins and the consistency check stays a morning script. Delivery options and payloads are in the monitor reference.

The consistency rule is the only prop firm rule that punishes you for a day going well. Know your ceiling before the session starts, and a big day stops being a surprise in either direction.