TradeTech Analytics

All strategies · Longbow Weekly review page

Longbow Weekly: strategy documentation

Update 31 Oct 2026 (version 2). Re-tested on a price history that includes every stock that traded, delisted ones included: 18.9% a year at 1x costs, 15.0% at 2x and 11.0% at 3x over 2007 to September 2025 against the index at 10.8%; the earlier 25% was inflated by missing stocks. Read the survivorship-free re-test, comparison and Kelly analysis. The figures below are the earlier version (Dhan price history without delisted stocks, 4%/yr allowance) and are kept for the record.

Version 1.0.1. Frozen 2026-10-19. Owner: Prashant Maheshwari. Status: forward paper run active, no real money, no orders. Everything in this document describes what the code in research/weekly/ actually does. If the code and this document ever disagree, the code is the specification and this document has a bug: report it.


1. One-page summary

Item Value
Idea Buy the Nifty 500 stocks that have risen the most steadily over the past ~9 months (skipping the last month), but only while the overall market is above its 26-week average. Otherwise hold cash.
Universe Nifty 500 members on the decision date, at least ₹5 crore traded per day, at least 60 weeks of price history
Holdings Up to 15 stocks, equal weight (6.67% each), long only
Rebalance Every 4th week; exits (stock drops out, or market filter off) can happen in any week
Decision time Friday close (or last session of the week)
Execution First session open of the next week
Costs assumed Delivery charges + 0.2% slippage per side; stress at 2x and 3x
Paper capital ₹5,00,000
Development result (2016 to 2025-09) 24.8% a year, worst fall 16.7%, Sharpe 1.40 (at 2x costs and a 4% a year survivorship haircut). Nifty 500 index: 13.3% and 34.4%
Hold-out result (2025-10 to 2026-10-16), opened once -1.4% (standard costs), worst fall 13.8%. Nifty 500: -3.3%
Honest status Candidate. The hold-out did not confirm a profit. The paper run is the only clean out-of-sample test left.

2. Data

2.1 Sources

2.2 Cleaning and adjustment (data.py)

2.3 Data limits you must know


3. The rules, exactly

3.1 Eligibility on a decision date t (end of week t)

A stock can be bought or held if all are true: 1. It is a Nifty 500 member on that date. 2. It has a valid weekly close in week t, and a valid open exists in week t+1 (so it can be traded). 3. ADV over the last 4 weeks is at least ₹5 crore a day. 4. It has at least 60 weeks of price history.

3.2 Score

For each eligible stock, with weekly closes C:

momentum = C[t-4] / C[t-39] - 1          (return from 39 weeks ago to 4 weeks ago; the latest 4 weeks are skipped)
risk     = standard deviation of the weekly returns of the last 26 weeks
score    = momentum / risk

Higher is better. Stocks with a missing score are ignored. Ties are broken by array order (practically never matters).

3.3 Market filter

regime = Nifty 500 weekly close > average of the last 26 weekly closes. * If regime is false at decision week t, no stock is eligible: the target is 100% cash, and every held stock is sold at the next open. This applies in any week, not only on rebalance weeks. * While cash, the account earns the RBI repo rate minus 1.5% a year, spread weekly. (Only used for the idle share of the account.)

3.4 Which weeks are rebalance weeks

Let j0 be the first decision week. Rebalance weeks are j0, j0+4, j0+8, .... For the paper run the first decision is the week ending Friday 2026-10-23, so rebalance weeks end on 2026-10-23, 11-20, 12-18, 2027-01-15, 02-12, 03-12, 04-09, 05-07, 06-04 and so on (a holiday on Friday only changes the date label, not the week).

3.5 What happens on a rebalance week

  1. Rank all eligible stocks by score, best first.
  2. Keep every currently held stock that is still eligible and ranks within the top 22 (1.5 x 15, rounded down).
  3. Fill the remaining slots, from the best-ranked unheld stocks down, until 15 names are chosen or no eligible stocks are left.
  4. Give every chosen stock the same target weight of 1/15 = 6.67% of account value, whether or not 15 names were found. Unused slots stay in cash. Winners are trimmed and laggards topped up back to equal weight.
  5. Stocks not chosen are sold completely.

