HeyTraders Documentation

Position Management & Advanced Execution

Scaling In - Pyramid Entry

Tags: position_management, scaling, pyramid, trend Functions: sma, rsi Description: Trend-confirmed staged entry with 50% initial position, adding more as the trend continues. Code:

ticker = context['ticker']
ma20 = sma(close, 20)
rsi_val = rsi(close, 14)

# Initial entry: price above MA + RSI not overbought
initial_entry = (close > ma20) & (rsi_val < 60)

# Add position: still above MA + momentum continuing
add_entry = (close > ma20) & (close > close.shift(5)) & (rsi_val < 70)

# Exit: below MA
exit_cond = close < ma20

# Initial position with NoPosition condition
emit(initial_entry, entry(ticker, 'LONG', Weight(0.5), when=NoPosition()))
# Add to position with HasPosition condition
emit(add_entry, entry(ticker, 'LONG', Weight(1.0), when=HasPosition()))
emit(exit_cond, exit_position(ticker))

Partial Take Profit

Tags: position_management, take_profit, partial_exit, scaling Functions: sma Description: Partial profit-taking at 5% gain by reducing position to 50%, with the remainder held until MA exit. Code:

ticker = context['ticker']
ma20 = sma(close, 20)

# Entry
entry_cond = (close > ma20) & (close.shift(1) <= ma20)

# First take profit: 5% gain - reduce to 50%
first_tp = (close > close.shift(10) * 1.05)

# Final exit: price below MA
exit_cond = close < ma20

emit(entry_cond, entry(ticker, 'LONG', Weight(1.0)))
emit(first_tp, entry(ticker, 'LONG', Weight(0.5)))  # Reduce to 50%
emit(exit_cond, exit_position(ticker))

Stop Loss with ATR

Tags: position_management, stop_loss, atr, risk Functions: sma, atr, ATRMultiple Description: Automatically sets an ATR-based stop loss on entry (2x ATR below entry price) for volatility-adjusted risk management. Code:

ticker = context['ticker']
ma20 = sma(close, 20)
atr_val = atr(high, low, close, 14)

entry_cond = (close > ma20) & (close.shift(1) <= ma20)

# Entry with ATR-based stop loss (2x ATR below entry)
emit(entry_cond, entry(
    ticker, 'LONG', Weight(1.0),
    stop_loss=ATRMultiple(2.0, 14)
))

Entry with Fixed Stop Loss

Tags: position_management, stop_loss, percent, fixed Functions: rsi, PercentFromEntry Description: Sets a fixed 3% stop loss on entry. Code:

ticker = context['ticker']
rsi_val = rsi(close, 14)

entry_cond = rsi_val < 30

emit(entry_cond, entry(
    ticker, 'LONG', Weight(1.0),
    stop_loss=PercentFromEntry(-0.03)  # 3% stop loss
))

Entry with Take Profit

Tags: position_management, take_profit, percent, target Functions: rsi, PercentFromEntry Description: Sets a fixed 5% take profit target on entry. Code:

ticker = context['ticker']
rsi_val = rsi(close, 14)

entry_cond = rsi_val < 30

emit(entry_cond, entry(
    ticker, 'LONG', Weight(1.0),
    take_profit=PercentFromEntry(0.05)  # 5% take profit
))

Risk-Reward Setup

Tags: position_management, stop_loss, take_profit, risk_reward Functions: rsi, PercentFromEntry Description: Configures a 1:3 risk-reward ratio with a 2% stop loss and 6% take profit. Code:

ticker = context['ticker']
rsi_val = rsi(close, 14)

entry_cond = rsi_val < 30

emit(entry_cond, entry(
    ticker, 'LONG', Weight(1.0),
    stop_loss=PercentFromEntry(-0.02),   # 2% SL
    take_profit=PercentFromEntry(0.06)   # 6% TP (1:3 R:R)
))

Conditional Entry - No Existing Position

Tags: position_management, condition, no_position, entry Functions: rsi, NoPosition Description: Only enters a new position when no position is currently held, preventing duplicate entries. Code:

ticker = context['ticker']
rsi_val = rsi(close, 14)

entry_cond = rsi_val < 30
exit_cond = rsi_val > 70

emit(entry_cond, entry(ticker, 'LONG', Weight(1.0), when=NoPosition()))
emit(exit_cond, exit_position(ticker))

Exit Only When Has Position

Tags: position_management, condition, has_position, exit Functions: rsi, HasPosition Description: Activates the exit condition only when a position is currently held. Code:

ticker = context['ticker']
rsi_val = rsi(close, 14)

entry_cond = rsi_val < 30
exit_cond = rsi_val > 70

emit(entry_cond, entry(ticker, 'LONG', Weight(1.0)))
emit(exit_cond, exit_position(ticker, when=HasPosition()))

Position Flip (Long to Short)

Tags: position_management, flip, long_short, perpetual Functions: sma Description: Bidirectional EMA crossover with market-data entry/exit signals and broker-state conditions placed only in each Intent's when= argument. Code:

ticker = context['ticker']
fast = ema(close, 20)
slow = ema(close, 50)

# These are Series[bool] market conditions.
long_entry = crossover(fast, slow)
short_entry = crossunder(fast, slow)
long_exit = crossunder(fast, slow)
short_exit = crossover(fast, slow)

