Python Script Documentation

Create and run Python scripts in a secure, sandboxed environment with full access to your exchange data

Automate trading, analyze positions, and react to real-time price changes

Script Types

⚑

One-Shot Scripts

Run once and exit. Ideal for calculations, reports, and one-time actions.

Max Runtime:5-300 seconds
Memory:64-256 MB
CPU:0.25-0.5 cores
Data Access:Polling
πŸ”„

Long-Running Scripts

Run indefinitely until stopped. Ideal for price watchers, pattern detection, and bots.

Max Runtime:Indefinite
Memory:128-512 MB
CPU:0.5-1.0 cores
Data Access:WebSocket + Polling

Getting Started

1

Navigate to Scripts

Go to Dashboard β†’ Scripts

2

Create a Script

Click + Create Script, choose a type (One-Shot or Long-Running), and enter a name

3

Write Your Code

The Traydar SDK is pre-imported. Use functions like get_positions() and place_order()

4

Execute

Click Test Run, select an exchange, and watch the output stream in real-time

πŸ€–

AI Coding Assistant

Get help writing, debugging, and optimizing your Python scripts with our built-in AI assistant

How to Use the AI Assistant

When editing a script, click the πŸ’¬ AI Assistant button to open the chat panel. The AI knows the complete Traydar SDK and can help you with:

  • Generate complete scripts from natural language descriptions
  • Explain code in plain English with detailed breakdowns
  • Debug errors and fix issues in your scripts
  • Add features to existing code with smart merging
  • Optimize performance and follow best practices
  • Add error handling with proper try/except blocks

Example Prompts

"Generate a script that monitors BTC price and alerts me when it crosses $100,000"

AI will create a long-running script with @on_price decorator

"Explain what this code does"

AI will analyze your current code and explain it step-by-step

"Add error handling to this script"

AI will wrap risky operations in try/except blocks

"Create a daily portfolio report script"

AI will generate a one-shot script that checks positions and sends a report

Smart Code Insertion

When the AI generates code, you can insert it into your editor with three modes:

Replace All

Replaces your entire script with AI-generated code

Append

Adds new code to the end of your script

Smart Merge

Intelligently merges new code with existing code

πŸ’‘ Pro Tip

The AI assistant understands the difference between one-shot and long-running scripts. It will automatically use the right patterns (@on_price, run_forever(), etc.) based on your script type. Your conversation history is saved per script, so you can continue where you left off!

SDK Reference

The Traydar SDK is automatically available in all scripts. No import is needed for basic functions.

Data Access Functions

get_positions()

Get all open positions from your connected exchange.

positions = get_positions()
# Returns: [
#   {"symbol": "BTC/USDT", "amount": 0.5, "unrealized_pnl": 150.25, ...},
#   ...
# ]

for pos in positions:
    print(f"{pos['symbol']}: {pos['amount']} ({pos['unrealized_pnl']})")

get_balances()

Get account balances for all currencies.

balances = get_balances()
# Returns: [
#   {"currency": "USDT", "free": 1000.0, "used": 500.0, "total": 1500.0},
#   {"currency": "BTC", "free": 0.5, "used": 0, "total": 0.5},
#   ...
# ]

get_orders()

Get all open orders.

orders = get_orders()
# Returns: [
#   {"id": "123", "symbol": "BTC/USDT", "side": "buy", "amount": 0.1, ...},
#   ...
# ]

get_trigger_payload()

Get the payload passed when the script was triggered (for webhook-triggered executions).

payload = get_trigger_payload()
# Returns: {"symbol": "BTC/USDT", "action": "BUY", ...} or {}

if payload.get('action') == 'BUY':
    place_order(symbol=payload['symbol'], side="buy", ...)

Trading Functions

place_order()

Place a new order on the exchange.

# Market order
order = place_order(
    symbol="BTC/USDT",
    side="buy",          # "buy" or "sell"
    amount=0.001,
    order_type="market"  # "market" or "limit"
)

# Limit order
order = place_order(
    symbol="ETH/USDT",
    side="sell",
    amount=0.1,
    order_type="limit",
    price=4000.0
)

cancel_order()

Cancel an existing order.

success = cancel_order(order_id="12345")

if success:
    print("Order cancelled successfully")
else:
    print("Failed to cancel order")

send_message()

Send a notification via Telegram.