3.6 What happens on a non-rebalance week

3.7 Execution

3.8 Costs (per side, as a fraction of the traded value)

Item Buy Sell
Brokerage (average assumption) 0.030% 0.030%
Securities transaction tax 0.100% 0.100%
Exchange transaction charge 0.00325% 0.00325%
SEBI turnover fee 0.0001% 0.0001%
Stamp duty 0.015% none
Depository (DP) charge none ₹15 + 18% GST = ₹17.70 per stock sold
Slippage 0.20% 0.20%

Buy side about 0.35% (including slippage); sell side about 0.33% plus ₹17.70. All cost items are multiplied by the cost multiple (1x standard, 2x and 3x stress). These are estimates until reconciled with a contract note; Dhan's actual delivery brokerage may be lower.

3.9 What the strategy does not do

No stop-losses (exits are rank-based or filter-based), no volatility scaling, no sector caps, no shorting, no leverage, no options, no intraday trading, no price-impact model, no taxes. Round 2 tested stops and volatility scaling and they added nothing, so they were left out.

3.10 Edge cases

Situation Behaviour
Market holiday on Friday Week still ends on its last session; decision once the week is over
Last weekly bar still in progress The paper run ignores it until the week is over
Stock has no price in the week Not eligible; if held, sold at the next open it has
Stock leaves the Nifty 500 Not eligible from its effective date; sold at the next open
Stock is suspended or delisted Not handled by the simulation (zero return while no price). In live use, exit manually and record the loss
Split, bonus, demerger Adjusted away in the simulation; in real life the broker adjusts the holding
Fewer than 15 eligible stocks Fewer positions, weight still 6.67% each, rest in cash
Market filter flips off then on All sold at the first open after the flip; new purchases only on the next rebalance week
Price circuit limits or very thin trading Not modelled; see section 9

4. How it was built and tested (the history you should know)

4.1 Process

  1. Scope. 14 weekly-bar ideas were proposed. Ten could be tested with price and volume data: momentum and 52-week highs, low volatility, trend following (moving average, Donchian, SuperTrend), a price-reaction stand-in for post-earnings drift, base breakouts, market structure, EMA support, anchored VWAP, weekly fair-value gaps, RSI/MACD. Two more were studied as events (index rebalancing) and pairs. Four could not be tested honestly for lack of data: quality and value factors, true post-earnings drift, event-driven and merger arbitrage, volatility dispersion.
  2. Windows. Development 2016-01-01 to 2025-09-30, split into train (2016 to 2021) and validation (2022 to 2025-09). A hold-out from 2025-10-01 was sealed.
  3. Round 1. 597 combinations (idea variants x three market-filter settings), each at 1x/2x/3x costs and 0/4/8% survivorship haircut. Screen: CAGR above 10% and worst fall under 20% at 2x costs plus 4% haircut. One combination passed.
  4. Round 2. 288 focused momentum combinations: four ranking types, 10/15/20 names, four market-filter versions, stock trailing stop (none, 20%, 30%), volatility scaling (off/on). 25 passed both periods. They cluster on one plateau: risk-adjusted momentum (39 or 52 weeks, skip 4), 10 to 20 names, filter on the 26- or 30-week average. Stops and volatility scaling did not help, so the simplest version was frozen: risk-adjusted 39-week, 15 names, filter on the 26-week average.
  5. Checks on the chosen rule. Cost and haircut stress, start-date sensitivity, two random-pick nulls, a walk-forward re-selection test, and White's reality check.
  6. Hold-out. Opened once on 2026-10-19 at the owner's explicit instruction (ledger: holdout_ledger.json).
  7. Paper run started the same day.

4.2 Development results (candidate, 2x costs, 4% haircut)

