SE100
SE100
Docs
  • Docs
  • Changelog
  • Feature requests
  • Support portal
    • Widgets
    • Domain-Specific Language (DSL)
    • SEIOO DSL Semantics
    • SEIOO DSL: The Definitive Guide to Building High Performance Trading Logic
    • Signal Production 1.0
    • Signal Production 2.0
    • SEIOO - Use Cases
    • Conditional Masking, Regime Gates, and State Machines in SEIOO
    • SEIOO Auto Trade Flow

SEIOO DSL: The Definitive Guide to Building High Performance Trading Logic

A compact, expression-driven domain specific language designed to build trading indicators, composite scores, dashboards, and signal logic by composing topological time series operations.
SEIOO DSL: The Definitive Guide to Building High Performance Trading Logic

This guide teaches SEIOO as a progressive journey, from first expressions to multi-layer signal architectures that behave like leading confirmation engines rather than noisy lagging triggers.

Introduction and Conceptual Foundations

What SEIOO is and why it exists

SEIOO is a formula system that lets you express market logic as readable, composable expressions over:

  • Assets (crypto, forex, stocks, futures, macro)

  • OHLCV fields (close, open, high, low, volume, etc.)

  • Indicators (RSI, MACD, ADX, ATR, MFI, VWAP, etc.)

  • Transform functions (sma, ema, roc, zscore, logdiff, diff, etc.)

  • Outputs for visualization and composition (card, chart, table)

  • Widget references so you can build systems, not single scripts

Its purpose is to make it fast to build robust trading logic without the overhead of a general purpose language, while still enabling sophisticated multi-signal systems through composition.

How SEIOO differs from Pine Script and Python frameworks

SEIOO vs Pine Script

  • Pine is a full scripting language with control flow, loops, and stateful series semantics.

  • SEIOO is expression-first and intentionally constrained: you compose functions and series rather than writing programs.

  • SEIOO is built around reuse across widgets via @WIDGET_ID.output, enabling modular signal graphs.

SEIOO vs Python (backtrader, vectorbt, pandas, etc.)

  • Python is unlimited but heavy: data plumbing, lookahead mistakes, state complexity, and deployment work.

  • SEIOO is opinionated toward common market transformations, fast indicator composition, normalized scoring, and dashboard-native outputs.

  • SEIOO gives you a consistent semantic model: time series in, time series out, with clear “latest value” behavior when a scalar is required.

The core philosophy and execution model

Think of SEIOO as a signal graph builder.

Everything is a series unless forced to be a scalar. Many functions return a time series. When used in a “latest value” context (like a card), you get the most recent computed value.

Indicators are self-contained, transforms are explicit-input.

Indicator usage: X:BTCUSD.rsi, X:BTCUSD.macd, X:BTCUSD.adx

Transform usage: sma(X:BTCUSD.close, 20), ema(X:BTCUSD.rsi, 14), normalize(X:BTCUSD.volume) This is a key design boundary: indicators “know what they consume”, transforms require you to supply the input series.

Composites are first-class.composite() and weighted() auto-normalize to a 0–100 score, turning messy heterogeneous inputs into a single decision-friendly signal surface.

Output DSL is built in. You do not just compute signals, you render them: card(), chart.*(), table.rows().cols().color()

Systems over scripts via widget referencing.@WIDGET.output is how you build modular pipelines: one widget produces a time series, another normalizes it, another builds a composite, another gates execution.

Beginner-Level Examples

1) Asset references and fields

Assets use consistent prefixes:

X:BTCUSD.close
C:EURUSD.close
AAPL.close
GoldFutures.close
VIX.close

Crypto is X:, forex is C:, stocks are bare tickers, macro can be symbols like VIX or PascalCase like CoreCpi.

2) The simplest possible indicator

X:BTCUSD.rsi

This returns RSI (0–100).

Render it as a value card:

card(X:BTCUSD.rsi)

card() is an output widget that displays the latest value.

3) Your first transform

A moving average requires an explicit series input:

sma(X:BTCUSD.close, 50)

Now compare price vs SMA:

X:BTCUSD.close > sma(X:BTCUSD.close, 50)

Comparison operators return 1 or 0.

4) A basic single-condition trade signal

Oversold mean reversion “setup flag”:

X:BTCUSD.rsi < 30

Add a trend quality filter:

X:BTCUSD.rsi < 30 AND X:BTCUSD.adx > 20

SEIOO logical operators are AND and OR.

5) A first “score” instead of a boolean

A boolean is brittle. A score is tradable.

composite(X:BTCUSD.rsi, X:BTCUSD.macd, X:BTCUSD.adx)

composite() auto-normalizes to 0–100. This is one of the most important building blocks for robust signal design.

6) Visualizing the series

chart.line(X:BTCUSD.rsi)
chart.area(X:BTCUSD.close)
chart.area.log(X:BTCUSD.close)

Log scale is a built-in chart modifier.

Intermediate Patterns

At intermediate level, the big shift is this:

You stop asking “is condition true” and start asking “is the market in the right context to trust the condition”.

Pattern 1: Condition stacking (probability stacking)

