User

एक-दूसरा, गहरा-Phantom-Fill-Bug मिला असली-Discovery: friend के-established-fix (occurrence-check-per-k_atr) को-implement-करने-के-बाद, मैंने-genuinely-अपने-controlled-test-में एक-दूसरा-bug पकड़ा — occurrence-check-genuinely-pullback_zone_high=breakout+k×A

Asked by CNI Follower · 14 minutes ago · 05-09-2026

1) `max(target_level, actual_touched_price)` वाला fix कितना सही है?

- Bullish case में आप असल में ये enforce कर रहे हैं:

- आप एक pre-defined limit/target level तय करते हैं (e.g. `entry_limit = breakout - k_atr * ATR` जैसा कुछ)।

- Bar के अंदर price path कुछ भी हो, fill price कभी भी उस limit से बेहतर (यानी buy के लिए उससे नीचे) नहीं हो सकता।

- अगर price उस level तक नहीं पहुँचा तो fill ही नहीं होगा; अगर पहुँचा, तो fill को ज़्यादा से ज़्यादा उस limit पर मानेंगे, उससे नीचे नहीं।

- अगर `actual_touched_price` = उस bar का low (bullish buy के लिए), तो:

- अगर `low <= target_level`:

- `max(target_level, low) = target_level` → fill यहीं पर; “limit पर भरा” model होता है।

- अगर `low > target_level`:

- मतलब target छुआ ही नहीं; अच्छी implementation में trade ही नहीं होना चाहिए। (आपने अगर कोई अलग logic रखा है तो बस ये ensure करें कि ‘fill’ तभी माने जब `low <= target_level`)

- Standard backtest practice में limit-order मॉडल प्रैक्टिकली यही करता है:

- Pre-decided limit price तय करो।

- अगर bar का low (buy के लिए) उस limit से नीचे/बराबर गया, तो मानो order fill हो गया, और execution price = limit price (ना इससे बेहतर, ना worse, जब तक slippage model अलग से न लगाएँ)।

इस नज़र से देखें तो आपका `entry_price = max(target_level, actual_touched_price)` एक defensible, conservative fix है — बशर्ते:

- आप पहले ये चेक कर रहे हों कि “price ने target_level छुआ ही या नहीं” (e.g. `if low <= target_level` for buy)।

- और उसके बाद ही `entry_price` assign कर रहे हों।

इसका फायदा:

- Phantom “super-deep” fills गायब हो जाते हैं।

- Entry logic deterministic और parameter-stable रहता है (k_atr बढ़ाने से fills खुद-ब-खुद better नहीं होते)।

तो, established quant/backtest practice के हिसाब से:

- हाँ, `max(target_level, actual_touch)` जैसा construct (सही touch-check के साथ) बिल्कुल ठीक और defensible approach है।

---

2) क्या target_level को हटाकर सिर्फ़ actual_touched_price को entry मानें?

इसे दो angle से देखिए:

A. अगर आप कह रहे हैं: “k_atr सिर्फ़ occurrence zone define करेगा, entry हमेशा ‘bar के अंदर जहाँ तक price गया उसके best point’ पर होगी”

- Bullish pullback buy में इसका मतलब होगा:

- Zone: `[breakout, breakout - k_atr*ATR]`

- Occurrence: जैसे ही price इस zone में कहीं भी आया, trade माना गया।

- Entry: हमेशा उस zone के अंदर सबसे low price पर (i.e. bar का low अगर zone में है)।

- ये असल में “ex-post best fill” है — practically realizable नहीं, क्योंकि:

- Real life में आप पहले से ये तय करके order लगा सकते हैं:

- या तो fixed limit (e.g. `breakout - 0.5*ATR`)

- या कोई rule-based dynamic execution (जैसे VWAP, TWAP, या “first touch” आदि)

- लेकिन आप कभी भी ये नहीं जानते कि बार के अंदर future path में आगे सबसे नीचे कौन-सा point आएगा; backtest जो सबसे अच्छा low चुन रहा है, वह hindsight है।

- इस तरह का model backtest को optimistically biased बना देगा:

- आप हर बार zone के अंदर “सबसे best possible” fill ले रहे हैं, जो practically किसी भी realistic order-model से better है।

- Sharpe, win-rate, drawdown सब over-optimistic लगेंगे।

B. Standard practice क्या कहती है?

- Signal/occurrence और execution को अलग रखते हैं:

1. Signal / Occurrence Rule

- e.g. “Breakout के बाद price X ATR के अंदर pullback करे” → ये सिर्फ़ trade की eligibility define करता है।