Window CAGR Worst fall Sharpe
Full 2016 to 2025-09 24.8% 16.7% 1.40
Train 2016 to 2021 25.3% 16.7% 1.44
Validation 2022 to 2025-09 23.3% 15.3% 1.31
Nifty 500 price index 13.3% 34.4% 0.85

4.3 Stress (full development window)

Costs Haircut CAGR Worst fall
1x 0% 32.4% 13.8%
1x 4% 29.0% 14.1%
2x 0% 28.1% 14.7%
2x 4% 24.8% 16.7%
3x 4% 20.5% 21.9%
3x 8% 17.2% 24.6%
5x 8% 8.3% 38.0%

4.4 Calendar years (2x, 4%)

2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 (to Sep)
+8.1% +24.0% -10.5% +1.3% +32.6% +128.4% -9.3% +81.0% +28.7% +0.5%

Two years (2021, 2023) do most of the work. This is the single most important weakness to keep in mind.

4.5 Other checks

4.6 The hold-out (opened once)

2025-10-01 to 2026-10-16 (55 weeks) Return Worst fall
Candidate, standard costs (paper settings) -1.4% 13.8%
Candidate, 2x costs + 4% haircut -7.0% 15.8%
Candidate, 3x costs + 8% haircut -12.5% 18.4%
Nifty 500 price index -3.3% 13.1%
Random 15 + same filter (40 runs) -14.1% average (sd 4.5%)

Market filter was on in 56% of weeks (cash in 44%). The candidate beat 98% of the random runs. Monthly returns at standard costs: Oct 2025 +2.2, Nov +1.1, Dec -1.2, Jan 2026 -6.4, Feb +0.3, Mar +0.3 (index -9.3), Apr +0.4 (index +7.9), May -1.6, Jun +0.3, Jul -4.6, Aug +7.9, Sep +0.4, Oct +0.2.

Correction added 2026-10-20: the hold-out total depends on the rebalance calendar. The strategy rebalances every fourth week, so the result depends on which of four weekly "phases" the cycle starts on. The -1.4% above is for the phase set by a 2016-01 start. Re-running the same rule with the cycle shifted by one, two or three weeks gave +5.3%, +0.6%, +1.5% and -1.4% over the same 55 weeks (standard costs): a range of about 7 points, all better than the index's -3.3%. So "did not confirm a profit" overstated the case: the honest statement is "between -1.4% and +5.3% at standard costs depending on phase, still far from a clear confirmation". Phase luck is a real property of any monthly strategy. A possible future design (a new version, not applied here) is to split the account into four equal sleeves that rebalance in different weeks, which removes the phase choice. The forward paper run uses one fixed phase (first rebalance 2026-10-23).

Reading: the ranking showed skill against random picks and the filter limited the fall, but there was no profit, and 55 weeks cannot separate skill from luck. The hold-out is now spent: it cannot be re-run with changed settings.

4.7 Other ideas, in one line each

Low volatility, trend following, anchored VWAP, EMA support, market structure, fair-value gaps and RSI/MACD had raw returns of 5% to 30% a year but drawdowns of 33% to 53% (or little return) at 2x costs: none passed the drawdown screen. Base breakouts lost money. Index-rebalancing effects were worth roughly 2% to 3% a year at best. Pairs showed no edge after costs.


5. How the paper run works

File Meaning
events.log One line per run: data date, week end, equity, positions, filter ON/OFF, number of next orders. "waiting" = no completed week yet
equity.csv Weekly paper account value in ₹ (from 5,00,000), share invested, Nifty 500 level
trades.csv Completed round trips: symbol, entry and exit dates, price return (before charges), approximate ₹ P&L
positions.csv Current holdings, shares, entry date and price, last close, value
orders_next.csv BUY (about 6.7% of equity each) and SELL orders for the next open. Empty on most weeks
signals_latest.csv Top-30 ranking now. Names 1 to 15 are targets; 16 to 22 are kept if held

6. How to read the results for a decision

