Skip to content
DiceSim

Flat betting · 49.5% chance

Fixed wager in sats: dice script with a bankroll guard (Lua)

This script reads the session balance in satoshis with Units.ToSats(balance), refuses to start below 100,000 sats, and then bets 100 sats on every roll at 49.5% for a 2.00x payout.

It ends the run itself with stop(reason): once the session is up 10,000 sats or down 20,000 sats. The reason text shows in the result strip and the console. 1 sat is 0.00000001 of the selected coin.

The script

Lua 5.4 with DiceBot-style globals. The top level runs once to set chance and the first nextbet, then dobet() runs after every roll. Every global is described in the Lua reference.

luafixed-wager-sats.lua
-- Fixed wager in sats, with a session guard and stop(reason)
-- The starting balance comes from Settings, not from the script: at the top level `balance`
-- IS the session bankroll. This template reads it in satoshis, refuses to start when it is
-- too small, bets a fixed number of sats, and ends the run with a reason you can read in
-- the result strip and the console. 1 sat = 0.00000001 of the selected coin.

chance  = 49.5
bethigh = false

local WAGER_SATS    = params.wagersats or 100       -- fixed bet, in satoshis
local MIN_BAL_SATS  = params.minbalsats or 100000   -- need at least 0.001 of the coin to start
local TARGET_SATS   = params.targetsats or 10000    -- stop once the session is up this much
local MAX_LOSS_SATS = params.maxlosssats or 20000   -- stop once the session is down this much

local startSats = Units.ToSats(balance)
print(string.format("session balance %.0f sats (%.8f %s), wager %d sats", startSats, balance, currency, WAGER_SATS))

if startSats < MIN_BAL_SATS then
  -- Stops before the first roll: zero rolls, nothing wagered, balance and nonce untouched.
  stop(string.format("needs at least %d sats, this session has %.0f", MIN_BAL_SATS, startSats))
end

nextbet = Units.FromSats(WAGER_SATS)
basebet = nextbet

function dobet()
  nextbet = basebet
  local pnl = math.floor(Units.ToSats(profit) + 0.5)   -- whole sats (float noise would miss "== 10000")
  if pnl >= TARGET_SATS then
    stop(string.format("target reached: +%.0f sats after %d bets", pnl, bets))
  elseif pnl <= -MAX_LOSS_SATS then
    stop(string.format("loss limit: %.0f sats after %d bets", pnl, bets))
  end
end

How it works

  1. chance = 49.5 and bethigh = false win on a roll below 49.5, paying 2.00x.
  2. Four locals hold the settings in sats: WAGER_SATS, MIN_BAL_SATS, TARGET_SATS and MAX_LOSS_SATS, each with a params override.
  3. At the top level balance is the starting balance from Settings. The script prints it in sats and, if it is below MIN_BAL_SATS, calls stop() with a message. That ends the run before the first roll: no wager is placed and no roll is consumed.
  4. nextbet = Units.FromSats(WAGER_SATS) converts the wager to coin, and basebet is set to the same value.
  5. dobet() keeps nextbet = basebet and rounds profit to whole sats. At TARGET_SATS or above, or at -MAX_LOSS_SATS or below, it calls stop() with the profit and the number of bets.

Risk at a glance

Settings: 49.5% chance, 1% house edge, starting balance 0.001 (the template default, BTC in the simulator), base bet 0.000001 (balance / 1000.0000000000001).

Payout2.00x(100 - 1) / 49.5
Chance the stop loss hits first86.7%Down 200 base bets (20%) before up 100 (10%)
Chance the take profit hits first13.3%Up 100 base bets before down 200
Expected bets per session16,005Average number of bets until one of the two stops
Expected loss per session0.000160051% of the 0.01600466 wagered on average

A fixed wager never grows, so a losing run costs 100 sats per loss and the loss limit ends the session after 200 losses in a row from the start. Sessions normally end by drift over many bets instead. The tiles use the gambler's ruin formula for a bet that wins or loses exactly one wager, which holds at 49.5% and a 2.00x payout.

