CurrencyStrength
The relative strength of the major currencies as bars, strongest first, given or worked out from pairs' changes.
Demo
Currency strength
Today- AUDAustralian dollar+0.38%, the strongest
- EUREuro+0.16%
- CADCanadian dollar+0.12%
- CHFSwiss franc0.00%
- JPYJapanese yen-0.03%
- GBPBritish pound-0.11%
- USDUS dollar-0.15%, the weakest
Strength score, 0 to 10
Past week- CHFSwiss franc7.2, the strongest
- USDUS dollar6.8
- GBPBritish pound5.6
- EUREuro5.1
- JPYJapanese yen3.4, the weakest
Get it
It needs theme.qwe, as every component does; or take the whole kit, quillo-ui.qwe. Each component brings its own styles to the pages that show it.
$ curl -O https://quillolang.org/components/ui/theme.qwe$ curl -O https://quillolang.org/components/ui/currency_strength.qwemain.qwe
import ui/theme.qwe use theme_cssuse ui/currency_strength.qweroute GET / = <html><head><style>{theme_css}</style></head><body class="ui-root">...</body></html>Example
The code of the preview above.
demos/currency_strength.qwe
view CurrencyStrengthDemo() = <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 12px; align-items: start"> <CurrencyStrength id="currency-strength-demo" period="Today" pairs={[ { pair: "EUR/USD", change: 0.22m }, { pair: "GBP/USD", change: -0.21m }, { pair: "USD/JPY", change: -0.42m }, { pair: "USD/CHF", change: 0m }, { pair: "AUD/USD", change: 0.35m }, { pair: "USD/CAD", change: -0.12m }, { pair: "EUR/GBP", change: 0.08m }, { pair: "EUR/JPY", change: 0.18m }, { pair: "GBP/JPY", change: -0.05m }, { pair: "AUD/JPY", change: 0.40m }, ]}/> <CurrencyStrength id="currency-strength-demo-score" label="Strength score, 0 to 10" period="Past week" decimals={1} values={{ USD: 6.8m, EUR: 5.1m, GBP: 5.6m, JPY: 3.4m, CHF: 7.2m }}/> </div>Source
ui/currency_strength.qwe
// CurrencyStrength: how strong the major currencies are against each other, as a// bar each, strongest first. The strengths are given, or worked out from pairs'// changes: a currency's strength is the average of how it moved in every pair it is// in (a pair's change counts for its base and against its quote). When some are// negative the bars grow left and right of a middle line, green and red.//// <CurrencyStrength pairs={[{ pair: "EUR/USD", change: 0.22m }, { pair: "USD/JPY", change: -0.42m }, ...]} period="Today"/>// <CurrencyStrength values={{ USD: 6.8m, EUR: 5.1m, JPY: 3.4m }} suffix="" decimals={1} label="Strength score, 0 to 10"/>//// pairs: a list of { pair, change }: "EUR/USD" and its change over the period, in// percent (decimals best; numbers are read as decimals). values: instead, a map of// code to its strength, on any scale. currencies: which to show (all that appear).// label: the heading ("Currency strength"). period: what the change is over, beside it// ("Today", "Past week"). suffix: after each number ("%" from pairs, "" from values).// decimals: digits shown (2). names: the currencies' names ({ CHF: "Swiss franc" };// the majors are known). locale: how numbers are written ("en-US"). id: the element's id.//// currency_strength_from_pairs(pairs) gives the map of code to strength, for other code.import ui/theme.qwe use ui_clslet currency_strength_css = css`.ui-fxstr { box-sizing: border-box; display: grid; gap: 10px; width: 100%; min-width: 0; max-width: 520px; padding: 16px 18px; border: 1px solid var(--ui-border); border-radius: var(--ui-radius); background: var(--ui-surface); font: 13px/1.35 var(--ui-font); color: var(--ui-fg); }.ui-fxstr-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }.ui-fxstr .ui-fxstr-title { margin: 0; font-size: 15px; font-weight: 650; }.ui-fxstr-period { color: var(--ui-muted); font-size: 12px; }.ui-fxstr-list { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }.ui-fxstr-item { display: grid; grid-template-columns: 22px 96px minmax(60px, 1fr) 64px; align-items: center; gap: 10px; }.ui-fxstr-rank { color: var(--ui-muted); font-size: 12px; text-align: right; font-variant-numeric: tabular-nums; }.ui-fxstr-code b { font-weight: 650; }.ui-fxstr-code small { display: block; overflow: hidden; color: var(--ui-muted); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; }.ui-fxstr-track { position: relative; height: 12px; border-radius: 3px; background: var(--ui-subtle); }.ui-fxstr-split .ui-fxstr-track::after { content: ""; position: absolute; top: -3px; bottom: -3px; left: 50%; width: 1px; background: var(--ui-strong); }.ui-fxstr-bar { position: absolute; top: 0; bottom: 0; border-radius: 3px; background: var(--k); }.ui-fxstr-up { --k: var(--ui-success); } .ui-fxstr-down { --k: var(--ui-danger); } .ui-fxstr-level { --k: var(--ui-accent); }.ui-fxstr-value { text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--k); }.ui-fxstr-level .ui-fxstr-value { color: var(--ui-fg); }.ui-fxstr-empty { margin: 0; color: var(--ui-muted); }@media (max-width: 420px) { .ui-fxstr-item { grid-template-columns: 18px 48px minmax(40px, 1fr) 56px; } .ui-fxstr-code small { display: none; } }`let currency_strength_names = { USD: "US dollar", EUR: "Euro", GBP: "British pound", JPY: "Japanese yen", CHF: "Swiss franc", CAD: "Canadian dollar", AUD: "Australian dollar", NZD: "New Zealand dollar", CNY: "Chinese yuan", SEK: "Swedish krona", NOK: "Norwegian krone", MXN: "Mexican peso" }// Each currency's strength from pairs' changes: the average of + the change where it is// the base and − the change where it is the quote. A map of code to a decimal.fn currency_strength_from_pairs(pairs: list) { let moves = flatten(pairs | map((p) => { let parts = split(upper(p.pair), "/") let c = dec(p.change) len(parts) > 1 ? [[parts[0], c], [parts[1], -c]] : [] })) let groups = group_by(moves, (m) => m[0]) reduce(keys(groups), {}, (acc, k) => { let xs = groups[k] | map((m) => m[1]) set(acc, k, sum(xs) / len(xs)) })}// A width or a place in percent, to two decimals.fn currency_strength_pct(n: num) -> str { let r = round(n * 100) / 100 r == floor(r) ? str(floor(r)) : str(r)}view CurrencyStrength(pairs: list? = null, values: map? = null, currencies: list? = null, label: str = "Currency strength", period: str? = null, suffix: str? = null, decimals: int = 2, names: map? = null, locale: str = "en-US", id: str? = null, class: str? = null) { style global currency_strength_css let scores = values != null ? values : currency_strength_from_pairs(pairs ?? []) let codes = currencies ?? keys(scores) let items = codes | filter((c) => scores[c] != null) | map((c) => { code: c, v: round(dec(scores[c]), decimals, "half_up") }) | sort_by((it) => -it.v) let top = len(items) > 0 ? max(items | map((it) => abs(it.v))) : 0 let split_bars = any(items, (it) => it.v < 0) let unit = suffix ?? (values != null ? "" : "%") let title = (c: str) => (names != null ? names[c] : null) ?? currency_strength_names[c] <div class={ui_cls(["ui-fxstr", split_bars && "ui-fxstr-split", class])} id={id}> <div.ui-fxstr-head> <h3.ui-fxstr-title>{label}</h3> {period != null && <span.ui-fxstr-period>{period}</span>} </div> {len(items) == 0 ? <p.ui-fxstr-empty>No currencies to compare.</p> : <ol.ui-fxstr-list> {for [i, it] in enumerate(items) { let share = top == 0 ? 0 : float(abs(it.v)) / float(top) let width = split_bars ? share * 50 : share * 100 let left = split_bars ? (it.v >= 0 ? 50 : 50 - width) : 0 let tone = !split_bars ? "ui-fxstr-level" : (it.v > 0 ? "ui-fxstr-up" : (it.v < 0 ? "ui-fxstr-down" : "ui-fxstr-level")) let shown = `${split_bars && it.v > 0 ? "+" : ""}${format_number(it.v, locale, decimals)}${unit}` <li key={it.code} class={`ui-fxstr-item ${tone}`} data-code={it.code}> <span.ui-fxstr-rank aria-hidden="true">{i + 1}</span> <span.ui-fxstr-code><b>{it.code}</b>{title(it.code) != null && <small>{title(it.code)}</small>}</span> <span.ui-fxstr-track aria-hidden="true"> <span.ui-fxstr-bar style={`left: ${currency_strength_pct(left)}%; width: ${currency_strength_pct(width)}%`}></span> </span> <span.ui-fxstr-value>{shown}{i == 0 && <span.ui-sr>, the strongest</span>}{i == len(items) - 1 && len(items) > 1 && <span.ui-sr>, the weakest</span>}</span> </li> }} </ol>} </div>}Related
CreditScoreA credit score on a gauge of its bands from poor to excellent, the band it falls in, the change since the last report and the factors that move it.7 views · 8 downloadsCurrencyPairCardOne currency pair: the bid and ask large with the pip digits biggest, the spread, the day's change, low and high, and a sparkline of the day.7 views · 6 downloadsAccountCardA bank account at a glance: type, nickname, masked number, current and available balance, what is on hold, and quick actions.8 views · 7 downloadsCrossRatesA matrix of cross rates among a few currencies, each worked out from their rates against one base, the diagonal left blank.6 views · 6 downloadsCurrencyConverterAn amount and two currencies with a swap button, the rate both ways and the converted amount, crossed through the base from the rates given.8 views · 11 downloadsCurrencyWalletBalances in several currencies with the total in a base currency, each with its rate, its worth and share, and convert and send actions.9 views · 6 downloads
Thread
Thread 0 posts
On CurrencyStrength: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.