📰 Latest: HaasOnline Academy Is Back — Structured Education for Smarter Trade Bots
Account
Converting Other Languages

Python Part 1 - Introduction

Converting from Python to HaasScript

This is the most involved conversion because Python and HaasScript operate on fundamentally different paradigms. PineScript and Lua share syntax and execution models with HaasScript, but Python strategies typically process dataframes of historical bars, call exchange APIs directly, and run as standalone scripts. HaasScript does none of that.

This page covers the paradigm shift. For a full annotated conversion, see Strategy Conversion. For how specific Python patterns map conceptually, see Common Patterns.

The Core Difference

Python trading strategies typically follow this pattern:

# Load historical data
df = exchange.fetch_ohlcv('BTC/USDT', '1h', limit=500)
df = pd.DataFrame(df, columns=['time', 'open', 'high', 'low', 'close', 'volume'])

# Calculate indicators on the full dataset
df['rsi'] = ta.rsi(df['close'], 14)
df['ema'] = ta.ema(df['close'], 50)

# Iterate and find signals
for i in range(len(df)):
    if df['rsi'][i] < 30 and df['close'][i] > df['ema'][i]:
        exchange.create_market_buy_order('BTC/USDT', amount)

# Manage positions
if position:
    exchange.create_order('BTC/USDT', 'limit', 'sell', amount, stop_price=stop)

HaasScript follows this pattern:

local closePrices = ClosePrices()
local rsi = RSI(closePrices, 14)
local ema = EMA(closePrices, 50)

if rsi < 30 and closePrices > ema and GetPositionDirection() == NoPosition then
    DoLong()
end

StopLoss(2.5)
TakeProfit(5.0)

The differences are not cosmetic — they are structural:

  • No dataframes. HaasScript does not load or process historical bars in bulk. Indicators calculate automatically on each tick from data the platform provides.
  • No exchange API calls. You never call create_market_buy_order() or any exchange function. The bot platform handles order execution. You generate signals.
  • No iteration over bars. Your code runs once per tick. There is no for loop over historical data.
  • No position tracking objects. The platform tracks positions. You query state with GetPositionDirection() and manage risk with StopLoss() / TakeProfit().

What You Lose

These Python patterns have no direct equivalent in HaasScript:

Python Concept Why It Does Not Exist
pandas DataFrame operations HaasScript processes one tick at a time, not bulk data
ccxt / exchange API calls The platform manages all exchange communication
Custom order routing Managed trading handles execution; unmanaged trading provides limited control
Async loops / asyncio Execution is synchronous per tick
Background threads / schedulers The platform invokes your script on a schedule
File I/O for data persistence Use Save() and Load() for state between ticks
Web scraping / external API calls Network access is restricted
import / third-party packages No module system — only built-in commands

What Changes

Indicator Calculation

In Python, you compute indicators on a dataframe and access results by row index. In HaasScript, you call the indicator function and it returns the current value automatically:

# Python: compute on full history, access by index
df['rsi'] = ta.rsi(df['close'], 14)
current_rsi = df['rsi'].iloc[-1]
previous_rsi = df['rsi'].iloc[-2]
-- HaasScript: call the function, get current value
local rsi = RSI(ClosePrices(), 14)
-- rsi resolves to the latest value automatically in comparisons

-- For historical values, access by index (1 = latest)
local currentRSI = rsi[1]
local previousRSI = rsi[2]

Entry and Exit

Python strategies typically place orders directly through an exchange library. HaasScript generates signals that the bot platform executes:

# Python
exchange.create_market_buy_order('BTC/USDT', 0.1)
exchange.create_order('BTC/USDT', type='stop_loss', amount=0.1, price=stop_price)
-- HaasScript
DoLong()
StopLoss(2.5)  -- percentage, not price

The bot handles order placement, execution, position sizing, and exchange communication. Your script decides when to trade, not how.

Risk Management

Python strategies often implement stop losses as manual price checks or exchange-side orders. In HaasScript, risk management is declarative:

