Re: Some of my indicators and ea's free

81
PTR777 wrote: Sun Feb 08, 2026 7:35 pm Peek++ oscillator v2
PTR777 strikes again. Outstanding work, I really like the added Histogram as well as the smoothing enhancements.

I had to feature this on our Daily Downloads today!

These users thanked the author Jimmy for the post (total 3):
PTR777, simon_n3z, BeatlemaniaSA
List of our most powerful reversal indicators | Guide to the "All Averages" Filters (ADXvma, Laguerre etc.)
Using Fibonacci "numbers" for indicator settings 💡
How to draw Fibonacci Extensions easily | The best way to draw Support & Resistance

Re: Some of my indicators and ea's free

85
lapigna wrote: Sun Apr 19, 2026 6:03 pm Yes, it works well. Could you please add also the option to have the alert every candle close?
I thank you in advance in any case.
Different version and histo only
These users thanked the author PTR777 for the post (total 9):
Krunal Gajjar, Jimmy, FXchaos, lapigna, mazibee, enthusiastiAIuser, elvenso, BeatlemaniaSA, Tur005

Re: Some of my indicators and ea's free

87
PTR777 wrote: Sun Apr 19, 2026 8:12 pm Different version and histo only
Updated it so the histogram bars auto-adjust their width, and arrows are added (on the main chart) when the histogram changes colour/direction. ;)

Thanks, PTR777, for your excellent indicator codes. :) :thumbup:
These users thanked the author BeatlemaniaSA for the post:
PTR777
Millionaire Maker - “Amateurs chase. Professionals wait. Legends wait with a plan.”

BEATS V5 - "Enjoy The Quiet Between Trades”
Improve Your Trading Psychology - No fear, no doubt
Ultimate Risk Management - Maximize Your Trades
Supply and Demand Course - Learn Supply and Demand
Believe That You Can - Believe That You Can

Re: Some of my indicators and ea's free

88
Hi PTR777, I hope you don't mind that I asked Claude to give me a detailed, in-depth analysis of the indicator and suggest any improvements, if necessary, to further enhance it. This is how I get to understand and learn what an indicator does and attempts to achieve. This what it came back with:

Code: Select all

I'll do a thorough pass across every layer of the indicator — logic, math, performance, and robustness.

---

## 1. Core Signal Logic

### 1.1 Membrane Potential Calculation

The potential is derived as:

```
potential = (pre - post) / ATR(14)
```

then squashed through a sigmoid and centred at zero:

```
MembranePotential = Sigmoid(potential × PotentialAmplifier) - 0.5
```

**Issues:**

- **Sigmoid saturation.** With `PotentialAmplifier = 10`, even tiny MA crossovers produce potentials near ±0.5, permanently saturating the sigmoid. This makes `MembranePotential` almost always near its extremes, rendering the threshold comparison nearly binary and insensitive to the *magnitude* of the crossover. A value of 2–4 would give the sigmoid room to breathe and produce genuinely graded output.
- **ATR normalisation is correct in principle** but uses a fixed period of 14 hardcoded inside `OnCalculate`. This should be an exposed input — different instruments and timeframes have very different volatility regimes.
- **Hull MA construction is only half-complete.** A proper Hull MA requires a final WMA over `sqrt(period)` bars applied to the `2×WMA(n/2) - WMA(n)` result. The current code skips that final smoothing step, meaning what it labels "HullMA" is actually just a double-WMA (DWMA), which is less smooth and more lag-reduced than a true HMA.

### 1.2 Neurotransmitter Accumulation

```
Neurotransmitter[i] = Neurotransmitter[i+1] * decay_rate
...
if(fireUp || fireDown)
    Neurotransmitter[i] += MathAbs(MembranePotential[i])
```

**Issues:**

