Skip to main content

StrategyConfigMsg Schema

FieldTypeRequiredDescription
target_profit_pctnumberYesTake profit threshold as a percentage (e.g., 5 = 5%).
stop_loss_pctnumberYesStop loss threshold as a percentage (e.g., 1.5 = 1.5%).
trailing_stop_pctnumberNoTrailing stop percentage from the peak. Activates only after the position is in profit.
sell_on_graduationbooleanNoIf true, auto sells when a bonding curve token graduates to an AMM pool.
take_profit_levelsTakeProfitLevelMsg[]NoExit ladder: sell partial amounts at multiple profit thresholds. Each level has profit_pct (trigger), sell_pct (portion to sell), and trailing_stop_pct (optional trailing stop for that level).
liquidity_guardbooleanNoWhen enabled, the stream checks available pool liquidity before generating an exit signal. Prevents exits into thin liquidity. Default: false.
breakeven_trail_pctnumberNoA trailing stop that activates once the position breaks even, trailing from the breakeven point rather than the peak.
At least one of target_profit_pct, stop_loss_pct, trailing_stop_pct, or deadline_timeout_sec (on the configure message) must be greater than zero.

TakeProfitLevelMsg Schema

FieldTypeRequiredDescription
profit_pctnumberYesProfit percentage at which this level triggers (e.g., 20 = 20%).
sell_pctnumberYesPercentage of the position to sell at this level (e.g., 50 = sell 50%).
trailing_stop_pctnumberNoOptional trailing stop for this level. If set, instead of selling immediately at profit_pct, a trailing stop activates at this level. Default: 0 (sell immediately).

Setting Strategy at Connection Time

Strategy is provided in the configure message when you first connect:
const session = await StreamSession.connect(client, {
  wallet_pubkeys: ["WALLET_PUBKEY"],
  strategy: {
    target_profit_pct: 10,
    stop_loss_pct: 2,
    trailing_stop_pct: 5,
    sell_on_graduation: true,
  },
  deadline_timeout_sec: 60,
  send_mode: "helius_sender",
  tip_lamports: 1000,
});

Using StrategyConfigBuilder

All 4 SDKs provide a fluent builder for strategy configuration. The builder validates that at least one exit condition is set when you call build().
import { StrategyConfigBuilder } from "@lasersell/lasersell-sdk";

const strategy = new StrategyConfigBuilder()
  .targetProfitPct(50)
  .stopLossPct(10)
  .trailingStopPct(5)
  .takeProfitLevels([
    { profit_pct: 20, sell_pct: 25, trailing_stop_pct: 0 },
    { profit_pct: 50, sell_pct: 50, trailing_stop_pct: 3 },
    { profit_pct: 100, sell_pct: 100, trailing_stop_pct: 5 },
  ])
  .liquidityGuard(true)
  .breakevenTrailPct(2)
  .build();

Exit Ladder (Take Profit Levels)

An exit ladder lets you take partial profits at multiple thresholds instead of exiting your entire position at a single price. Each level specifies a profit target and the percentage of the remaining position to sell.

How it works

  1. When profit reaches a level’s profit_pct, the stream sells sell_pct of the current position.
  2. If a level has trailing_stop_pct > 0, a trailing stop activates at that level instead of selling immediately.
  3. Levels are evaluated in order from lowest to highest profit_pct.
  4. The global target_profit_pct still applies as a hard cap; if reached before all levels fire, the remaining position is sold.

Example

With this exit ladder and an entry of 1 SOL:
{
  "take_profit_levels": [
    { "profit_pct": 20, "sell_pct": 25, "trailing_stop_pct": 0 },
    { "profit_pct": 50, "sell_pct": 50, "trailing_stop_pct": 3 },
    { "profit_pct": 100, "sell_pct": 100, "trailing_stop_pct": 5 }
  ],
  "stop_loss_pct": 15
}
  • At 20% profit (position worth 1.2 SOL): sell 25% immediately.
  • At 50% profit (position worth 1.5 SOL): activate a 3% trailing stop on 50% of the remaining position.
  • At 100% profit (position worth 2 SOL): activate a 5% trailing stop on the remaining position.

