Skip to main content

AutoConfig filter types

AutoConfig jobs support various filter types. These include:

TypeUsage
Ticker filtersUsed for jobs that require external data.
Pair state filtersUsed for jobs that require internal data.
Generic filtersUsed for all job types.
User VariablesThis is not a filter category category of, instead it is data that can be stored and retrieved from within any job.
User variables can be filtered, and accessed by other jobs than the one that saved them.

Ticker filters

Ticker filters request data from exchange tickers at the time the job runs. Different types of filters can be applied to add or remove pairs, but not all filter types work on every exchange due to varying availability of required data. For example, on Huobi AutoConfig, last price is used instead of bid/ask for all price-related filters.

The following table provides an overview of available filter types with their descriptions and any additional details.

TypeDescriptionExampleExtras
minPriceChecks if the asset's current price is greater than a specified value. Fails if the price is not defined, zero, or below this value.Filtering assets above a specified price.n/a
maxPriceChecks if the asset's current price is less than a specified value. Fails if the price is not defined, zero, or above this value.Filtering assets below a specified price.n/a
minVolumeRankChecks if the asset's volume rank is greater than a specified value. Volume rank means that assets are sorted by trading volume, for example USDT-BTC would usually have rank 1 on all USDT pairs on an exchange. Fails if the volume is undefined, zero, or the rank is below this value.Identifying assets with significant trading activity for potential liquidity.n/a
maxVolumeRankChecks if the asset's volume rank is less than a specified value. Volume rank means that assets are sorted by trading volume, for example USDT-BTC would usually have rank 1 on all USDT pairs on an exchange. Fails if the volume is undefined, zero, or the rank is above this value.Filtering out overly popular assets that might be overvalued.n/a
minPricePctChangeIntervalChecks if the price change percentage compared with the average price over an interval is greater than a specified value, considering the job's snapshot count.Finding assets with recent upwards price movement.lastSnapshots
maxPricePctChangeIntervalChecks if the price change percentage compared with the average price over an interval is less than a specified value, considering the job's snapshot count.Finding assets with recent upwards price movement.lastSnapshots
minVolumePctChangeIntervalChecks if the volume change percentage over an interval is greater than a specified value, considering the job's snapshot count.Identifying assets gaining interest for potential entry.lastSnapshots
maxVolumePctChangeIntervalChecks if the volume change percentage over an interval is less than a specified value, considering the job's snapshot count.Highlighting assets that might be losing momentum.lastSnapshots
minVolume24hChecks if the 24h volume is greater than a specified value.Filtering for assets with significant daily trading activity.n/a
maxVolume24hChecks if the 24h volume is less than a specified value.Avoiding assets with potentially inflated daily activity.n/a
minVolatilityPct24hChecks if the 24h price volatility is greater than a specified value.Identifying assets with significant price movements for high-reward strategies.n/a
maxVolatilityPct24hChecks if the 24h price volatility is less than a specified value.Finding stable assets for low-risk investment approaches.n/a
minSpreadPctChecks if the bid-ask spread percentage is greater than a specified value.Filtering out assets with likely high slippage when using market orders.n/a
maxSpreadPctChecks if the bid-ask spread percentage is less than a specified value.Filtering out assets with likely high slippage when using market orders.n/a
minSlopePctIntervalChecks if the price slope percentage over an interval is greater than a specified value, considering the job's snapshot count.Spotting assets with a strong positive trend.lastSnapshots
maxSlopePctIntervalChecks if the price slope percentage over an interval is less than a specified value, considering the job's snapshot count.Finding assets with a diminishing upward trend for potential sell signals.lastSnapshots
bullishStandardDeviationChannelChecks if the price is below the lower band of a bullish standard deviation channel, with a positive slope and matching snapshot count.Identifying potential bullish reversals within a downtrend.lastSnapshots
bearishStandardDeviationChannelChecks if the price is above the upper band of a bearish standard deviation channel, with a negative slope and matching snapshot count.Spotting potential bearish reversals within an uptrend.lastSnapshots
linearRegressionChannelChecks if the price is below the lower band of a linear regression channel.Finding assets with prices below trend for potential buy opportunities.lastSnapshots
minStandardDevPctIntervalChecks if the standard deviation percentage over an interval is greater than a specified value, with matching snapshot count.Identifying assets with increasing price variability for risk assessment.lastSnapshots
maxStandardDevPctIntervalChecks if the standard deviation percentage over an interval is less than a specified value, with matching snapshot count.Finding assets with decreasing price variability for stability.lastSnapshots
aboveMedianVolumeChecks if the current 24-hour volume is above the median for other assets.Targeting assets with above-average interest.n/a
belowMedianVolumeChecks if the current 24-hour volume is below the median for other assets.Identifying assets that may be undervalued or overlooked.n/a
tip

