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.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
deployment_id
|
str
|
The deployment id (passed straight through from
|
必需 |
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.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
deployment_id
|
str
|
The deployment id. |
必需 |
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.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
deployment_id
|
str
|
The deployment id (passed straight through from
|
必需 |
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):
# Pass deployment_id so the price chart follows the operator-selected
# NAV range (24h/7d/30d) when one is picked (VIB-5114); omitting it
# keeps the legacy recent-window fetch.
session_state = prepare_ta_session_state(
api_client, session_state, config, deployment_id=deployment_id
)
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, deployment_id=deployment_id
)
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(),
display_window_seconds: int = DEFAULT_DISPLAY_WINDOW_SECONDS,
)
Configuration for a TA dashboard.
属性:
| 名称 | 类型 | 描述 |
|---|---|---|
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: |
display_window_seconds |
int
|
Default visible span of the price/indicator
x-axis, in seconds (VIB-5345). Decoupled from the FETCH span: the
dashboard still fetches the wide candle window ( |
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,
*,
deployment_id: str | 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).
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
api_client
|
Any
|
|
必需 |
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
|
deployment_id
|
str | None
|
Optional deployment id used to read the operator's
selected NAV range from |
None
|
返回:
| 类型 | 描述 |
|---|---|
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.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
deployment_id
|
str
|
The deployment identifier |
必需 |
strategy_config
|
dict[str, Any]
|
Strategy configuration dictionary |
必需 |
session_state
|
dict[str, Any]
|
Current session state with indicator values |
必需 |
config
|
TADashboardConfig
|
TADashboardConfig for this dashboard |
必需 |
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): # Pass session_state + deployment_id so the pool price chart follows the # operator-selected NAV range (24h/7d/30d) when one is picked (VIB-5114); # omitting them keeps the legacy recent-window fetch. session_state = prepare_lp_session_state( api_client, session_state, config=config, deployment_id=deployment_id ) # 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.
属性:
| 名称 | 类型 | 描述 |
|---|---|---|
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,
*,
deployment_id: 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.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
api_client
|
Any
|
DashboardAPIClient instance. |
必需 |
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
|
deployment_id
|
str | None
|
Optional deployment id used to read the operator's
selected NAV range from |
None
|
返回:
| 类型 | 描述 |
|---|---|
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.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
deployment_id
|
str
|
The deployment identifier |
必需 |
strategy_config
|
dict[str, Any]
|
Strategy configuration dictionary |
必需 |
session_state
|
dict[str, Any]
|
Current session state with position data.
Use :func: |
必需 |
config
|
LPDashboardConfig
|
LPDashboardConfig for this dashboard |
必需 |
api_client
|
Any | None
|
Optional |
None
|
registry_handles_from_trade_tape
¶
Map position_id (e.g. UniV3 NFT tokenId) → the strategy's actual registry handle.
Source: the trade-tape join (ledger × accounting × position event). Every
accounting OPEN/CLOSE row carries position_reference.registry_handle —
the handle the strategy itself stamped on the intent — alongside the
joined position_id. This is the SAME provenance the Trade Tape
headline chip and the registry table surface, so the Position Status
cards and the Liquidity Distribution legend can never disagree with them
(VIB-5073: the lp_dual dashboard used to label the Nth distinct
position_id leg_<N>, so a rebalanced leg — same handle, new tokenId —
rendered as a phantom leg_3 that exists nowhere in the strategy
config).
Never synthesizes a handle: positions whose events carry no
registry_handle are simply absent from the map. Callers must fall
back to a clearly-non-handle label (the tokenId / a generic placeholder).
Rows arrive newest-first (gateway sorts timestamp DESC) and the first
handle seen per position_id wins, so a re-bound handle reflects the
most recent accounting write.
Returns {} on any failure — never raises (dashboard render path).
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.
属性:
| 名称 | 类型 | 描述 |
|---|---|---|
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.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
deployment_id
|
str
|
The deployment identifier |
必需 |
strategy_config
|
dict[str, Any]
|
Strategy configuration dictionary |
必需 |
session_state
|
dict[str, Any]
|
Current session state with position data |
必需 |
config
|
LendingDashboardConfig
|
LendingDashboardConfig for this dashboard |
必需 |
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.
属性:
| 名称 | 类型 | 描述 |
|---|---|---|
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.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
deployment_id
|
str
|
The deployment identifier |
必需 |
strategy_config
|
dict[str, Any]
|
Strategy configuration dictionary |
必需 |
session_state
|
dict[str, Any]
|
Current session state with position data |
必需 |
config
|
PerpDashboardConfig
|
PerpDashboardConfig for this dashboard |
必需 |
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.
属性:
| 名称 | 类型 | 描述 |
|---|---|---|
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.
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
deployment_id
|
str
|
The deployment identifier |
必需 |
strategy_config
|
dict[str, Any]
|
Strategy configuration dictionary |
必需 |
session_state
|
dict[str, Any]
|
Current session state with position data |
必需 |
config
|
PredictionDashboardConfig
|
PredictionDashboardConfig for this dashboard |
必需 |
get_polymarket_config
¶
Get pre-configured Polymarket dashboard config.
get_polymarket_arbitrage_config
¶
Get pre-configured Polymarket arbitrage dashboard config.