What Are Formulas?
SKIF formulas are expressions for stock analysis. Use them when the visual condition builder is not enough. A formula can define:
- A condition: which stocks to include.
- A calculated column: which value to display for each stock.
One formula contains one expression.
Quick Wins
Oversold:
rsi(14) < 30
Uptrend with liquidity:
c > sma(c, 50) and v > 1M
Large caps with positive momentum:
f.market_cap > 10B and rsi(14) > 50
SKIF expressions do not support comments. Put notes outside the formula; #
is part of trailing-window syntax, not a comment marker.
Basic Building Blocks
Candle fields
corclose— Close priceooropen— Open pricehorhigh— High pricelorlow— Low pricevorvolume— Volume
Indicator calls
rsi(14)
sma(c, 20)
Many moving-average calls also accept a period by itself and use close price:
sma(20)
Fundamental fields
f.market_cap
Fundamental fields are available only in hosts that provide fundamentals.
Comparison Operators
rsi(14) < 30
f.market_cap >= 1B
f.country == "United States"
The comparison operators are:
<Less than>Greater than<=Less than or equal>=Greater than or equal==Equal to!=Not equal to=~Regular-expression or string-pattern match!~Does not match
Single = is not an equality operator.
Logical Operators
Use and when both conditions must be true:
rsi(14) < 30 and f.market_cap > 1B
Use or when either condition may be true:
rsi(14) < 30 or rsi(14) > 70
Use not to invert a condition:
not (rsi(14) > 50)
Use parentheses to make combinations clear:
(rsi(14) < 30 or rsi(14) > 70) and f.market_cap > 1B
Math Operators
(c - sma(c, 20)) / sma(c, 20) * 100
The math operators are +, -, *, /, and %. % returns the remainder
with the dividend's sign. Division or remainder by zero produces a missing
column value, not zero.
Series History
Use @N to read a value N bars ago:
c > c@1
Use #N.method for a trailing window. The available methods are sum, mean,
max, min, and stddev:
v > v#20.mean * 1.5
Lag sizes range from 0 through 5000. Window sizes range from 1 through 5000. Write both as whole numbers.
Common Functions
Price and volume
roc(N)— Close-price rate of change overNbars, in percentage pointschange(x, N)— Absolute change in any seriessma(x, N)— Simple moving averageema(x, N)— Exponential moving averagervol(N)— Relative volumevwap— Default volume-weighted average price
Momentum
rsi(N)— Relative Strength Indexmacd_line(fast, slow)— MACD linemacd_signal(fast, slow, signal)— MACD signal linemacd_histogram— Default MACD line minus signalcross_up(a, b)—acrosses abovebon the current barcross_down(a, b)—acrosses belowbon the current bar
Volatility
atr(N)— Average True Rangeatrp(N)— ATR as a percentage of pricebb_upper(N, k)— Upper Bollinger Bandbb_middle(N, k)— Middle Bollinger Bandbb_lower(N, k)— Lower Bollinger Band
Fundamentals
f.market_cap— Market capitalizationf.pe— Price-to-earnings ratiof.ps— Price-to-sales ratiof.revenue_ttm— Trailing-12-month revenuef.revenue_growth_yoy— Year-over-year revenue growth as a fractionf.eps_growth_yoy— Year-over-year EPS growth as a fractionf.gross_margin— Gross margin percentagef.operating_margin— Operating margin percentagef.debt_to_ebitda— Debt divided by EBITDAf.dividend_yield— Annual dividend yield in percentage pointsf.fcf_yield— Free-cash-flow yield in percentage pointsf.rule_of_40— Rule of 40 score
For example, this finds stocks yielding between 2% and 6%:
f.dividend_yield >= 2 and f.dividend_yield <= 6
The in-product function catalog is the complete list. It is more reliable than guessing a name from another charting language.
Numeric Literals
Standard and scientific notation work. _ may separate digits. Finance
suffixes are case-insensitive:
K— ThousandMorMM— MillionBorBN— BillionTorTN— Trillion
f.market_cap > 1.5B
String and Regex Matching
Use == for exact string equality:
f.country == "United States"
Use a regular-expression literal for more flexible matching. The supported
flags are i for case-insensitive matching and m for multiline matching:
f.sector =~ /^tech/i
A string pattern with * or ? performs case-insensitive wildcard matching:
f.industry =~ "Software*"
Crossovers
cross_up(c, sma(c, 50))
cross_down(rsi(14), 30)
Crossovers detect the event on the current bar, not the sustained state after the crossing.
Operator Precedence
From highest to lowest:
- Literals, fields, calls, and parentheses
- Postfix lag, window, and member access:
@N,#N.method,.member - Unary
not,!, and- - Multiplication, division, and remainder:
*,/,% - Addition and subtraction:
+,- - Ordering:
<,>,<=,>= - Equality and matching:
==,!=,=~,!~ andor
When in doubt, use parentheses:
(rsi(14) < 30) and (f.market_cap > 1B)
Common Errors
Unsupported function name
rsi14()
Fix: use the catalog name and arguments: rsi(14).
Missing operator
rsi(14) 30
Fix: add the comparison: rsi(14) < 30.
Mismatched parentheses
(rsi(14) < 30
Fix: close the expression: (rsi(14) < 30).
Invalid function arguments
sma()
Fix: provide a period or series and period: sma(20) or sma(c, 20).
Inline comment
rsi(14) < 30 # oversold
Fix: remove the comment from the expression.
Formula Patterns
Oversold bounce
rsi(14) < 30 and c > sma(c, 200) and f.market_cap > 1B
Fundamental growth
f.revenue_growth_yoy > 0.15 and f.eps_growth_yoy > 0.20 and f.gross_margin > 50 and f.pe < 25
Momentum breakout
c > sma(c, 20) and sma(c, 20) > sma(c, 50) and v > sma(v, 20) * 1.5
Volatility contraction
atrp(14) < 2 and f.market_cap > 500M
MACD bullish crossover
cross_up(macd_line(12, 26), macd_signal(12, 26, 9)) and c > sma(c, 200)
Tips
- Start with one condition and confirm it before adding another.
- Use explicit periods in formulas you intend to save or share.
- Read validation errors; unsupported names do not fall back to a different implementation.
- Test a complex formula on a small watchlist before running a large universe.
What's Next?
- Cookbook Recipes — Ready-made strategies
- Your First Scan — Apply your formulas
- Troubleshooting — Common issues
Chart indicators
Custom chart indicators use SKIF expressions inside a small chart-only
document. input, let, and output define calculations; a final view {}
selects a price, volume, or oscillator pane. Each rendered layer uses a named
primitive whose header names the output and whose direct properties describe
its chart behavior. The server evaluates the outputs and the chart draws the
resulting series. See the in-product indicator editor for validation at exact
line and column locations.