Poinbase 订单簿、永续滑点减半、预测盘滑点调整、浏览器统一记账
- Poinbase 主池改为订单簿冲击曲线:第 38 天 2 PSC 约 0.1%、200 PSC 约 4% - 永续成交深度 50,000 → 100,000,滑点减半 - 预测盘 b = 1.8 × 额度 / ln 2(5% 盘口押 50 约贵 10%),消息价 2% / 5% / 12% - 统一记账函数 Chain:钱包每一笔进出写进浏览器和钱包记录,合约调用按执行前后余额差记账;Ponero 不上浏览器;账本上限 500 - 存档数据版本 3 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f0bbba2305
commit
6d8b05215c
24 files changed
+234
-81
No files matched your search
@@ -5,8 +5,10 @@ namespace Decentralized.Domain
|
||||
public enum Venue { Exchange, Dex, Darknet }
|
||||
|
||||
/// <summary>
|
||||
/// 一个交易对 = 一个恒定乘积池(x·y = k)。Base 是被交易的币,Quote 是计价币;价格 = Quote 储备 / Base 储备。
|
||||
/// 每个交易对各有深度;夜间由 NPC 套利者把价格按比例拉向目标价。
|
||||
/// 一个交易对。DEX 是恒定乘积池(x·y = k):Base 是被交易的币,Quote 是计价币,价格 = Quote 储备 / Base 储备。
|
||||
/// Poinbase 主池是订单簿(<see cref="Book"/>):价格只取决于当天的累计净买入量,冲击随单子变大而增长得比线性慢
|
||||
/// (价格 = 参考价 × exp(κ · sign(x) · |x|^α),x = 净买入的名义价值 / 深度),拆单不占便宜,同量买进再卖出回到原价。
|
||||
/// 每个交易对各有深度;夜间由 NPC 套利者把价格按比例拉向目标价,订单簿的累计量清零。
|
||||
/// </summary>
|
||||
public sealed class Pool
|
||||
{
|
||||
@@ -14,10 +16,44 @@ namespace Decentralized.Domain
|
||||
public Venue Venue;
|
||||
public double BaseReserve, QuoteReserve;
|
||||
public double Fee;
|
||||
/// <summary>订单簿模式:参考价、当天累计净买入的 Base 数量、深度(Quote)。</summary>
|
||||
public bool Book;
|
||||
public double Ref, Net, Depth;
|
||||
|
||||
public string Id => $"{Venue}:{Base}/{Quote}";
|
||||
|
||||
public double Price => QuoteReserve / BaseReserve;
|
||||
public double Price => Book ? PriceAt(Net) : QuoteReserve / BaseReserve;
|
||||
|
||||
public static Pool CreateBook(Venue venue, string baseAsset, string quote, double price, double depth, double fee) =>
|
||||
new Pool { Venue = venue, Base = baseAsset, Quote = quote, Book = true, Ref = price, Depth = depth, Fee = fee };
|
||||
|
||||
private double PriceAt(double net)
|
||||
{
|
||||
double x = net * Ref / Depth;
|
||||
return Ref * Math.Exp(Math.Sign(x) * Tuning.BookK * Math.Pow(Math.Abs(x), Tuning.BookAlpha));
|
||||
}
|
||||
|
||||
/// <summary>订单簿上累计净买入从 a 走到 b 的成交额(Quote,不含手续费;b < a 为负)。辛普森积分,同一区间正反两个方向结果互为相反数。</summary>
|
||||
private double Cost(double a, double b)
|
||||
{
|
||||
const int n = 128;
|
||||
double h = (b - a) / n, sum = PriceAt(a) + PriceAt(b);
|
||||
for (int i = 1; i < n; i++) sum += PriceAt(a + i * h) * (i % 2 == 1 ? 4 : 2);
|
||||
return sum * h / 3;
|
||||
}
|
||||
|
||||
/// <summary>订单簿:花 quote(不含手续费)能买到多少 Base。牛顿迭代解 Cost(Net, Net + b) = quote。</summary>
|
||||
private double BookBaseFor(double quote)
|
||||
{
|
||||
double b = quote / Price;
|
||||
for (int i = 0; i < 30; i++)
|
||||
{
|
||||
double step = (Cost(Net, Net + b) - quote) / PriceAt(Net + b);
|
||||
b = Math.Max(0, b - step);
|
||||
if (Math.Abs(step) < 1e-10 * (1 + b)) break;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
public static Pool Create(Venue venue, string baseAsset, string quote, double price, double quoteDepth, double fee) =>
|
||||
new Pool { Venue = venue, Base = baseAsset, Quote = quote, QuoteReserve = quoteDepth, BaseReserve = quoteDepth / price, Fee = fee };
|
||||
@@ -25,6 +61,7 @@ namespace Decentralized.Domain
|
||||
/// <summary>预估:卖出 baseIn 个 Base 能得到多少 Quote(不改池子)。</summary>
|
||||
public double QuoteOut(double baseIn)
|
||||
{
|
||||
if (Book) return baseIn > 0 ? Cost(Net - baseIn, Net) * (1 - Fee) : 0;
|
||||
double x = BaseReserve + baseIn * (1 - Fee);
|
||||
return QuoteReserve - BaseReserve * QuoteReserve / x;
|
||||
}
|
||||
@@ -32,6 +69,7 @@ namespace Decentralized.Domain
|
||||
/// <summary>预估:花 quoteIn 个 Quote 能买到多少 Base(不改池子)。</summary>
|
||||
public double BaseOut(double quoteIn)
|
||||
{
|
||||
if (Book) return quoteIn > 0 ? BookBaseFor(quoteIn * (1 - Fee)) : 0;
|
||||
double y = QuoteReserve + quoteIn * (1 - Fee);
|
||||
return BaseReserve - BaseReserve * QuoteReserve / y;
|
||||
}
|
||||
@@ -40,6 +78,7 @@ namespace Decentralized.Domain
|
||||
public double QuoteIn(double baseOut)
|
||||
{
|
||||
if (baseOut <= 0) return 0;
|
||||
if (Book) return Cost(Net, Net + baseOut) / (1 - Fee);
|
||||
if (baseOut >= BaseReserve) return double.PositiveInfinity;
|
||||
return (BaseReserve * QuoteReserve / (BaseReserve - baseOut) - QuoteReserve) / (1 - Fee);
|
||||
}
|
||||
@@ -49,6 +88,7 @@ namespace Decentralized.Domain
|
||||
{
|
||||
if (baseIn <= 0) return 0;
|
||||
double out_ = QuoteOut(baseIn);
|
||||
if (Book) { Net -= baseIn; return out_; }
|
||||
BaseReserve += baseIn;
|
||||
QuoteReserve -= out_;
|
||||
return out_;
|
||||
@@ -59,6 +99,7 @@ namespace Decentralized.Domain
|
||||
{
|
||||
if (quoteIn <= 0) return 0;
|
||||
double out_ = BaseOut(quoteIn);
|
||||
if (Book) { Net += out_; return out_; }
|
||||
QuoteReserve += quoteIn;
|
||||
BaseReserve -= out_;
|
||||
return out_;
|
||||
@@ -68,6 +109,7 @@ namespace Decentralized.Domain
|
||||
public double ImpactOfBuy(double quoteIn)
|
||||
{
|
||||
double before = Price;
|
||||
if (Book) return PriceAt(Net + BaseOut(quoteIn)) / before - 1;
|
||||
double y = QuoteReserve + quoteIn * (1 - Fee);
|
||||
double x = BaseReserve * QuoteReserve / y;
|
||||
return (y / x) / before - 1;
|
||||
@@ -85,6 +127,7 @@ namespace Decentralized.Domain
|
||||
|
||||
public void SetPrice(double price, double quoteDepth)
|
||||
{
|
||||
if (Book) { Ref = price; Net = 0; Depth = quoteDepth; return; }
|
||||
QuoteReserve = quoteDepth;
|
||||
BaseReserve = quoteDepth / price;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Decentralized.Domain
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 全局账本:只记真实发生的转账(玩家的转出和转入、矿机收益、出金),不生成 NPC 流水;最新的在前,超过 <see cref="Tuning.LedgerMax"/> 条丢最旧的。
|
||||
/// 全局账本:只记真实发生的转账(玩家钱包的每一笔进出,含合约调用和地址投毒的 0 币转入),不生成 NPC 流水;最新的在前,超过 <see cref="Tuning.LedgerMax"/> 条丢最旧的。
|
||||
/// </summary>
|
||||
public sealed class Ledger
|
||||
{
|
||||
@@ -22,7 +22,7 @@ namespace Decentralized.Domain
|
||||
|
||||
public void Add(LedgerEntry e)
|
||||
{
|
||||
if (e == null || e.Amount <= 0) return;
|
||||
if (e == null || e.Amount < 0) return;
|
||||
Entries.Insert(0, e);
|
||||
if (Entries.Count > Tuning.LedgerMax) Entries.RemoveRange(Tuning.LedgerMax, Entries.Count - Tuning.LedgerMax);
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace Decentralized.Domain
|
||||
{
|
||||
var m = new Market();
|
||||
double depth = Tuning.PoolDepth(day), p = Tuning.PscStartPrice;
|
||||
m.Pools.Add(Pool.Create(Venue.Exchange, Assets.PSC, Assets.CRC, p, depth, Tuning.ExchangeFee));
|
||||
m.Pools.Add(Pool.CreateBook(Venue.Exchange, Assets.PSC, Assets.CRC, p, depth, Tuning.ExchangeFee));
|
||||
m.Pools.Add(Pool.Create(Venue.Dex, Assets.PSC, Assets.CRC, p, depth * SideDepthShare, Tuning.DexFee));
|
||||
m.Pools.Add(Pool.Create(Venue.Dex, Assets.CRT, Assets.CRC, 1, depth * SideDepthShare, Tuning.DexFee));
|
||||
m.Pools.Add(Pool.Create(Venue.Dex, Assets.CRA, Assets.CRC, 1, depth * SideDepthShare, Tuning.DexFee));
|
||||
|
||||
@@ -33,8 +33,10 @@ namespace Decentralized.Domain
|
||||
public const double RefurbishHealth = 30;
|
||||
|
||||
// 市场
|
||||
/// <summary>主交易对(PSC/CRC)信用点一侧的深度。按全网日产出(约 {BlockReward} PSC)的比例对照头部交易所:买 2 PSC 的价格冲击约 0.02%,卖两天的产出约 2%。</summary>
|
||||
/// <summary>交易对信用点一侧的基础深度(DEX 侧池按比例取)。</summary>
|
||||
public const double PoolDepth0 = 600000;
|
||||
/// <summary>Poinbase 订单簿的冲击曲线:价格 = 参考价 × exp(κ · |x|^α),x = 当天净买入的名义价值 / 深度。第 38 天买 2 PSC 平均滑点约 0.1%,卖 200 PSC 约 4%。</summary>
|
||||
public const double BookK = 1.54, BookAlpha = 0.8;
|
||||
/// <summary>DEX 手续费;Poinbase 现货与出金的手续费(对照头部交易所 taker 约 0.1%)。</summary>
|
||||
public const double DexFee = 0.003, ExchangeFee = 0.001;
|
||||
/// <summary>NPC 大户每笔成交额(信用点)的范围。</summary>
|
||||
@@ -66,7 +68,7 @@ namespace Decentralized.Domain
|
||||
/// <summary>Poinbase 出金到钱包的确认动画:基础秒数,加每个确认的秒数(确认数同 PLEDGER 的 TxConfirm*)。</summary>
|
||||
public const double FundsBaseSecs = 1.2, FundsConfSecs = 0.6;
|
||||
/// <summary>浏览器账本最多保留的转账条数,一次最多显示的条数。</summary>
|
||||
public const int LedgerMax = 200, LedgerShow = 12;
|
||||
public const int LedgerMax = 500, LedgerShow = 12;
|
||||
public const double CraSpiralWeekly = 0.03;
|
||||
public const int CraWarnLeadMin = 4, CraWarnLeadMax = 7;
|
||||
public static readonly double[] CraSpiralPath = { 0.85, 0.30, 0.02 };
|
||||
@@ -215,8 +217,8 @@ namespace Decentralized.Domain
|
||||
public const double PerpFundCoef = 0.10, PerpFundCap = 0.003;
|
||||
/// <summary>永续的成交深度占现货主池的比例:开平仓的平均滑点 = 名义价值 / (深度倍数 × 池深),和现货一样大单更贵。</summary>
|
||||
public const double PerpDepthMult = 5.0;
|
||||
/// <summary>永续成交深度的基数(与现货池深分开:永续的滑点压住均值回归策略,校准见 research/perpsim)。</summary>
|
||||
public const double PerpDepth0 = 50000;
|
||||
/// <summary>永续成交深度的基数(与现货分开;原来 50,000,减半滑点后 100,000,校准见 research/perpsim)。</summary>
|
||||
public const double PerpDepth0 = 100000;
|
||||
/// <summary>开仓时按现价算权益至少要高出强平线多少(占名义价值的比例),否则拒绝(滑点太大,开了就被强平)。</summary>
|
||||
public const double PerpOpenBuffer = 0.02;
|
||||
public const double PerpDebtInterest = 0.02;
|
||||
@@ -242,7 +244,7 @@ namespace Decentralized.Domain
|
||||
public const int PredictUnlockDay = 8;
|
||||
public const double PredictFee = 0.01, PredictLoss0 = 800, PredictLossPerDay = 25, PredictCap = 2;
|
||||
/// <summary>预测盘的流动性:LMSR 的 b = 倍数 × 单盘额度 / ln 2,与先验无关(低先验盘不再更浅)。单盘额度只决定份额上限和消息价。</summary>
|
||||
public const double PredictDepth = 10;
|
||||
public const double PredictDepth = 1.8;
|
||||
public const int PredictOpenMin = 3, PredictOpenMax = 6, PredictNewPerDay = 2;
|
||||
public const double PredictInsiderShare = 0.4, PredictInsiderCatch = 0.7, PredictFraudShare = 0.5, PredictFraudCap = 400;
|
||||
public const double PredictFactionDaily = 0.06, PredictPMin = 0.03, PredictPMax = 0.97;
|
||||
@@ -255,7 +257,7 @@ namespace Decentralized.Domain
|
||||
public const double PredictMoveLog = 0.15;
|
||||
/// <summary>情报贩子:局势简报价格(CRT)、三档内幕消息的价格(占盘口最大亏损的比例)与准确率、假情报概率(claim 与真相相反)、需要的黑市声望。</summary>
|
||||
public const double IntelBriefPrice = 120, IntelFake = 0.10;
|
||||
public static readonly double[] IntelTipPrice = { 0.03, 0.08, 0.20 }, IntelTipAcc = { 0.60, 0.80, 0.95 };
|
||||
public static readonly double[] IntelTipPrice = { 0.02, 0.05, 0.12 }, IntelTipAcc = { 0.60, 0.80, 0.95 };
|
||||
public const int IntelRep = 20;
|
||||
/// <summary>操纵检出:玩家自己的大单把价格推离"没有你时的水平"的对数幅度(取绝对值)低于 ManipFree 不查;
|
||||
/// 超过后被查概率 = ManipBase + ManipSlope × (幅度 − ManipFree),封顶 ManipMax;被查后永续账户冻结几天。</summary>
|
||||
|
||||
@@ -157,6 +157,8 @@ namespace Decentralized.Domain
|
||||
["BmWeightCrt"] = Tuning.BmWeightCrt,
|
||||
["BmWeightPonero"] = Tuning.BmWeightPonero,
|
||||
["BmWeightPsc"] = Tuning.BmWeightPsc,
|
||||
["BookAlpha"] = Tuning.BookAlpha,
|
||||
["BookK"] = Tuning.BookK,
|
||||
["CardBracketScratch"] = Tuning.CardBracketScratch,
|
||||
["CardFanChipped"] = Tuning.CardFanChipped,
|
||||
["CardFanDust"] = Tuning.CardFanDust,
|
||||
|
||||
Reference in new issue
Block a user