- **Double-decay bug.** The decay is applied *twice* per bar. Look at the code carefully — the first application is:
  ```
  Neurotransmitter[i] = Neurotransmitter[i+1] * NeurotransmitterDecay;
  ```
  Then later the adaptive block *overwrites* it:
  ```
  Neurotransmitter[i] = Neurotransmitter[i+1] * decay_rate;
  ```
  The first assignment is completely wasted and misleading. Only the second one survives. This is a latent bug — if the adaptive block is ever refactored or reordered, the first assignment will silently take effect with the wrong decay rate.

- **Neurotransmitter feeds back into SynapticWeight via `delta`**, but because the sigmoid is nearly always saturated (see 1.1), `MembranePotential` is almost always ≈ ±0.5, making `delta` predominantly a function of `Neurotransmitter` rather than signal strength. The plasticity mechanism becomes mostly a ramp rather than a genuine Hebbian-style adaptive weighting.

### 1.3 Synaptic Weight & Threshold

```
base_threshold = SynapticThreshold × (1 + SynapticWeight[i]) / 2
```

With `SynapticWeight` clamped to `[0.1, 0.9]`, `base_threshold` ranges between `SynapticThreshold × 0.55` and `SynapticThreshold × 0.95`. This is a reasonable adaptive band, but:

- **Weight is initialised to 0.5 only at the oldest bar.** All other bars derive their weight from the forward-propagation chain. On a full recalculation (`prev_calculated == 0`), this is fine. But on the live bar, `SynapticWeight[0]` is derived from `SynapticWeight[1]` plus a delta — correct. However there is **no warm-up guard**: the first `PostsynapticPeriod` bars will have unreliable MA values (MT4 returns 0 for insufficient history), silently poisoning the weight chain from the very beginning of history.

---

## 2. Repainting & Bar-0 Behaviour

As noted in the v1.4 analysis, bar 0 repaints on every tick. More subtly:

- **The arrow transition check uses `i >= 1`**, which is correct for avoiding arrow repainting. However, `start_bar = prev_calculated - 1` means on incremental updates only bar 0 (and sometimes bar 1) are recalculated. If a transition occurs at bar 1 on the *previous* tick and bar 1's signal then changes (which can happen if `NeuralTimeframe != PERIOD_CURRENT` and the referenced timeframe bar is still open), an arrow drawn at bar 1 will **not** be removed — `DrawArrow` will just reposition it, but if the fire condition flips off, no deletion occurs. A stale arrow can remain on the chart.

**Fix needed:** The arrow drawing loop should explicitly delete an arrow object for bar `i` if neither `fireUp` nor `fireDown` is true for that bar (and an object for that time already exists).

---

## 3. Multi-Timeframe (MTF) Handling

```
int shift = iBarShift(NULL, NeuralTimeframe, time[i]);
```

- `iBarShift` with `exact=false` (the default) will return the nearest bar if `time[i]` falls in a gap (weekend, holiday, broker gap). This is generally safe but can cause **multiple current-chart bars to map to the same MTF bar**, producing identical `MembranePotential` values across a run of bars — giving the false appearance of a sustained signal when it is really just one MTF bar being repeated.
- When `NeuralTimeframe == PERIOD_CURRENT`, `iBarShift` is called unnecessarily on every bar. A simple guard (`if NeuralTimeframe == PERIOD_CURRENT, shift = i`) would save significant overhead, especially with `SignalDepth = 500`.

---

## 4. Performance

### 4.1 `iMA` and `iATR` call count

For each bar in the loop, with `UseHullMA = true`, the indicator makes **5 calls** to `iMA` + 1 call to `iATR` = **6 indicator calls per bar**. Over 500 bars that is 3,000 calls per `OnCalculate` invocation, and `OnCalculate` fires on every tick. On busy pairs this is a meaningful CPU load.

**Improvement:** Use `IndicatorCreate` / `CopyBuffer` (MT5-style) or pre-cache MA arrays with `ArrayCopySeries` to batch-fetch values rather than calling `iMA` bar-by-bar in a loop.

### 4.2 `ObjectsTotal` scan in `DeleteAllArrows`

