Gunbot's AutoConfig feature allows for intricate, stateful automation by not only using global variables but also variables specific to each trading pair on an exchange. The setPairVariable
object, when used as an action in an AutoConfig job, enables you to create or update these per-pair variables for all pairs that successfully pass the job's defined filters. This allows for highly targeted and adaptive logic.
Nearly every option that follows can be set without editing files by hand.
Click the โฎ (three-dots) menu โ AutoConfig, step through the wizard, and press Save; it will write a correct autoconfig.json
for you.
The setPairVariable
Action: Tailoring State to Each Pairโ
The setPairVariable
action is a powerful component of AutoConfig jobs that process lists of trading pairs (like manageOverrides
, addPairs
, removePairs
, changeStrategy
). If a pair meets all the conditions defined in the job's filters
(or filters2
, etc.), the instructions within the setPairVariable
object are executed for that specific pair.
This means you can:
- Mark a pair with a status (e.g.,
lastAction: "bought"
). - Increment a counter specific to that pair (e.g.,
dcaLevelForThisPair: 2
). - Store a timestamp relevant to that pair (e.g.,
cooldownUntilForPairX: 1678886400
).
These per-pair variables are stored in autoconfig-pairVariables.json
, organized by exchange name, then by pair name, ensuring they are unique and persistent.
Configuration Exampleโ
Let's consider a manageOverrides
job that identifies pairs that have just had a buy order (hypothetically detected by other means or a complex custom filter not shown here for brevity) and sets a per-pair variable status
to "awaiting_first_sell_target".
{
"markBoughtPairsJob": {
"enabled": true,
"type": "manageOverrides", // This job type iterates through existing pairs
"schedule": "*/1 * * * *", // Runs frequently
"pairs": {
"exchange": "binance",
"include": "USDT-"
},
"filters": {
"justBoughtCondition": { // A filter that identifies pairs recently bought
"filterType": "custom",
"script": "return this.pair && this.pair.lastBuyPrice > 0 && (this.pair.lastSellPrice === 0 || this.pair.lastBuyPrice > this.pair.lastSellPrice);" // Simplified example
}
},
"setPairVariable": { // User setting: Action to set per-pair variables
"status": "awaiting_first_sell_target",
"lastBuyTimestamp": " new Date().getTime() ", // Dynamic value: current timestamp
"initialStopLoss": " this.pair.lastBuyPrice * 0.95 " // Dynamic: 5% below last buy
}
// This job might not even have an 'overrides' section if its sole purpose is to set pair variables
}
}
In the markBoughtPairsJob
:
- For every USDT pair on Binance that passes the
justBoughtCondition
filter:- A per-pair variable named
status
will be set to the string"awaiting_first_sell_target"
. So, if USDT-BTC passes,this.pairVariables.binance['USDT-BTC'].status
becomes"awaiting_first_sell_target"
. lastBuyTimestamp
for that specific pair will be set to the current Unix timestamp (in milliseconds).initialStopLoss
for that pair will be calculated as 95% of itslastBuyPrice
(accessed viathis.pair.lastBuyPrice
because the value string starts with a space).
- A per-pair variable named
Later, another AutoConfig job could use a pairVariableExact
filter for status: "awaiting_first_sell_target"
to find these specific pairs and apply further logic or overrides.
Dynamic Values in setPairVariable
โ
As shown in the example, values within setPairVariable
can be JavaScript expressions if the string starts with a leading space. This is extremely powerful for per-pair variables, as you can use data from this.pair
(the current pair's ledger data), this.variables
(global variables), or even this.tickers
.
More Dynamic Examples:
"setPairVariable": {
// Increment a pair-specific counter
"buyAttemptsThisCycle": " ( (this.pairVariables[this.exchangeName]?.[this.pairName]?.buyAttemptsThisCycle || 0) + 1 ) ",
// Store a calculated value based on ledger and global variable
"targetSellPrice": " this.pair.lastBuyPrice * (1 + (this.variables.globalProfitTargetPercent || 2) / 100) ",
// Set a boolean flag based on a condition
"isHighRisk": " this.pair.volatility > (this.variables.highRiskVolatilityThreshold || 5) "
}
buyAttemptsThisCycle
: Safely increments a counter specific to the pair. It reads the existing value (defaulting to 0 if not present), adds 1, and stores it back.targetSellPrice
: Calculates a target sell price based on the pair'slastBuyPrice
and a global profit target percentage.isHighRisk
: Sets a boolean flag for the pair if its (hypothetical)this.pair.volatility
is above a global threshold.
resetPairVariable
: Conditional Setting for Non-Passing Pairsโ
Similar to resetVariable
for global variables, resetPairVariable
can be used to set or clear per-pair variables for pairs that were evaluated by the job but did not pass the filter conditions.
{
"statusUpdaterJob": {
// ...
"filters": { "isActiveTradingWindow": { /* ... */ } },
"setPairVariable": { // For pairs passing 'isActiveTradingWindow'
"tradingWindowAlert": false
},
"resetPairVariable": { // For pairs NOT passing 'isActiveTradingWindow'
"tradingWindowAlert": true // Flag these pairs for attention
}
}
}
This ensures that tradingWindowAlert
is false
for active pairs and true
for inactive ones processed by this job.
Key Use Casesโ
- Pair-Specific State Machines: Guide a pair through multiple stages (e.g., "bought_dip_1", "bought_dip_2", "target_reached").
- Individual Counters/Limits: Track DCA levels, number of consecutive wins/losses, or retry attempts for each pair like
USDT-ETH
orBTC-ETH
. - Storing Pair-Contextual Data: Save calculated indicators, important prices (like first buy price), or timestamps of specific events related to that pair.
- Conditional Workflows: Enable complex sequences where one job sets a per-pair variable, and other jobs or even different filter sets within the same job react specifically to that pair's state. For example, if a job identifies that
USDT-BTC
needs a specific override due to unique conditions, it can set a flag likebtcNeedsSpecialOverride: true
. A subsequentmanageOverrides
job can filter for this specific flag onUSDT-BTC
to apply the change.
Important Pointsโ
- Context is Key:
setPairVariable
applies to each pair that passes the filters. Dynamic values usingthis.pair
will correctly reference the data of the specific pair being processed in that iteration. - Initialization: When using dynamic expressions to modify existing per-pair variables (like counters), always provide a default using
||
(e.g.,(this.pairVariables[ex]?.[p]?.myCounter || 0) + 1
) to handle cases where the variable hasn't been initialized for that pair yet. - Data Persistence: Changes are saved to
autoconfig-pairVariables.json
. - Read with
pairVariableExact
etc.: To use these variables in subsequent filter decisions, employ thepairVariableExact
,pairVariableBiggerThan
, orpairVariableSmallerThan
filter types, or read them incustom
scripts usingthis.pairVariables[this.exchangeName]?.[this.pairName]?.yourVariable
.
The setPairVariable
action is a cornerstone for creating truly adaptive and intelligent AutoConfig setups that treat each trading pair as an individual entity with its own history and state, leading to more nuanced and potentially more effective automated trading.