# Broker execution conditions stay on the Intent, never in the Series expression.
emit(long_entry, entry(ticker, 'LONG', Weight(1.0), when=NoPosition()))
emit(short_entry, entry(ticker, 'SHORT', Weight(1.0), when=NoPosition()))
emit(long_exit, exit_position(ticker, when=HasPosition(side='LONG')))
emit(short_exit, exit_position(ticker, when=HasPosition(side='SHORT')))

Multi-Level Take Profit

Tags: position_management, take_profit, multi_level, scaling_out Functions: sma Description: Three-stage profit-taking: exit 1/3 at 3% gain, another 1/3 at 6%, and trail the remainder. Code:

ticker = context['ticker']
ma20 = sma(close, 20)

# Track entry price (simplified - use first entry point)
entry_cond = (close > ma20) & (close.shift(1) <= ma20)

# Gain levels (simplified calculation)
gain = (close - close.shift(20)) / close.shift(20)

tp1 = gain > 0.03  # 3% gain
tp2 = gain > 0.06  # 6% gain
final_exit = close < ma20

# Initial full position
emit(entry_cond, entry(ticker, 'LONG', Weight(1.0)))
# Reduce at TP1
emit(tp1, entry(ticker, 'LONG', Weight(0.67)))
# Reduce more at TP2
emit(tp2, entry(ticker, 'LONG', Weight(0.33)))
# Final exit
emit(final_exit, exit_position(ticker))

Time-Based Exit

Tags: position_management, time_based, exit, holding_period Functions: sma Description: Automatically exits after holding for 20 candles, with an additional stop condition. Code:

ticker = context['ticker']
ma20 = sma(close, 20)

entry_cond = (close > ma20) & (close.shift(1) <= ma20)

# Create a counter that resets on entry
# Simplified: exit after 20 bars from any entry signal
bar_count = close.cum_count()
time_exit = (bar_count % 20) == 0

# Also exit on stop condition
stop_exit = close < ma20 * 0.95

emit(entry_cond, entry(ticker, 'LONG', Weight(1.0)))
emit(time_exit | stop_exit, exit_position(ticker))

Trailing Stop - Basic

Tags: position_management, trailing_stop, stop_loss, trend_following Functions: sma, TrailingStop Description: 3% trailing stop that tracks the highest price after entry and exits on a 3% pullback from the peak. Code:

ticker = context['ticker']
ma20 = sma(close, 20)

# Enter on MA crossover with trailing stop
entry_cond = (close > ma20) & (close.shift(1) <= ma20)

emit(entry_cond, entry(
    ticker, 'LONG', Weight(1.0),
    stop_loss=TrailingStop(3)  # 3% trailing stop, immediate activation
))

Trailing Stop - With Activation Gate

Tags: position_management, trailing_stop, activation, profit_protection Functions: ema, rsi, TrailingStop Description: Activates a 3% trailing stop only after 5% profit is reached, with a 7% fixed stop loss protecting the position before activation. Code:

ticker = context['ticker']
ema20 = ema(close, 20)
rsi_val = rsi(close, 14)

entry_cond = (close > ema20) & (rsi_val < 40) & (rsi_val.shift(1) >= 40)

emit(entry_cond, entry(
    ticker, 'LONG', Weight(1.0),
    stop_loss=TrailingStop(
        3,                       # 3% trail from watermark
        activation_percent=5,    # Activate after 5% profit
        initial_stop_percent=7   # 7% fixed SL before activation (also floor after)
    )
))

Trailing Stop - ATR Based

Tags: position_management, trailing_stop, atr, volatility, adaptive Functions: sma, atr, TrailingATR Description: ATR-based trailing stop that automatically adjusts the trail distance proportionally to current volatility. Code:

ticker = context['ticker']
ma50 = sma(close, 50)
atr_val = atr(high, low, close, 14)

# Trend following entry
entry_cond = (close > ma50) & (close.shift(1) <= ma50)

emit(entry_cond, entry(
    ticker, 'LONG', Weight(1.0),
    stop_loss=TrailingATR(2.0, period=14)  # Trail at 2x ATR distance
))

Trailing Stop - Short Position

Tags: position_management, trailing_stop, short, perpetual, futures Functions: ema, rsi, TrailingStop Description: Applies a 4% trailing stop to a short futures position, tracking the lowest price and exiting on a 4% bounce. Code:

ticker = context['ticker']
ema20 = ema(close, 20)
rsi_val = rsi(close, 14)

# Short entry: price below EMA + overbought reversal
short_entry = (close < ema20) & (rsi_val > 70) & (rsi_val.shift(1) <= 70)

emit(short_entry, entry(
    ticker, 'SHORT', Weight(1.0),
    stop_loss=TrailingStop(4)  # 4% trailing stop for short
))

Trailing Stop with Take Profit

Tags: position_management, trailing_stop, take_profit, combined, risk_management Functions: sma, rsi, TrailingStop, PercentFromEntry Description: Combines a 2% trailing stop (activating at 3% profit) with a hard 10% take profit target. Code:

ticker = context['ticker']
ma20 = sma(close, 20)
rsi_val = rsi(close, 14)

entry_cond = (close > ma20) & (rsi_val < 35)

emit(entry_cond, entry(
    ticker, 'LONG', Weight(1.0),
    stop_loss=TrailingStop(2, activation_percent=3),  # 3% profit to activate, 2% trail
    take_profit=PercentFromEntry(0.10)                   # Hard cap at 10% profit
))