```
int total = ObjectsTotal(0, 0, OBJ_ARROW);
for(int i = total - 1; i >= 0; i--)
{
    string name = ObjectName(0, i, 0, OBJ_ARROW);
    if(StringFind(name, arrowPrefix) == 0)
        ObjectDelete(0, name);
}
```

This is called only in `OnDeinit` so it is not a hot path. However, on a chart with many objects it still iterates everything. Maintaining an internal `string arrowNames[]` registry would make cleanup O(n arrows) rather than O(total chart objects).

### 4.3 `ArrayResize` on every tick

```
ArrayResize(MembranePotential, rates_total);
ArrayResize(Neurotransmitter,  rates_total);
ArrayResize(SynapticWeight,    rates_total);
```

`ArrayResize` on every tick when `rates_total` hasn't changed is a no-op internally but still incurs a function call and size-check overhead. Cache the last known size and only resize when `rates_total` changes:

```mql4
static int lastRatesTotal = 0;
if(rates_total != lastRatesTotal)
{
    ArrayResize(MembranePotential, rates_total);
    ArrayResize(Neurotransmitter,  rates_total);
    ArrayResize(SynapticWeight,    rates_total);
    lastRatesTotal = rates_total;
}
```

---

## 5. Signal Quality

### 5.1 No confirmation filter

Every histogram colour transition immediately produces an arrow and (optionally) an alert. In choppy, low-volatility markets the indicator will fire repeatedly as the membrane potential oscillates around the threshold — producing a rapid sequence of alternating arrows. A **minimum run-length filter** (e.g. "only fire a transition arrow if the new colour has persisted for at least N bars") would significantly reduce noise.

### 5.2 No trend filter

The excitatory/inhibitory signals are generated purely from the MA crossover structure with no higher-timeframe context. Adding an optional higher-timeframe trend filter (e.g. only show buy arrows when the HTF signal is also excitatory) would improve signal quality substantially.

### 5.3 Threshold symmetry assumption

`BuyThresholdMult` and `SellThresholdMult` allow asymmetric thresholds, which is good. However, both are applied to the same `base_threshold` which is itself derived from the same `SynapticWeight`. In instruments with a strong directional bias (e.g. trending stocks), a separately maintained up-weight and down-weight would be more adaptive.

---

## 6. Arrow Implementation

### 6.1 Offset scaling

```
double offset = ArrowOffsetPips × _Point × 10;
```

This hardcodes a "1 pip = 10 points" assumption, which is correct for 5-digit brokers on forex majors, but **wrong** for indices, commodities, crypto, and 4-digit brokers. The proper approach is to use ATR-based offset or expose a separate `ArrowOffsetPoints` input and use `_Point` directly without the ×10 multiplier.

### 6.2 Anchor property

```
ObjectSetInteger(0, name, OBJPROP_ANCHOR,
    direction > 0 ? ANCHOR_TOP : ANCHOR_BOTTOM);
```

`ANCHOR_TOP` means the top of the arrow glyph sits at `arrowPrice`. For a buy arrow placed below the bar, you actually want the tip pointing up toward the bar, so `ANCHOR_TOP` is semantically inverted here. It should be `ANCHOR_BOTTOM` for buy (arrow tip points up, bottom of glyph at `arrowPrice`) and `ANCHOR_TOP` for sell. This is a minor cosmetic issue but causes arrows to appear slightly further from price than intended.

### 6.3 Stale arrow leak (repeated from Section 2)

As noted, arrows are never explicitly deleted for a given bar when its signal flips off mid-recalculation. A `DeleteArrowIfExists` helper should be called when `!fireUp && !fireDown` for bars within the recalculation window.

---

## 7. Alert Logic

### 7.1 `lastSignal` persistence across full recalculations

`lastSignal` is a global that persists across `OnCalculate` calls but is reset to `0` only implicitly (never explicitly). On a chart reload or timeframe switch, `prev_calculated` resets to 0, but `lastSignal` retains its value from the previous session. This can suppress the very first alert after a reload if the signal happens to match `lastSignal`.