6.1 Principles

  1. The back-test is a hypothesis. The paper run is the only clean out-of-sample evidence left.
  2. Judge on weeks and rebalances, not days. Nothing before 26 weeks and 7 rebalances is evidence.
  3. A good back-test followed by a weak hold-out is the typical signature of optimism in the back-test. Do not respond by tuning on the hold-out; that turns it into training data.
  4. One year of a 15-stock portfolio has ±15% of pure noise. A single result, good or bad, proves little.

6.2 Check dates

6.3 Pass, hold and stop criteria (written now, before any paper result)

Measured on the paper equity curve at standard (1x) costs, versus the Nifty 500 price index and cash (repo minus 1.5%, about 4.5% a year):

Review PASS to the next stage HOLD (keep paper, no money) STOP (abandon or redesign as a new version)
26 weeks Worst fall under 20% and no worse than the index's; return at least equal to cash Anything between Worst fall above 25% from peak, or more than 10 points behind the index while the market filter was on for most of the period
52 weeks Worst fall under 20%; annualised return at least 5 points above cash after costs; at least 4 of the 12 months positive and no single month contributing more than half of the total gain; not more than 5 points behind the index in total Return positive but below the pass bar Worst fall above 25% from peak; or more than 10 points behind the Nifty 500

Passing both reviews means permission to consider a small live pilot, not an instruction to go live.

6.4 If it passes: a cautious live path (owner decides)

6.5 What the numbers cannot tell you


7. Weekly operating routine (for the paper run today and a live pilot later)

Friday or Saturday morning 1. Open the strategy-review page or events.log: check that the latest line shows the data date of this Friday (or the last session) and no "stale" warning. 2. Read orders_next.csv. If empty: nothing to do. If it has SELL or BUY lines: these are the next open's orders. 3. Read signals_latest.csv for context (top 15 are the targets).

Monday, after 9:15 open 4. Paper: nothing to do, the replay fills at the open price automatically next evening. 5. Live pilot (later): place the sells first, then the buys, using limit orders near the open; record price and quantity in a log.

Monday evening 6. Check that positions.csv matches the broker positions (live pilot) and that cash is as expected.

Monthly 7. Compare equity with the index; note months where the filter was off.

Never 8. Change a rule because of one bad or good week. Add a stock by hand. Skip a SELL because "it will recover".


8. Change control


9. Risks, honestly

Risk Why it matters here
Overfitting / selection bias About 900 variants were examined; the chosen rule is the best of a plateau, not a pre-registered hypothesis. Reality-check p is 0.047
Dependence on a few strong years 2021 (+128%) and 2023 (+81%)
Market filter lag and whipsaw It was off in 44% of the hold-out weeks and missed the April 2026 rebound
Rebalance-phase luck A monthly cycle starting on a different week gave hold-out totals from -1.4% to +5.3%; one fixed phase is a draw from that range
Survivorship One third of past index members missing in 2016
Momentum reversals January and July 2026 in the hold-out
Concentration 15 stocks, 6.7% each: one stock can cost 1% of the account in a single day
Liquidity and impact ₹33,000 tickets are small, but small-cap names can gap and hit circuits
Costs and taxes Turnover about 4.8 times a year; STT on both sides; short-term capital gains tax not modelled
Operational Late data, a missed order, or a stale index series. The paper run warns if data is more than 5 days old
Behavioural Abandoning a plan after a drawdown that the plan expected

10. Known issues and fix log


11. Questions people ask

Why weekly and not daily? Weekly bars cut noise, cut turnover, and match how momentum is usually measured. Daily versions were not tested for this strategy.

Why skip the latest 4 weeks? Stocks that have just risen sharply tend to give back part of the move over the next month (short-term reversal). Skipping that month is the standard "12-1" convention (here 9-1).

Why divide by volatility? Two stocks with the same return are not equally good if one got there smoothly and the other lurched. Dividing favours the smooth one. It was better than raw momentum in testing (Round 2).

Why the 26-week market filter? It keeps the account out of broad sell-offs (for example 2020). It costs missed rebounds.

