Actions
Actions are the building blocks of your strategy. Each action defines what the bot should do when its trigger conditions are met. A strategy can have any number of actions, and each is evaluated independently on every candle.
The Three Action Types
Botmarley supports three action types, each serving a distinct purpose in the lifecycle of a trade:
flowchart LR
A["open_long<br/>Open new position"] --> B["buy<br/>Add to position (DCA)"]
B --> C["sell<br/>Exit position"]
style A fill:#22c55e,color:#fff
style B fill:#4a9eff,color:#fff
style C fill:#ef4444,color:#fff
open_long -- Open a New Position
The open_long action creates a new position by buying an asset. This is the entry point of any trade.
When to use: Use open_long for the initial entry into a trade. This action only fires when there is no existing open position (or when max_open_positions has not been reached).
Example:
[[actions]]
type = "open_long"
amount = "100 USDC"
average_price = false
[[actions.triggers]]
indicator = "rsi_14"
operator = "<"
target = "30"
This opens a new position worth 100 USDC when RSI(14) drops below 30.
open_long is the only action type that creates a new position. If you already have an open position and want to add more, use buy instead.
buy -- Add to an Existing Position (DCA)
The buy action adds to an already open position. This is how you implement Dollar-Cost Averaging (DCA) -- buying more when the price drops to lower your average entry price.
When to use: Use buy to add to a position that was opened by open_long. This action only fires when a position is already open.
Example:
[[actions]]
type = "buy"
amount = "200 USDC"
average_price = true
[[actions.triggers]]
type = "pos_price_change"
value = "-2%"
max_count = 1
This adds 200 USDC to the existing position when the price drops 2% from the entry price. The average_price = true flag means the entry price is recalculated (see average_price explained below). The max_count = 1 ensures this DCA level only triggers once per position.
sell -- Exit a Position
The sell action exits part or all of an open position. You can sell a percentage of your position or sell everything.
When to use: Use sell for taking profit, cutting losses (stop-loss), or any exit condition.
Example -- partial exit:
[[actions]]
type = "sell"
amount = "50%"
[[actions.triggers]]
indicator = "rsi_14"
operator = ">"
target = "50"
This sells half the position when RSI rises above 50, locking in partial profit while letting the rest ride.
Example -- full exit:
[[actions]]
type = "sell"
amount = "100%"
[[actions.triggers]]
type = "pos_price_change"
value = "3%"
This sells the entire position when the price rises 3% from entry, closing the trade completely.
Amount Formats
Every action requires an amount field that specifies how much to buy or sell. Botmarley supports two formats:
Fixed Amount: "100 USDC"
A fixed dollar amount. The bot buys or sells exactly this much.
amount = "100 USDC"
When to use: For entries and DCA levels where you want predictable position sizing. Most strategies use fixed amounts for open_long and buy actions.
Supported currencies: USDC, USD, BTC, ETH, and other standard ticker symbols.
Percentage Amount: "50%"
A percentage of either the available balance (for buys) or the current position size (for sells).
amount = "50%" # Sell half the position
amount = "100%" # Sell the entire position
When to use:
- For sell actions:
"50%"means sell half your position;"100%"means exit completely. - For buy actions:
"50%"means use 50% of available balance.
Use percentage amounts for sells and fixed amounts for buys. This gives you predictable entry sizing while allowing flexible exit sizing. For example, selling "50%" first and then "100%" of the remainder lets you scale out of a position as the price rises.
Amount Format Rules
| Format | Example | Valid For | Description |
|---|---|---|---|
| Fixed | "100 USDC" | open_long, buy | Buy exactly 100 USDC worth |
| Fixed | "0.01 BTC" | open_long, buy | Buy exactly 0.01 BTC |
| Percentage | "50%" | buy, sell | 50% of balance or position |
| Percentage | "100%" | sell | Sell the entire position |
Negative amounts are not allowed. The amount must be a positive number. Use the action type (sell) to indicate selling, not a negative amount.
average_price Explained
The average_price flag controls whether the bot recalculates the position's entry price after a buy or open_long action. This is the core mechanism behind Dollar-Cost Averaging (DCA).
How It Works
When average_price = true and the bot buys more of an asset, the entry price is recalculated as a weighted average:
new_entry_price = (old_qty * old_price + new_qty * new_price) / (old_qty + new_qty)
Example:
- You open a position: buy 100 USDC worth of BTC at $50,000. Entry price = $50,000.
- Price drops to $48,000. A DCA
buytriggers: buy 200 USDC more at $48,000. - With
average_price = true, the new entry price becomes:- Total cost: $100 + $200 = $300
- Total BTC: 0.002 + 0.004167 = 0.006167 BTC
- New entry price: $300 / 0.006167 = $48,649
- Now the price only needs to rise to $48,649 (not $50,000) to break even.
When to Use It
| Scenario | average_price | Why |
|---|---|---|
| DCA buy on dip | true | Lower your average entry so you break even sooner |
| Adding to a winner | false | Keep the original entry price for P&L tracking |
Initial open_long | false | No previous position to average with |
All sell actions | false | Selling does not affect entry price |
The average_price flag is only meaningful for open_long and buy actions. Setting it on a sell action has no effect.
Multiple Actions: How They Work Together
A strategy typically has multiple actions -- at least one entry (open_long) and one exit (sell). Here is how they interact:
Evaluation Order
Actions are evaluated independently and in order on every candle:
flowchart TD
A["Candle Closes"] --> B["Evaluate Action 1<br/>(open_long)"]
B --> C["Evaluate Action 2<br/>(buy / DCA level 1)"]
C --> D["Evaluate Action 3<br/>(buy / DCA level 2)"]
D --> E["Evaluate Action 4<br/>(sell / take profit)"]
E --> F["Evaluate Action 5<br/>(sell / stop loss)"]
style A fill:#4a9eff,color:#fff
Key Rules
open_longonly fires when no position is open (or whenmax_open_positionsallows another).buyonly fires when a position IS open -- it has nothing to add to otherwise.sellonly fires when a position IS open -- you cannot sell what you do not have.- Multiple sell actions can coexist -- you might have a take-profit sell at +3% AND a stop-loss sell at -8%. Whichever condition is met first will fire.
- After a 100% sell, the position is closed -- subsequent
buytriggers will not fire untilopen_longcreates a new position.
Typical Action Structure
Most strategies follow this pattern:
# 1. Entry
[[actions]]
type = "open_long"
amount = "100 USDC"
# ... entry triggers ...
# 2. DCA Level 1 (optional)
[[actions]]
type = "buy"
amount = "200 USDC"
average_price = true
# ... dip trigger ...
# 3. DCA Level 2 (optional)
[[actions]]
type = "buy"
amount = "300 USDC"
average_price = true
# ... deeper dip trigger ...
# 4. Take Profit
[[actions]]
type = "sell"
amount = "100%"
# ... profit trigger ...
# 5. Stop Loss
[[actions]]
type = "sell"
amount = "100%"
# ... loss trigger ...