Cost of a straight losing run from a fresh start
Losses in a rowChance of the streakResult from a fresh start
101 in 927 (0.108%)Lost 0.00001 (1.0%), next bet 0.000001
501 in 6.8e14 (1.5e-13%)Lost 0.00005 (5.0%), next bet 0.000001
1001 in 4.7e29 (2.1e-28%)Lost 0.0001 (10.0%), next bet 0.000001
2001 in 2.2e59 (4.6e-58%)Script stops. Lost 0.0002 (20.0%)

Theoretical figures for a fresh start, not a simulation. The chance of N losses in a row is qN with q = 1 - chance / 100, the same formula the dice calculator uses. The stop loss and take profit figures are the gambler’s ruin formulas for a bet that wins or loses one base bet: with r = q / p, the chance of reaching the take profit first is (1 - rL) / (1 - rL+W), where L and W are the two thresholds in base bets. None of this changes the expected result: at a 1% house edge the average loss is 1% of the total wagered, whatever the progression.

Tuning it

Each setting below is read as params.name or default, so the script runs with the default until something passes a value in.

Parameters read by the Fixed wager in sats script
ParamDefaultWhat changing it does
params.wagersats100Bet on every roll, in sats. With the 100,000 sat default balance that is 0.1% of the bankroll.
params.minbalsats100000Smallest starting balance the script accepts, in sats. Below it the run stops before the first roll.
params.targetsats10000Session profit in sats at which the script stops.
params.maxlosssats20000Session loss in sats at which the script stops.

The guard compares the Settings balance with MIN_BAL_SATS, so with the defaults the run only starts from 0.001 of the coin or more. Lower minbalsats or raise the starting balance in Settings; the script is not rewritten for you.

FAQ

Why does the run stop before the first roll?

The starting balance in Settings is below 100,000 sats (0.001 of the coin), so the script called stop() at the top level. No wager was placed and no roll was consumed. Raise the balance or pass a smaller params.minbalsats.

How likely is the loss limit compared with the target?

With the defaults the session has to move 200 wagers down or 100 wagers up. At 49.5% the loss limit comes first 86.7% of the time and the target 13.3%, over an average of 16,005 bets.

What do Units.ToSats and Units.FromSats do?

They convert between coin amounts and satoshis: Units.ToSats(0.000001) is 100 and Units.FromSats(100) is 0.000001. The script uses them so every threshold can be written as a whole number of sats.

Can I run this script in DiceBot or another Lua dice bot?

The script uses the global names from Seuntjie's DiceBot (chance, bethigh, nextbet, previousbet, win, dobet()). The params table only exists in DiceSim, so replace each params.name or value with the value before you paste it into another bot. It also reads Units.ToSats(), so check that your bot provides it. DiceSim itself never places bets on a casino.

Other scripts

Martingale

Doubles the bet after each loss and goes back to the base bet after a win.

Chance
49.5%
Type
Martingale

Delayed escalation

Bets 3.35% for a 29.55x payout. Flat bets through 50 losses, then 4% more per loss.

Chance
3.35%
Type
Dynamic scaling

Paroli 3-step

Doubles after a win, banks the profit after 3 wins in a row, resets on any loss.

Chance
49.5%
Type
Paroli

Dynamic recovery

Sizes each bet so one win recovers the drawdown plus one base bet, capped at 10% of balance.

Chance
33%
Type
Recovery

D'Alembert

Adds one unit after a loss and removes one after a win, never going below the base bet.

Chance
49.5%
Type
D'Alembert

Labouchere

Bets the first plus the last number of a list. Wins cross numbers off, losses add one.

Chance
49.5%
Type
Labouchere

Fibonacci

Bets follow the Fibonacci sequence: one step up after a loss, two steps back after a win.

Chance
49.5%
Type
Fibonacci

Oscar's Grind

Plays in cycles that aim for +1 unit: same bet after a loss, one unit more after a win.

Chance
49.5%
Type
Oscar's Grind

1-3-2-6

Bets 1, 3, 2 and 6 units on consecutive wins. Any loss, or the 4th win, resets to 1.

Chance
49.5%
Type
Positive progression

Flat betting

Same bet on every roll, with a stop loss and a take profit at 10% of the starting balance.

Chance
49.5%
Type
Flat betting

Martingale + vault

Martingale that moves half of every 1% profit step to the vault with vault().

Chance
49.5%
Type
Martingale