Dashboards¶
Strategy dashboards are Streamlit pages loaded by the hosted platform's
dashboard image and by almanak dashboard locally. Both call your
render_custom_dashboard() with the same arguments.
Anatomy of a dashboard¶
If a built-in template renderer fits your strategy, call it. The renderer
owns the title, the strategy header (Deployment ID / pool / chain
markdown), and the three audit sections (PnL, cost stack, trade tape).
Do not wrap it with your own st.title(...) or audit-section helpers — that
double-renders the title and the audit panels.
from almanak.framework.dashboard.templates import get_bollinger_config, render_ta_dashboard
def render_custom_dashboard(deployment_id, strategy_config, api_client, session_state):
config = get_bollinger_config(period=20, std_dev=1.0)
render_ta_dashboard(deployment_id, strategy_config, session_state, config)
Need to add summary cards or extra metrics? Call the renderer first and
append your own widgets after — see
strategies/accounting/lp/dashboard/ui.py and
strategies/accounting/looping/dashboard/ui.py for committed reference
implementations of that pattern (renderer + st.divider() + bespoke
st.metric(...) cards below).
Need a custom title or to replace the audit sections entirely? Hand-roll
the dashboard instead — see the next snippet. What you must NOT do is
wrap render_*_dashboard() with extra st.title(...) /
render_pnl_section(...) calls; the template already emits those, so
you'll double-render.
If no template fits, hand-roll Streamlit and wire the audit primitives
yourself (this is what almanak strat new scaffolds for blank / multi-step
templates; LP / lending / TA / perp templates scaffold the template-renderer
path above):
import streamlit as st
from almanak.framework.dashboard import (
render_pnl_section, render_cost_stack_section, render_trade_tape_section,
)
def render_custom_dashboard(deployment_id, strategy_config, api_client, session_state):
st.title("My Custom Strategy")
render_pnl_section(deployment_id)
# your indicator / position / performance UI
render_cost_stack_section(deployment_id)
render_trade_tape_section(deployment_id)
Audit primitives¶
almanak.framework.dashboard
¶
Almanak Strategy Framework v2.0 - Dashboard
Public exports for dashboard data access, rendering, and PM integration. External consumers (PM dashboard, custom UIs) should import from here.
The streamlit-using render_*_section helpers are resolved lazily via
:pep:562 __getattr__ so that gateway-side consumers — which import
almanak.framework.dashboard.quant_aggregations to build PnL / cost-stack
RPC responses — do not transitively pay the cost of loading streamlit at
package init. The gateway image strips streamlit (see
deploy/docker/strip-list-gateway.txt); an eager re-export here would
ModuleNotFoundError on every dashboard RPC in production (VIB-4048).
Regression guard: tests/gateway/test_imports_lean.py.
For strategy authors writing a dashboard/ui.py for their strategy,
the recommended convention is to frame render_custom_dashboard()
with three section helpers (VIB-3969) so accounting is visually QA'able
locally and on the hosted platform from the same single-source code
path:
render_pnl_section(deployment_id)— top, the 5-second eyeballrender_cost_stack_section(deployment_id)— bottom, life-to-date costsrender_trade_tape_section(deployment_id)— bottom, TX-level audit
Usage::
from almanak.framework.dashboard import (
DashboardDataClient,
Strategy,
render_cost_stack_section,
render_pnl_section,
render_strategy_detail,
render_strategy_timeline,
render_trade_tape_section,
strategy_from_pm_dict,
)
render_pnl_section
¶
Render the 5-second-eyeball PnL section (VIB-3969).
Money Trail row: Deployed / NAV / Lifetime PnL / Net APR. The
standard top-of-dashboard card so an operator answers "am I making
or losing money?" before scrolling. Backed by the gateway's
GetPnLSummary RPC; on RPC failure the section degrades to an
info banner rather than crashing the page.
Conventionally placed immediately below the strategy title.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
deployment_id
|
str
|
The deployment id (passed straight through from
|
required |
render_cost_stack_section
¶
Render the life-to-date Cost Stack section (VIB-3969).
Gas / Fees / Slippage / Earn — generic across primitives (every
primitive emits these into transaction_ledger +
accounting_events). Backed by the gateway's GetCostStack
RPC; on RPC failure the section degrades to an info banner.
Conventionally placed at the start of an "Audit" section, just above the trade tape.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
deployment_id
|
str
|
The deployment id. |
required |
heading
|
str
|
Override the section heading. Pass an empty string to suppress the heading entirely (useful when composing inside a larger Audit panel that already has its own heading). |
'### Cost Stack'
|
render_trade_tape_section
¶
Render the standard trade-tape section.
Conventionally placed at the bottom of every
render_custom_dashboard() so accounting can be visually QA'd
locally and on the hosted platform from the same code path. The
underlying render_trade_tape reads through the gateway's
DashboardService.GetTradeTape, which abstracts SQLite (local)
and Postgres (hosted) — the section travels everywhere the gateway
does.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
deployment_id
|
str
|
The deployment id (passed straight through from
|
required |
limit
|
int
|
Most recent intents to fetch. Defaults to 50. |
50
|
Template renderers¶
Pre-built sections for common strategy types. Each renderer is paired with factory configs that adapt the rendering to a specific protocol or indicator. Use these to fill the middle of the dashboard instead of hand-rolling indicator/position/performance UI.
Technical analysis (RSI, MACD, Bollinger, …)¶
almanak.framework.dashboard.templates.ta_dashboard
¶
Technical Analysis (TA) Dashboard Template.
Reusable template for creating dashboards for indicator-based strategies. Supports any TA indicator with configurable signal logic and visualization.
Scope (single-position): the template drives one position on one
base_token/quote_token pair. The 3 accounting sections (PnL, Cost
Stack, Trade Tape) are baked in so every TA dashboard ships with full
accounting by default.
- Single indicator — pass one
TADashboardConfig. - Multiple indicators (multi-signal, VIB-4897) — compose with
:func:
multi_ta_config. The template stacks one panel per indicator under a shared price chart (all on one time axis). Useful for confluence strategies (e.g. RSI + MACD + Bollinger).
For genuinely multi-position layouts the template is still the wrong tool —
hand-roll from the section helpers (render_pnl_section,
render_cost_stack_section, render_trade_tape_section) plus the
primitive plot helpers in almanak.framework.dashboard.plots. See the
dashboard blueprints.
Usage (single indicator): from almanak.framework.dashboard.templates import TADashboardConfig, render_ta_dashboard
config = TADashboardConfig(
indicator_name="RSI", indicator_period=14,
upper_threshold=70, lower_threshold=30, signal_type="reversion",
)
def render_custom_dashboard(deployment_id, strategy_config, api_client, session_state):
session_state = prepare_ta_session_state(api_client, session_state, config)
render_ta_dashboard(deployment_id, strategy_config, session_state, config)
Usage (multi-signal): from almanak.framework.dashboard.templates import ( get_rsi_config, get_macd_config, get_bollinger_config, multi_ta_config, prepare_ta_session_state, render_ta_dashboard, )
config = multi_ta_config(get_rsi_config(), get_macd_config(), get_bollinger_config())
def render_custom_dashboard(deployment_id, strategy_config, api_client, session_state):
session_state = prepare_ta_session_state(api_client, session_state, config)
render_ta_dashboard(deployment_id, strategy_config, session_state, config)
TADashboardConfig
dataclass
¶
TADashboardConfig(
indicator_name: str,
indicator_period: int = 14,
secondary_periods: list[int] = list(),
upper_threshold: float | None = None,
lower_threshold: float | None = None,
signal_type: Literal[
"reversion", "momentum"
] = "reversion",
value_format: str = "{:.1f}",
value_suffix: str = "",
custom_signal_fn: Callable[[dict[str, Any]], str]
| None = None,
chain: str = "Arbitrum",
protocol: str = "Uniswap V3",
base_token: str = "WETH",
quote_token: str = "USDC",
timeframe: str = "1h",
extra_indicators: list[TADashboardConfig] = list(),
)
Configuration for a TA dashboard.
Attributes:
| Name | Type | Description |
|---|---|---|
indicator_name |
str
|
Name of the indicator (e.g., "RSI", "MACD", "CCI") |
indicator_period |
int
|
Primary period for the indicator |
secondary_periods |
list[int]
|
Additional periods (e.g., signal line for MACD) |
upper_threshold |
float | None
|
Upper threshold for signals (overbought/bullish) |
lower_threshold |
float | None
|
Lower threshold for signals (oversold/bearish) |
signal_type |
Literal['reversion', 'momentum']
|
Type of signal logic - "reversion" or "momentum" |
value_format |
str
|
Format string for displaying indicator value (e.g., "{:.1f}", "{:+.2f}") |
value_suffix |
str
|
Suffix for indicator value (e.g., "%", " bps") |
custom_signal_fn |
Callable[[dict[str, Any]], str] | None
|
Optional custom function for signal determination |
chain |
str
|
Default chain name |
protocol |
str
|
Default protocol name |
base_token |
str
|
Default base token |
quote_token |
str
|
Default quote token |
timeframe |
str
|
OHLCV candle interval the dashboard fetches and computes the
indicator series from — one of |
extra_indicators |
list[TADashboardConfig]
|
Additional indicator configs to render as stacked
panels (multi-signal layout, VIB-4897). Empty by default — the
single-indicator path is unchanged. Compose via
:func: |
multi_ta_config
¶
Compose a multi-indicator (multi-signal) TA dashboard config.
The first config is the primary — it drives the dashboard title, the
configured pair/chain, the shared OHLCV fetch, and the signal-status
section. Each additional config renders as one more stacked indicator panel
beneath the price chart. Indicator params (periods / thresholds) on the
extras are honoured; their base_token / quote_token / chain are
not — the primary's pair is authoritative so every panel shares one time
axis.
Example::
config = multi_ta_config(
get_rsi_config(period=14),
get_macd_config(),
get_bollinger_config(period=20, std_dev=2.0),
)
session_state = prepare_ta_session_state(api_client, session_state, config)
render_ta_dashboard(deployment_id, strategy_config, session_state, config)
Returns a new config (does not mutate primary).
prepare_ta_session_state
¶
prepare_ta_session_state(
api_client: Any,
session_state: dict[str, Any] | None = None,
config: TADashboardConfig | None = None,
) -> dict[str, Any]
Enrich session state for render_ta_dashboard (chart subplot).
Mirrors :func:prepare_lp_session_state: fetches OHLCV via the
api_client, computes the indicator series client-side, reads the trade
tape for buy/sell markers, and loads wallet balances for the Current
Position section — strategy authors don't write any of that plumbing.
Without this helper the chart section silently degrades to Price
history data not available (nothing populates price_history /
rsi_history / buy_signals / sell_signals) and the Current
Position section reads 0.0000 / $0.00 / $0.00 (nothing populates
base_balance / quote_balance / base_price).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
api_client
|
Any
|
|
required |
session_state
|
dict[str, Any] | None
|
Optional pre-existing state. Caller-supplied keys
are preserved — never overwritten — so custom dashboards that
already populate |
None
|
config
|
TADashboardConfig | None
|
|
None
|
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
The enriched session_state dict. Always returns; degrades to the |
dict[str, Any]
|
unenriched state on any API failure rather than raising. |
render_ta_dashboard
¶
render_ta_dashboard(
deployment_id: str,
strategy_config: dict[str, Any],
session_state: dict[str, Any],
config: TADashboardConfig,
) -> None
Render a technical analysis dashboard using the provided configuration.
Single-position template. Renders one indicator panel by default; pass a
:func:multi_ta_config (config.extra_indicators set) to stack one panel
per indicator under a shared price chart (multi-signal, VIB-4897). Bakes in
the 3 accounting sections (PnL → chart content → Cost Stack → Trade Tape).
For multi-position layouts, compose a custom dashboard from the section
helpers directly rather than parameterizing this template.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
deployment_id
|
str
|
The deployment identifier |
required |
strategy_config
|
dict[str, Any]
|
Strategy configuration dictionary |
required |
session_state
|
dict[str, Any]
|
Current session state with indicator values |
required |
config
|
TADashboardConfig
|
TADashboardConfig for this dashboard |
required |
get_rsi_config
¶
get_rsi_config(
period: int = 14,
overbought: float = 70,
oversold: float = 30,
timeframe: str = "1h",
) -> TADashboardConfig
Get pre-configured RSI dashboard config.
timeframe must match the strategy's data_granularity so the
dashboard RSI is computed from the same candles the strategy decides on
(VIB-4969). Defaults to "1h" for back-compat.
get_macd_config
¶
get_macd_config(
fast: int = 12,
slow: int = 26,
signal: int = 9,
timeframe: str = "1h",
) -> TADashboardConfig
Get pre-configured MACD dashboard config.
timeframe must match the strategy's data_granularity (VIB-4969).
get_cci_config
¶
get_cci_config(
period: int = 20,
overbought: float = 100,
oversold: float = -100,
timeframe: str = "1h",
) -> TADashboardConfig
Get pre-configured CCI dashboard config.
timeframe must match the strategy's data_granularity (VIB-4969).
get_stochastic_config
¶
get_stochastic_config(
fast_k: int = 14,
slow_k: int = 3,
slow_d: int = 3,
overbought: float = 80,
oversold: float = 20,
timeframe: str = "1h",
) -> TADashboardConfig
Get pre-configured Stochastic dashboard config.
timeframe must match the strategy's data_granularity (VIB-4969).
get_atr_config
¶
Get pre-configured ATR dashboard config.
timeframe must match the strategy's data_granularity (VIB-4969).
get_adx_config
¶
get_adx_config(
period: int = 14,
trend_threshold: float = 25,
timeframe: str = "1h",
) -> TADashboardConfig
Get pre-configured ADX dashboard config.
timeframe must match the strategy's data_granularity (VIB-4969).
get_bollinger_config
¶
get_bollinger_config(
period: int = 20,
std_dev: float = 2.0,
timeframe: str = "1h",
) -> TADashboardConfig
Get pre-configured Bollinger Bands dashboard config.
timeframe must match the strategy's data_granularity (VIB-4969).
Liquidity provision¶
almanak.framework.dashboard.templates.lp_dashboard
¶
Liquidity Provider (LP) Dashboard Template.
Reusable template for creating dashboards for LP strategies on concentrated liquidity protocols like Uniswap V3, PancakeSwap V3, TraderJoe V2, and Aerodrome.
Scope (single-signal / single-position): the template renders one
active LP position on one token0/token1 pair. LPSessionState
is intentionally scalar (position_id, range_lower, range_upper);
strategies that hold multiple LP NFTs simultaneously are not modelled here
even though the gateway data model (PositionSummary.lp_positions) is
multi-aware. The 3 accounting sections (PnL, Cost Stack, Trade Tape) are
baked in so every LP dashboard ships with full accounting. For multi-
position or multi-signal layouts, compose a custom dashboard from the
section helpers (render_pnl_section, render_cost_stack_section,
render_trade_tape_section) plus primitive plot helpers from
almanak.framework.dashboard.plots directly. See the dashboard
blueprints for the recommended composition.
Usage
from almanak.framework.dashboard.templates import ( LPDashboardConfig, render_lp_dashboard, prepare_lp_session_state, get_uniswap_v3_config, )
config = get_uniswap_v3_config(token0="WETH", token1="USDC")
def render_custom_dashboard(deployment_id, strategy_config, api_client, session_state): session_state = prepare_lp_session_state(api_client, config=config) # Pass api_client so the template renders the gateway-backed # Positions registry + Position Lifecycle sections (PR #2373). render_lp_dashboard(deployment_id, strategy_config, session_state, config, api_client=api_client)
LP_CRITICAL_KEYS
module-attribute
¶
LP_CRITICAL_KEYS: list[str] = [
"position_id",
"range_lower",
"range_upper",
"total_value_usd",
"is_active",
"current_price",
"in_range",
"token0_amount",
"token1_amount",
]
Keys that prepare_lp_session_state must produce and the template reads.
LP_LIVE_STATE_KEYS
module-attribute
¶
LP_LIVE_STATE_KEYS: frozenset[str] = frozenset(
LP_CRITICAL_KEYS
) | {
"current_position_id",
"lower_tick",
"upper_tick",
"current_tick",
}
LP-critical state owned by the live gateway/market reads.
These keys reflect on-chain / market truth at render time. A caller-supplied
session_state must not seed them ahead of the live reads — otherwise a
stale, preserved dashboard state masks fresh state after the strategy has
rebalanced on-chain (VIB-5025). The live read always wins; a caller value is
used only as a last-resort fallback when the live path produced nothing
(Empty != Zero), or when a caller explicitly pins the key via preserve_keys.
Any other key a caller passes (custom chart data such as position_history /
price_history, fixture/display extras) is not live-owned and passes
through untouched.
LPDashboardConfig
dataclass
¶
LPDashboardConfig(
protocol: str = "uniswap_v3",
token0: str = "WETH",
token1: str = "USDC",
fee_tier: str = "0.30%",
chain: str = DEFAULT_CHAIN,
show_liquidity_distribution: bool = True,
show_position_history: bool = True,
show_impermanent_loss: bool = True,
show_fee_accumulation: bool = True,
invert_prices: bool = False,
position_bounds_ratio: float | None = 0.8,
pool_address: str | None = None,
token0_address: str | None = None,
token1_address: str | None = None,
timeframe: str = "1h",
)
Configuration for an LP dashboard.
Attributes:
| Name | Type | Description |
|---|---|---|
protocol |
str
|
Protocol name (e.g., "uniswap_v3", "aerodrome", "traderjoe_v2") |
token0 |
str
|
First token symbol |
token1 |
str
|
Second token symbol |
fee_tier |
str
|
Fee tier display string (e.g., "0.30%") |
chain |
str
|
Chain name |
show_liquidity_distribution |
bool
|
Whether to show liquidity distribution chart |
show_position_history |
bool
|
Whether to show position history chart |
show_impermanent_loss |
bool
|
Whether to show IL tracking |
show_fee_accumulation |
bool
|
Whether to show fee accumulation chart |
invert_prices |
bool
|
Whether to invert price display |
position_bounds_ratio |
float | None
|
Ratio for position bounds lines (None to disable) |
timeframe |
str
|
OHLCV candle interval for the price-history chart — one of
|
LPSessionState
¶
Bases: TypedDict
Keys expected by render_lp_dashboard() in session_state.
Use prepare_lp_session_state(api_client, config=config) to populate
this automatically from the gateway.
Keys from strategy state (read directly, no mapping): position_id: Active LP position identifier. range_lower: Lower price bound of the LP position. range_upper: Upper price bound of the LP position. total_value_usd: Total position value in USD.
Keys derived/loaded by prepare_lp_session_state(): is_active: Whether a position is currently active. current_price: Current market price of token0 in USD. in_range: Whether current_price is within [range_lower, range_upper]. token0_amount: Amount of token0 in the position. token1_amount: Amount of token1 in the position.
Optional keys (strategy may or may not provide): total_fees_usd, impermanent_loss_pct, net_pnl_usd: Performance metrics. tick_data, lower_tick, upper_tick, current_tick: Liquidity distribution. position_history, price_history, fee_history, il_history: Chart data.
prepare_lp_session_state
¶
prepare_lp_session_state(
api_client: Any,
session_state: dict[str, Any] | None = None,
config: LPDashboardConfig | None = None,
preserve_keys: Collection[str] | None = None,
) -> dict[str, Any]
Load strategy data from the gateway and enrich for the LP dashboard.
The dashboard is a live view: the gateway/market reads are the source of
truth (blueprint 22/23; VIB-2838 "dashboard as a validation client"). The
result is therefore built from the live api_client.get_state() read
first, then enriched with derived fields (is_active, in_range) and
live market data (current_price, token amounts).
A caller-supplied session_state contributes custom / non-live keys
only (custom chart data such as position_history / price_history,
fixture/display extras). The LP-critical live-state keys
(:data:LP_LIVE_STATE_KEYS) are owned by the live reads and are never
seeded from the caller ahead of them — this prevents a stale, preserved
dashboard state from masking fresh on-chain state after a rebalance
(VIB-5025). A caller value for a live key is used only as a last-resort
fallback when the live path produced nothing (Empty != Zero), or when the
caller explicitly pins the key via preserve_keys.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
api_client
|
Any
|
DashboardAPIClient instance. |
required |
session_state
|
dict[str, Any] | None
|
Optional pre-existing state. Non-live keys pass through and are preserved; live-state keys are refreshed from the gateway. Pass None (or an empty dict) for a pure fresh fetch. |
None
|
config
|
LPDashboardConfig | None
|
LPDashboardConfig -- needed to know which token to price.
If None, |
None
|
preserve_keys
|
Collection[str] | None
|
Optional explicit opt-out. Keys listed here keep the
caller-provided value over the live read (e.g. a replay / snapshot
dashboard that intentionally renders a historical state rather than
live state). The safe default ( |
None
|
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Enriched dict containing all :data: |
render_lp_dashboard
¶
render_lp_dashboard(
deployment_id: str,
strategy_config: dict[str, Any],
session_state: dict[str, Any],
config: LPDashboardConfig,
api_client: Any | None = None,
) -> None
Render an LP strategy dashboard using the provided configuration.
Single-signal / single-position template — renders one active LP position on one configured pair. Bakes in the 3 accounting sections (PnL → primitive content → Cost Stack → Trade Tape). For multi- position or multi-signal layouts, compose a custom dashboard from the section helpers directly rather than parameterizing this template.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
deployment_id
|
str
|
The deployment identifier |
required |
strategy_config
|
dict[str, Any]
|
Strategy configuration dictionary |
required |
session_state
|
dict[str, Any]
|
Current session state with position data.
Use :func: |
required |
config
|
LPDashboardConfig
|
LPDashboardConfig for this dashboard |
required |
api_client
|
Any | None
|
Optional |
None
|
get_uniswap_v3_config
¶
get_uniswap_v3_config(
token0: str = "WETH",
token1: str = "USDC",
fee_tier: str = "0.30%",
chain: str = "arbitrum",
timeframe: str = "1h",
) -> LPDashboardConfig
Get pre-configured Uniswap V3 LP dashboard config.
timeframe sets the price-chart candle interval (VIB-4969); defaults to "1h".
get_aerodrome_config
¶
get_aerodrome_config(
token0: str = "WETH",
token1: str = "USDC",
pool_type: str = "volatile",
chain: str = "base",
timeframe: str = "1h",
) -> LPDashboardConfig
Get pre-configured Aerodrome LP dashboard config.
timeframe sets the price-chart candle interval (VIB-4969); defaults to "1h".
get_traderjoe_v2_config
¶
get_traderjoe_v2_config(
token0: str = "WAVAX",
token1: str = "USDC",
bin_step: str = "20",
chain: str = "avalanche",
timeframe: str = "1h",
) -> LPDashboardConfig
Get pre-configured TraderJoe V2 LP dashboard config.
timeframe sets the price-chart candle interval (VIB-4969); defaults to "1h".
get_pancakeswap_v3_config
¶
get_pancakeswap_v3_config(
token0: str = "WBNB",
token1: str = "USDT",
fee_tier: str = "0.25%",
chain: str = "bsc",
timeframe: str = "1h",
) -> LPDashboardConfig
Get pre-configured PancakeSwap V3 LP dashboard config.
timeframe sets the price-chart candle interval (VIB-4969); defaults to "1h".
Lending¶
almanak.framework.dashboard.templates.lending_dashboard
¶
Lending Protocol Dashboard Template.
Reusable template for creating dashboards for lending strategies on protocols like Aave V3, Morpho Blue, Compound V3, and Spark.
Scope (single-signal / single-position): the template renders one
collateral / borrow pair with one scalar health factor and LTV — the
shape of a single supply-borrow loop. Multi-collateral is partially
supported through collateral_assets (a dict feeding the breakdown
plot), but the headline metrics remain singular. The 3 accounting
sections (PnL, Cost Stack, Trade Tape) are baked in so every lending
dashboard ships with full accounting. For multi-signal layouts (e.g.
"supply on Aave + supply on Morpho" as separate motivations), do not
parameterize this template — write a custom dashboard composed from the
section helpers (render_pnl_section, render_cost_stack_section,
render_trade_tape_section) plus primitive plot helpers from
almanak.framework.dashboard.plots directly. See the dashboard
blueprints for the recommended composition.
Usage
from almanak.framework.dashboard.templates import LendingDashboardConfig, render_lending_dashboard
config = LendingDashboardConfig( protocol="aave_v3", collateral_token="WETH", borrow_token="USDC", )
def render_custom_dashboard(deployment_id, strategy_config, api_client, session_state): render_lending_dashboard(deployment_id, strategy_config, session_state, config)
LendingDashboardConfig
dataclass
¶
LendingDashboardConfig(
protocol: str = "aave_v3",
collateral_token: str = "WETH",
borrow_token: str = "USDC",
chain: str = DEFAULT_CHAIN,
liquidation_threshold: float = 1.0,
safe_threshold: float = 1.5,
max_ltv: float = 0.8,
liquidation_ltv: float = 0.85,
show_health_factor: bool = True,
show_ltv: bool = True,
show_collateral_breakdown: bool = True,
show_rate_comparison: bool = False,
)
Configuration for a lending dashboard.
Attributes:
| Name | Type | Description |
|---|---|---|
protocol |
str
|
Protocol name (e.g., "aave_v3", "morpho_blue", "compound_v3") |
collateral_token |
str
|
Primary collateral token symbol |
borrow_token |
str
|
Primary borrow token symbol |
chain |
str
|
Chain name |
liquidation_threshold |
float
|
Health factor threshold for liquidation (default 1.0) |
safe_threshold |
float
|
Health factor threshold considered safe (default 1.5) |
max_ltv |
float
|
Maximum LTV ratio (default 0.8) |
liquidation_ltv |
float
|
LTV at which liquidation occurs (default 0.85) |
show_health_factor |
bool
|
Whether to show health factor gauge |
show_ltv |
bool
|
Whether to show LTV ratio visualization |
show_collateral_breakdown |
bool
|
Whether to show collateral breakdown |
show_rate_comparison |
bool
|
Whether to show rate comparison (for multi-protocol) |
prepare_lending_session_state
¶
prepare_lending_session_state(
api_client: Any,
*,
session_state: dict[str, Any],
config: LendingDashboardConfig,
strategy_config: dict[str, Any] | None = None,
) -> dict[str, Any]
Hydrate generic lending dashboard fields from strategy state.
Hosted/custom dashboards receive raw strategy persistence, which often
stores domain names such as supplied_token_amount and
borrowed_token_amount. The lending template renders generic fields
(collateral_amount, borrowed_amount, ltv, health_factor).
This adapter keeps strategy dashboards thin while making the SDK template
useful for Aave-style supply/borrow loops.
render_lending_dashboard
¶
render_lending_dashboard(
deployment_id: str,
strategy_config: dict[str, Any],
session_state: dict[str, Any],
config: LendingDashboardConfig,
) -> None
Render a lending strategy dashboard using the provided configuration.
Single-signal / single-position template — one collateral/borrow pair with scalar health factor and LTV. Bakes in the 3 accounting sections (PnL → primitive content → Cost Stack → Trade Tape). For multi- position or multi-signal layouts, compose a custom dashboard from the section helpers directly rather than parameterizing this template.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
deployment_id
|
str
|
The deployment identifier |
required |
strategy_config
|
dict[str, Any]
|
Strategy configuration dictionary |
required |
session_state
|
dict[str, Any]
|
Current session state with position data |
required |
config
|
LendingDashboardConfig
|
LendingDashboardConfig for this dashboard |
required |
get_aave_v3_config
¶
get_aave_v3_config(
collateral_token: str = "WETH",
borrow_token: str = "USDC",
chain: str = DEFAULT_CHAIN,
) -> LendingDashboardConfig
Get pre-configured Aave V3 lending dashboard config.
get_morpho_blue_config
¶
get_morpho_blue_config(
collateral_token: str = "wstETH",
borrow_token: str = "USDC",
chain: str = "ethereum",
) -> LendingDashboardConfig
Get pre-configured Morpho Blue lending dashboard config.
get_compound_v3_config
¶
get_compound_v3_config(
collateral_token: str = "WETH",
borrow_token: str = "USDC",
chain: str = "ethereum",
) -> LendingDashboardConfig
Get pre-configured Compound V3 lending dashboard config.
get_spark_config
¶
get_spark_config(
collateral_token: str = "WETH",
borrow_token: str = "DAI",
chain: str = "ethereum",
) -> LendingDashboardConfig
Get pre-configured Spark lending dashboard config.
Perpetuals¶
almanak.framework.dashboard.templates.perp_dashboard
¶
Perpetual Futures Dashboard Template.
Reusable template for creating dashboards for perpetual trading strategies on protocols like GMX V2 and Hyperliquid.
Scope (single-signal / single-position): the template renders one
perp position on one market. has_position is a boolean and
entry_price / is_long / liquidation_price are scalars; an
account holding multiple perps simultaneously is not modelled here. The
3 accounting sections (PnL, Cost Stack, Trade Tape) are baked in so every
perp dashboard ships with full accounting. For multi-position or
multi-signal layouts (e.g. a basket of perp legs hedging spot exposure),
do not parameterize this template — write a custom dashboard composed
from the section helpers (render_pnl_section,
render_cost_stack_section, render_trade_tape_section) plus
primitive plot helpers from almanak.framework.dashboard.plots
directly. See the dashboard blueprints for the recommended composition.
Usage
from almanak.framework.dashboard.templates import PerpDashboardConfig, render_perp_dashboard
config = PerpDashboardConfig( protocol="gmx_v2", market="ETH/USD", collateral_token="WETH", )
def render_custom_dashboard(deployment_id, strategy_config, api_client, session_state): render_perp_dashboard(deployment_id, strategy_config, session_state, config)
PerpDashboardConfig
dataclass
¶
PerpDashboardConfig(
protocol: str = "gmx_v2",
market: str = "ETH/USD",
collateral_token: str = "WETH",
chain: str = DEFAULT_CHAIN,
max_leverage: float = 50.0,
safe_leverage: float = 10.0,
show_position_dashboard: bool = True,
show_funding_history: bool = True,
show_leverage_gauge: bool = True,
show_liquidation_levels: bool = True,
)
Configuration for a perpetual futures dashboard.
Attributes:
| Name | Type | Description |
|---|---|---|
protocol |
str
|
Protocol name (e.g., "gmx_v2", "hyperliquid") |
market |
str
|
Market identifier (e.g., "ETH/USD", "BTC/USD") |
collateral_token |
str
|
Collateral token symbol |
chain |
str
|
Chain name |
max_leverage |
float
|
Maximum allowed leverage |
safe_leverage |
float
|
Recommended safe leverage |
show_position_dashboard |
bool
|
Whether to show the main position dashboard |
show_funding_history |
bool
|
Whether to show funding rate history |
show_leverage_gauge |
bool
|
Whether to show leverage gauge |
show_liquidation_levels |
bool
|
Whether to show liquidation levels |
render_perp_dashboard
¶
render_perp_dashboard(
deployment_id: str,
strategy_config: dict[str, Any],
session_state: dict[str, Any],
config: PerpDashboardConfig,
) -> None
Render a perpetual futures strategy dashboard using the provided configuration.
Single-signal / single-position template — one perp position on one market. Bakes in the 3 accounting sections (PnL → primitive content → Cost Stack → Trade Tape). For multi-position or multi-signal layouts, compose a custom dashboard from the section helpers directly rather than parameterizing this template.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
deployment_id
|
str
|
The deployment identifier |
required |
strategy_config
|
dict[str, Any]
|
Strategy configuration dictionary |
required |
session_state
|
dict[str, Any]
|
Current session state with position data |
required |
config
|
PerpDashboardConfig
|
PerpDashboardConfig for this dashboard |
required |
get_gmx_v2_config
¶
get_gmx_v2_config(
market: str = "ETH/USD",
collateral_token: str = "WETH",
chain: str = DEFAULT_CHAIN,
) -> PerpDashboardConfig
Get pre-configured GMX V2 perpetuals dashboard config.
get_hyperliquid_config
¶
get_hyperliquid_config(
market: str = "ETH",
collateral_token: str = "USDC",
chain: str = "hyperliquid",
) -> PerpDashboardConfig
Get pre-configured Hyperliquid perpetuals dashboard config.
Prediction markets¶
almanak.framework.dashboard.templates.prediction_dashboard
¶
Prediction Market Dashboard Template.
Reusable template for creating dashboards for prediction market strategies on platforms like Polymarket.
Scope (single-signal / single-position): the template renders one
active market with one YES/NO position. market_id /
yes_shares / no_shares / cost_basis are scalars; an account
holding positions across multiple markets simultaneously is not modelled
in the headline panels (the optional tracked_markets plot is
informational only). The 3 accounting sections (PnL, Cost Stack, Trade
Tape) are baked in so every prediction dashboard ships with full
accounting. For multi-market or multi-signal layouts (e.g. an arbitrage
basket spanning N markets), do not parameterize this template — write a
custom dashboard composed from the section helpers (render_pnl_section,
render_cost_stack_section, render_trade_tape_section) plus
primitive plot helpers from almanak.framework.dashboard.plots
directly. See the dashboard blueprints for the recommended composition.
Usage
from almanak.framework.dashboard.templates import PredictionDashboardConfig, render_prediction_dashboard
protocol defaults to the connector default ("polymarket"); pass¶
protocol="" to override for another prediction venue.¶
config = PredictionDashboardConfig()
def render_custom_dashboard(deployment_id, strategy_config, api_client, session_state): render_prediction_dashboard(deployment_id, strategy_config, session_state, config)
PredictionDashboardConfig
dataclass
¶
PredictionDashboardConfig(
protocol: str = (
lambda: _default_prediction_protocol()
or "polymarket"
)(),
chain: str = "polygon",
show_position_overview: bool = True,
show_probability_chart: bool = True,
show_market_outcomes: bool = True,
show_arbitrage_analysis: bool = True,
show_pnl_breakdown: bool = True,
)
Configuration for a prediction market dashboard.
Attributes:
| Name | Type | Description |
|---|---|---|
protocol |
str
|
Protocol name (e.g., "polymarket") |
chain |
str
|
Chain name |
show_position_overview |
bool
|
Whether to show position overview |
show_probability_chart |
bool
|
Whether to show probability over time |
show_market_outcomes |
bool
|
Whether to show market outcomes comparison |
show_arbitrage_analysis |
bool
|
Whether to show arbitrage opportunity analysis |
show_pnl_breakdown |
bool
|
Whether to show PnL breakdown |
render_prediction_dashboard
¶
render_prediction_dashboard(
deployment_id: str,
strategy_config: dict[str, Any],
session_state: dict[str, Any],
config: PredictionDashboardConfig,
) -> None
Render a prediction market strategy dashboard using the provided configuration.
Single-signal / single-position template — one active market with one YES/NO position. Bakes in the 3 accounting sections (PnL → primitive content → Cost Stack → Trade Tape). For multi-position or multi-signal layouts, compose a custom dashboard from the section helpers directly rather than parameterizing this template.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
deployment_id
|
str
|
The deployment identifier |
required |
strategy_config
|
dict[str, Any]
|
Strategy configuration dictionary |
required |
session_state
|
dict[str, Any]
|
Current session state with position data |
required |
config
|
PredictionDashboardConfig
|
PredictionDashboardConfig for this dashboard |
required |
get_polymarket_config
¶
Get pre-configured Polymarket dashboard config.
get_polymarket_arbitrage_config
¶
Get pre-configured Polymarket arbitrage dashboard config.