# Python: manual stop loss check
if position and current_price <= stop_price:
    exchange.create_market_sell_order('BTC/USDT', position['amount'])
-- HaasScript: declarative, runs automatically
StopLoss(2.5)
TakeProfit(5.0)
TrailingStopLoss(1.5)

Call these once and the bot monitors them on every tick. No manual price checking needed.

Multi-Timeframe Analysis

Python strategies often resample dataframes to different timeframes:

# Python
df_1h = df.resample('1h').agg({'open': 'first', 'high': 'max', 'low': 'min', 'close': 'last'})
df_daily = df.resample('1D').agg({'open': 'first', 'high': 'max', 'low': 'min', 'close': 'last'})

HaasScript handles this through the interval parameter on price data functions:

local hourlyClose = ClosePrices(60)
local dailyClose = ClosePrices(1440)
local hourlyRSI = RSI(hourlyClose, 14)
local dailyEMA = EMA(dailyClose, 50)

State Persistence

Python strategies often use global variables, class instances, or databases to maintain state between runs. HaasScript uses Save() and Load():

# Python
class Strategy:
    def __init__(self):
        self.trade_count = 0

    def on_tick(self):
        self.trade_count += 1
-- HaasScript
local tradeCount = Load('tradeCount', 0)
tradeCount = tradeCount + 1
Save('tradeCount', tradeCount)

What You Gain

HaasScript removes the infrastructure burden. In a Python setup, you are responsible for:

  • Exchange API connections and error handling
  • WebSocket management for real-time data
  • Order submission, tracking, and reconciliation
  • Position state management
  • Backtesting infrastructure
  • Deployment and monitoring

HaasScript handles all of this through the TradeServer platform. Your script focuses entirely on trading logic — indicators, conditions, and risk parameters.

What Transfers Directly

Some Python concepts map cleanly:

  • Conditional logicif/elif/else becomes if/elseif/else
  • Boolean operatorsand, or, not are the same in Lua
  • Arithmetic+, -, *, /, % all work the same
  • Variable assignmentx = 10 works in Lua (use local x = 10)
  • String concatenationf"RSI: {value}" becomes 'RSI: ' .. value
  • Math functionsmath.abs(), math.sqrt() are available in Lua's math.* library, with HaasScript equivalents that handle collections

Syntax Quick Reference

Python HaasScript / Lua Notes
x = 10 local x = 10 local scopes the variable
# comment -- comment Different comment syntax
elif elseif One word, no space
== / != / > / < == / ~= / > / < Not-equal uses ~=
and / or / not and / or / not Same keywords
True / False true / false Lowercase
None nil Different keyword
"text" + str(x) "text" .. tostring(x) .. concatenates
f"{x}" tostring(x) or .. concatenation No f-strings
len(arr) Count(arr) HaasScript command
arr[-1] arr[1] HaasScript: 1 = latest, no negative indexing
for i in range(n) for i = 1, n do Inclusive upper bound
while condition: while condition do Ends with end
def func(x): local function func(x) Ends with end
import math Not available Use built-in commands or math.*
class Not available Use Save()/Load() for state

When Python Strategies Need Rethinking

Some Python strategy patterns do not translate cleanly and need a different approach:

  • Machine learning models — You cannot import scikit-learn or tensorflow. HaasScript has no ML library. These strategies stay in Python.
  • Statistical arbitrage across hundreds of pairs — HaasScript runs per-bot on a single market. Cross-market analysis requires multiple bots coordinated externally.
  • Custom order types or routing — If your edge is in execution (TWAP, VWAP, iceberg orders), the managed trading model abstracts away the details you need.
  • Real-time data pipelines — If you consume order book L2 data, liquidations, or funding rates directly, HaasScript works at the candle/tick level, not the order book level.

HaasScript is best suited for indicator-based, rule-driven strategies on a single market — the kind of logic that makes up the majority of retail trading bots.