Stage 7.2: manipulation detection (player price push, prediction/perp forfeits)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
002606056d
commit
786de325da
11 files changed
+99
-8
No files matched your search
@@ -21,6 +21,15 @@ namespace Decentralized.Domain
|
||||
public List<Pool> Pools = new List<Pool>();
|
||||
/// <summary>开门时的参考价,夜间用它和收盘价算当日均价(合约的标记价)。</summary>
|
||||
public double OpenPrice = Tuning.PscStartPrice;
|
||||
/// <summary>玩家自己的现货大单把价格推高(正)或压低(负)的对数幅度,每晚随价格回归一起衰减。操纵检出和预测盘用它估"没有玩家时的价格"。</summary>
|
||||
public double PlayerPush;
|
||||
public double NeutralPrice => Price * Math.Exp(-PlayerPush);
|
||||
/// <summary>被查概率:推价幅度(绝对值)超过 ManipFree 后随幅度升高。</summary>
|
||||
public static double ManipChance(double push)
|
||||
{
|
||||
push = Math.Abs(push);
|
||||
return push < Tuning.ManipFree ? 0 : Math.Min(Tuning.ManipMax, Tuning.ManipBase + Tuning.ManipSlope * (push - Tuning.ManipFree));
|
||||
}
|
||||
|
||||
public const double ArbRate = Tuning.SideArbRate; // 非主交易对每晚被拉回参考价的比例
|
||||
public const double SideDepthShare = Tuning.SideDepthShare; // 非主交易对的深度占主交易对的比例
|
||||
@@ -104,6 +113,7 @@ namespace Decentralized.Domain
|
||||
/// </summary>
|
||||
public void Night(ICollection<MarketEvent> active, Rng rng, int day, Func<string, double> stablePrice)
|
||||
{
|
||||
PlayerPush *= 1 - Tuning.Revert;
|
||||
Sentiment *= Math.Exp(Tuning.SentimentKappa * -Math.Log(Sentiment) + rng.Gauss() * Tuning.SentimentVol);
|
||||
double anchor = Anchor(active);
|
||||
double lp = Math.Log(Price);
|
||||
|
||||
@@ -183,7 +183,7 @@ namespace Decentralized.Domain
|
||||
/// 夜间:先登记今晚的观测,再结算 ToDay 到了的盘口(赢的钱回到下注的钱包,wallet 按地址找)。outcome 由接入层给出(事件 / 派系读观测,纯度和行情读游戏数值),null 表示拿不到数据。
|
||||
/// 赢家每份兑付 1 信用点;内幕持仓达到份额上限的 <see cref="Tuning.PredictInsiderShare"/> 后,有概率被查:只退本金,收益的一半记罪证。
|
||||
/// </summary>
|
||||
public List<PredictEvent> Night(int day, IEnumerable<string> activeNow, Func<PredictMarket, bool?> outcome, Func<string, Wallet> wallet, Rng rng)
|
||||
public List<PredictEvent> Night(int day, IEnumerable<string> activeNow, Func<PredictMarket, bool?> outcome, Func<string, Wallet> wallet, Rng rng, double push = 0)
|
||||
{
|
||||
var now = activeNow.Distinct().ToList();
|
||||
if (Prev != null) Started[day] = now.Where(x => !Prev.Contains(x)).ToList();
|
||||
@@ -206,6 +206,14 @@ namespace Decentralized.Domain
|
||||
}
|
||||
m.Outcome = res.Value ? 1 : 0;
|
||||
var winners = all.Where(x => x.Yes == res.Value).ToList();
|
||||
// 操纵:行情盘上,赢家的方向和玩家推价的方向一致时按推价幅度被查——本金和收益都没收,收益的一半记罪证
|
||||
if (m.Kind == PredictKind.Price && winners.Count > 0 && winners.Any(x => x.Yes ? push > 0 : push < 0) && rng.Chance(Market.ManipChance(push)))
|
||||
{
|
||||
double profitM = winners.Sum(x => x.Shares) - cost;
|
||||
evs.Add(new PredictEvent { Kind = "manip", Title = m.Title, Market = m, Amount = cost, Fraud = Math.Min(Tuning.PredictFraudCap, Math.Max(0, profitM) * Tuning.PredictFraudShare) });
|
||||
Record(day, m, m.Outcome, -cost, true);
|
||||
continue;
|
||||
}
|
||||
if (all.Count > 0 && winners.Count == 0)
|
||||
{
|
||||
evs.Add(new PredictEvent { Kind = "lose", Title = m.Title, Market = m, Amount = cost });
|
||||
|
||||
@@ -203,6 +203,10 @@ namespace Decentralized.Domain
|
||||
public const double IntelBriefPrice = 120, IntelFake = 0.10;
|
||||
public static readonly double[] IntelTipPrice = { 0.01, 0.025, 0.05 }, IntelTipAcc = { 0.60, 0.80, 0.95 };
|
||||
public const int IntelRep = 20;
|
||||
/// <summary>操纵检出:玩家自己的大单把价格推离"没有你时的水平"的对数幅度(取绝对值)低于 ManipFree 不查;
|
||||
/// 超过后被查概率 = ManipBase + ManipSlope × (幅度 − ManipFree),封顶 ManipMax;被查后永续账户冻结几天。</summary>
|
||||
public const double ManipFree = 0.02, ManipBase = 0.25, ManipSlope = 6, ManipMax = 0.95;
|
||||
public const int ManipFreezeDays = 3;
|
||||
|
||||
/// <summary>主交易对(信用点一侧)的深度随天数增长。</summary>
|
||||
public static double PoolDepth(int day) => PoolDepth0 * (1 + day / 60.0);
|
||||
|
||||
Reference in new issue
Block a user