The bot follows a classic DCA (Dollar-Cost Averaging) model: it opens a position with a Base Order (BO), then, if price drops, buys more in stages via Safety Orders (SOs) to lower the average entry price, and exits using one or more take-profit/stop-loss mechanisms running in parallel.
Each trading pair (symbol) is managed by its own independent worker loop, scanning conditions every 0.5 seconds: buy conditions are checked first, then sell conditions, in that exact sequential order on every iteration.
[Waiting for buy signal] -> BASE ORDER filled
|
v
[Holding a position] ---- price drops ----> SAFETY ORDER 1, 2, ... (if enabled)
|
+- price rises enough -> TAKE PROFIT (Static / Dynamic / Trailing)
|
+- price drops to threshold -> STOP LOSS (Static / Dynamic)
|
v
[Position fully closed] -> state reset -> back to step 1
An important point to grasp before reading the sections below: every buy/sell order in the bot is reactive. The bot does not pre-place any resting orders on the exchange order book. It continuously watches the price, and only once a condition is detected as met does it submit a LIMIT order priced exactly at the market price observed at that moment (deliberately, so it fills immediately, accepting the Taker role). This applies to both buy orders (BO/SO) and LIMIT sell orders used for take profit (Static TP, Dynamic TP).
The bot only buys a Base Order when all enabled technical indicators are satisfied at the same time (a logical AND, not OR):
| Indicator | Buy condition |
|---|---|
| RSI | rsi_min < RSI < rsi_oversold (default: 20 < RSI < 30) |
| MA | Short-term MA crosses above long-term MA (ma_short > ma_long) |
| MACD | MACD line above the Signal line |
| ADX | ADX > adx_threshold and +DI > -DI (uptrend strong enough) |
| Bollinger Bands | Current price touches or is below the lower band |
| Volume | Trading volume exceeds the configured threshold |
Important note: if you do not enable any indicator, the bot will buy the Base Order immediately once the capital condition is met, without waiting for any technical signal. This is deliberate behavior, and the bot will send a one-time alert when it detects this situation.
When price drops after the Base Order, the bot buys more in configured SO tiers:
[1.0, 2.0] means: SO1 triggers when the market price drops 1% below your initial Base Order fill price. SO2 triggers when the price drops 2% below that same original Base Order price. By referencing the initial entry rather than the moving average cost, the bot maintains your exact intended spacing and prevents the safety net from compressing as your average cost lowers.allocated_capital × safety_order_volume_scale. This multiplier is applied as a fixed, static value across all SO tiers–it does not compound or scale exponentially (Martingale) with subsequent orders. Each dip-buying order will deploy the exact same amount of USDT. (Note: If you previously used a progressively scaling Martingale strategy, please note this version utilizes a linear volume approach to strictly control maximum capital exposure).rsi_min (default 20). If the RSI drops below this threshold, the bot will refuse to buy any Safety Order regardless of how far the price has dropped. This is a crucial defense mechanism that prevents the bot from blindly buying into a sharp market crash (deep oversold condition) just because a grid percentage was hit, saving your capital from "catching a falling knife."This section covers the meaning, strengths/weaknesses, and practical usage of each indicator the bot supports.
alpha = 1/period). Smoother and reacts slightly slower than a "raw" RSI formula.rsi_min (20) < RSI < rsi_oversold (30). The bot deliberately avoids buying both when RSI is too low (treated as a risk that price keeps falling) and when RSI has already recovered above 30.short MA > long MA.ADX > adx_threshold (25) and +DI > -DI.+DI > -DI condition to determine the direction of the trend (up).(current volume / 20-candle average) x 100 > volume_threshold (150.0).The use_closed_candle_only parameter determines whether the bot calculates indicators on fully closed candles or on the candle currently forming (live).
| Closed candles only (default, True) | Allow using the live candle (False) | |
|---|---|---|
| Pros | Stable signals, no "repainting" of values; RSI/MA/MACD values are final. | Reacts faster, may catch an entry point earlier during a sharp move. |
| Cons | Always lags real price action by up to one full candle. | "Flickering" signals risk entry based on an unstable state. |
The bot has 5 exit mechanisms, each can be toggled independently and they run in parallel.
Split into 3 levels, TP1, TP2, and TP3, each selling a portion of the position according to configured percentages. The actual sell amount is always capped by the real quantity currently held, ensuring the position is never stuck with leftover coins after all 3 tiers have triggered, as long as tp3_sell_percent is kept high enough (100% is safe).
If a tier's calculated amount comes out below 5.5 USDT (under the exchange's minimum), the bot automatically merges that portion into the next tier.
The take-profit level is calculated dynamically: entry price + (ATR x atr_tp_multiplier). If Static TP is also enabled at the same time, Dynamic TP is completely locked out until TP3 (static) has triggered. If Static TP is disabled, Dynamic TP operates independently from the start.
Instead of selling at a fixed price, Trailing TP follows the price upward to maximize profits during strong pumps.
Example (Min Profit = 2.0%, Trailing TP = 1.0%):⚠️ WARNING: MARKET ORDER FEES & SLIPPAGE
Trailing TP uses a MARKET SELL order to ensure immediate execution when the price drops.Sells the entire position with a MARKET order when price drops to either the fixed percentage (Static) or the ATR-based level (Dynamic). The bot cuts the loss as soon as either condition is hit first. There is no Trailing Stop Loss feature.
The user presses a button to immediately sell an open position with a MARKET order. If you select a specific pair, it sells only that pair. If no pair is selected, it triggers a 'Panic Sell All' for your entire active portfolio. After a successful Panic Sell, that pair is automatically paused to prevent the bot from immediately buying back in.
Allows you to "isolate" a currently held position out of the DCA management system and set a manual target sell price. The position moves to a separate tracking list, checked every 5 minutes, freeing the bot to resume trading that pair from scratch whenever a new signal appears.
Because every Safety Order is placed reactively, there is no SO order sitting on the exchange to "cancel". Instead, a state flag is set. If any TP tier has ever triggered, the bot will not buy more to lower the average price even if the price reverses sharply. This avoids a conflict between "currently taking profit" and "currently averaging down a loss".
Static TP always takes absolute priority. With the default configuration (tp3_sell_percent = 100%), the position is always fully sold at TP3, so in practice Dynamic TP never gets a chance to run. Recommendation: if you choose Static TP, disable Dynamic TP entirely.
Dynamic TP only sells dynamic_tp_sell_percent% once the ATR-based TP level is reached, and hands the remainder to Trailing TP, which continues tracking the price peak.
Because Trailing TP has the constraint of "never selling at a loss", in a scenario where price rises slightly then drops sharply, Stop Loss (if enabled) is the only line of defense preventing the position from losing further.
When a pair reaches 3 consecutive stop-loss exits, the bot automatically pauses trading for that pair for 24 hours from the most recent loss, then automatically resumes.
| Parameter | Default | Meaning |
|---|---|---|
capital | 100.0 | USDT capital allocated to this pair's Base Order |
interval | 15m | Candle timeframe used for indicator calculations |
use_closed_candle_only | True | Only calculate indicators on closed candles (avoids noise mid-candle) |
use_rsi / rsi_period / rsi_min / rsi_oversold | True / 14 / 20 / 30 | RSI zone condition allowing a buy |
use_ma / ma_short_period / ma_long_period | False / 9 / 21 | Moving average crossover condition |
use_macd | False | MACD crossing above Signal condition |
use_adx / adx_period / adx_threshold | False / 14 / 25 | Trend strength condition (+DI > -DI is hardcoded) |
use_bollinger / bollinger_period / bollinger_std | False / 20 / 2.0 | Price touching the lower Bollinger band condition |
use_volume / volume_threshold | False / 150.0 | Minimum trading volume condition |
max_safety_orders | 2 | Maximum number of Safety Order tiers |
safety_order_steps | [1.0, 2.0] | Percentage drop to trigger each SO tier |
safety_order_volume_scale | 1.0 | Multiplier applied to capital to get each SO's size |
use_static_tp | True | Enable/disable fixed staged profit-taking |
tp1_percent / tp1_sell_percent | 2.0 / 40.0 | Profit level % and sell % at TP1 |
tp2_percent / tp2_sell_percent | 4.0 / 50.0 | Profit level % and sell % at TP2 |
tp3_percent / tp3_sell_percent | 6.0 / 100.0 | Profit level % and sell % at TP3 |
use_dynamic_tp | False | Enable/disable ATR-based profit-taking |
atr_tp_multiplier | 2.0 | ATR multiplier used to calculate the dynamic profit-taking level |
dynamic_tp_sell_percent | 50.0 | Sell % at Dynamic TP (only meaningful when Trailing TP is also enabled) |
use_trailing_tp | False | Enable/disable peak-based profit-taking |
trailing_take_profit_percent | 1.0 | Percentage price is allowed to pull back from the peak before selling |
min_profit_percent | 0.5 | Minimum required profit before Trailing TP or Dynamic TP is allowed to sell |
use_static_sl / static_sl_percent | False / 5.0 | Fixed-percentage stop loss |
use_dynamic_sl / stop_loss_atr_multiplier | False / 2.0 | ATR-based stop loss |
atr_period | 14 | ATR calculation period (shared by Dynamic TP and Dynamic SL) |
These are architectural characteristics users should know before trading with significant capital:
Prioritizing Taker orders results in slightly higher transaction fees for the user. However, in the architecture of an automated trading bot (especially a DCA grid), the practice of holding orders internally on the server and only executing Taker orders when conditions are met is not a sign of poor programming; rather, it is a deliberate trade-off made to secure the following four critical strategic advantages:
3. Once any Take Profit tier has triggered, Safety Orders are permanently locked out for that position, so the remaining position after a partial profit-take is not any better protected against subsequent adverse moves, beyond whatever Stop Loss you may have enabled.
When to use it: you want to exit one or all open positions immediately, regardless of what the indicators/TP/SL are currently saying.
Steps:
Things to note after clicking it:
is_running = False) to prevent the bot from immediately buying back in.When to use it: you want to "shelve" a position that is losing money, freeing the bot to resume trading that pair from scratch whenever a new signal appears.
Steps to isolate a position:
When to use it: before turning on a new configuration with real money, you want to estimate how it would have performed based on actual historical price data.
Steps:
Key points to understand before trusting the backtest results:
This document will be updated whenever the bot's architecture changes.