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
justBoughtConditionfilter:- A per-pair variable named
statuswill be set to the string"awaiting_first_sell_target". So, if USDT-BTC passes,this.pairVariables.binance['USDT-BTC'].statusbecomes"awaiting_first_sell_target". lastBuyTimestampfor that specific pair will be set to the current Unix timestamp (in milliseconds).initialStopLossfor that pair will be calculated as 95% of itslastBuyPrice(accessed viathis.pair.lastBuyPricebecause 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'slastBuyPriceand a global profit target percentage.isHighRisk: Sets a boolean flag for the pair if its (hypothetical)this.pair.volatilityis 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-ETHorBTC-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-BTCneeds a specific override due to unique conditions, it can set a flag likebtcNeedsSpecialOverride: true. A subsequentmanageOverridesjob can filter for this specific flag onUSDT-BTCto apply the change.
Important Pointsโ
- Context is Key:
setPairVariableapplies to each pair that passes the filters. Dynamic values usingthis.pairwill 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
pairVariableExactetc.: To use these variables in subsequent filter decisions, employ thepairVariableExact,pairVariableBiggerThan, orpairVariableSmallerThanfilter types, or read them incustomscripts 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.