Trade Execution
Learn how to execute trades from your custom strategies.
Overview
Trade execution is handled through the td.trade object. All trade functions queue signals that are processed after your strategy code completes.
Available Functions
Core Functions
td.trade.buy(options?) // Open long position
td.trade.sell(options?) // Open short position
td.trade.close(reason?) // Close current position
td.trade.setStopLoss(price) // Modify stop loss
td.trade.setTakeProfit(price) // Modify take profit
Limit Orders
td.trade.buyLimit(price, options?) // Buy at specified price
td.trade.sellLimit(price, options?) // Sell at specified price
Advanced Entry Methods
td.trade.buyTrail(options) // Buy with trailing stop
td.trade.sellTrail(options) // Sell with trailing stop
td.trade.buyRisk(options) // Buy with risk-based sizing
td.trade.sellRisk(options) // Sell with risk-based sizing
td.trade.buyATR(options) // Buy with ATR-based SL/TP
td.trade.sellATR(options) // Sell with ATR-based SL/TP
td.trade.dcaBuy(options) // Dollar-cost average buy
td.trade.dcaSell(options) // Dollar-cost average sell
td.trade.grid(options) // Grid trading setup
Advanced Exit Methods
td.trade.closeTrail(options) // Close with trailing
td.trade.closeInSteps(steps) // Close in multiple steps
td.trade.closeAfter(options) // Time-based close
td.trade.scaleOutAtTargets(targets) // Scale out at price targets
td.trade.lockProfits(options) // Progressive profit lock
td.trade.breakevenAfter(options) // Auto-breakeven
Position Reversal
td.trade.flip(reason?) // Reverse position (close + open opposite)
td.trade.hedge(options) // Open hedge position
Trade Options
interface TradeOptions {
amount?: number; // Fixed amount in base currency
amountPercent?: number; // Percentage of balance (1-100)
price?: number; // Limit price (market order if omitted)
stopLoss?: number; // Stop loss price
takeProfit?: number; // Take profit price
leverage?: number; // Position leverage (futures)
reason?: string; // Log reason for trade
}
Opening Positions
Market Orders
Execute immediately at current market price:
// Buy with 100% of available balance
td.trade.buy({
amountPercent: 100,
reason: 'Market entry'
});
// Short with fixed amount
td.trade.sell({
amount: 0.1, // 0.1 BTC
reason: 'Short entry'
});
Limit Orders
Execute at specified price or better:
// Buy limit below current price
td.trade.buy({
amountPercent: 50,
price: td.market.price * 0.99, // 1% below market
reason: 'Limit buy order'
});
// Sell limit above current price
td.trade.sell({
amountPercent: 100,
price: td.market.price * 1.02, // 2% above market
reason: 'Limit sell order'
});
With Stop Loss and Take Profit
const price = td.market.price;
td.trade.buy({
amountPercent: 100,
stopLoss: price * 0.98, // 2% stop loss
takeProfit: price * 1.04, // 4% take profit
reason: 'Entry with SL/TP'
});
With Leverage (Futures)
td.trade.buy({
amountPercent: 100,
leverage: 10, // 10x leverage
stopLoss: td.market.price * 0.99,
reason: 'Leveraged long'
});
Closing Positions
Simple Close
// Close entire position
td.trade.close('Exit signal triggered');
// Close with reason for logging
if (td.position.pnlPercent > 5) {
td.trade.close('Taking profit at 5%');
}
Partial Close
To close a partial position, open an opposite position:
// Close half of a long position
if (td.position.side === 'long') {
td.trade.sell({
amount: td.position.size / 2,
reason: 'Scaling out 50%'
});
}
Modifying Positions
Trailing Stop Loss
if (td.position.hasPosition && td.position.side === 'long') {
const trailDistance = td.indicators.atr * 2;
const newStop = td.market.price - trailDistance;
// Only move stop up, never down
if (!td.position.stopLoss || newStop > td.position.stopLoss) {
td.trade.setStopLoss(newStop);
td.utils.log('Trailing stop updated', { newStop });
}
}
Adjusting Take Profit
// Move take profit based on momentum
if (td.position.hasPosition && td.indicators.adx.value > 40) {
// Strong trend - extend take profit
const extendedTP = td.position.entryPrice * 1.08; // 8% instead of 4%
td.trade.setTakeProfit(extendedTP);
}
Position Sizing
Percentage-based
// Use 50% of available balance
td.trade.buy({ amountPercent: 50 });
Fixed Amount
// Fixed 0.1 BTC
td.trade.buy({ amount: 0.1 });
Risk-based Sizing
// Risk 1% of account per trade
const accountBalance = td.account.balance;
const riskPercent = 1;
const stopLossPercent = 2;
// Position size = (Balance × Risk%) / Stop Loss%
const positionValue = (accountBalance * riskPercent) / stopLossPercent;
const positionSize = positionValue / td.market.price;
td.trade.buy({
amount: positionSize,
stopLoss: td.market.price * (1 - stopLossPercent / 100),
reason: `Risk-based entry: ${positionSize.toFixed(4)}`
});
Kelly Criterion
// Kelly Criterion position sizing
const winRate = td.state.get('winRate', 0.55);
const avgWin = td.state.get('avgWin', 0.04);
const avgLoss = td.state.get('avgLoss', 0.02);
// Kelly % = W - [(1-W) / R]
// W = win rate, R = win/loss ratio
const kellyPercent = winRate - ((1 - winRate) / (avgWin / avgLoss));
// Use half Kelly for safety
const positionPercent = Math.max(0, Math.min(kellyPercent * 50, 25));
td.trade.buy({ amountPercent: positionPercent });
Trade Limits
- Maximum 5 signals per spin - Additional signals are ignored
- Duplicate signals ignored - Same action won't repeat in one spin
- Signals queue for execution - Processed after strategy completes
// This will only execute 5 trades max
for (let i = 0; i < 10; i++) {
td.trade.buy({ amountPercent: 10 }); // Only first 5 execute
}
Error Handling
Trades may fail for various reasons. Check position status on next spin:
// Track pending trades
const pendingBuy = td.state.get('pendingBuy', false);
if (pendingBuy && !td.position.hasPosition) {
// Trade might have failed
const attempts = td.state.get('buyAttempts', 0);
if (attempts >= 3) {
td.utils.log('Buy failed after 3 attempts');
td.state.set('pendingBuy', false);
td.state.set('buyAttempts', 0);
} else {
td.state.set('buyAttempts', attempts + 1);
td.trade.buy({ reason: `Retry attempt ${attempts + 1}` });
}
}
// Set pending flag when buying
if (!td.position.hasPosition && buyCondition) {
td.trade.buy({ reason: 'Entry' });
td.state.set('pendingBuy', true);
} else if (td.position.hasPosition) {
td.state.set('pendingBuy', false);
td.state.set('buyAttempts', 0);
}
Common Patterns
Scaling Into Positions
const maxPositions = 3;
const positionsOpened = td.state.get('positionsOpened', 0);
if (positionsOpened < maxPositions && buyCondition) {
td.trade.buy({
amountPercent: 100 / maxPositions,
reason: `Scale in ${positionsOpened + 1}/${maxPositions}`
});
td.state.set('positionsOpened', positionsOpened + 1);
}
Time-based Exits
// Exit after 24 hours regardless of P&L
if (td.position.hasPosition) {
const holdingTime = Date.now() - td.position.openTime;
const maxHoldingTime = 24 * 60 * 60 * 1000; // 24 hours
if (holdingTime > maxHoldingTime) {
td.trade.close('Max holding time reached');
}
}
Break-even Stop
if (td.position.hasPosition && td.position.side === 'long') {
// Move stop to break-even after 2% profit
if (td.position.pnlPercent > 2) {
const breakEven = td.position.entryPrice * 1.001; // Tiny buffer
if (!td.position.stopLoss || td.position.stopLoss < breakEven) {
td.trade.setStopLoss(breakEven);
td.utils.log('Stop moved to break-even');
}
}
}
Advanced Entry Methods
Trailing Entry
Enter with a trailing stop automatically set:
td.trade.buyTrail({
amountPercent: 100,
trailPercent: 2, // Trail 2% behind
activationPrice: 50000, // Activate at this price
reason: 'Entry with trailing stop'
});
Risk-based Sizing
Automatically calculate position size based on risk:
td.trade.buyRisk({
riskPercent: 2, // Risk 2% of account
stopLoss: td.market.price * 0.97, // 3% stop loss
takeProfit: td.market.price * 1.06,
reason: 'Risk-based entry'
});
ATR-based Entry
Use ATR for dynamic stop loss and take profit:
td.trade.buyATR({
amountPercent: 100,
slMultiplier: 1.5, // SL at 1.5x ATR
tpMultiplier: 3.0, // TP at 3x ATR
reason: 'ATR-based entry'
});
Dollar-Cost Averaging
Split entry across multiple price levels:
td.trade.dcaBuy({
totalAmount: 1000, // Total $1000
levels: 4, // Split into 4 entries
spreadPercent: 1, // 1% between each level
reason: 'DCA entry'
});
Grid Trading
Set up a grid of orders:
td.trade.grid({
levels: 5,
spacingPercent: 1,
upperBound: 52000,
lowerBound: 48000,
amountPerLevel: 100,
reason: 'Grid setup'
});
Advanced Exit Methods
Trailing Close
Close position with trailing stop:
td.trade.closeTrail({
trailPercent: 1.5, // Trail 1.5% behind
reason: 'Trailing exit'
});
Step-based Close
Close position in multiple steps:
td.trade.closeInSteps([
{ percent: 30, atPrice: td.position.entryPrice * 1.03 },
{ percent: 30, atPrice: td.position.entryPrice * 1.05 },
{ percent: 40, atPrice: td.position.entryPrice * 1.08 }
]);
Time-based Close
Close after a specific time:
td.trade.closeAfter({
seconds: 3600, // Close after 1 hour
reason: 'Time-based exit'
});
// Or after candles
td.trade.closeAfter({
candles: 10, // Close after 10 candles
reason: 'Candle-based exit'
});
Scale Out at Targets
Automatically scale out at price targets:
td.trade.scaleOutAtTargets([
{ percent: 25, price: td.position.entryPrice * 1.02 },
{ percent: 25, price: td.position.entryPrice * 1.04 },
{ percent: 25, price: td.position.entryPrice * 1.06 },
{ percent: 25, price: td.position.entryPrice * 1.08 }
]);
Progressive Profit Lock
Move stop loss as profit increases:
td.trade.lockProfits({
stepPercent: 5, // Every 5% profit gained
trailPercent: 50, // Lock in 50% of profits
reason: 'Profit lock'
});
Auto-Breakeven
Automatically move to breakeven:
td.trade.breakevenAfter({
profitPercent: 1, // After 1% profit
offsetPercent: 0.1, // Move SL to entry + 0.1%
reason: 'Auto breakeven'
});
Position Reversal
Flip Position
Close current position and open opposite:
if (bearishSignal && td.position.side === 'long') {
td.trade.flip('Trend reversal - flipping to short');
}
Hedge Position
Open opposite position as a hedge:
td.trade.hedge({
percent: 50, // Hedge 50% of position
reason: 'Hedging against volatility'
});
Best Practices
- Always use stop losses - Protect against unexpected moves
- Check position before trading - Avoid duplicate entries
- Use appropriate position sizing - Don't risk too much per trade
- Log trade reasons - Helps with debugging and analysis
- Handle edge cases - Account for failed trades
Next Steps
- State Management - Persist data across spins
- Best Practices - Risk management guidelines
- Examples - Complete strategy examples