**Fix:** Reset `lastSignal = 0` when `prev_calculated == 0`.

### 7.2 Alert and arrow fire on different bars

The alert block fires based on `MembranePotential[1]` (the last closed bar), while the arrow transition logic fires during the main loop which also processes bar 0. This means an arrow can appear on bar 0 (the live bar) without a corresponding alert, and vice versa — they are not guaranteed to be synchronised. Unifying the signal source would make behaviour more predictable.

---

## 8. Code Structure & Maintainability

- **Magic number `14`** for ATR period appears hardcoded in `OnCalculate`. Should be an input.
- **Magic number `50.0`** in `MathMin(rel_vol * 50.0, 1.0)` inside the plasticity block has no documented rationale. This is a volatility normalisation constant that will behave very differently across instruments and should be an input or at minimum a named constant with a comment.
- **`PeriodToString`** duplicates functionality available via `EnumToString` in MT4 with minor formatting. Not a bug, just redundant code.
- The indicator has **no `#define` constants** for things like the width table values, making them invisible to users who want to tune behaviour without diving into `ScaleToWidth`.

---

## Summary of Recommended Changes

| Priority | Issue | Fix |
|---|---|---|
| 🔴 High | Double-decay bug | Remove the first `Neurotransmitter` decay assignment |
| 🔴 High | Sigmoid saturation | Lower `PotentialAmplifier` default to 2–4, or make sigmoid input-scaled |
| 🔴 High | Stale arrow leak | Delete arrows explicitly when signal flips off within recalc window |
| 🔴 High | Pip offset assumption | Replace `× _Point × 10` with `× _Point` and rename input to `ArrowOffsetPoints` |
| 🔴 High | Arrow anchor inversion | Swap `ANCHOR_TOP`/`ANCHOR_BOTTOM` for buy/sell |
| 🟡 Medium | Incomplete Hull MA | Add final `WMA(sqrt(period))` smoothing step |
| 🟡 Medium | ATR period hardcoded | Expose as `ATRPeriod` input |
| 🟡 Medium | `lastSignal` not reset | Reset to 0 when `prev_calculated == 0` |
| 🟡 Medium | MTF redundant `iBarShift` | Skip when `NeuralTimeframe == PERIOD_CURRENT` |
| 🟡 Medium | No warm-up guard | Skip signal calculation for first `PostsynapticPeriod` bars |
| 🟢 Low | `ArrayResize` every tick | Cache last size, only resize on change |
| 🟢 Low | Run-length noise filter | Add minimum N-bar confirmation before arrow/alert |
| 🟢 Low | `magic number 50.0` | Name it, document it, consider making it an input |
| 🟢 Low | Arrow name registry | Maintain `string arrowNames[]` for efficient cleanup |
Okay, then I asked, Claude, can you implement all the above-suggested improvements to the code and return the complete, fully updated code without any omissions or placeholders for brevity? Here is the result. I do not know if some of the "issues" it found were intended by you.

Code: Select all

Let me work through this carefully before writing a single line — there are a lot of interlocking changes.
Now, let me write the complete implementation. This is a large, careful rewrite so I'll build it in a file:
All 14 improvement points are accounted for. 
Let me copy to outputs:
Here is a precise account of every change made and the reasoning behind each:

---

## v1.6 Change Log

### 🔴 High Priority

**1. Double-decay bug removed**
The original had two `Neurotransmitter[i] = Neurotransmitter[i+1] * ...` assignments — the first was always silently overwritten by the second. Now there is exactly one, selected by the `AdaptiveNeuroDecay` flag.

**2. Sigmoid saturation fixed**
`PotentialAmplifier` default lowered from `10.0` to `3.0`. At 10, virtually every bar produced a potential of ±0.499, making the graded output meaningless. At 3.0, the full dynamic range of the sigmoid is in play and signal strength is genuinely proportional to MA separation.

**3. Stale arrow leak fixed**
`DeleteArrowIfExists()` is now called inside the arrow block whenever a bar's signal is absent. If bar[1] fires on one tick then flips off on the next, the orphaned arrow is removed immediately rather than persisting indefinitely.