Example: oversold + trend strength + participation.

X:BTCUSD.rsi < 30AND X:BTCUSD.adx > 25AND X:BTCUSD.volume_surge > 150

This is a classic confirmation pattern explicitly shown in the reference.

Interpretation:

  • RSI provides location (stretch)

  • ADX provides regime quality (trend or impulse environment)

  • Volume surge provides validity (participation)

Pattern 2: Smoothing the noisy parts, keeping the edge

Instead of raw momentum, use smoothed ROC:

ema(roc(X:BTCUSD.close, 10), 5)

Or ROC of a smoothed price:

roc(ema(X:BTCUSD.close, 14), 10)

These patterns reduce noise without turning your logic into a lagging crossover-only strategy.

Pattern 3: “Distance from mean” as a standardized signal

A mean reversion pressure gauge:

(X:BTCUSD.close - sma(X:BTCUSD.close, 50)) / std(X:BTCUSD.close, 50)

This behaves like a z-style distance metric, but stays fully interpretable.

Pattern 4: Use tables for cross-asset confirmation

A table is not a toy. It is how you prevent single-asset tunnel vision.

table.rows(X:BTCUSD, X:ETHUSD, X:SOLUSD).cols(
  close_price,
  price_change,
  "Tech Score": composite(rsi, macd, adx, atr),
  "BTC Corr": correlation(close, X:BTCUSD.close),
  "Momentum": weighted(2:rsi, 1:macd, 1:adx)
).color("Tech Score")

This is exactly the kind of view that supports discretionary trading and automated portfolio logic.

Pattern 5: Widget chaining (build modular systems)

You can reference other widgets:

  • @WIDGET.value for a computed value

  • @WIDGET.signal for a 0–10 signal

  • @WIDGET.timeseries for chaining series operations

Example: normalize another widget’s output:

normalize(@ABC123-C.timeseries)

Example: rolling correlation between two widget-generated series:

rollingCorrelation(@INFLATION_SCORE.timeseries, @CRYPTO_INDEX.timeseries, 30)

Widget referencing is how SEIOO becomes a full signal architecture language.

Advanced and Multi-Dimensional Algorithms

Advanced SEIOO is about building multi-axis evidence:

  • Price structure axis (trend, mean deviation)

  • Momentum axis (rate, acceleration)

  • Volatility axis (risk regime)

  • Participation axis (volume flows)

  • Cross-asset axis (correlations, relative strength)

  • Composite axis (normalized scoring)

1) Build a market regime classifier-like composite

Create interpretable sub-scores:

Trend quality score

composite(
  X:BTCUSD.adx,
  (ema(X:BTCUSD.close, 12) - ema(X:BTCUSD.close, 26)) / X:BTCUSD.close * 100
)

The second term is a trend magnitude normalized by price, shown as a trend-following example in the reference.

Risk regime score

normalize(zscore(X:BTCUSD.atr))

ATR as volatility proxy, standardized then normalized for comparability.

Participation score

normalize(X:BTCUSD.volume_usd)

Now combine them:

weighted(
  0.45:composite(X:BTCUSD.rsi, X:BTCUSD.macd),
  0.35:normalize(zscore(X:BTCUSD.atr)),
  0.20:normalize(X:BTCUSD.volume_usd)
)

This produces a single 0–100 score that is dynamically influenced by multiple market dimensions.

2) Cross-asset context as an edge filter

A common failure mode is trading BTC in isolation. Use correlation regime:

rollingCorrelation(X:BTCUSD.close, X:ETHUSD.close, 30)

Then use it as a filter conceptually:

  • High correlation means crypto beta is unified, momentum signals may follow through.

  • Falling correlation can imply dispersion, idiosyncratic moves, or rotation, requiring different playbooks.

Rolling correlation is first-class in SEIOO.

3) Composite signals that can act “leading”

SEIOO will not magically predict the future. But you can design signals that behave more leading by using:

  • Momentum change (diff of smoothed momentum)

  • Volatility compression / expansion

  • Mean deviation + momentum deceleration

Example: deceleration proxy using ROC change:

diff(ema(roc(X:BTCUSD.close, 10), 5))

If momentum is weakening while price is extended, you are closer to a turning zone than with lagging crossovers.

4) Multi-asset indices as context clocks

Build a crypto index:

weighted(0.50:X:BTCUSD.close,0.25:X:ETHUSD.close,0.10:X:SOLUSD.close,0.05:X:XRPUSD.close,0.05:X:ADAUSD.close,0.05:X:DOGEUSD.close)

Then compare an asset to the index:

X:BTCUSD.close / avg(X:BTCUSD.close, X:ETHUSD.close, X:SOLUSD.close)

These ratio constructs are explicitly supported and extremely useful for relative strength systems.

Winning Trade Signal Architecture

A “winning” signal is rarely one condition. It is an architecture.

The SEIOO way: build a trade thesis as stacked evidence

A strong setup usually has:

  1. Context gate (regime, risk, market state)

  2. Trigger (timing)

  3. Validation (participation, cross-asset support)

  4. Risk awareness (avoid high chaos regimes, avoid weak follow-through states)

