What This Tool Ranks
The calculator ranks NPC LP-store offers by realistic ISK per LP. It compares selling into Jita buy orders with listing against Jita sell orders, after taxes, broker fees, required item costs, and — when blueprint manufacture rows are shown — material costs and the manufacturing job installation fee.
The default leaderboard:
- Shows all access-risk tiers and ranks by the higher of buy-order and sell-order ISK/LP.
- Groups duplicate store economics, uses
minVolume=0, and assumes30000LP/hour for the ISK/hour column. - Excludes SDE corporations without an earnable LP source before any user filter runs; normal agent, CONCORD/special, and faction warfare LP sources remain eligible. Level 5 mission corporations are shown by default.
- Enables the No warns, No vanity, and Sec L4+ quality filters, so rows with strong warnings or multiple warning flags, vanity/cosmetic products, plus corporations without normal level 4 or 5 Security agents are hidden until those toggles are switched off.
- Includes standard corporation LP; faction warfare, special-source LP, and blueprint-copy rows (both direct sale and manufacture) are opt-in.
- Keeps rows below
100units and250mISK of average daily market volume visible but flags themLOW_VOLUME. Rows above100m3 carry a cargo-volume flag, with a stronger red flag above500m3.
The Space control can narrow results to highsec-accessible stores or show all known access tiers. The Level 5 Missions control can show all corporations, only corporations with level 5 agents, or hide them. Ranking controls can choose the valuation basis, scale runs, set LP/hour, require minimum 28-day market volume, and optionally hide rows above a maximum packaged cargo volume in m3. Quality toggles control Jita-only pricing, suspicious rows, vanity rows, no-Security-L4+ corporations, faction warfare, special LP stores, and duplicate store rows. The BPC control picks which blueprint-copy rows appear: none, direct contract sales, manufacture conversions, or both.
Data Sources
- LP offers: public ESI
/latest/loyalty/stores/{corporation_id}/offers/. - Jita orders: public ESI region 10000002 market orders, persisted as top 50 sell and buy levels per type.
- Market history: public ESI region 10000002 history, summarized into a 28 calendar-day average daily volume (days with no trades count as zero) and median price.
- Adjusted reference prices: public ESI
/latest/markets/prices/, stored per type and used as the EIV basis for the manufacturing job installation fee. - Static data: official Fenris Creations (formerly CCP Games) JSON Lines SDE ZIP, cached under
data/sde/and imported into SQLite. - Earnable LP sources: derived from SDE agent references for normal, CONCORD/special, and faction warfare agent corporations, then applied before LP-store fetches and leaderboard filters.
- SDE metadata: recorded in
source_importsand exposed through/api/health.
Refresh Cadence
The scheduler refreshes:
- Hot market prices every 15 minutes.
- Cold referenced market types hourly at minute 7.
- LP offers daily at 11:10 UTC, market history daily at 11:20 UTC, adjusted reference prices daily at 11:22 UTC, and snapshots daily at 11:45 UTC.
Startup warmup fills missing or stale SDE, LP, market, and history data before normal cadence takes over. Fetchers honor ESI Expires headers through the SQLite ESI cache, retry transient upstream failures carefully, and pause before exhausting the ESI error-limit budget.
The leaderboard header reports hot and cold market-price ages separately, LP offer freshness as a daily feed, and an overall Updates OK or Needs attention state from /api/health. A daily LP timestamp that is a few hours old is expected; hot prices are the freshness signal that should normally move every 15 minutes.
Core Calculation
buy_order_sell = sell products into buy orders, pay sales tax
sell_order_listing = list products near sell orders, pay sales tax plus one broker-fee pass
input_cost = LP-store ISK cost + required items bought from sell orders
build_cost = BPC materials (after Material Efficiency) bought from sell orders
job_cost = manufacturing job installation fee on built rows (see BPC Manufacturing)
net_buy_order = product_value_buy_order * (1 - sales_tax_rate) - input_cost - build_cost - job_cost
net_sell_order = product_value_sell_order * (1 - sales_tax_rate - broker_fee_rate) - input_cost - build_cost - job_cost
isk_per_lp = selected net_profit / LP cost
capital_required = input_cost + build_cost + job_cost
roi = selected net_profit / capital_required
The valuation basis can use buy-order cashout, sell-order listing, or the higher of both. runs scales LP, ISK, required items, manufacturing materials, cargo, and order-book depth. When lpBudget or iskBudget is provided, the calculator chooses the maximum feasible run count for that row. The ISK/hour display multiplies the selected ISK/LP basis by the URL-backed lpPerHour value. Contract-priced rows show a dash instead: their ISK/LP is a real one-off conversion rate, but public contracts for such items sell at most a few times per day game-wide, so extrapolating by LP/hour would invent income the market cannot absorb. These rows also sort last when the leaderboard is sorted by ISK/hour.
Fees And Skills
sales_tax_rate = 0.075 * (1 - 0.11 * Accounting)
broker_fee_rate = max(
0.03
- 0.003 * BrokerRelations
- 0.0003 * factionStanding
- 0.0002 * corporationStanding,
0.01
)
These are the Tranquility NPC-station rates: sales tax starts at 7.5% and falls to 3.375% at Accounting V; the broker fee starts at 3%, drops 0.3 percentage points per Broker Relations level plus up to 0.3 from faction and 0.2 from corporation standing, and never goes below 1%. Accounting, Broker Relations, Advanced Broker Relations, faction standing, and corporation standing are URL-backed filters. Defaults are zero so the default view is pessimistic for a fresh character. Advanced Broker Relations only affects relist fees in Realistic patient mode.
The optional No market fees (contract sale) channel — bundled into Manufacturer mode — models selling through item-exchange contracts instead of the market. A contract charges only a flat creation fee (about 10k ISK, noise at faction-item prices), so this channel zeroes both the sales tax and the broker fee. It is the only way to reach a true 0%: the skill sliders above floor at 3.375% sales tax and 1% broker. This is how serious LP farmers actually move high-value faction implants and modules, and it matches the fee-free treatment contract-priced rows already receive.
Depth Walking
Every priced leg walks the persisted Jita order book for the full requested quantity instead of using only top-of-book. Products sold through buy orders walk buy orders — but only buy orders a seller standing at Jita 4-4 could actually fill: region-range orders, plus station- or system-range orders that sit at Jita 4-4 or in the Jita system. Products listed through sell orders, required items, and build materials walk sell orders. If the saved top 50 orders do not cover the requested fill, the row is flagged as insufficient depth and the missing quantity is extrapolated at the last consumed price.
Patient Listing Realism
The sell-order (patient) basis above assumes a listing fills in full at the walked prices. In reality a listing joins a queue and waits. Every row therefore carries an estimated fill time for the primary output, shown in the detail drawer:
queue_ahead = sell-book units listed at or below the volume-weighted list price
sell_rate = 0.5 * avg_daily_volume_28d
days_to_fill = (queue_ahead + quantity) / sell_rate
The 0.5 factor exists because ESI daily volume mixes both trade directions and only buyer-initiated trades consume the sell book; with no public split, half is the symmetric prior. Items with no market history get no estimate. The SLOW_FILL flag uses this queue-aware estimate for the output leg: warn past 7 days, strong past 28.
The optional Realistic patient quality toggle (off by default, URL-backed) goes further and discounts the sell-order valuation itself:
relist_discount = 0.5 + 0.06 * AdvancedBrokerRelations (80% at V)
expected_relists = ceil(days_to_fill / 2) - 1, floored at 0
relist_cost = expected_relists * (1 - relist_discount) * broker_fee_rate * product_value
patient_effective = net_buy_order + (net_sell_order - relist_cost - net_buy_order)
* exp(-days_to_fill / 7)
The exponential decay pulls slow fills toward the guaranteed buy-order cashout: a fill estimated a week out keeps about 37% of the patient premium, and a month-long fill keeps almost none. Relist fees model staying competitive against undercutting, using the Tranquility relist mechanic where modifying an order down costs the undiscounted share of the broker fee on the new price; Advanced Broker Relations is a URL-backed skill filter next to the other fee skills. With the toggle off, nothing changes — the patient and best columns keep the optimistic immediate-fill values.
BPC Manufacturing
When an offered product is a blueprint copy with a manufacturing recipe in the SDE, the calculator can value the manufactured output and subtract material costs ("manufacture" rows), and when fresh public-contract asks exist it can value the copy as a direct contract sale ("sell" rows). Both are hidden by default because blueprint rows can dominate the table with assumptions that are more sensitive to build settings, material liquidity, and contract depth. The four-position BPC control in the Quality filters picks which rows appear: None (default), Sell, Build (manufacture conversions), or All. Build is a buildables-only lens: it shows manufacture conversion rows alone and hides plain direct-item LP offers, because the facility, Material Efficiency, and job-cost settings act only on built rows — those direct items stay in the default None view.
LP-store blueprint copies are unresearched (Material Efficiency 0), so the default view buys the full base material quantities — matching a build in an NPC station with no rigs. Manufacturer mode's Facility preset instead models a rigged structure: a T2 ME rig in highsec (about 3.2% material savings) or in null / wormhole space (about 5.8%), applying EVE's per-material round-then-ceil ME formula. Manufacturer mode is a standalone top-bar toggle that bundles these blueprint build rows — and only those, so every row responds to the build settings; plain direct-item offers are hidden — this facility, the job installation fee below, and the no-market-fees contract channel, and tints the workspace to signal it is not the default view.
Built rows also carry the manufacturing job installation fee, which is on by default. EVE charges this per job as a percentage of the job's Estimated Item Value (EIV = the sum of each base material quantity times CCP's daily adjusted reference price, ignoring Material Efficiency):
job_cost = EIV * (system_cost_index * structure_bonus + 0.0025 facility_tax + 0.04 SCC)
The facility tax and SCC surcharge (about 4.25% together) are location-independent; only the system cost index varies, so Manufacturer mode exposes it as a single configurable percent (default 2.5% for an NPC station, where structure_bonus is 1). The fee is real ISK the builder fronts, so unlike the LP-paid blueprint it lowers net profit and raises capital_required and the ROI denominator. Adjusted reference prices come from public ESI /latest/markets/prices/, refreshed daily; a material CCP does not price is skipped from EIV, so job cost is understated rather than wrong.
Risk And Access
Space filtering and row risk icons use practical LP-store access risk, derived from the least risky known NPC station owned by the corporation. The corporation HQ system is still shown as location metadata, but it does not by itself make a highsec-accessible corporation look like a nullsec-only store. Highsec is security 0.5 and above, lowsec is 0.0 through 0.4, and nullsec covers below 0.0 plus any wormhole or unknown-security store access.
DED, CONCORD, and similar special-source LP stores are marked as special LP and excluded from the global default leaderboard. Faction warfare offers are also opt-in. Choosing a specific corporation or faction in the Corporation / Faction filter overrides these global exclusions and the no-Security-agent filter, so the selected owner's full catalog is shown even when the matching toggles are off — for example picking a faction-warfare militia returns its offers instead of an empty table. LP-store corporations with no earnable LP source, such as event or placeholder LP stores without agents, are excluded before these user-facing filters are applied. Risk chips are visual warnings on the row; highsec-accessible rows do not get a risk chip.
Quality Flags
| Flag | Rule | Severity |
|---|---|---|
LOW_VOLUME | 28-day average daily volume is below 100 units and below 250m ISK; expensive items that move serious ISK on few units are not flagged. | Warn; shown as a yellow flag. |
SLOW_FILL | The estimated sell-order fill of the output — queue ahead at the walked list price plus the requested quantity, against the sell-side half of daily volume (see Patient Listing Realism) — exceeds 7 days. Cost legs keep the plain quantity-versus-volume rule. | Warn; strong above 28 days. |
HEAVY | Packaged cargo volume is above 100 m3 and at or below 500 m3. | Warn; shown as a yellow flag. |
VERY_HEAVY | Packaged cargo volume is above 500 m3. | Strong visual; shown as a red flag. |
THIN_BOOK | Sell order count is 2 or less, or the top sell order has more than 80% of sell quantity. | Warn |
WIDE_SPREAD | Sell minimum is more than 50% above buy maximum. | Warn |
PRICE_SPIKE | Current sell minimum is more than twice the 28-day median price. | Strong |
BUY_SPIKE | Current buy maximum on the output is more than 1.5x the 28-day median price. Buy maxima normally sit below the median, so this usually means a seeded buy wall is inflating the buy-order valuation. | Strong |
OFF_HUB | Cheapest sell order is not at Jita 4-4. | Warn, or strong when multiple significant cost legs are off-hub. |
NO_HISTORY | Market history has fewer than seven days. | Warn |
INSUFFICIENT_DEPTH | Persisted order-book depth does not cover the requested fill. | Strong |
CONTRACT_PRICED | The product cannot be listed on the regular market (no market group, typically a faction blueprint copy) and is valued from scam-filtered public-contract asks in The Forge: blueprint copies are normalized to price per run, decoy listings are screened by a recipe cap (a copy's per-run value cannot exceed what the built product sells for) and a band anchored on the cheapest credible ask, and at least two independent asks must survive. The patient basis skips the sales tax and broker fee because item-exchange contracts pay only a flat creation fee; no instant-sell value exists. Blueprint offers with both a manufacture recipe and a contract price appear twice — a (sell) row for the direct contract sale and a (manufacture) conversion row whose net profit keeps total-realization math; the consumed copy is paid for in LP, so its contract value is excluded from net profit, capital required, and ROI alike, and the (sell) row is where that value surfaces. The (sell) row's only ISK cost is the token LP-store fee, so it shows no ROI (like ISK/hour): its return is measured per LP, not per ISK. Both are hidden until the BPC control enables them. | Warn |
NICHE_DEMAND | A contract-priced blueprint copy where one copy covers at least half a day of the built product's entire Jita demand (copy runs against the product's 28-day average daily volume). The whole market absorbs only a handful of fresh copies per day, so sale velocity — not LP/hour — caps what the offer can actually earn; the flag message states the copy-to-demand ratio. | Warn |
VANITY | The product is a vanity or cosmetic item: SDE apparel, SKIN, or personalization categories and groups, or a SKIN-named type. | Warn; frontend chip from row metadata. |
RISK_LOWSEC | Best known LP-store access is a low security station (see Risk And Access); highsec-accessible rows get no chip. | Warn; frontend chip from row metadata. |
RISK_NULLSEC | Best known LP-store access is null security or wormhole space. | Strong; frontend chip from row metadata. |
RISK_UNKNOWN | No known NPC station for the corporation, so the access risk tier is unknown. | Strong; frontend chip from row metadata. |
Tapping or clicking a flag chip on the leaderboard expands it into its full message; the ? inside links back to this section. Cargo-volume, vanity, and access-risk chips are added by the frontend from row metadata so they remain visible even when the persisted market-quality flags are otherwise clean.
Three quality filters interact with these flags:
- Hide suspicious removes any row with at least one strong persisted market-quality flag or at least two persisted market-quality warning flags.
- Jita-priced only requires every output, required input, and build-material sell leg to have its cheapest order at Jita 4-4.
- Sec L4+ is a separate optional quality filter that removes corporations with no normal level 4 or 5 Security agents in the SDE-derived agent reference; it does not control the base earnable-LP gate.
Search And Grouping
The compute step materializes offer names, product signatures, risk/source fields, flag counts, ratios, and compact API summaries into calc, then rebuilds SQLite FTS search for offer and product names. Corporation filtering uses a name autocomplete: typing a corporation or faction name resolves it to a hidden corporation ID, and selecting one scopes the leaderboard to that single owner (relaxing the faction-warfare, special-source, and no-Security-agent guardrails for that owner, as noted under Risk and Access). Identical offer economics are grouped by default so duplicate corporation stores do not crowd out distinct opportunities; "Show duplicate stores" returns each store row.
Frontend Loading And Diagnostics
The LP page starts the rows, corporations, and health requests without blocking the browser page-load event. It renders skeleton rows for a first load, reuses session-cached rows immediately for repeated filters, ignores stale filter responses, and shows a compact topbar loading state only while the current request is still active.
A persistent browser client ID is shown in the header and sent as X-EVE-Client-Id on API calls. The server also returns a fresh X-Request-Id for every request and writes problem-only JSON lines for 4xx and 5xx responses to logs/http-problems.log. The visible client ID helps correlate a player report without exposing request IDs in the UI.
API And Health
Read endpoints are rate-limited to 180 requests per minute per IP and set permissive CORS. Public LP API paths work at both /api/* and /lp/api/*. /api/health reports fetcher freshness, empty core tables, database size, last compute time, and SDE import metadata. POST /api/refresh recomputes the leaderboard and requires X-Admin-Token.
After each compute, canonical leaderboard, CSV, and corporation responses are materialized into SQLite with ETags and Brotli bodies. Dynamic read responses use short browser caching and longer CDN caching, while health stays short-lived. When Cloudflare credentials are configured, compute purges the LP API prefixes; deploys that change unhashed LP HTML/CSS/JS should run the static purge helper after build.
Known Limitations
- Market pricing is Jita-only.
- No ESI OAuth or per-character standing import exists in v1.
- Manufacturing supports the Material Efficiency facility presets and an EIV-based job installation fee, but not per-blueprint Time Efficiency, structure-specific job-cost bonuses, or T2 reaction-chain modeling.
- Market history is summarized for liquidity and spike checks, not shown as long-range charts.
- The fill estimator assumes half of daily volume consumes the sell book and a fixed two-day relist cadence; ESI does not publish trade direction or order ages, so both are priors rather than measurements.
- The visible client ID is a support diagnostic only, not an ESI identity or account link.
- The missions section at
/missions/is a separate static reference surface and does not change LP calculations. - The current LP frontend is served directly at the
/lpbase path.