Why 15 stocks? A compromise: enough to diversify, few enough for the ranking to matter; 10 and 20 names gave broadly similar results (10 had larger falls, 20 slightly lower returns).

Why monthly rebalancing? Weekly rebalancing raised turnover by about half (6.0 versus 4.0 times a year in the grid) and did worse after costs.

Will it make money next year? Unknown. The development result was strong; the hold-out year was slightly negative at standard costs and positive relative to the index. Only the paper run can add evidence.

Is this advice? No. It is research and education. Not investment advice; the publisher is not a registered investment adviser or research analyst.


12. Where everything is

Path What
research/weekly/data.py Weekly data builder
research/weekly/engine.py Portfolio simulator and costs
research/weekly/families.py Signal generators for all tested ideas
research/weekly/run.py, round2.py Round 1 and round 2 grids
research/weekly/final.py Detailed checks on the chosen rule
research/weekly/events_pairs.py Index-change event study and pairs
research/weekly/holdout.py, holdout_ledger.json The one-time hold-out run and its log
research/weekly/paper.py, nightly_paper.sh, paper_spec.json Paper run
research/weekly/results/ Result tables (grid, round 2, family summary, hold-out)
data/paper/weekly_mom/ Paper run outputs
Review page https://strategyreview.tradetechanalytics.com/strategies/weekly-nifty500-study.html

Reproduce the development numbers: python research/weekly/run.py, round2.py, final.py (development data only). Do not run holdout.py again: it refuses to.


13. Execution audit: how to confirm trades follow the signals (added 2026-10-20)

What you can check, and where. The review page has an "Execution audit" section and a trade log with these columns: signal date (the Friday close when the ranking was computed), entry fill (the next week's first session), entry price, rank on the signal date, exit signal, exit fill, exit price, and the exit reason. The downloadable fills_*.csv lists every transaction (including top-ups and trims) with signal rank and score.

Checks run automatically on every build (they can be re-run from the CSV files): 1. Every transaction happens after its signal (fill date later than signal date; the typical gap is 3 days, Friday to Monday). 2. Every new purchase is for a stock ranked inside the target list on its signal date (new entries rank 1 to 15; top-ups of names already held can rank lower). 3. Every full exit has a documented reason: rank fell below the keep limit (22), no longer eligible, or the market filter turned off. 4. Every execution price is a real traded price: the stock's open on the fill date lies inside that day's low to high. 5. Never more than 15 names held at once, and entry dates precede exit dates. 6. The trade ledger reconciles to the equity curve: an independent rupee accounting of every fill (cash, positions, costs paid from cash) ends within about 1.4% of the simulator's equity.

Extra proof for the forward paper run. * One signal snapshot file per decision week (paper_signals/<name>/signals_log/YYYY-MM-DD.csv) is written the evening of the decision and never overwritten. It holds the top-40 ranking with scores, the target weights and the action for each name. * signals_ledger.jsonl chains each file's SHA-256 hash to the previous one with the time it was generated. The review page has a button that re-hashes every file in your browser and compares the chain. * The nightly job commits the snapshots to GitHub; GitHub's server time on the commit is an independent timestamp that the signal existed before Monday's open. * Every night the system re-derives each past decision from the data and compares it with the stored snapshot. Any difference is reported as a failed check. * Check "each snapshot was written before the session in which it was traded opened" compares the ledger's generation time with 09:15 IST on the fill date. * Limits. A paper run proves internal consistency and timing; it cannot prove that real orders would have filled at those prices. When trading real money, reconcile these logs with the broker's contract notes. Tests that replay history (not generated live) correctly show the timing check as failed: only live-generated snapshots can pass it.

Fix log. 2026-10-20: the first ledger version used the signal date's own session as a possible fill date for holiday-shortened weeks; fixed so only sessions strictly after the signal count (the audit caught this: it failed the "after its signal" check until fixed).


Research and education only. Hypothetical and back-tested results have inherent limitations and do not guarantee future results. Not investment advice; the publisher is not presented as a SEBI-registered investment adviser or research analyst.