If you collect 48 ticker snapshots and the job runs every five minutes, that means any *Interval job works with 4h of market data (48 x 5).

Note that some filters have additional parameters that must be set to function properly. The minPricePctChangeInterval and maxPricePctChangeInterval filters require the lastSnapshots parameter to calculate the average price of all snapshots.

The lastSnapshots input allows you to select a specific number of recent snapshots to use for calculating a filter. For instance, if your task generates 100 snapshots but you only want to use the last 10 snapshots to calculate slope for a particular filter, you can specify this using lastSnapshots.

Filter notation examples

"spread": {
"type": "minSpreadPct",
"min": 0.5
},
"volume": {
"type": "belowMedianVolume"
},
"stdev": {
"type": "maxStandardDevPctInterval",
"max": 0.3
},
"channel": {
"type": "bullishStandardDeviationChannel",
"range": -10
},
"maxStandardDevPctInterval": {
"type": "minVolumePctChangeInterval",
"max": 1,
"lastSnapshots": 3
}
"hedge": {
"type": "allowsHedging",
"BTC": "USDT"
}

Trailing filters

Trailing filters are ticker filters that trail down prices or volume. There are three types of trailing filters: buyTrailing, volumeTrailing, and slopeTrailing. Buy trailing is similar to a regular Gunbot strategy and can be used to add pairs to your configuration only after they have hit their trailing stop. This is useful for trailing massive numbers of pairs without the downsides of long cycling times.

Note that these filter types can only be used in addPairs jobs on exchanges that provide ask prices or volume in tickers, and only work when used in the first filter set of a job.

Here's an example configuration for buy trailing:

  • Collect up to 60 ticker snapshots, adding a new snapshot every time the job runs (every minute).
  • Use the 60 collected bid prices for a pair to calculate an EMA.
  • Continuously trail down all pairs using a trailingRange of 1% of the ask price.
  • The filter passes when the ask prices cross over the trailing stop while being below buyLevel (which is a percentage below the EMA calculated by this filter).

Volume trailing works the same as buy trailing, but base volume is used where prices are used in buy trailing. Slope trailing works like buy trailing but trails the slope percentage of a pair. Buy level is based on the same EMA as it is for buy trailing.