Liquidity Guard

When liquidity_guard is enabled, the stream checks pool liquidity before generating an exit signal. If the pool cannot absorb the sell at a reasonable slippage, the signal is deferred until liquidity improves or a timeout forces the exit. This is useful for large positions in thin pools where an immediate sell would result in excessive slippage.
{
  "target_profit_pct": 50,
  "stop_loss_pct": 10,
  "liquidity_guard": true
}

Breakeven Trail

The breakeven_trail_pct field enables a trailing stop that activates once a position breaks even (profit >= 0), trailing from the breakeven point rather than the peak. Unlike the standard trailing_stop_pct which trails from the highest observed profit, the breakeven trail protects you from giving back all gains on a position that briefly went profitable.

Example

With breakeven_trail_pct: 2 and an entry of 1 SOL:
TimeProfit (%)Breakeven Trail ActiveTrigger
t=0-5No (not at breakeven)
t=10Yes (at breakeven)
t=23YesNo trigger (profit > 0)
t=3-1YesNo trigger (drop < 2% from breakeven)
t=4-2.5YesTriggered (drop >= 2% from breakeven)
Combine with a standard trailing_stop_pct to protect both the breakeven point and the profit peak.

Trailing Stop Explained

The trailing stop tracks the highest profit observed since the position opened. When profit drops from that peak by trailing_stop_pct, an exit signal fires.

Numerical Example

TimeProfit (%)Peak (%)Drop from Peak (%)Trailing Stop (5%)
t=0000Not active
t=1330Not active
t=2880Active, no trigger
t=3682Active, no trigger
t=4484Active, no trigger
t=52.585.5Triggered (drop >= 5%)
The trailing stop only activates once the position is in profit. If the position goes negative before ever being in profit, the stop loss triggers instead.

Updating Strategy Mid Session

You can change the strategy at any time without reconnecting by sending an update_strategy message:
{
  "type": "update_strategy",
  "strategy": {
    "target_profit_pct": 15,
    "stop_loss_pct": 3,
    "trailing_stop_pct": 7
  }
}
Using the SDK:
session.updateStrategy({
  target_profit_pct: 15,
  stop_loss_pct: 3,
  trailing_stop_pct: 7,
});
The new strategy takes effect immediately for all tracked positions. No positions are closed or reopened; the server simply re evaluates existing positions against the new thresholds.

Deadline Timeout

The deadline_timeout_sec is set on the configure message (not on the strategy object itself). It defines the maximum time in seconds to hold a position before requesting an exit signal, regardless of profit or loss. Setting deadline_timeout_sec: 60 means the Exit Intelligence Stream will attempt to exit any position held for more than 60 seconds. When using StreamSession, the deadline timer runs client side and automatically calls requestExitSignal when it fires. If you are using StreamClient directly, you must implement deadline logic yourself.

Validation Rules

  • target_profit_pct must be >= 0.
  • stop_loss_pct must be >= 0.
  • trailing_stop_pct (if provided) must be >= 0.
  • deadline_timeout_sec must be >= 0.
  • At least one of these values must be > 0.
Violating these rules raises a StreamClientError with kind "protocol".

Per-Position Strategy Override

You can override the global strategy for individual positions without affecting other tracked positions. This is useful when you want different exit rules for specific tokens.
{
  "type": "update_position_strategy",
  "position_id": 1,
  "strategy": {
    "target_profit_pct": 200,
    "stop_loss_pct": 5,
    "trailing_stop_pct": 10
  }
}
Using the SDK:
session.sender().updatePositionStrategy(positionId, {
  target_profit_pct: 200,
  stop_loss_pct: 5,
  trailing_stop_pct: 10,
});
The override applies only to the specified position. All other positions continue using the global strategy. To revert a position back to the global strategy, send another update_position_strategy with the current global strategy values. Per-position overrides are ephemeral and are not persisted across reconnections.