Skip to content
enarjord edited this page Jul 2, 2021 · 8 revisions

passivbot v3.6.4

What

A python script is given access to user's binance or bybit account and listens to websocket stream of live trades in futures markets, automatically creating and cancelling limit buy and sell orders.

The bot bases its decisions on account's positions, open orders and balance, and multiple EMAs of different spans.

Bot's live behavior is deterministic and may be simulated on historical price data, using the included backtester.

Its behavior is changed by adjusting the configuration to suit a particular market and user's preference.

Configuration's parameters may be optimized to a given period of historical data by backtesting up to thousands of candidates, converging upon the config whose backtest result best satisfy specified criteria.

Why

The bot's purpose is to accumulate tokens over time. It is observed that prices in a market will fluctuate up and down, creating opportunities for capitalizing on the "noise".

How

passivbot may be described as a market making DCA scalping grid trader.

  • Market maker: passivbot is a pure maker. It never takes orders, only makes them.

  • DCA: Dollar Cost Averaging. It will typically make up to several reentries after an initial entry, in an attempt to acheive better average entry price.

  • Scalping: It will typically close positions at small markups, in the range of 0.1-2.0%

  • Grid trading: Its reentries may be calculated in advance and put on the books, thus making a grid of orders.

Where

passivbot currently supports all Binance and Bybit futures markets. The script may be run from a local computer, but in most cases using a remote VPS is more convenient. For example, several bot instances may be run on a $5/month VPS without issue.

Configuration (live config)

Included live configs are found in configs/live/name.json

config_name

Arbitrary name given to config

logging_level

Set to 0, no logging. Set to 1, logs positions, open orders, order creations, order cancellations to logs/{exchange}/{config_name}.log

min_span/max_span/n_spans

Bot uses exponential moving averages EMAs to limit entries and stop losses.

EMAs are not based on OHLCVs, but on raw trades, or "ticks"

EMA is defined as

ema = prev_ema * (1 - alpha) + tick_price * alpha

where

alpha = 2 / (span + 1)

Fastest EMA is given by min_span, slowest EMA is given by max_span, and n_spans gives how many EMAs.

long/shrt

Config parameters for long and short are separated.

enabled

Set to false to disable long/shrt

all MAr_coeffs

Selected parameters may be modified by ratios between EMAs of different spans.

Set to 0.0 to disable parameter modification by EMA ratios.

More details may come later.

iqty_const

Initial quantity percentage of balance.

Initial entry quantity is defined as balance_ito_contracts * iqty_const

E.g. if balance is $200 and iqty_const = 0.03, cost of initial entry will be at least 200 * 0.03 == $6

iprc_const

An upper and a lower band of EMAs are made by taking min(EMAs) and max(EMAs), respectively.

Initial long entry price is lower_EMA_band * iprc_const and initial shrt entry price is upper_EMA_band * iprc_const

For example, if EMAs = [33.4, 32.1, 32.9], upper band is 33.4 and lower band is 32.1.

If shrt_iprc_const = 1.005, shrt_entry_price = 33.4 * 1.005 == 33.567

rqty_const

Reentry quantity is initial entry quantity plus position size times rqty_const.

For example, say psize is 10.0, rqty_const is 1.2 and initial entry qty is 2.2 (see iqty_const).

Then reentry qty is 2.2 + 10.0 * 1.2 == 14.2.

rprc_const

Long reentry price is min(initial_long_entry_price, long_position_price * long_rprc_const)

Short reentry price is max(initial_shrt_entry_price, shrt_position_price * shrt_rprc_const)

PBr_coeffs

This parameter's purpose is to increase spacing between reentries in proportion to position size.

The ratio of position cost to balance times PBr_coeffs is added to rprc_const.

Say psize is 0.23, pprice is 250.0 and balance is 80.0. Position cost is 0.23 * 250.0 = 57.5 and PBr is position_cost / balance == 57.5 / 80 == 0.71875.

The formula is rprc_modifier = pbr**2 * PBr_coeffs[0] + pbr * PBr_coeffs[1]

Say long rprc_const = 0.98 If PBr_coeffs is (-0.05, 0.01), rprc = rprc_const + 0.71875**2 * -0.05 + 0.71875 * 0.01 == 0.98 + -0.018642578125000003 == 0.961357421875

So next long reentry will be ~3.86% instead of 2.0% lower than long pprice.

markup_const

Bot closes entire position at static position_price * markup_const

pbr_limit

pbr is position_cost / balance, where position_cost is position_size / position_price if inverse, otherwise position_size * position_price

A position's cost may not be greater than pbr_limit + pbr_stop_loss.

pbr_stop_loss

Specifies how much a position's cost may overstep its pbr_limit.

Bot will partially close position at a loss if position_cost / balance is greater than pbr_limit.

Configuration (configs/backtest/default.hjson)

exchange

binance or bybit

user

set your account name here, needed to fetch ticks

symbol

symbol to backtest. note differences between USDT margined symbols (ends with USDT) and inverse symbols (ends with USD). also note difference between binance inverse perpetual and inverse futures (e.g. ETHUSD_PERP or ETHUSD_210625)

latency_simulation_ms

simulate latency between bot and exchange

starting_balance

starting balance in margin token (USDT in linear markets, coin in inverse markets)

start_date/end_date

timeframe to backtest

Configuration (configs/optimize/default.hjson)

pso options

particle swarm optimization options

iters: n backtests

num_cpus: max n cpus for parallel testing

options: c1, c2, w. pso specific options, see for example https://pymoo.org/algorithms/pso.html for more info

n_particles: n particles, see above link for more info

minimum_bankruptcy_distance

optimizer will penalize configs whose bankruptcy in backtests came closer than given threshold

minimum_equity_balance_ratio

optimizer will penalize configs whose equity / balance ratio in backtests came closer than given threshold

minimum_slice_adg

more info may be added

max_n_hours_between_fills

optimizer will penalize configs whose max duration between consecutive fills in backtest was higher than given threshold

ranges

search space for each tunable parameter. if min and max are equal, parameter is fixed and not tuned.

Clone this wiki locally