68 lines
2.8 KiB
C#
68 lines
2.8 KiB
C#
namespace BlueLaminate.Core.Tradeups;
|
|
|
|
/// <summary>One possible result of a contract and what it would net if it lands.</summary>
|
|
/// <param name="Probability">Chance this specific output is produced (single-collection: 1/k).</param>
|
|
/// <param name="NetSellPrice">
|
|
/// Realisable sale value after undercut + sell fee, or null when nothing comparable is
|
|
/// listed (treated as unsellable for the worst-case test).
|
|
/// </param>
|
|
/// <param name="Liquidity">Active listings backing the price, in the same wear band.</param>
|
|
/// <param name="PriceSource">Where the price came from: "market" (our stored listings) or
|
|
/// "csfloat-live" (re-priced from the CSFloat API because the stored liquidity was thin).</param>
|
|
public sealed record TradeupOutcome(
|
|
int SkinId,
|
|
string Name,
|
|
decimal OutputFloat,
|
|
WearBand Band,
|
|
decimal Probability,
|
|
decimal? NetSellPrice,
|
|
int Liquidity,
|
|
string PriceSource = "market");
|
|
|
|
/// <summary>
|
|
/// One collection's share of a (possibly multi-collection) contract: how many of the ten
|
|
/// inputs came from it, and which output tier those inputs roll into. Single-collection
|
|
/// contracts have exactly one of these.
|
|
/// </summary>
|
|
public sealed record TradeupContribution(
|
|
int CollectionId,
|
|
string CollectionName,
|
|
WeaponRarity OutputRarity,
|
|
int InputCount);
|
|
|
|
/// <summary>
|
|
/// A concrete, actionable tradeup: which ten copies to buy, what they cost, the output
|
|
/// distribution, and the resulting economics. The finder returns these ranked; a frontend
|
|
/// only formats them.
|
|
/// <para>
|
|
/// A contract may mix several collections (all inputs share the input rarity, but each
|
|
/// collection rolls into its own next tier). <see cref="Composition"/> records the per-
|
|
/// collection split; <see cref="CollectionCount"/> is its length. <see cref="OutputRarity"/>
|
|
/// is the tier of the largest contributor (a display convenience for the common case).
|
|
/// </para>
|
|
/// </summary>
|
|
public sealed record TradeupCandidate(
|
|
int CollectionId,
|
|
string CollectionName,
|
|
WeaponRarity InputRarity,
|
|
WeaponRarity OutputRarity,
|
|
bool StatTrak,
|
|
decimal AverageFraction,
|
|
decimal InputCost,
|
|
decimal ExpectedNet,
|
|
decimal WorstCaseNet,
|
|
bool Guaranteed,
|
|
IReadOnlyList<InputListing> Inputs,
|
|
IReadOnlyList<TradeupOutcome> Outcomes,
|
|
IReadOnlyList<TradeupContribution> Composition)
|
|
{
|
|
/// <summary>Number of distinct collections the inputs are drawn from (1 = single-collection).</summary>
|
|
public int CollectionCount => Composition.Count;
|
|
|
|
/// <summary>Expected profit across the output distribution, net of cost.</summary>
|
|
public decimal ExpectedProfit => ExpectedNet - InputCost;
|
|
|
|
/// <summary>Profit if the worst (lowest-value) output lands — negative unless guaranteed.</summary>
|
|
public decimal WorstCaseProfit => WorstCaseNet - InputCost;
|
|
}
|