**4. Arrow offset corrected**
`ArrowOffsetPips` renamed to `ArrowOffsetPoints`. The `× _Point × 10` multiplier is gone — just `ArrowOffsetPoints × _Point`. This works correctly for 4-digit and 5-digit forex brokers, indices, commodities, and crypto without any hidden assumptions.

**5. Arrow anchor corrected**
Swapped `ANCHOR_TOP`/`ANCHOR_BOTTOM`. Buy arrows (pointing up at the bar below) now use `ANCHOR_BOTTOM` so the tip is closest to price. Sell arrows use `ANCHOR_TOP` for the same reason.

---

### 🟡 Medium Priority

**6. True Hull MA implemented**
`HullMA()` is a new dedicated function that correctly computes `WMA(2×WMA(n/2) − WMA(n), sqrt(n))` — the genuine Hull MA formula. The previous code skipped the final `WMA(sqrt(n))` smoothing pass entirely, producing a DWMA.

**7. ATR period exposed**
New input `ATRPeriod` (default 14) replaces the hardcoded `14` inside `OnCalculate`.

**8. `lastSignal` reset on full recalc**
`lastSignal = 0` is now set when `prev_calculated == 0`, preventing the first legitimate alert after a chart reload from being suppressed if it happens to match the stale `lastSignal` value.

**9. `iBarShift` skipped on same timeframe**
`sameTimeframe` is resolved once before the loop. When `NeuralTimeframe == PERIOD_CURRENT`, `shift = i` directly — saving one external function call per bar (up to 500 per tick).

**10. Warm-up guard added**
The first `PostsynapticPeriod` bars are zeroed and skipped. This prevents unreliable MA values from the start of broker history, poisoning the `SynapticWeight` chain forward through the entire calculation.

---

### 🟢 Low Priority

**11. `ArrayResize` cached**
`lastRatesTotal` tracks the previously used size. The three `ArrayResize` calls now only fire when `rates_total` actually changes, not on every tick.

**12. Run-length confirmation filter**
New input `MinConfirmBars` (default 1, preserving v1.5 behaviour). Set to e.g. 2 or 3 to require the new histogram colour to hold for that many consecutive closed bars before an arrow is drawn — significantly reduces noise in choppy conditions.

**13. `PlasticityVolNorm` exposed**
The magic number `50.0` in the plasticity clamping formula is now `input double PlasticityVolNorm = 50.0`. Default preserves original behaviour; power users can tune it per instrument.

**14. Arrow name registry**
`arrowRegistry[]` and `arrowRegistryCount` track all created arrow names. `DeleteAllArrows()` now iterates only the registry (O(n arrows)) rather than scanning every object on the chart, which was O(total chart objects).
Thanks again for sharing your source code, allowing us to see and learn the inner workings of your indicators.

Warmest regards,
Beatle 🪲
These users thanked the author BeatlemaniaSA for the post (total 2):
PTR777, Asante
Millionaire Maker - “Amateurs chase. Professionals wait. Legends wait with a plan.”

BEATS V5 - "Enjoy The Quiet Between Trades”
Improve Your Trading Psychology - No fear, no doubt
Ultimate Risk Management - Maximize Your Trades
Supply and Demand Course - Learn Supply and Demand
Believe That You Can - Believe That You Can

Re: Some of my indicators and ea's free

90
PTR777 wrote: Tue Apr 21, 2026 6:25 pm ASC Arrows Engine

Simple close on opposite with martingale step

Don't know if profit or loss are true or not

Test is best

ASC Arrows Engine.mq4

XAUUSDM15.png
the profit calculations are a bit OFF I think
when I backtest the indi on XAUUSD (martingale disabled, 10k bars) I get around +$2500.
but when I backtest only the arrows on my engine, I get -5350 pips !! (without spread)

something's off
These users thanked the author ionone for the post:
PTR777
Scalping the Century TimeFrame since 1999