In SEIOO, you implement this by mixing:

  • Booleans (hard gates)

  • Scores (soft evidence)

  • Composites (normalized multi-factor confidence)

Example: risk-aware long setup score for daily swings (1–14 bars)

Here is a pattern you can adapt for both dashboards and automation:

Step A: Define sub-scores

# Stretch / locationnormalize(100 - X:BTCUSD.rsi)
# Trend qualitynormalize(X:BTCUSD.adx)
# Participationnormalize(X:BTCUSD.volume_surge)
# Risk regime (lower is better, invert via 100 - normalize)100 - normalize(zscore(X:BTCUSD.atr))

Step B: Combine into a confidence score

weighted(
  0.35:normalize(100 - X:BTCUSD.rsi),
  0.25:normalize(X:BTCUSD.adx),
  0.20:normalize(X:BTCUSD.volume_surge),
  0.20:(100 - normalize(zscore(X:BTCUSD.atr)))
)

This yields a 0–100 “long attractiveness” score.

Step C: Add a hard safety gate For example, require participation:

X:BTCUSD.volume_surge > 120 AND
weighted(
  0.35:normalize(100 - X:BTCUSD.rsi),
  0.25:normalize(X:BTCUSD.adx),
  0.20:normalize(X:BTCUSD.volume_surge),
  0.20:(100 - normalize(zscore(X:BTCUSD.atr)))
) > 65

SEIOO comparisons return 1 or 0, so this can become a strict signal if you want.

Manual dashboard version

Use a table to scan multiple assets with the same architecture:

table.rows(X:BTCUSD, X:ETHUSD, X:SOLUSD, X:XRPUSD).cols(
  close_price,
  price_change,
  "Long Score": weighted(
    0.35:normalize(100 - rsi),
    0.25:normalize(adx),
    0.20:normalize(volume_surge),
    0.20:(100 - normalize(zscore(atr)))
  )
).color("Long Score")

This is where SEIOO shines: strategy logic and trader interface are the same artifact.

Fully automated execution version

Connect exchange and SEIOO can output:

  • A boolean signal (0/1)

  • A confidence score (0–100)

  • Supporting context series for logging and audits

Use card() to show the final “go/no-go” and score:

card(
  weighted(
    0.35:normalize(100 - X:BTCUSD.rsi),
    0.25:normalize(X:BTCUSD.adx),
    0.20:normalize(X:BTCUSD.volume_surge),
    0.20:(100 - normalize(zscore(X:BTCUSD.atr)))
  )
)

Best Practices and Design Strategies

1) Design like a system designer, not an indicator collector

Bad: “Add RSI, MACD, ADX because they are popular.”

Good: “Each component has a job.”

  • Location (stretch): RSI, mean deviation

  • Trend quality: ADX, trend magnitude

  • Participation: volume surge, volume USD

  • Risk: ATR, rolling std

  • Cross-asset: correlation, relative strength ratios

SEIOO’s composite() and weighted() exist specifically to make this systems approach practical.

2) Prefer scores over brittle booleans

Booleans are fine as safety gates, but scores let you:

  • Tune thresholds

  • Rank opportunities

  • Combine signals without “all-or-nothing” failure

3) Normalize before combining heterogeneous inputs

If you combine raw RSI (0–100) with MACD (unbounded) without normalization, your composite will be distorted. Use:

  • composite() or weighted() because they auto-normalize

  • Or use normalize() / zscore() explicitly when building custom pipelines

4) Use smoothing selectively

Smooth the noisy parts (returns, momentum, ROC), not the entire decision chain. Examples already supported:

  • ema(roc(close, 12), 9)

  • roc(ema(close, 14), 10)

5) Avoid common mistakes

  • Mistake: treating X:BTCUSD.sma as a generic moving average. In SEIOO, SMA is fundamentally a transform requiring an input series: sma(X:BTCUSD.close, 50).

  • Mistake: stacking derivatives until NaNs dominate. Repeated derivatives like logdiff(logdiff(x)) can produce NaNs; use diff(logdiff(x)) for smoother second derivative behavior.

  • Mistake: mixing scales without normalization. If you do avg(rsi, macd, adx) you have a scale problem. Prefer composite() or normalize each input.

6) Structure scripts for clarity

A clean SEIOO style looks like:

  • Define subcomponents as separate widgets (or separate expressions)

  • Chain with @WIDGET.timeseries

  • Combine with weighted()

  • Render with card(), chart.*(), and table.*()

This makes your logic:

  • Auditable

  • Reusable

  • Easy to optimize without rewriting everything

A Practical Learning Path

If you want to master SEIOO quickly, build in this order:

  1. Single asset cards: RSI, close, ATR

  2. One transform: SMA or EMA of close

  3. One boolean: price above SMA

  4. One composite score: composite(rsi, macd, adx)

  5. One table scanner: multiple assets, add a score column

  6. One chained system: produce a score in one widget, normalize or correlate it in another

  7. One “trade architecture”: context gate + confidence score + visualization

Everything above is already supported by the SEIOO syntax and function set.

PrevSEIOO DSL Semantics
NextSignal Production 1.0
Was this helpful?