Stage 7 numeric pass and market legibility (price moves, history, insider exits)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZHU MINCHAOandClaude Opus 5.5 committed 2026-11-04 08:36:17 +08:00
1 parent 6c5db17758
commit 7b5080984a
9 files changed
+152 -21

No files matched your search

+13
View File
@@ -4,6 +4,19 @@
### 第七阶段:预测市场、操纵与骗局(7.1、7.2、7.3) ### 第七阶段:预测市场、操纵与骗局(7.1、7.2、7.3)
- 阶段 7 数值总复核(ops `research/stage7sim`,用真实的域层,30 天平均每天净收益,对照原版第 30 天约 1,990 / 天的毛收入)。改动:
- 预测内幕被查改为本金和收益全部没收(原来只退本金,等于没有风险);先买后卖、赶在结算前离场,卖出有赚时同样按内幕查处(原来卖出不查,"开盘买、隔夜涨价卖"是零风险的 +47~+70 / 天)。复核后:每 5 天一条消息、5% 盘口下 300 持有到结算约 +230 / 天、亏钱概率约 0;下 1500 持有到结算平均 +3(第 30 天)、亏钱概率 64%——小单安全,大单被查。
- 高息理财的罪证 1200 → 400:单次记 1200 会直接越过 300 的逮捕线(calibration §1.4),卷走一次等于游戏结束;400 和预测、操纵的罪证上限一致,需要叠加其他罪证才危险。
- 第三方收益池单池上限 2000 + 60 × 天数 → 4000 + 120 × 天数:原来最好的策略每天只赚 40,没人会去碰;现在"只存骗局概率低的"约 +80~+114 / 天、30 天亏钱概率约 9%,全存约 −25~−34 / 天、亏钱概率约一半。
- 水纯度盘的阈值从各 4 档减到 2 档(下层 8300 / 8700,上层 9050 / 9100):纯度先验精确、没有信息可挖,原来占了候选盘口的大头。
- gas 盘的公开价改为一半按真实相位、一半按不知道相位:七天周期是链上公开的,原来盘口完全不看相位,数清周期的人每盘都能稳赚。
- 空投:钓鱼空投改为七成要无上限授权、三成要奖励 20–100 倍的大额授权(看着像"有限授权"),转走时不超过授权额度。全领 30 天约 −94 / 天、几乎必亏;只领没问题的约 +14 / 天。
- 插针抄底:向下插针买 3000 / 10000、第二天卖回,约 +13 / +29 每天,亏钱概率约一成;保持小额,不改。
- 交互:让玩家看得懂市场怎么动:
- 盘口列表上,夜里价格变化超过 0.02 的写"(昨晚 0.03 ↑)";变化超过 0.15 的进晨间日志,附上第一条线索作为原因,例如"预测盘「第 19 天:出现「停电」」价格 0.03 → 0.59(排期:第 19 天开始)"。
- 预测页左栏底部"历史(开盘均价 / 实际发生)":按盘口类型统计开过几个、开盘均价、实际发生的比例,玩家能看出哪类盘口系统性地定价偏高或偏低(例如新闻事件开盘均价 0.03、实际 33%)。
- 可交易的盘口排在列表前面,已封盘的排后面。
- 游戏内验证(用"Run night (test)"走游戏自己的开日流程):调试排一个第 19 天的已知停电 → 第 16 天开盘 0.03 → 第 17 天晨间日志"0.03 → 0.59(排期:第 19 天开始)"→ 第 18 天"0.59 → 0.82"→ 第 19 天夜里结算"是",历史面板"新闻事件:3 个,开盘均价 0.03,发生 33%"。注意:AutoMod 探查的 `day N` 不走游戏的开日流程,排期事件不会触发,测这类盘口要用"Run night (test)"。
- 7.3 NPC 骗局: - 7.3 NPC 骗局:
- 插针:第 10 天起,每天开门 7% 概率价格被瞬间打上或砸下 15–30%(PSC 主池);七成当晚回去 60–100%,三成是真的(不回去)。永续当晚的标记价仍用"开门价与收盘价的平均",开门价取插针前的价格,所以强平只吃一半;预测盘和夜间结算读回去之后的价格。 - 插针:第 10 天起,每天开门 7% 概率价格被瞬间打上或砸下 15–30%(PSC 主池);七成当晚回去 60–100%,三成是真的(不回去)。永续当晚的标记价仍用"开门价与收盘价的平均",开门价取插针前的价格,所以强平只吃一半;预测盘和夜间结算读回去之后的价格。
- 空投与钓鱼授权(Web3 新增"空投"页签):每晚 35% 概率出一个空投,2 天内可领;四成是钓鱼。正规空投不要授权或只要 10–60 的小额授权,奖励 20–120 CRC;钓鱼空投七成要"无上限授权"、三成要奖励 20–100 倍的大额授权,名字六成是仿冒(0/o、1/l、m/n 之类),领到的只有标称奖励的 5%,1–2 晚后在授权额度内把那个钱包里的这种币转走(污点按比例一起走)。领取是合约调用,PLEDGER 核对页写明授权范围;右栏列出当前钱包的授权,可以签名撤销,撤销后就转不走。 - 空投与钓鱼授权(Web3 新增"空投"页签):每晚 35% 概率出一个空投,2 天内可领;四成是钓鱼。正规空投不要授权或只要 10–60 的小额授权,奖励 20–120 CRC;钓鱼空投七成要"无上限授权"、三成要奖励 20–100 倍的大额授权,名字六成是仿冒(0/o、1/l、m/n 之类),领到的只有标称奖励的 5%,1–2 晚后在授权额度内把那个钱包里的这种币转走(污点按比例一起走)。领取是合约调用,PLEDGER 核对页写明授权范围;右栏列出当前钱包的授权,可以签名撤销,撤销后就转不走。
+45 -7
View File
@@ -22,6 +22,8 @@ namespace Decentralized.Domain
public double Param; public double Param;
public int OpenDay, FromDay, ToDay; public int OpenDay, FromDay, ToDay;
public double P0, B, QYes, QNo; public double P0, B, QYes, QNo;
/// <summary>昨晚消息反应之前的价格(-1 = 还没反应过):列表里显示涨跌,让玩家看到消息怎样推动价格。</summary>
public double PrevP = -1;
/// <summary>-1 未结算,0 否,1 是,2 作废(缺观测数据,退还本金)。</summary> /// <summary>-1 未结算,0 否,1 是,2 作废(缺观测数据,退还本金)。</summary>
public int Outcome = -1; public int Outcome = -1;
@@ -83,6 +85,21 @@ namespace Decentralized.Domain
public double Paid; public double Paid;
} }
public sealed class PredictStat
{
public int Count, Hits;
public double SumP0;
public double AvgP0 => Count > 0 ? SumP0 / Count : 0;
public double HitRate => Count > 0 ? Hits / (double)Count : 0;
}
/// <summary>一次夜间价格反应。</summary>
public sealed class PredictMove
{
public PredictMarket Market;
public double From, To;
}
/// <summary>结算记录(盘口列表下面的"最近结果")。</summary> /// <summary>结算记录(盘口列表下面的"最近结果")。</summary>
public sealed class PredictRecord public sealed class PredictRecord
{ {
@@ -118,6 +135,8 @@ namespace Decentralized.Domain
public List<PredictPos> Positions = new List<PredictPos>(); public List<PredictPos> Positions = new List<PredictPos>();
public List<PredictRecord> Recent = new List<PredictRecord>(); public List<PredictRecord> Recent = new List<PredictRecord>();
public List<PredictTip> Tips = new List<PredictTip>(); public List<PredictTip> Tips = new List<PredictTip>();
/// <summary>按盘口类型的历史:开过几个、开盘价之和、实际发生几次。玩家据此看出哪类盘口系统性地定价偏高或偏低。</summary>
public Dictionary<string, PredictStat> Stats = new Dictionary<string, PredictStat>();
public int Seq; public int Seq;
/// <summary>每晚观测:当天新出现的事件标识(和 "F:派系")。窗口里缺任何一天的观测,盘口作废退款。</summary> /// <summary>每晚观测:当天新出现的事件标识(和 "F:派系")。窗口里缺任何一天的观测,盘口作废退款。</summary>
public Dictionary<int, List<string>> Started = new Dictionary<int, List<string>>(); public Dictionary<int, List<string>> Started = new Dictionary<int, List<string>>();
@@ -159,16 +178,28 @@ namespace Decentralized.Domain
} }
/// <summary>全部卖出这个钱包在盘口里的持仓(盘口关闭前):收回 LMSR 的卖价减 2% 手续费,污点按比例退回,赚的部分是干净的。返回收回的 CRC。</summary> /// <summary>全部卖出这个钱包在盘口里的持仓(盘口关闭前):收回 LMSR 的卖价减 2% 手续费,污点按比例退回,赚的部分是干净的。返回收回的 CRC。</summary>
public PredictResult SellAll(Wallet acct, PredictMarket m, int day, out double got) public PredictResult SellAll(Wallet acct, PredictMarket m, int day, out double got) => SellAll(acct, m, day, null, out got, out _);
/// <summary>
/// 全部卖出;内幕持仓(这个盘口合计)达到查处线、而且卖出有赚,按查处概率被查:本金和收益全部没收,收益的一半记罪证(fraud &gt; 0)。
/// 先买后卖、赶在结算前离场,同样会被查。
/// </summary>
public PredictResult SellAll(Wallet acct, PredictMarket m, int day, Rng rng, out double got, out double fraud)
{ {
got = 0; got = 0; fraud = 0;
var pos = PosOf(m.Id, acct.Address); var pos = PosOf(m.Id, acct.Address);
if (pos == null) return PredictResult.NoPosition; if (pos == null) return PredictResult.NoPosition;
if (!m.IsOpen(day)) return PredictResult.Closed; if (!m.IsOpen(day)) return PredictResult.Closed;
double value = m.SellValue(pos.Yes, pos.Shares); double value = m.SellValue(pos.Yes, pos.Shares);
got = value * (1 - Tuning.PredictFee); got = value * (1 - Tuning.PredictFee);
bool insider = PosAll(m.Id).Sum(x => x.Insider) >= Tuning.PredictInsiderShare * m.ShareCap;
if (pos.Yes) m.QYes -= pos.Shares; else m.QNo -= pos.Shares; if (pos.Yes) m.QYes -= pos.Shares; else m.QNo -= pos.Shares;
Positions.Remove(pos); Positions.Remove(pos);
if (rng != null && insider && pos.Insider > 0 && got > pos.Cost && rng.Chance(Tuning.PredictInsiderCatch))
{
fraud = Math.Min(Tuning.PredictFraudCap, (got - pos.Cost) * Tuning.PredictFraudShare);
got = 0;
}
Pay(acct, pos, got); Pay(acct, pos, got);
return PredictResult.Ok; return PredictResult.Ok;
} }
@@ -181,7 +212,7 @@ namespace Decentralized.Domain
/// <summary> /// <summary>
/// 夜间:先登记今晚的观测,再结算 ToDay 到了的盘口(赢的钱回到下注的钱包,wallet 按地址找)。outcome 由接入层给出(事件 / 派系读观测,纯度和行情读游戏数值),null 表示拿不到数据。 /// 夜间:先登记今晚的观测,再结算 ToDay 到了的盘口(赢的钱回到下注的钱包,wallet 按地址找)。outcome 由接入层给出(事件 / 派系读观测,纯度和行情读游戏数值),null 表示拿不到数据。
/// 赢家每份兑付 1 信用点;内幕持仓达到份额上限的 <see cref="Tuning.PredictInsiderShare"/> 后,有概率被查:只退本金,收益的一半记罪证。 /// 赢家每份兑付 1 信用点;内幕持仓达到份额上限的 <see cref="Tuning.PredictInsiderShare"/> 后,有概率被查:本金和收益全部没收,收益的一半记罪证。
/// </summary> /// </summary>
public List<PredictEvent> Night(int day, IEnumerable<string> activeNow, Func<PredictMarket, bool?> outcome, Func<string, Wallet> wallet, Rng rng, double push = 0) public List<PredictEvent> Night(int day, IEnumerable<string> activeNow, Func<PredictMarket, bool?> outcome, Func<string, Wallet> wallet, Rng rng, double push = 0)
{ {
@@ -205,6 +236,9 @@ namespace Decentralized.Domain
continue; continue;
} }
m.Outcome = res.Value ? 1 : 0; m.Outcome = res.Value ? 1 : 0;
string sk = m.Kind.ToString();
if (!Stats.TryGetValue(sk, out var st)) Stats[sk] = st = new PredictStat();
st.Count++; st.SumP0 += m.P0; if (res.Value) st.Hits++;
var winners = all.Where(x => x.Yes == res.Value).ToList(); 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))) if (m.Kind == PredictKind.Price && winners.Count > 0 && winners.Any(x => x.Yes ? push > 0 : push < 0) && rng.Chance(Market.ManipChance(push)))
@@ -225,9 +259,9 @@ namespace Decentralized.Domain
// 内幕持仓按盘口合计(拆到几个钱包里也一样) // 内幕持仓按盘口合计(拆到几个钱包里也一样)
if (all.Sum(x => x.Insider) >= Tuning.PredictInsiderShare * m.ShareCap && rng.Chance(Tuning.PredictInsiderCatch)) if (all.Sum(x => x.Insider) >= Tuning.PredictInsiderShare * m.ShareCap && rng.Chance(Tuning.PredictInsiderCatch))
{ {
foreach (var pos in winners) Pay(wallet(pos.Wallet), pos, pos.Cost); // 查实:本金和收益全部没收
evs.Add(new PredictEvent { Kind = "caught", Title = m.Title, Market = m, Amount = profit, Fraud = Math.Min(Tuning.PredictFraudCap, Math.Max(0, profit) * Tuning.PredictFraudShare) }); evs.Add(new PredictEvent { Kind = "caught", Title = m.Title, Market = m, Amount = payout, Fraud = Math.Min(Tuning.PredictFraudCap, Math.Max(0, profit) * Tuning.PredictFraudShare) });
Record(day, m, m.Outcome, 0, true); Record(day, m, m.Outcome, -cost, true);
} }
else else
{ {
@@ -264,17 +298,21 @@ namespace Decentralized.Domain
/// 夜间的消息反应:还能交易的盘口(明天仍开着)向"公开信息下的合理概率"靠拢 PredictDrift,再加 logit 噪声(NPC 流量)。 /// 夜间的消息反应:还能交易的盘口(明天仍开着)向"公开信息下的合理概率"靠拢 PredictDrift,再加 logit 噪声(NPC 流量)。
/// 价格在夜里才反应,所以白天先看到报纸、传闻的人可以抢在前面买、等涨价再卖。target 返回 null 表示这个盘口没有新信息。 /// 价格在夜里才反应,所以白天先看到报纸、传闻的人可以抢在前面买、等涨价再卖。target 返回 null 表示这个盘口没有新信息。
/// </summary> /// </summary>
public void Drift(int day, Func<PredictMarket, double?> target, Rng rng) public List<PredictMove> Drift(int day, Func<PredictMarket, double?> target, Rng rng)
{ {
var moves = new List<PredictMove>();
foreach (var m in Markets.Where(x => x.Outcome < 0 && x.FromDay > day + 1)) foreach (var m in Markets.Where(x => x.Outcome < 0 && x.FromDay > day + 1))
{ {
m.PrevP = m.PYes;
double p = m.PYes, t = target(m) ?? p; double p = m.PYes, t = target(m) ?? p;
t = Math.Max(Tuning.PredictPMin, Math.Min(Tuning.PredictPMax, t)); t = Math.Max(Tuning.PredictPMin, Math.Min(Tuning.PredictPMax, t));
double pt = p + Tuning.PredictDrift * (t - p); double pt = p + Tuning.PredictDrift * (t - p);
double lp = Math.Log(pt / (1 - pt)) + Tuning.PredictNoise * rng.Gauss(); double lp = Math.Log(pt / (1 - pt)) + Tuning.PredictNoise * rng.Gauss();
pt = Math.Max(Tuning.PredictPMin, Math.Min(Tuning.PredictPMax, 1 / (1 + Math.Exp(-lp)))); pt = Math.Max(Tuning.PredictPMin, Math.Min(Tuning.PredictPMax, 1 / (1 + Math.Exp(-lp))));
m.QYes = m.QNo + m.B * Math.Log(pt / (1 - pt)); m.QYes = m.QNo + m.B * Math.Log(pt / (1 - pt));
moves.Add(new PredictMove { Market = m, From = m.PrevP, To = m.PYes });
} }
return moves;
} }
/// <summary>读观测:窗口里每一天都有记录才能判断;有任何一天缺就返回 null(作废)。</summary> /// <summary>读观测:窗口里每一天都有记录才能判断;有任何一天缺就返回 null(作废)。</summary>
+4 -2
View File
@@ -199,6 +199,8 @@ namespace Decentralized.Domain
public const int PredictHistory = 8; public const int PredictHistory = 8;
/// <summary>盘口对消息的反应:每晚向"公开信息下的合理概率"靠拢的比例,以及盘口 logit 上的随机噪声(NPC 流量)。</summary> /// <summary>盘口对消息的反应:每晚向"公开信息下的合理概率"靠拢的比例,以及盘口 logit 上的随机噪声(NPC 流量)。</summary>
public const double PredictDrift = 0.5, PredictNoise = 0.35; public const double PredictDrift = 0.5, PredictNoise = 0.35;
/// <summary>夜里价格变化超过多少(概率)写进晨间日志。</summary>
public const double PredictMoveLog = 0.15;
/// <summary>情报贩子:局势简报价格(CRT)、三档内幕消息的价格(占盘口最大亏损的比例)与准确率、假情报概率(claim 与真相相反)、需要的黑市声望。</summary> /// <summary>情报贩子:局势简报价格(CRT)、三档内幕消息的价格(占盘口最大亏损的比例)与准确率、假情报概率(claim 与真相相反)、需要的黑市声望。</summary>
public const double IntelBriefPrice = 120, IntelFake = 0.10; 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 static readonly double[] IntelTipPrice = { 0.01, 0.025, 0.05 }, IntelTipAcc = { 0.60, 0.80, 0.95 };
@@ -216,7 +218,7 @@ namespace Decentralized.Domain
public const double PonziBase0 = 300, PonziBasePerDay = 15, PonziRateExp = 1.5; public const double PonziBase0 = 300, PonziBasePerDay = 15, PonziRateExp = 1.5;
public const double PonziCap0 = 6000, PonziCapPerDay = 200, PonziWithdraw = 0.03; public const double PonziCap0 = 6000, PonziCapPerDay = 200, PonziWithdraw = 0.03;
public const double PonziReport0 = 0.02, PonziReportRate = 0.5, PonziReportSize = 0.04; public const double PonziReport0 = 0.02, PonziReportRate = 0.5, PonziReportSize = 0.04;
public const double PonziCrime = 1200; public const double PonziCrime = 400;
/// <summary>插针:每天开门时出现的概率、幅度范围(对数价格的绝对值)、当晚回去的比例范围、不回去(真跌真涨)的概率。</summary> /// <summary>插针:每天开门时出现的概率、幅度范围(对数价格的绝对值)、当晚回去的比例范围、不回去(真跌真涨)的概率。</summary>
public const double WickChance = 0.07, WickMin = 0.15, WickMax = 0.30, WickRevertMin = 0.6, WickRevertMax = 1.0, WickReal = 0.3; public const double WickChance = 0.07, WickMin = 0.15, WickMax = 0.30, WickRevertMin = 0.6, WickRevertMax = 1.0, WickReal = 0.3;
@@ -226,7 +228,7 @@ namespace Decentralized.Domain
/// <summary>第三方收益池:同时最多几个、每晚新开的概率;日息档位;按日息的骗局概率,时间锁、审计各减多少;骗局池每晚跑路概率; /// <summary>第三方收益池:同时最多几个、每晚新开的概率;日息档位;按日息的骗局概率,时间锁、审计各减多少;骗局池每晚跑路概率;
/// 单池存款上限(随天数);正规池的储备(日息 × 存款上限 × 天数);时间锁取款等待天数。</summary> /// 单池存款上限(随天数);正规池的储备(日息 × 存款上限 × 天数);时间锁取款等待天数。</summary>
public const int YieldPoolMax = 3, YieldLockDays = 2; public const int YieldPoolMax = 3, YieldLockDays = 2;
public const double YieldPoolChance = 0.25, YieldRugNightly = 0.18, YieldCap0 = 2000, YieldCapPerDay = 60, YieldReserveDays = 25; public const double YieldPoolChance = 0.25, YieldRugNightly = 0.18, YieldCap0 = 4000, YieldCapPerDay = 120, YieldReserveDays = 25;
public static readonly double[] YieldRates = { 0.01, 0.02, 0.03 }, YieldScamByRate = { 0.15, 0.40, 0.75 }; public static readonly double[] YieldRates = { 0.01, 0.02, 0.03 }, YieldScamByRate = { 0.15, 0.40, 0.75 };
public const double YieldScamTimelock = 0.25, YieldScamAudit = 0.20; public const double YieldScamTimelock = 0.25, YieldScamAudit = 0.20;
/// <summary>假客服:每天上门的概率;伪造转账:用币付款的顾客里是骗子的比例;两者都从第几天起。</summary> /// <summary>假客服:每天上门的概率;伪造转账:用币付款的顾客里是骗子的比例;两者都从第几天起。</summary>
+15 -2
View File
@@ -268,7 +268,7 @@ black.kind.Contraband.3,Contraband (high)
black.kind.Tech,High-tech (markup) black.kind.Tech,High-tech (markup)
nightlog.bm.ready,"Black market: {0} arrived; a courier will come by once you open." nightlog.bm.ready,"Black market: {0} arrived; a courier will come by once you open."
item.web3guide.name,Web3 Handbook item.web3guide.name,Web3 Handbook
item.web3guide.desc,"Bank: depositing turns credits into CRC in your Poinbase account; withdrawing turns CRC back into credits and goes through compliance screening, which looks at the Poinbase account's taint. Trading: buys are paid in the quote coin, sells in the traded coin. Mixer: pick a coin, amount and rounds; each round takes a fee and lowers taint, rounds equal days of waiting, and the coins come back to the same address; the more you deposit, the worse the cleaning. Hardware wallets: on-chain coins sit in PLEDGER hardware wallets, each with its own balances and taint; open and connect them on the terminal's Wallets page. The Web3 page's trading, black market and mixer use the connected wallet, and coin-paying customers and mining rewards go into it too. Payments (black market, mixer, Ponero desk, listing fees) start as an invoice on the terminal; type the payee address on the wallet and hold ✓ to sign. The last two characters of an address are a checksum, so a one-character typo is usually caught; once in a while it happens to be valid and the coins go to an address nobody uses. DEX swaps also need a signature on the wallet. RatDigg miners (M1 / M2 / M3) are standalone machines with far more hash than a card and a lower power draw per hash; they need a battery, take modules and use no rig slots. Only the black market's miner dealers sell them, gated by black-market standing (M1 40, M2 60, M3 80), sometimes second-hand. When one burns out, repair it by putting electronic components in its repair slot in order; it comes back 20 health lower. Somewhere between day 50 and day 90 a "miner era" arrives, announced in the paper a few days earlier: the big farms halve their power costs, network hash climbs, GPU miners are diluted and low-end cards barely earn, while miners still do fine. Perps: the Perps tab on Poinbase uses your account CRC as margin, up to 5× on PSC and 3× on SPARK, one position per product, never long and short at once. Fills are worse than the quote (more so for bigger orders, like the spot pool) and opening and closing both cost a fee. Liquidation is checked only overnight against the day's average price: equity under 10% of notional wipes the margin. There is also a nightly funding payment; when the price is above its 7-day average, longs pay shorts. If a liquidation loses more than the margin, the insurance fund covers the gap; when it runs dry (a SPARK collapse can do that) winning positions are auto-deleveraged and give up half their profit; anything beyond that becomes your debt. Debt grows 2% a day, is repaid first from CRC in the account every night, blocks new positions and cash-outs, and after seven days items in your shop are seized to cover it; whatever is still short is written off and the perp account is banned for 30 days. Poinbase is a custodial account and can withdraw straight to the connected wallet; depositing from a wallet means sending to Poinbase's deposit address, which takes only CRC and PSC. More hardware wallets are sold by Dr. Jackson; drag one onto the trading terminal to add it, up to 5. The black market has cheaper ones. A wallet you no longer want can be destroyed on the Wallets page once its coins are moved out. Transfers pay a fee: slow, normal or fast, and gas prices rise and fall over roughly a week; when the network is congested fees rise and slow transactions may be dropped from the mempool. Check the full address before sending. Staking: CRA staked in the Revolution pool earns a daily rate that compounds into the stake; withdrawing means requesting first and waiting four days, with no interest while waiting and no way to take it early. The pool pays from a subsidy fund; when it runs low the rate is cut and word of big holders pulling out may spread. Treat that as a warning: once it collapses CRA is worthless within three days and four days of unlocking is too slow. The balance token SPARK can be minted and burned against CRA at the going price (with a fee); its price swings hard and crashes with the collapse. Staking, minting and burning are contract calls and need a signature on the wallet. Black market: coin only, no CRC, 30% above normal channels, with extra markup on high-tech goods and GPUs; the coin you pay leaves its share of taint with the seller and the goods carry no stolen tag; GPUs may be fake, inspect them yourself. Orders are cheaper than spot but take days and may be intercepted; merchants sell by type at their own price factor, 5+ items get 5% off and 10+ get 10% off, and a bulk merchant appears at random with the lowest prices but six days of waiting; escrow costs 5%, is released on delivery and refunded if the seller runs; advance release takes another 10% off, but a scammer keeps the money and only sellers with 30+ trades accept; the platform itself can rug, be taken over by enforcement, or a seller can be arrested, after which your orders get traced and crime logged; forum rumors can be warnings. An intercepted parcel sometLine truncated item.web3guide.desc,"Bank: depositing turns credits into CRC in your Poinbase account; withdrawing turns CRC back into credits and goes through compliance screening, which looks at the Poinbase account's taint. Trading: buys are paid in the quote coin, sells in the traded coin. Mixer: pick a coin, amount and rounds; each round takes a fee and lowers taint, rounds equal days of waiting, and the coins come back to the same address; the more you deposit, the worse the cleaning. Hardware wallets: on-chain coins sit in PLEDGER hardware wallets, each with its own balances and taint; open and connect them on the terminal's Wallets page. The Web3 page's trading, black market and mixer use the connected wallet, and coin-paying customers and mining rewards go into it too. Payments (black market, mixer, Ponero desk, listing fees) start as an invoice on the terminal; type the payee address on the wallet and hold ✓ to sign. The last two characters of an address are a checksum, so a one-character typo is usually caught; once in a while it happens to be valid and the coins go to an address nobody uses. DEX swaps also need a signature on the wallet. RatDigg miners (M1 / M2 / M3) are standalone machines with far more hash than a card and a lower power draw per hash; they need a battery, take modules and use no rig slots. Only the black market's miner dealers sell them, gated by black-market standing (M1 40, M2 60, M3 80), sometimes second-hand. When one burns out, repair it by putting electronic components in its repair slot in order; it comes back 20 health lower. Somewhere between day 50 and day 90 a "miner era" arrives, announced in the paper a few days earlier: the big farms halve their power costs, network hash climbs, GPU miners are diluted and low-end cards barely earn, while miners still do fine. Perps: the Perps tab on Poinbase uses your account CRC as margin, up to 5× on PSC and 3× on SPARK, one position per product, never long and short at once. Fills are worse than the quote (more so for bigger orders, like the spot pool) and opening and closing both cost a fee. Liquidation is checked only overnight against the day's average price: equity under 10% of notional wipes the margin. There is also a nightly funding payment; when the price is above its 7-day average, longs pay shorts. If a liquidation loses more than the margin, the insurance fund covers the gap; when it runs dry (a SPARK collapse can do that) winning positions are auto-deleveraged and give up half their profit; anything beyond that becomes your debt. Debt grows 2% a day, is repaid first from CRC in the account every night, blocks new positions and cash-outs, and after seven days items in your shop are seized to cover it; whatever is still short is written off and the perp account is banned for 30 days. Poinbase is a custodial account and can withdraw straight to the connected wallet; depositing from a wallet means sending to Poinbase's deposit address, which takes only CRC and PSC. More hardware wallets are sold by Dr. Jackson; drag one onto the trading terminal to add it, up to 5. The black market has cheaper ones. A wallet you no longer want can be destroyed on the Wallets page once its coins are moved out. Transfers pay a fee: slow, normal or fast, and gas prices rise and fall over roughly a week; when the network is congested fees rise and slow transactions may be dropped from the mempool. Check the full address before sending. Staking: CRA staked in the Revolution pool earns a daily rate that compounds into the stake; withdrawing means requesting first and waiting four days, with no interest while waiting and no way to take it early. The pool pays from a subsidy fund; when it runs low the rate is cut and word of big holders pulling out may spread. Treat that as a warning: once it collapses CRA is worthless within three days and four days of unlocking is too slow. The balance token SPARK can be minted and burned against CRA at the going price (with a fee); its price swings hard and crashes with the collapse. Staking, minting and burning are contract calls and need a signature on the wallet. Black market: coin only, no CRC, 30% above normal channels, with extra markup on high-tech goods and GPUs; the coin you pay leaves its share of taint with the seller and the goods carry no stolen tag; GPUs may be fake, inspect them yourself. Orders are cheaper than spot but take days and may be intercepted; merchants sell by type at their own price factor, 5+ items get 5% off and 10+ get 10% off, and a bulk merchant appears at random with the lowest prices but six days of waiting; escrow costs 5%, is released on delivery and refunded if the seller runs; advance release takes another 10% off, but a scammer keeps the money and only sellers with 30+ trades accept; the platform itself can rug, be taken over by enforcement, or a seller can be arrested, after which your orders get traced and crime logged; forum rumors can be warnings. An intercepted parcel sometLine truncated
courier.odd1,...Package is here. courier.odd1,...Package is here.
courier.odd2,"(His hand stays in his pocket.) Sign here." courier.odd2,"(His hand stays in his pocket.) Sign here."
courier.sign,Sign courier.sign,Sign
@@ -581,7 +581,7 @@ predict.purity.rust,Upper water
nightlog.predict.win,"Prediction right: ""{0}"", paid out {1}." nightlog.predict.win,"Prediction right: ""{0}"", paid out {1}."
nightlog.predict.lose,"Prediction wrong: ""{0}"", stake {1} lost." nightlog.predict.lose,"Prediction wrong: ""{0}"", stake {1} lost."
nightlog.predict.void,"Prediction void: ""{0}"", stake {1} refunded." nightlog.predict.void,"Prediction void: ""{0}"", stake {1} refunded."
nightlog.predict.caught,"Insider bet caught: ""{0}"", profit {1} confiscated, fraud on record." nightlog.predict.caught,"Insider bet caught: ""{0}"", stake and winnings {1} confiscated, fraud on record."
predict.tab.markets,Markets predict.tab.markets,Markets
predict.tab.intel,Intel predict.tab.intel,Intel
predict.acct.crt,On-chain wallet {0}: CRT {1} predict.acct.crt,On-chain wallet {0}: CRT {1}
@@ -714,3 +714,16 @@ scam.support.name,Poinbase Support
scam.support.1,"Hello, Poinbase support here. We detected an unusual login on your account and it has been flagged." scam.support.1,"Hello, Poinbase support here. We detected an unusual login on your account and it has been flagged."
scam.support.2,Please send {0} CRC to the safe address {1} today for verification; it will be returned right after. scam.support.2,Please send {0} CRC to the safe address {1} today for verification; it will be returned right after.
scam.support.3,"Otherwise the account will be frozen for good. I have to go, remember to send it." scam.support.3,"Otherwise the account will be frozen for good. I have to go, remember to send it."
predict.sold.caught,"Insider trading caught on sale: stake and profit confiscated, fraud on record."
predict.row.move, (last night {0} {1})
predict.stats.h,History (avg opening price / actual rate)
predict.stats.row,"{0}: {1} markets, avg open {2}, happened {3}%"
predict.kind.Event,News events
predict.kind.Faction,Faction ops
predict.kind.Purity,Water purity
predict.kind.Price,PSC price
predict.kind.Gas,Gas
predict.kind.Cra,CRA warning
predict.kind.Era,ASIC era
nightlog.predict.move,"Prediction ""{0}"" moved {1} -> {2}"
nightlog.predict.why, ({0})
+15 -2
View File
@@ -267,7 +267,7 @@ black.kind.Contraband.3,违禁品(高)
black.kind.Tech,高科技物品(加价) black.kind.Tech,高科技物品(加价)
nightlog.bm.ready,"黑市:{0} 到货,开店后会有快递员上门。" nightlog.bm.ready,"黑市:{0} 到货,开店后会有快递员上门。"
item.web3guide.name,Web3 手册 item.web3guide.name,Web3 手册
item.web3guide.desc,"银行:存入把信用点换成 Poinbase 账户里的 CRC;提取把 CRC 换回信用点,要过合规审查,审查看 Poinbase 账户的污点。交易:买入按计价币的数量支付,卖出按所交易币的数量卖出。混币器:选币种、填数量和轮数,每轮扣手续费并降低污点,轮数即等待天数,到期提回同一个地址;存入越多,清洗越差。硬件钱包:链上的币放在 PLEDGER 硬件钱包里,每个钱包的余额和污点各算各的;在终端的钱包页打开、连接。Web3 页的交易、黑市、混币器用已连接的钱包,用币付款的顾客和挖矿收益也进它。付款(黑市、混币器、Ponero 兑换处、上架费)先在终端开账单,再在钱包里手输收款地址、按住 ✓ 签名;地址末尾两位是校验位,输错一位多半会被拦下,偶尔碰巧合法,币就转进了没人用的地址。DEX 兑换也要在钱包上签名。Poinbase 是托管账户,可以直接提到已连接的钱包;从钱包充值要转到 Poinbase 的充值地址,只收 CRC 和 PSC。更多硬件钱包向杰克逊博士购买,拖到交易终端上添加,最多 5 个;黑市上也有更便宜的。不要的钱包可以在钱包页销毁,要先把币转走。转账要付手续费,分慢、普通、快三档,gas 价格大约一周一个起落;网络拥堵时手续费变贵,慢档可能被挤出内存池。转账前核对完整地址。质押:把 CRA 质押进革命军质押池每天有日息,利息并入本金;取出要先申请,等四天才到账,等待期间没有利息,也不能提前拿。质押池靠补贴池付息,补贴池见底会降息,有时还会传出大户撤出的消息,那是预兆:一旦崩盘,三天内 CRA 就一文不值,四天的解锁期来不及。平衡代币 SPARK 可以和 CRA 按价格互相铸销(收手续费),价格波动很大,崩盘时会跟着暴跌。质押、铸销都是合约调用,要在钱包上签名。RatDigg 矿机(M1 / M2 / M3)是独立的机器,算力比显卡大得多、耗电更省,要放电池才挖,可以放模块,不占矿架槽位;只在黑市的矿机商那里有,要黑市声望(M1 40、M2 60、M3 80),偶尔有二手的。暴毙后要往修理槽里放电子元件按顺序修好,修好健康少 20。第 50 到 90 天之间会有一次"矿机时代",提前几天上报纸预告,之后大矿场的耗电成本砍半,全网算力涨上去,显卡矿工的收益被摊薄,低档显卡几乎不赚钱,矿机还行。永续合约:Poinbase 的"永续"页,用账户里的 CRC 当保证金,PSC 最高 5 倍、SPARK 最高 3 倍,一个品种只有一个仓位,不能同时多空。成交价比现价差一截(单越大差得越多,和现货池一样),开平仓还收手续费。强平只在夜里按当天均价检查,权益不到名义价值的 10% 就被强平,保证金没了;每晚还有资金费,价格比近 7 天均价高时多头付给空头。强平后亏光保证金还不够的缺口,先由保险基金垫,基金见底(SPARK 崩盘这类大行情会抽干它)后盈利的仓位会被自动减仓、少拿一半盈利,再不够就记成你的欠款:欠款每天涨 2%,账户里的 CRC 每晚先拿去还,没还清不能开仓、不能出金,七天不还就没收店里的物品抵债,抵不够的核销并拉黑永续账户 30 天。黑市:只收币,不收 CRC,价格比正常渠道贵 30%,高科技物品和显卡另有加价;付出去的币带着按比例的污点留在卖家那边,货不带赃物标签;显卡不保证真假,自己鉴定。订单比现货便宜,要等几天,路上可能被截获;商家按类型卖货,价格系数各不相同,一次订 5 件以上 95 折、10 件以上 9 折,大宗商家随机出现,价格最低但要等六天;托管多付 5% 托管费,收货后放款,卖家跑路时退款;提前放款再打九折,卖家若是骗子钱就没了,只有成交 30 单以上的卖家接受;平台自己也可能跑路,也可能被执法接管,或者卖家落网,之后你的订单会被追查、记罪证;论坛上的传闻可以当预兆。被截获的包裹有时会变成执法人员上门:签收当场记罪证并查封,拒签只损失货款。出售:在黑市的卖货页把储藏区里的违禁品、高科技物品和显卡上架,标价是参考价的 0.6 到 1.8 倍。倍率越高成交越慢(0.9 以下约一天,1.0 约两天,1.8 约十四天),货款带污点的可能性和比例也越高,近 7 天出售的量越大,污点越重;同时最多上架 10 件,上架收 5% 上架费,上架后可以改价(收 2% 改价费,标价按参考价重算,成交的快慢跟着新倍率走),成交扣 8% 抽成,货款托管 3 天后进钱包;卖假卡可能被买家看穿而退货,拉低好评;平台跑路时上架的货和未放款的货款都没了Line truncated item.web3guide.desc,"银行:存入把信用点换成 Poinbase 账户里的 CRC;提取把 CRC 换回信用点,要过合规审查,审查看 Poinbase 账户的污点。交易:买入按计价币的数量支付,卖出按所交易币的数量卖出。混币器:选币种、填数量和轮数,每轮扣手续费并降低污点,轮数即等待天数,到期提回同一个地址;存入越多,清洗越差。硬件钱包:链上的币放在 PLEDGER 硬件钱包里,每个钱包的余额和污点各算各的;在终端的钱包页打开、连接。Web3 页的交易、黑市、混币器用已连接的钱包,用币付款的顾客和挖矿收益也进它。付款(黑市、混币器、Ponero 兑换处、上架费)先在终端开账单,再在钱包里手输收款地址、按住 ✓ 签名;地址末尾两位是校验位,输错一位多半会被拦下,偶尔碰巧合法,币就转进了没人用的地址。DEX 兑换也要在钱包上签名。Poinbase 是托管账户,可以直接提到已连接的钱包;从钱包充值要转到 Poinbase 的充值地址,只收 CRC 和 PSC。更多硬件钱包向杰克逊博士购买,拖到交易终端上添加,最多 5 个;黑市上也有更便宜的。不要的钱包可以在钱包页销毁,要先把币转走。转账要付手续费,分慢、普通、快三档,gas 价格大约一周一个起落;网络拥堵时手续费变贵,慢档可能被挤出内存池。转账前核对完整地址。质押:把 CRA 质押进革命军质押池每天有日息,利息并入本金;取出要先申请,等四天才到账,等待期间没有利息,也不能提前拿。质押池靠补贴池付息,补贴池见底会降息,有时还会传出大户撤出的消息,那是预兆:一旦崩盘,三天内 CRA 就一文不值,四天的解锁期来不及。平衡代币 SPARK 可以和 CRA 按价格互相铸销(收手续费),价格波动很大,崩盘时会跟着暴跌。质押、铸销都是合约调用,要在钱包上签名。RatDigg 矿机(M1 / M2 / M3)是独立的机器,算力比显卡大得多、耗电更省,要放电池才挖,可以放模块,不占矿架槽位;只在黑市的矿机商那里有,要黑市声望(M1 40、M2 60、M3 80),偶尔有二手的。暴毙后要往修理槽里放电子元件按顺序修好,修好健康少 20。第 50 到 90 天之间会有一次"矿机时代",提前几天上报纸预告,之后大矿场的耗电成本砍半,全网算力涨上去,显卡矿工的收益被摊薄,低档显卡几乎不赚钱,矿机还行。永续合约:Poinbase 的"永续"页,用账户里的 CRC 当保证金,PSC 最高 5 倍、SPARK 最高 3 倍,一个品种只有一个仓位,不能同时多空。成交价比现价差一截(单越大差得越多,和现货池一样),开平仓还收手续费。强平只在夜里按当天均价检查,权益不到名义价值的 10% 就被强平,保证金没了;每晚还有资金费,价格比近 7 天均价高时多头付给空头。强平后亏光保证金还不够的缺口,先由保险基金垫,基金见底(SPARK 崩盘这类大行情会抽干它)后盈利的仓位会被自动减仓、少拿一半盈利,再不够就记成你的欠款:欠款每天涨 2%,账户里的 CRC 每晚先拿去还,没还清不能开仓、不能出金,七天不还就没收店里的物品抵债,抵不够的核销并拉黑永续账户 30 天。黑市:只收币,不收 CRC,价格比正常渠道贵 30%,高科技物品和显卡另有加价;付出去的币带着按比例的污点留在卖家那边,货不带赃物标签;显卡不保证真假,自己鉴定。订单比现货便宜,要等几天,路上可能被截获;商家按类型卖货,价格系数各不相同,一次订 5 件以上 95 折、10 件以上 9 折,大宗商家随机出现,价格最低但要等六天;托管多付 5% 托管费,收货后放款,卖家跑路时退款;提前放款再打九折,卖家若是骗子钱就没了,只有成交 30 单以上的卖家接受;平台自己也可能跑路,也可能被执法接管,或者卖家落网,之后你的订单会被追查、记罪证;论坛上的传闻可以当预兆。被截获的包裹有时会变成执法人员上门:签收当场记罪证并查封,拒签只损失货款。出售:在黑市的卖货页把储藏区里的违禁品、高科技物品和显卡上架,标价是参考价的 0.6 到 1.8 倍。倍率越高成交越慢(0.9 以下约一天,1.0 约两天,1.8 约十四天),货款带污点的可能性和比例也越高,近 7 天出售的量越大,污点越重;同时最多上架 10 件,上架收 5% 上架费,上架后可以改价(收 2% 改价费,标价按参考价重算,成交的快慢跟着新倍率走),成交扣 8% 抽成,货款托管 3 天后进钱包;卖假卡可能被买家看穿而退货,拉低好评;平台跑路时上架的货和未放款的货款都没了Line truncated
courier.odd1,……东西到了。 courier.odd1,……东西到了。
courier.odd2,"(他的手一直放在口袋里)在这儿签个字。" courier.odd2,"(他的手一直放在口袋里)在这儿签个字。"
courier.sign,签收 courier.sign,签收
@@ -580,7 +580,7 @@ predict.purity.rust,上层水
nightlog.predict.win,预测押中:「{0}」,兑付 {1}。 nightlog.predict.win,预测押中:「{0}」,兑付 {1}。
nightlog.predict.lose,预测押错:「{0}」,本金 {1} 没了。 nightlog.predict.lose,预测押错:「{0}」,本金 {1} 没了。
nightlog.predict.void,预测作废:「{0}」,退回本金 {1}。 nightlog.predict.void,预测作废:「{0}」,退回本金 {1}。
nightlog.predict.caught,内幕下注被查:「{0}」,收益 {1} 没收,记诈骗罪证。 nightlog.predict.caught,内幕下注被查:「{0}」,本金和收益 {1} 全部没收,记诈骗罪证。
predict.tab.markets,盘口 predict.tab.markets,盘口
predict.tab.intel,情报 predict.tab.intel,情报
predict.acct.crt,链上钱包 {0}:CRT {1} predict.acct.crt,链上钱包 {0}:CRT {1}
@@ -713,3 +713,16 @@ scam.support.name,Poinbase 客服
scam.support.1,您好,我是 Poinbase 客服。系统检测到您的账户有异常登录,已经被风控了。 scam.support.1,您好,我是 Poinbase 客服。系统检测到您的账户有异常登录,已经被风控了。
scam.support.2,请在今天内把 {0} CRC 转到安全地址 {1} 做验证,验证完马上退回。 scam.support.2,请在今天内把 {0} CRC 转到安全地址 {1} 做验证,验证完马上退回。
scam.support.3,不处理的话账户会被永久冻结。我先走了,记得转。 scam.support.3,不处理的话账户会被永久冻结。我先走了,记得转。
predict.sold.caught,卖出时内幕交易被查:本金和收益全部没收,记诈骗罪证。
predict.row.move,(昨晚 {0} {1})
predict.stats.h,历史(开盘均价 / 实际发生)
predict.stats.row,{0}:{1} 个,开盘均价 {2},发生 {3}%
predict.kind.Event,新闻事件
predict.kind.Faction,派系行动
predict.kind.Purity,水纯度
predict.kind.Price,PSC 价格
predict.kind.Gas,gas
predict.kind.Cra,CRA 预警
predict.kind.Era,矿机时代
nightlog.predict.move,预测盘「{0}」价格 {1} → {2}
nightlog.predict.why,({0})
+6 -1
View File
@@ -234,7 +234,12 @@ namespace Decentralized
} }
var predictEvents = PredictGame.Available(day) || d.Predict.Markets.Count > 0 var predictEvents = PredictGame.Available(day) || d.Predict.Markets.Count > 0
? d.Predict.Night(day, PredictGame.ActiveIds(), m => PredictGame.Outcome(m, d), d.WalletAt, d.Rng, PredictGame.ClosePush) : new List<PredictEvent>(); ? d.Predict.Night(day, PredictGame.ActiveIds(), m => PredictGame.Outcome(m, d), d.WalletAt, d.Rng, PredictGame.ClosePush) : new List<PredictEvent>();
d.Predict.Drift(day, m => PredictGame.PublicProb(m, d, day), d.Rng); foreach (var mv in d.Predict.Drift(day, m => PredictGame.PublicProb(m, d, day), d.Rng))
{
if (Math.Abs(mv.To - mv.From) < Tuning.PredictMoveLog) continue;
var why = PredictGame.Clues(mv.Market);
ps.AddNightLog(L.T("nightlog.predict.move", PredictGame.Question(mv.Market), mv.From.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture), mv.To.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)) + (why.Count > 0 ? L.T("nightlog.predict.why", why[0]) : ""));
}
var ponzi = d.Ponzi.Night(day, StoreReputation.GetStoreReputation(StoreReputation.FACTION_LOWER_LEVEL)?.GetReputation() ?? 0, d.Own(d.Ponzi.Wallet ?? "") ?? d.Hot, d.Rng); var ponzi = d.Ponzi.Night(day, StoreReputation.GetStoreReputation(StoreReputation.FACTION_LOWER_LEVEL)?.GetReputation() ?? 0, d.Own(d.Ponzi.Wallet ?? "") ?? d.Hot, d.Rng);
if (ponzi != null) if (ponzi != null)
{ {
+7 -3
View File
@@ -12,7 +12,7 @@ namespace Decentralized
public static class PredictGame public static class PredictGame
{ {
public static readonly string[] Factions = { "FACTION_SECURITY", "FACTION_REVOLUTION", "FACTION_LOWER_LEVEL", "FACTION_UPPER_LEVEL", "FACTION_BLACK_MARKET" }; public static readonly string[] Factions = { "FACTION_SECURITY", "FACTION_REVOLUTION", "FACTION_LOWER_LEVEL", "FACTION_UPPER_LEVEL", "FACTION_BLACK_MARKET" };
private static readonly double[] GutterCuts = { 8200, 8400, 8600, 8800 }, RustCuts = { 9030, 9060, 9090, 9120 }; private static readonly double[] GutterCuts = { 8300, 8700 }, RustCuts = { 9050, 9100 };
private static readonly double[] PriceMult = { 0.9, 0.95, 1.0, 1.05, 1.1 }; private static readonly double[] PriceMult = { 0.9, 0.95, 1.0, 1.05, 1.1 };
private static readonly double[] GasCuts = { 0.8, 1.0, 1.2, 1.4 }; private static readonly double[] GasCuts = { 0.8, 1.0, 1.2, 1.4 };
@@ -117,7 +117,7 @@ namespace Decentralized
foreach (var t in GasCuts) foreach (var t in GasCuts)
{ {
double thr = t; double thr = t;
list.Add(new PredictCandidate { Kind = PredictKind.Gas, Key = "gas", Title = "Gas", Param = thr, Tomorrow = true, Prob = (a, b) => PredictMath.GasFlat(day + 1, thr) }); list.Add(new PredictCandidate { Kind = PredictKind.Gas, Key = "gas", Title = "Gas", Param = thr, Tomorrow = true, Prob = (a, b) => GasPublic(d, day + 1, thr) });
} }
if (d.Stable.CraWarnDay < 0 && d.Stable.CraSpiralDay < 0) if (d.Stable.CraWarnDay < 0 && d.Stable.CraSpiralDay < 0)
list.Add(new PredictCandidate { Kind = PredictKind.Cra, Key = "cra", Title = "CRA", Prob = (from, to) => PredictMath.CraWarnProb(d.Stable.CraSubsidy, CraDrain(d), day, from, to, CraHazard) }); list.Add(new PredictCandidate { Kind = PredictKind.Cra, Key = "cra", Title = "CRA", Prob = (from, to) => PredictMath.CraWarnProb(d.Stable.CraSubsidy, CraDrain(d), day, from, to, CraHazard) });
@@ -126,6 +126,10 @@ namespace Decentralized
return list; return list;
} }
/// <summary>gas 盘的公开价:一半按真实相位、一半按不知道相位——七天周期是链上公开的,但盘口里的 NPC 只有一半在看;自己数清周期的人还有一点优势。</summary>
private static double GasPublic(SaveData d, int day, double thr) =>
d.GasPhase < 0 ? PredictMath.GasFlat(day, thr) : 0.5 * PredictMath.GasAtLeast(day, d.GasPhase, thr) + 0.5 * PredictMath.GasFlat(day, thr);
private static double CraHazard => 1 - Math.Pow(1 - Tuning.CraSpiralWeekly, 1.0 / 7); private static double CraHazard => 1 - Math.Pow(1 - Tuning.CraSpiralWeekly, 1.0 / 7);
private static double CraDrain(SaveData d) => (Tuning.CraNpcStake + d.Staking.Earning) * d.Stable.CraRate; private static double CraDrain(SaveData d) => (Tuning.CraNpcStake + d.Staking.Earning) * d.Stable.CraRate;
@@ -191,7 +195,7 @@ namespace Decentralized
case PredictKind.Price: case PredictKind.Price:
return PredictMath.PriceAtLeast(d.Market.Price, d.Market.Anchor(d.ActiveEvents), Tuning.PscVol, Tuning.Revert, Math.Max(1, m.ToDay - day), m.Param); return PredictMath.PriceAtLeast(d.Market.Price, d.Market.Anchor(d.ActiveEvents), Tuning.PscVol, Tuning.Revert, Math.Max(1, m.ToDay - day), m.Param);
case PredictKind.Gas: case PredictKind.Gas:
return d.GasPhase < 0 ? (double?)null : PredictMath.GasAtLeast(m.ToDay, d.GasPhase, m.Param); return d.GasPhase < 0 ? (double?)null : GasPublic(d, m.ToDay, m.Param);
case PredictKind.Cra: case PredictKind.Cra:
if (d.Stable.CraWarnDay >= 0 || d.Stable.CraSpiralDay >= 0) return 0.02; if (d.Stable.CraWarnDay >= 0 || d.Stable.CraSpiralDay >= 0) return 0.02;
return PredictMath.CraWarnProb(d.Stable.CraSubsidy, CraDrain(d), day + 1, m.FromDay, m.ToDay, CraHazard); return PredictMath.CraWarnProb(d.Stable.CraSubsidy, CraDrain(d), day + 1, m.FromDay, m.ToDay, CraHazard);
+17 -3
View File
@@ -600,7 +600,7 @@ namespace Decentralized
var bk = d.Predict; var bk = d.Predict;
var w = d.Hot; var w = d.Hot;
int day = StoreStation.GetDayCounter(); int day = StoreStation.GetDayCounter();
var open = bk.Markets.Where(m => m.Outcome < 0).OrderBy(m => m.FromDay).ThenBy(m => m.Id).ToList(); var open = bk.Markets.Where(m => m.Outcome < 0).OrderBy(m => m.IsOpen(day) ? 0 : 1).ThenBy(m => m.FromDay).ThenBy(m => m.Id).ToList();
var sel = open.Find(m => m.Id == _predPick) ?? open.FirstOrDefault(); var sel = open.Find(m => m.Id == _predPick) ?? open.FirstOrDefault();
_predPick = sel?.Id ?? 0; _predPick = sel?.Id ?? 0;
Columns(b, l => Columns(b, l =>
@@ -618,7 +618,15 @@ namespace Decentralized
l.AddButton(m.Id == _predPick ? "[" + q + "]" : q, () => { _predPick = mk.Id; _message = null; Open(); }); l.AddButton(m.Id == _predPick ? "[" + q + "]" : q, () => { _predPick = mk.Id; _message = null; Open(); });
l.End(); l.End();
string state = m.IsOpen(day) ? "" : " " + L.T("predict.closed"); string state = m.IsOpen(day) ? "" : " " + L.T("predict.closed");
l.AddLabel(L.T("predict.row", P2(m.PYes), P2(1 - m.PYes)) + (all.Count > 0 ? " " + L.T("predict.held", L.T(all[0].Yes ? "predict.yes" : "predict.no"), Fmt.Num(all.Sum(x => x.Shares)), Fmt.Num(all.Sum(x => x.Cost))) : "") + state); string move = m.PrevP >= 0 && Math.Abs(m.PYes - m.PrevP) >= 0.02 ? L.T("predict.row.move", P2(m.PrevP), m.PYes > m.PrevP ? "↑" : "↓") : "";
l.AddLabel(L.T("predict.row", P2(m.PYes), P2(1 - m.PYes)) + move + (all.Count > 0 ? " " + L.T("predict.held", L.T(all[0].Yes ? "predict.yes" : "predict.no"), Fmt.Num(all.Sum(x => x.Shares)), Fmt.Num(all.Sum(x => x.Cost))) : "") + state);
}
if (bk.Stats.Count > 0)
{
l.AddSeparator();
l.AddLabel(L.T("predict.stats.h"));
foreach (var kv in bk.Stats.OrderByDescending(k => k.Value.Count))
l.AddLabel(L.T("predict.stats.row", L.T("predict.kind." + kv.Key), kv.Value.Count, P2(kv.Value.AvgP0), (kv.Value.HitRate * 100).ToString("0", CultureInfo.InvariantCulture)));
} }
if (bk.Recent.Count > 0) if (bk.Recent.Count > 0)
{ {
@@ -792,8 +800,14 @@ namespace Decentralized
Summary = L.T("predict.sum.sell", PredictGame.Question(m)), Summary = L.T("predict.sum.sell", PredictGame.Question(m)),
Execute = pw => Execute = pw =>
{ {
var res = d.Predict.SellAll(pw, m, StoreStation.GetDayCounter(), out double got); var res = d.Predict.SellAll(pw, m, StoreStation.GetDayCounter(), d.Rng, out double got, out double fraud);
_message = res == PredictResult.Ok ? L.T("predict.sold", Fmt.Num(got)) : L.T("predict.err." + res); _message = res == PredictResult.Ok ? L.T("predict.sold", Fmt.Num(got)) : L.T("predict.err." + res);
if (fraud > 0)
{
PlayerStore.Instance.secData.CommitCrime("FRAUD", (int)Math.Round(fraud));
_message = L.T("predict.sold.caught", Fmt.Num(got));
Log.Info($"内幕卖出被查:只退本金 {got:0},罪证 {fraud:0}");
}
if (res == PredictResult.Ok) Session.Save(); if (res == PredictResult.Ok) Session.Save();
Open(); Open();
}, },
+30 -1
View File
@@ -1156,7 +1156,7 @@ internal static class Program
var aa = new Wallet { Address = "p" }; var aa = new Wallet { Address = "p" };
m4.Outcome = -1; m4.Outcome = -1;
var ee = bb.Night(5, new string[0], mm => true, _ => aa, new Rng(sd)); var ee = bb.Night(5, new string[0], mm => true, _ => aa, new Rng(sd));
if (ee[0].Kind == "caught") { Check(Math.Abs(aa.Get(Assets.CRC) - (b4.Positions[0].Cost)) < 1e-6, "被查只退本金"); break; } if (ee[0].Kind == "caught") { Check(aa.Get(Assets.CRC) < 1e-6, "被查本金和收益全部没收"); break; }
} }
}); });
@@ -1201,6 +1201,8 @@ internal static class Program
var closing = PredictMarket.Create(++bk.Seq, PredictKind.Event, "e", "t", 0, 5, 6, 6, 0.1); bk.Markets.Add(closing); var closing = PredictMarket.Create(++bk.Seq, PredictKind.Event, "e", "t", 0, 5, 6, 6, 0.1); bk.Markets.Add(closing);
double before = closing.PYes; bk.Drift(5, x => 0.9, rng); double before = closing.PYes; bk.Drift(5, x => 0.9, rng);
Check(Math.Abs(closing.PYes - before) < 1e-12, "明天封盘的盘口不再反应"); Check(Math.Abs(closing.PYes - before) < 1e-12, "明天封盘的盘口不再反应");
var mv = bk.Drift(5, x => 0.9, rng);
Check(mv.Count == 1 && mv[0].Market == m && Math.Abs(mv[0].To - m.PYes) < 1e-12 && m.PrevP == mv[0].From, "反应记下前后价格");
Check(m.PYes >= Tuning.PredictPMin && m.PYes <= Tuning.PredictPMax, "价格夹在范围内"); Check(m.PYes >= Tuning.PredictPMin && m.PYes <= Tuning.PredictPMax, "价格夹在范围内");
// 反应是有噪声的:同一目标多次结果不全一样 // 反应是有噪声的:同一目标多次结果不全一样
var set = new System.Collections.Generic.HashSet<double>(); var set = new System.Collections.Generic.HashSet<double>();
@@ -1220,6 +1222,7 @@ internal static class Program
var w = new Wallet { Address = "x" }; var w = new Wallet { Address = "x" };
bk.Night(6, new string[0], mm => true, _ => w, rng); bk.Night(6, new string[0], mm => true, _ => w, rng);
Check(bk.Tips.Count == 0, "盘口结算后情报作废"); Check(bk.Tips.Count == 0, "盘口结算后情报作废");
Check(bk.Stats.TryGetValue("Event", out var stE) && stE.Count >= 1 && stE.Hits >= 1, "结算计入按类型的历史");
// gas / CRA / 时代 先验 // gas / CRA / 时代 先验
double flat = PredictMath.GasFlat(10, 1.2); double flat = PredictMath.GasFlat(10, 1.2);
double phase0 = PredictMath.GasAtLeast(10, 0, 1.2), sum2 = 0; double phase0 = PredictMath.GasAtLeast(10, 0, 1.2), sum2 = 0;
@@ -1379,6 +1382,32 @@ internal static class Program
Check(Math.Abs(rugs / 400.0 - Tuning.YieldRugNightly) < 0.05, $"骗局池每晚跑路概率:{rugs / 400.0:0.00}"); Check(Math.Abs(rugs / 400.0 - Tuning.YieldRugNightly) < 0.05, $"骗局池每晚跑路概率:{rugs / 400.0:0.00}");
}); });
Test("预测市场:内幕先买后卖也会被查", () =>
{
int caught = 0, n = 400;
for (ulong sd = 1; sd <= (ulong)n; sd++)
{
var bk = new PredictBook(); var w = new Wallet { Address = "w" }; w.Add(Assets.CRC, 1e6);
var m = PredictMarket.Create(++bk.Seq, PredictKind.Event, "e", "t", 0, 4, 7, 7, 0.05); bk.Markets.Add(m);
double target = Tuning.PredictInsiderShare * m.ShareCap * 1.02;
bk.Buy(w, m, true, m.BuyCost(true, target) * (1 + Tuning.PredictFee), 4, a => 1, true, out _);
double cost = bk.PosOf(m.Id, "w").Cost;
double p1 = m.PYes, p2 = p1 + (1 - p1) / 2;
m.QYes = m.QNo + m.B * Math.Log(p2 / (1 - p2)); // 夜里价格又涨了一截
bk.SellAll(w, m, 5, new Rng(sd), out double got, out double fraud);
if (fraud > 0) { caught++; Check(got == 0 && fraud <= Tuning.PredictFraudCap, "被查本金和收益全部没收"); }
else Check(got > cost, "没被查时赚到价差");
}
Check(Math.Abs(caught / (double)n - Tuning.PredictInsiderCatch) < 0.08, $"约一半被查:{caught}/{n}");
// 小额内幕、非内幕卖出不查
var bk2 = new PredictBook(); var w2 = new Wallet { Address = "w" }; w2.Add(Assets.CRC, 1e6);
var m2 = PredictMarket.Create(++bk2.Seq, PredictKind.Event, "e", "t", 0, 4, 7, 7, 0.05); bk2.Markets.Add(m2);
bk2.Buy(w2, m2, true, 200, 4, a => 1, true, out _);
m2.QYes = m2.QNo + m2.B * Math.Log(0.6 / 0.4);
bk2.SellAll(w2, m2, 5, new Rng(1), out _, out double f2);
Check(f2 == 0, "小额内幕卖出安全");
});
Test("预测市场:先验概率", () => Test("预测市场:先验概率", () =>
{ {
Check(Math.Abs(PredictMath.PurityAtLeast(8500, 8000, 8999) - 0.5) < 1e-9, "纯度 8500 以上一半"); Check(Math.Abs(PredictMath.PurityAtLeast(8500, 8000, 8999) - 0.5) < 1e-9, "纯度 8500 以上一半");