Monte Carlo Simulation - Random Walk
"Monte Carlo Simulation - Random Walk" by LonesomeTheBlue, MPL-2.0. Ported to FloScript by FloSignals; modifications under MPL-2.0. Original: Monte Carlo Simulation - Random Walk (v3.0), read 2026-10-12T16:08:51.807Z; source language v4.
Licence: Mozilla Public License 2.0 (MPL-2.0) — full text. The source is published with it, modifications included, under the same licence.
Monte Carlo Simulation - Random Walk by LonesomeTheBlue, ported from Pine v4. Overlay indicator with 2 plots, drawings and 8 inputs.
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © LonesomeTheBlue
// ------------------------------------------------------------------------------------------------
// Original author: LonesomeTheBlue
// Original title: Monte Carlo Simulation - Random Walk
// Licence: MPL-2.0 (the header above is the original notice, kept verbatim)
// Pine version: 4
// Fetched: 2026-10-12
// Ported to FloScript by FloSignals; modifications under MPL-2.0.
// Converter: @flosignals/floscript 0.1.0, strict mode, score 100/100
// ------------------------------------------------------------------------------------------------
//@floscript=1
//@version=5
// Converted by the FloScript converter from a Pine-compatible v4 source.
indicator("Monte Carlo Simulation - Random Walk", overlay=true, max_lines_count=500)
numprct = input.int(defval=50, title="Number of Bars to Predict", minval=10, maxval=100)
numsim = input.int(defval=500, title="Number of Simulations", minval=5)
datalen = input.int(defval=2000, title="Number of Bars to use as Data Source", minval=100)
keepmm = input(defval=false, title="Keep Past Min-Max Levels")
minmaxupcol = input(defval=color.blue, title="Min-Max Levels Up Color")
minmaxdncol = input(defval=color.navy, title="Min-Max Levels Down Color")
rwupcol = input(defval=color.lime, title="Random Walk Up Color")
rwdncol = input(defval=color.red, title="Random Walk Down Color")
//==================================================================================================
// Thanks to Ricardo Santos for letting me use his Random Number Generator Function (@RicardoSantos)
//==================================================================================================
var array<float> seed = array.new_float(size=1, initial_value=42.0)
f_prng(_range) =>
//| pseudo random function:
var float _return = 1.0
float _seed = array.get(id=seed, index=0)
float _reseed = 271.828
_return := 3.1416 * _return % _seed * _reseed % _range
array.set(id=seed, index=0, value=1 + _seed * 1.618 % _range + _return)
_return
//==================================================================================================
timediff = time - time[1]
// total walks except min/max levels
var totalwalk = math.floor(500 / numprct) - 2
var prdc_lines = array.new_line(numprct * (totalwalk + 2))
if barstate.isfirst
for x = 0 to array.size(prdc_lines) - 1
array.set(prdc_lines, x, line.new(x1=time, y1=close, x2=time, y2=close, xloc=xloc.bar_time, width=x < totalwalk * numprct ? 2 : 3))
// keep periodic daily returns using the natural logarithm
var pc = array.new_float(0)
array.unshift(pc, math.log(close / close[1]))
if array.size(pc) > datalen
array.pop(pc)
float minlevel = na
float maxlevel = na
if barstate.islast
cls = array.new_float(numprct, na)
maxcls = array.new_float(numprct, -1e15)
mincls = array.new_float(numprct, 1e15)
r = 0
drift = array.avg(pc) - array.variance(pc) / 2
//start simulations and get random 5 random and max-min paths
for x = 0 to numsim - 1
lastclose = close
for y = 0 to numprct - 1
rchg = math.round(f_prng(math.min(array.size(pc) - 1, bar_index - 1)))
nextclose = math.max(0, lastclose * math.exp(array.get(pc, rchg) + drift))
array.set(cls, y, nextclose)
lastclose := nextclose
array.set(maxcls, y, math.max(array.get(maxcls, y), nextclose))
array.set(mincls, y, math.min(array.get(mincls, y), nextclose))
// draw random paths
if r < totalwalk
line.set_xy1(array.get(prdc_lines, r * numprct), time, close)
line.set_xy2(array.get(prdc_lines, r * numprct), time + timediff, array.get(cls, 0))
line.set_color(array.get(prdc_lines, r * numprct), array.get(cls, 0) >= close ? rwupcol : rwdncol)
for y = 1 to numprct - 1
line.set_xy1(array.get(prdc_lines, r * numprct + y), time + timediff * y, array.get(cls, y - 1))
line.set_xy2(array.get(prdc_lines, r * numprct + y), time + timediff * (y + 1), array.get(cls, y))
line.set_color(array.get(prdc_lines, r * numprct + y), array.get(cls, y) >= array.get(cls, y - 1) ? rwupcol : rwdncol)
r := r + 1
// draw estimaded max-min closing prices
line.set_xy1(array.get(prdc_lines, totalwalk * numprct), time, close)
line.set_xy2(array.get(prdc_lines, totalwalk * numprct), time + timediff, array.get(maxcls, 0))
line.set_color(array.get(prdc_lines, totalwalk * numprct), array.get(maxcls, 0) >= close ? minmaxupcol : minmaxdncol)
line.set_xy1(array.get(prdc_lines, (totalwalk + 1) * numprct), time, close)
line.set_xy2(array.get(prdc_lines, (totalwalk + 1) * numprct), time + timediff, array.get(mincls, 0))
line.set_color(array.get(prdc_lines, (totalwalk + 1) * numprct), array.get(mincls, 0) >= close ? minmaxupcol : minmaxdncol)
for y = 1 to numprct - 1
line.set_xy1(array.get(prdc_lines, totalwalk * numprct + y), time + timediff * y, array.get(maxcls, y - 1))
line.set_xy2(array.get(prdc_lines, totalwalk * numprct + y), time + timediff * (y + 1), array.get(maxcls, y))
line.set_color(array.get(prdc_lines, totalwalk * numprct + y), array.get(maxcls, y) >= array.get(maxcls, y - 1) ? minmaxupcol : minmaxdncol)
line.set_xy1(array.get(prdc_lines, (totalwalk + 1) * numprct + y), time + timediff * y, array.get(mincls, y - 1))
line.set_xy2(array.get(prdc_lines, (totalwalk + 1) * numprct + y), time + timediff * (y + 1), array.get(mincls, y))
line.set_color(array.get(prdc_lines, (totalwalk + 1) * numprct + y), array.get(mincls, y) >= array.get(mincls, y - 1) ? minmaxupcol : minmaxdncol)
maxlevel := array.get(maxcls, 0)
minlevel := array.get(mincls, 0)
plot(maxlevel, color=keepmm ? (maxlevel >= maxlevel[1] ? minmaxupcol : minmaxdncol) : na)
plot(minlevel, color=keepmm ? (minlevel >= minlevel[1] ? minmaxupcol : minmaxdncol) : na)
This file is under the Mozilla Public License 2.0; it is a port of the original by LonesomeTheBlue, with the original licence header kept and the changes made for FloScript noted in the file.
- v2
Library refresh 2026-10-14
- v1
Library refresh 2026-10-12
Disclaimer. Scripts are written and published by members, or ported by FloSignals from open-source originals, and are their authors' own work and opinion. FloSignals does not review them for correctness and nothing in a script is financial advice or a recommendation to buy or sell anything — read the Risk Disclaimer. Posting here is under the Community Rules; a script that is not the poster's to post can be reported as the Copyright & Takedowns page says.

Comments (0)
No comments yet. Members can leave one.