2. Execution Rule

- Fixed limit (e.g. `breakout - k_entry*ATR`), या

- Next-bar open market order, या

- stop/stop-limit का कोई clear deterministic rule।

- Execution rule हमेशा forward-looking और pre-specified होना चाहिए; backtest bar की अंदरूनी path से ex-post “सबसे अच्छा” price नहीं चुन सकता।

इसलिए:

- Target/limit level को पूरी तरह हटाकर “सिर्फ़ actual_touched_price = best low” को entry बनाना standard / defensible practice नहीं है (जब तक आप कोई बहुत specific, realistic execution algorithm detail नहीं करते, और तब भी “best low” लगभग कभी भी justified नहीं होगा)।

- Better है:

- k_atr से या तो target/limit को ही define कीजिए,

- या zone और limit दोनों के लिए अलग-अलग deterministic functions रखिए, लेकिन execution हमेशा किसी explicit order price पर हो (जैसे `entry_limit`), न कि बाद में चुना गया “सबसे अच्छा low/high”।

आपका वर्तमान `max(target_level, actual_touch)` approach ठीक इसी conservative principle पर बैठता है, इसलिए ये ज्यादा standard-aligned है बनिस्बत “pure actual_touched_price (best low)” वाले model के।

---

3) पुराने Parameter Perturbation (n=87, rising Sharpe) results का status क्या है?

आपने जो double-bug identify किया, उसमें core problem ये थी कि:

- Occurrence condition और entry-price formula दो अलग-अलग levels यूज़ कर रहे थे।

- k_atr बढ़ाने से:

- Occurrence easier होती गई (zone expand या shift हो रहा था),

- Entry price गहरी होती गई (phantom-improvement in fill),

- यानी higher k_atr पर systematically “better-than-realistic” fills, जो पूरी तरह bug-induced edge है।

इससे दो serious biases आते हैं:

1. Parameter-dependent optimism:

- जैसे-जैसे k_atr बढ़ रहा था, आपका model कृत्रिम रूप से better fills दे रहा था।

- Sharpe का उठना बहुत संभावना से इसी phantom fill की वजह से था, न कि असली strategy robustness की वजह से।

2. Comparability का टूटना:

- Low k_atr vs high k_atr runs अब apples-to-apples comparison नहीं रहे, क्योंकि execution model practically अलग-अलग हो गया था (एक तरफ कम artificial improvement, दूसरी तरफ ज़्यादा)।

इसलिए, research-standard/established standpoint से:

- पहले के सारे parameter-perturbation नतीजों को genuinely invalid / contaminated मानना चाहिए।

- उन्हें सिर्फ़ “bugged v1 experiment log” की तरह archive कर दीजिए, लेकिन किसी भी serious inference (optimal k_atr, robustness, Sharpe improvements) के लिए use नहीं करना चाहिए।

- Strategy को अब bug-fixed execution model के साथ पूरा experiment दोबारा चलाना चाहिए:

- Same universe, same sample period, same costs और slippage assumptions,

- लेकिन नए, correct fill logic के साथ।

इसके बाद ही:

- नए Sharpe vs k_atr curve पर भरोसा करना logical होगा।

- अगर bug-fixed runs में भी वही qualitative pattern (e.g. Sharpe monotonic या hump-shaped) दिखे, तो उसे real effect मानने की कुछ credibility मिलेगी; वरना मानना होगा कि पहले का “edge” असल में bug था।

---

संक्षिप्त actionable summary:

1. `entry_price = max(target_level, actual_touched_price)`

- अगर आप पहले सही तरीके से “did price touch target?” चेक कर रहे हैं (e.g. `if low <= target_level` for buy), तो ये limit-order style implementation है और standard, defensible, और conservative है।

2. Target_level हटाकर pure “best actual_touched_price” को entry बनाना

- Practically ex-post optimization है, standard नहीं है, और over-optimistic bias लाएगा।

- Recommended नहीं है, जब तक आप कोई बहुत स्पष्ट, realistic execution algorithm define न कर दें — और तब भी “best low/high” approach गलत है।

3. पुराने parameter-perturbation (n=87) results

- Double-bug के बाद इन्हें research-grade standpoint से invalid मानिए।

- Strategy को corrected fill logic के साथ पूरी तरह re-run करना चाहिए; पुराने Sharpe improvements को सिर्फ़ bug-artefact के तौर पर archived रखिए, conclusions के लिए नहीं।

If you have any further queries, please connect with us on 022-6290-10141 (Timings : 09.00 AM to 05.00 PM) or you can email us on info@cniinfoxchange.com