send_message("BTC position closed with $150 profit!")

# With formatting
send_message(f"πŸš€ Trade executed: {symbol} at ${price}")

set_result()

Set the script result (stored in execution history).

set_result({
    "profit": 150.25,
    "trades_executed": 3,
    "status": "success"
})

# The result is visible in the execution history

Real-Time Streaming

Long-running scripts only. Use decorators to react to real-time price changes.

@on_price decorator

React to price changes for a specific symbol.

from traydar import on_price, run_forever

@on_price("BTC/USDT", exchange="binance")
def handle_btc_price(price: float, timestamp):
    print(f"BTC price: ${price}")

    if price > 100000:
        place_order(
            symbol="BTC/USDT",
            side="sell",
            amount=0.001,
            order_type="market"
        )
        send_message(f"BTC hit ${price}! Sold 0.001 BTC")

# Required at the end of long-running scripts
run_forever()

@on_ticker decorator

Get full ticker data including 24h change and volume.

from traydar import on_ticker, run_forever

@on_ticker("ETH/USDT", exchange="binance")
def handle_eth_ticker(ticker):
    print(f"ETH: ${ticker.last}")
    print(f"24h Change: {ticker.change_percent}%")
    print(f"Volume: {ticker.volume}")

run_forever()

PriceWatcher class

Utility class for common price patterns.

from traydar import PriceWatcher, run_forever

watcher = PriceWatcher("BTC/USDT", exchange="binance")

@watcher.on_crosses_above(100000)
def btc_above_100k(price):
    send_message(f"BTC crossed $100k! Current: ${price}")

@watcher.on_crosses_below(90000)
def btc_below_90k(price):
    send_message(f"BTC dropped below $90k!")

@watcher.on_percent_change(5, timeframe="1h")
def big_move(change_percent, price):
    send_message(f"BTC moved {change_percent}% in the last hour!")

run_forever()

Message Listeners

Long-running scripts only. Listen for real-time messages from webhooks using the @on_message decorator.

@on_message decorator

Long-running scripts can listen for real-time messages from webhooks. Webhooks send messages using the script_listener parameter.

from traydar import on_message, run_forever, place_order, send_message

@on_message
def handle_webhook_alert(payload):
    """
    Receives messages from webhooks with script_listener parameter.
    Payload contains the entire webhook data.
    """
    print(f"Received alert: {payload}")

    alert_type = payload.get('alert_type')
    price = payload.get('price')

    if alert_type == 'resistance_break' and price > 98000:
        place_order(
            symbol="BTC/USDT",
            side="buy",
            amount=0.1,
            order_type="market"
        )
        send_message(f"πŸš€ Resistance broken at ${price}! Bought 0.1 BTC")

    elif alert_type == 'stop_loss':
        # Close all positions
        positions = get_positions()
        for pos in positions:
            place_order(
                symbol=pos.symbol,
                side='sell' if pos.side == 'long' else 'buy',
                amount=pos.size,
                order_type='market'
            )
        send_message("πŸ›‘ Stop loss triggered. All positions closed.")

# Start the script and keep it running
run_forever()

Webhook Configuration

Send a webhook with the script_listener parameter to deliver messages to your running script:

{
  "script_listener": "btc_monitor",
  "alert_type": "resistance_break",
  "price": 98500.50,
  "volume_spike": true,
  "custom_data": "any data you want"
}

Important Notes

  • The script must be running before webhooks can send messages to it
  • Only long-running scripts support message listeners
  • Messages are delivered instantly via Redis pub/sub (< 10ms latency)
  • If no @on_message handler is defined, messages are silently dropped
  • The script name in the webhook must exactly match the script's name in Traydar
  • Multiple @on_message handlers can be registered in the same script

Complete Example: Monitoring Bot

A long-running monitoring script that reacts to both price changes and webhook commands:

from traydar import on_price, on_message, run_forever, place_order, send_message, get_positions

# Listen for price updates
@on_price("BTC/USDT")
def check_price(price, timestamp):
    # Basic monitoring
    if price > 100000:
        send_message(f"πŸ“ˆ BTC crossed $100k: ${price}")