{
"trailingExample": {
"pairs": {
"exclude": "",
"include": "BTC-,USDT-",
"maxPairs": 10,
"exchange": "binance"
},
"filters": {
"trailing": {
"type": "buyTrailing",
"buyLevel": 0.5,
"trailingRange": 1
}
},
"schedule": "* * * * *",
"type": "addPairs",
"strategy": "instantBuy",
"enabled": true,
"resume": true,
"snapshots": 60
},

Ticker history filters

Most ticker filters are also available as *History variant. These work in the same way as described above, but they use a different data set as input. Available history filters:

  • minPriceHistory
  • maxPriceHistory
  • maxVolumeRankHistory
  • minVolumeRankHistory
  • minPricePctChangeIntervalHistory
  • maxPricePctChangeIntervalHistory
  • minVolumePctChangeIntervalHistory
  • maxVolumePctChangeIntervalHistory
  • minVolume24hHistory
  • maxVolume24hHistory
  • minVolatilityPct24hHistory
  • maxVolatilityPct24hHistory
  • minSpreadPctHistory
  • maxSpreadPctHistory
  • minSlopePctIntervalHistory
  • maxSlopePctIntervalHistory
  • minStandardDevPctIntervalHistory
  • maxStandardDevPctIntervalHistory
  • bearishStandardDeviationChannelHistory
  • bullishStandardDeviationChannelHistory

History filters take one additional input, defining which history data should be used. the config for a history filter looks like:

"filter": {
"type": "minPriceHistory",
"min": 10,
"historySource": 6
}

The historySource parameter in the example above means that it will use the price of the history entry with number 6. The oldest history entry has number 0.

How the history is built up is defined by the following parameters in the root level:

"history": 7,
"historyInterval": 15,

The example above would collect 7 history entries, with a minimum interval of 15 minutes.

New history entries are saved as follows:

  • When there is no history, the oldest ticker snapshot will be added as first history entry.
  • When there is at least one history entry, a new one is added when the time difference between the oldest ticker snapshot and the latest history entry is bigger than the time defined in historyInterval. The oldest ticker snapshot will be added as newest history entry. In case the maximum number of history entries is reached, the oldest history entry will get deleted once a new one gets added.

The config example below shows a job that filters for:

  • BTC pairs that currently ranks top10 for 24h volume
  • The 5 history entries have a slope of at least 1%
  • Pair must have ranked top10 24h volume in the oldest history entry
If oldest snapshot is > 60 minutes older than newest history entry, 
it gets moved to history

Snapshots, 1m interval
[s] [s] [s] [s] [s]
History entries, 60m interval |
[0] [1] [2] [3] [4] |
^-----------------------*


"addMoon": {
"pairs": {
"exclude": "",
"include": "BTC-",
"maxPairs": 10,
"exchange": "binance"
},
"filters": {
"filter1": {
"type": "maxVolumeRank",
"max": 10
},
"filter2": {
"type": "minSlopePctIntervalHistory",
"min": 1,
"historySource": 4
},
"filter3": {
"type": "maxVolumeRankHistory",
"max": 10,
"historySource": 0
}
},
"schedule": "* * * * * *",
"type": "addPairs",
"strategy": "moon",
"snapshots": 5,
"history": 5,
"historyInterval": 60,
"resume": true
},

tip

Both snapshots and history cause a relatively high load on I/O operations. Depending on your system, allowing for too many saved entries can negatively impact performance.

Pair state filters

State filters in Gunbot use data from the internal ledger to filter pairs that have already cycled since the last (re)start. State data includes indicator values, balance data, candle data, and much more.

TypeDescription
exactExact match between value and key in config and pair state; returns true when key and value match exactly.
biggerThanValue for key in pair state must be bigger than in config; returns true when emal in state is bigger than 0.25.
smallerThanValue for key in pair state must be smaller than in config; returns true when emal in state is smaller than 0.2.
compareBiggerCompares values for two keys in state, values in config are irrelevant; returns true when emal is bigger than ema2 in state.
compareSmallerCompares values for two keys in state, values in config are irrelevant; returns true when emal is smaller than ema2 in state.
differenceBiggerCompares values for two keys in state, values in config are irrelevant; returns true when percentage difference between emal and ema2 is bigger than delta (%).
differenceSmallerCompares values for two keys in state, values in config are irrelevant; returns true when percentage difference between emal and ema2 is smaller than delta (%).

Formula used in differenceBigger:
100 * ((ema2 - ema1) / ema1) > delta

Formula used in differenceSmaller:
100 * ((ema2 - ema1) / ema1) < delta

Please note that the ema1 and ema2 keys used in the formula examples can be replaced with any two keys. Just make sure you understand the positions of the keys to be compared in the configuration file because they matter.

Generic filters

Generic filters can be used with any job type, whether it primarily uses ticker or state filters. Here are the available filters:

Filter TypeDescription
variableExactReturns true when the variable value is exactly as defined.
variableNotExistReturns true when the variable key does not yet exist.
variableBiggerThanReturns true when the variable value is bigger than the target.
variableSmallerThanReturns true when the variable value is smaller than the target.
pairVariableSmallerThanReturns true when the pair-specific variable value is smaller than the target.
pairVariableBiggerThanReturns true when the pair-specific variable value is bigger than the target.
pairVariableExactReturns true when the pair-specific variable is exactly as defined. Can use an extra exchange input to check pair variables for another exchange.
strategyNameReturns true when the strategy of an enabled pair is similar to the defined strategy name.
minTimeInConfigReturns true when the pair has been in the config for longer than a set number of minutes.
maxTimeInConfigReturns true when the pair has not been in the config for longer than a set number of minutes.
customAllows you to use any custom JavaScript expression. The filter passes when the expression returns true.

Generic filter examples:

"Seconds since last order": {
"type": "custom",
"target": " (function timeCheck(data){if(typeof data.orders==='undefined'){return false;} else if(typeof data.orders[0]==='undefined'){return false;} const lastOrderTime=data.orders[0].time;const secondsSinceLastOrder=(Date.now()-lastOrderTime)/1000;if(secondsSinceLastOrder<180){return true;}})(this)"
},
"Price and EMA": {
"type": "custom",
"target": " this.pair.ema1 > this.pair.Bid"
},
"time": {
"type": "minTimeInConfig",
"min": 60
},
"time": {
"type": "maxTimeInConfig",
"max": 90
} ,
"var": {
"type": "variableNotExist",
"hedge": "BTC"
},
"strat": {
"type": "strategyName",
"name": "moon"
},

User variables

Gunbot allows you to define user variables for each job, which can be used for filtering in other jobs. You can use global variables and pair-specific variables to create more complex filter setups.

By using user variables, you can avoid repeating multiple filter conditions across multiple jobs and make job dependencies possible. For example, one job can monitor a specific condition and set a variable like liquidationStop: true when its conditions are met. Other jobs that depend on this liquidation stop can then set one filter looking for an exact match for liquidationStop: true, instead of repeating the same filters set in the job that monitors the distance between price and liquidation price.

A job sets a variable when at least one pair passes all filters for this job, and setVariable is defined in the job's configuration. User variables can hold true/false values, number values, or strings, and the new value will overwrite the old one if it was previously set with a different value.

To set a global variable:

"setVariable": {
"userVariable1": true
},

To set pair specific variables, use a block like this:

"setPairVariable": {
"awesomeVariable": true,
"evenBetter": true
},

All variables are written to a file and imported upon Gunbot restarts, but file corruption can occur in certain situations. Therefore, it's recommended to not fully depend on saved variables and run the jobs that set them relatively frequently. It's a good practice to save absolutely critical data as a pair override in the config itself.

To read a variable, use the filter type variableExact. It can be used in all job types.

"filter": {
"type": "variableExact",
"userVariable1": true
}

The filter type for user variables is an exact match only, which returns true when userVariable1 has a value of true.

air variables can be read with a filter like this:

"pairVar": {
"type": "pairVariableExact",
"awesomeVariable": true
}

The same job that sets a variable can also reset it when no pairs pass all filters; this option is called resetVariable. It can contain one or more variables whose value can be filtered as an exact match, similar to setting a variable.

resetVariable looks like this:

"resetVariable": {
"userVariable1": true
}

To reset pair specific variables, use a block like this:

"resetPairVariable": {
"awesomeVariable": false,
"evenBetter": false
}
tip

It's worth noting that variables are entirely optional, and no problem exists when no setVariable exists in a job.

Multiple filter sets

Instead of using a single set of filters, you can also add multiple sets of filters in a job.

Use this when you want to monitor for different conditions in a single job, if a pair passes all filters in any of the filter sets, changes are made.

Besides the obligatory first set of filters, you can add up to 9 more sets. named filters2 to filters10

Config example:

{
"example": {
"pairs": {
"exclude": "",
"include": "",
"maxPairs": 500,
"noBag": false,
"exchange": "binance"
},
"filters": {
"price": {
"type": "minPrice",
"min": 0.0000001
}
},
"filters2": {
"minVolume24h": {
"type": "minVolume24h",
"min": 100
}
},
"schedule": "*/30 * * * * *",
"type": "removePairs",
"enabled": true
}
}