Advanced Mode
Advanced Mode unlocks the full power of Tradecraft's strategy engine by allowing you to write custom trading strategies in JavaScript. Unlike Easy Mode's visual interface, Advanced Mode gives you complete programmatic control over your trading logic, enabling you to build sophisticated, multi-step strategies that respond to market conditions in real-time.
The syntax of the JavaScript strategy is relatively simple, and barrier to entry for less technical users is low.
What is Advanced Mode?
Advanced Mode is a JavaScript-based strategy editor that provides:
Full programming control - Write JavaScript code to define your trading logic
Multi-step execution - Create strategies with multiple conditional steps that execute sequentially
Real-time data access - Access live price data, historical price ticks and token metadata.
Custom indicators - Implement your own technical analysis and custom calculations
Strategy state management - Maintain context and variables across strategy executions
Debugging capabilities - Set breakpoints, inspect variables, and step through your strategy logic
Why Use Advanced Mode?
Choose Advanced Mode when you need:
Complex conditional logic - Implement sophisticated if/then rules that go beyond simple buy/sell targets
Custom calculations - Calculate your own indicators, moving averages, volatility measures, or trend analysis
Multi-phase strategies - Create strategies with different behavior at different stages (entry, accumulation, exit)
Dynamic position sizing - Calculate buy/sell percentages based on market conditions, not fixed amounts
Token metadata filtering - Filter trades based on token age, creation time, or other properties
Custom risk management - Implement stop-losses, trailing stops, or dynamic risk adjustment
How Strategies Work
Tradecraft strategies are JavaScript classes that define a series of steps. Each step:
Runs sequentially - Steps execute in order from first to last
Receives price data - Steps get the entry price and current price as parameters
Returns a decision - Each step returns whether to buy, sell, stay at the same step or continue to the next step without buying or selling. The decision contains how large part of the position should be bought or sold.
Can access context - Steps can read/write to shared strategy context for state management, to save data that persists over the lifetime of the strategy execution.
Here is a minimal example:
class Strategy {
constructor() {
this.strategy = {
data: {
token: {
address: "",
creationTime: 0
},
priceTicks: []
},
steps: [
{
run: (entry, current) => this.checkBuy(entry, current),
label: "Buy on 10% dip"
},
{
run: (entry, current) => this.checkSell(entry, current),
label: "Sell at 2x"
}
],
context: {}
}
}
checkBuy(entryPrice, currentPrice) {
// Buy if price drops 10% from entry
if (currentPrice <= entryPrice * 0.9) {
return {
buy: true,
partToBuyInPercentage: 100
};
}
return { buy: false, partToBuyInPercentage: 0 };
}
checkSell(entryPrice, currentPrice) {
// Sell when price doubles
if (currentPrice >= entryPrice * 2) {
return {
sell: true,
partToSellInPercentage: 100
};
}
return { sell: false, partToSellInPercentage: 0 };
}
}When Strategies Execute
Your strategy code runs continuously on the signals that comes from the connected signal source. The strategy engine executes each step in sequence, passing the entry price (signal price or buy price) and current price to each step's run() function.
In the example, the strategy will wait for a 10% price decrease compared to the price at the signal time. As soon as this occurs, it will open a position and start executing the strategy at it's second step, which sells the whole position at a 100% (2x) price increase.
JavaScript Syntax Reference
This section describes the complete JavaScript syntax specification for Tradecraft strategies.
Class Structure
Every strategy must be a JavaScript class named Strategy with a specific structure:
class Strategy {
constructor() {
this.strategy = {
data: {
token: {
address: "",
creationTime: 0
},
priceTicks: []
},
steps: [
// Array of step objects
run => this.myStep(entry, current)
],
context: {}
}
}
// Your custom step methods here
myStep(entry, current) {
// step logic
}
}Required Properties
1. this.strategy.data
Contains runtime data automatically injected by the strategy engine:
token- Object with token information:address(string) - Token mint addresscreationTime(number) - Token creation timestamp in milliseconds since epoch
priceTicks- Array of price objects:Each tick contains:
{ usdPrice: number, timestamp: number }Maximum 1000 ticks, in 5 second intervals
Ordered with the latest price at the start of the array
Example:
priceTicks[0]gives the current price
2. this.strategy.steps
Array of step objects that execute sequentially. Each step object has:
run(function) - The step execution functionParameters:
(entry, current)- MUST be exactly these two parametersentry- Entry price (signal price for first buy, purchase price for sells)current- Current market price
Return value: Must return one of the allowed return types (see below)
label(string) - Optional descriptive label for the step
Example:
steps: [
{
run: (entry, current) => this.checkBuy(entry, current),
label: "Buy on 10% dip from signal"
},
{
run: (entry, current) => this.checkSell(entry, current),
label: "Sell at 2x profit"
}
]3. this.strategy.context
Object for storing state across strategy executions. Use this for:
Tracking highest price for trailing stops
Recording when buys/sells occurred
Storing custom calculations or flags
Example:
// In a step function:
if (!this.strategy.context.highestPrice) {
this.strategy.context.highestPrice = current;
} else if (current > this.strategy.context.highestPrice) {
this.strategy.context.highestPrice = current;
}Step Function Return Values
Step functions MUST return one of these exact formats:
Buy Action
return {
buy: true, // boolean
partToBuyInPercentage: 100 // number (0-100)
};Sell Action
return {
sell: true, // boolean
partToSellInPercentage: 50 // number (0-100)
};Move to Next Step (without buying or selling)
return {
moveToNextStep: true
};No Action (stay on current step)
return null;Important Notes:
You CANNOT return anything else besides these four formats
Returning
nullkeeps you on the current step for the next price tickReturning
moveToNextStep: trueadvances to the next step permanently - use carefully!Once a step returns
buy: true,sell: true, ormoveToNextStep: true, that step will NEVER execute again
Common Patterns
Trailing Stops:
// Track highest price in context
if (!context.highestPrice || current > context.highestPrice) {
context.highestPrice = current;
}
// Sell if drops X% from peak
const dropPercent = (context.highestPrice - current) / context.highestPrice;
if (dropPercent >= 0.15) {
return { sell: true, partToSellInPercentage: 100 };
}Time-Based Exits:
// Store entry time in context during buy step
context.entryTime = Date.now();
// In sell step, check elapsed time
const hoursHeld = (Date.now() - context.entryTime) / (1000 * 60 * 60);
if (hoursHeld >= 24 && currentPrice > entryPrice) {
return { sell: true, partToSellInPercentage: 100 };
}Last updated
