> That's nice! smile What's the secret behind such a big optimization and speed step?

Nice question Footon,

Actually, the secret is removing the "clever" things I did before.

Initially, my idea was to modify random bars. Let's say we want to randomize 20% of the bars and we have 100 000 bars. The alogo before was something like that

```
barsToChange= []
do {
randomBar = RandomNumber(1, bars)
If (not barsToChange.contains(randomBar) ) {
barsToChange.add(randomBar)
}
} while(barsToChange.length < 20000)
```

In that way, we generate a random number between 1 and the number of bars in the data series and check if we already had this before. If not, we add it to the `barsToChange` list. The loop continues until we have 20 000 numbers on the list.

After that loop, EA Studio starts the actual bar randomization for the chosen bars.

This simple function looks well at a fierce glance. However, the problems start to appear when we want a higher percentage of randomized bars. Even more, the function is really wrong when we want to randomize 80% or 90% of the bars.

Do you see the problem?

It becomes progressively more difficult to find a random number, which is not already on the list. Obviously, this is not the way to find 20 000 unique random numbers from 1 to 100 000.

...

Actually, I saw this problem after optimizing the other part of the function - calculating the Average True Range and generating new High, Low and Close prices for the given bar.

The straightforward optimization I did was t replace function calls with online code as much as possible. This speeded up the calculations a lot.

Before:

```
for (bar ...) {
newDataSet.high[bar] += getPriceChangeDelta(atr[bar], maxAtrPercent)
newDataSet.low[bar] += getPriceChangeDelta(atr[bar], maxAtrPercent)
newDataSet.close[bar] += getPriceChangeDelta(atr[bar], maxAtrPercent)
}
...
function getPriceChangeDelta(atr: number, maxAtrPercent: number): number {
return (Math.random() < 0.5 ? -1 : 1) * (atr / 2.0) * ((maxAtrPercent / 100) * Math.random())
}
```

Now:

```
for (bar ...) {
const factor = (atr[bar] / 2.0) * (maxAtrPercent / 100)
newDataSet.high[bar] += (Math.random() < 0.5 ? -1 : 1) * factor * Math.random()
newDataSet.low[bar] += (Math.random() < 0.5 ? -1 : 1) * factor * Math.random()
newDataSet.close[bar] += (Math.random() < 0.5 ? -1 : 1) * factor * Math.random()
}
```

Now the Data Randomization function is relatively fast. It takes 4.5% of calculation time on default settings without caching.

Trade Safe!