# Listen for webhook messages
@on_message
def handle_webhook_command(payload):
    """
    Webhook sends:
    {"script_listener": "btc_bot", "command": "close_all"}
    """
    command = payload.get('command')

    if command == 'close_all':
        positions = get_positions()
        for pos in positions:
            place_order(
                symbol=pos.symbol,
                side='sell' if pos.side == 'long' else 'buy',
                amount=pos.size
            )
        send_message("βœ… Closed all positions via webhook command")

    elif command == 'pause':
        # Set internal state to pause trading
        global paused
        paused = True
        send_message("⏸️ Trading paused via webhook")

    elif command == 'resume':
        global paused
        paused = False
        send_message("▢️ Trading resumed via webhook")

run_forever()

Example Scripts

One-Shot: Position Alert

# Check positions and alert on losses
positions = get_positions()

alerts = []
for pos in positions:
    if pos['unrealized_pnl'] < -100:
        alerts.append(f"{pos['symbol']}: ${pos['unrealized_pnl']:.2f}")

if alerts:
    send_message("⚠️ Position Alerts:\n" + "\n".join(alerts))

set_result({
    "positions_checked": len(positions),
    "alerts_sent": len(alerts)
})

One-Shot: Close All Positions

# Close all open positions
positions = get_positions()

for pos in positions:
    if pos['amount'] > 0:
        place_order(
            symbol=pos['symbol'],
            side="sell",
            amount=pos['amount'],
            order_type="market"
        )
    elif pos['amount'] < 0:
        place_order(
            symbol=pos['symbol'],
            side="buy",
            amount=abs(pos['amount']),
            order_type="market"
        )

send_message(f"Closed {len(positions)} positions")

Long-Running: Multi-Asset Price Watcher

from traydar import on_price, run_forever

@on_price("BTC/USDT")
def watch_btc(price, ts):
    if price > 100000:
        send_message(f"πŸš€ BTC above $100k: ${price}")

@on_price("ETH/USDT")
def watch_eth(price, ts):
    if price > 5000:
        send_message(f"πŸ“ˆ ETH above $5k: ${price}")

@on_price("SOL/USDT")
def watch_sol(price, ts):
    if price > 200:
        send_message(f"β˜€οΈ SOL above $200: ${price}")

run_forever()

Long-Running: Simple DCA Bot

from traydar import on_price, run_forever
from datetime import datetime, timedelta

last_buy = None
buy_interval = timedelta(hours=4)
buy_amount = 0.001

@on_price("BTC/USDT", exchange="binance")
def dca_buy(price, ts):
    global last_buy

    now = datetime.now()
    if last_buy is None or now - last_buy > buy_interval:
        order = place_order(
            symbol="BTC/USDT",
            side="buy",
            amount=buy_amount,
            order_type="market"
        )
        last_buy = now
        send_message(f"DCA Buy: {buy_amount} BTC at ${price}")

run_forever()

Security

Sandbox Environment

Scripts run in isolated Docker containers with gVisor for enhanced security:

  • Read-only filesystem: Scripts cannot modify system files
  • Network isolation: Limited to Traydar API access only
  • Resource limits: Memory and CPU are capped
  • Process limits: Maximum 64 processes per container
  • No elevated privileges: All capabilities dropped

Blocked Operations

The following are not allowed in scripts:

  • os.system(), subprocess.run() - shell access
  • socket module - raw network access
  • ctypes, cffi - native code execution
  • __import__() - dynamic imports

Troubleshooting

Script Timeout

Increase the timeout in script settings (max 300 seconds), optimize your code to run faster, or consider breaking into multiple scripts.

Memory Errors

Increase memory limit in script settings, process data in smaller batches, or avoid loading large datasets entirely into memory.

Connection Errors

Verify you have an exchange connected in Traydar, check that the exchange API keys are valid, and ensure the exchange ID is correct.

Long-Running Script Crashes

Enable auto-restart in script settings, check error logs, and add error handling:

@on_price("BTC/USDT")
def handle_price(price, ts):
    try:
        # Your trading logic here
        pass
    except Exception as e:
        send_message(f"Error in script: {e}")
        # Script continues running

run_forever()

Limits by Plan

FeatureFreeProEnterprise
One-Shot Concurrent51025
Long-Running Scripts1520
Max Memory256 MB512 MB1 GB
Max CPU0.51.02.0
Hourly Executions50200Unlimited

Ready to Automate with Python?

Start writing Python scripts to automate your trading in minutes

Create Your First Script