Prediction markets use on-chain wallets (signed contract calls) instead of the Poinbase account
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e5a6e3e22c
commit
723724aa4b
8 files changed
+138
-73
No files matched your search
@@ -1080,14 +1080,14 @@ internal static class Program
|
||||
Check(bk.Buy(acct, m, true, 100, 6, pr, false, out _) == PredictResult.Closed, "窗口开始后封盘");
|
||||
var res = bk.Buy(acct, m, true, 102, 5, pr, false, out double sh);
|
||||
Check(res == PredictResult.Ok && sh > 0, "买入成功");
|
||||
var pos = bk.PosOf(m.Id);
|
||||
var pos = bk.PosOf(m.Id, acct.Address);
|
||||
Check(Math.Abs(pos.Cost - 100) < 1e-6 && Math.Abs(acct.Get(Assets.CRC) - 898) < 1e-6, $"成本 100(手续费 2):{pos.Cost:0.00}");
|
||||
Check(Math.Abs(pos.Taint - 40.8) < 1e-6 && Math.Abs(acct.Taint - 359.2) < 1e-6, $"污点按花掉的价值比例带进持仓:{pos.Taint:0.00}");
|
||||
Check(bk.Buy(acct, m, false, 10, 5, pr, false, out _) == PredictResult.Opposite, "不能同盘反方向");
|
||||
// 卖出:价差为 0,只付 2% 手续费
|
||||
double before = acct.Get(Assets.CRC);
|
||||
Check(bk.SellAll(acct, m, 5, out double got) == PredictResult.Ok && Math.Abs(got - 98) < 1e-6, $"原价卖回只扣手续费:{got:0.00}");
|
||||
Check(Math.Abs(acct.Get(Assets.CRC) - before - got) < 1e-6 && bk.PosOf(m.Id) == null, "回到账户");
|
||||
Check(Math.Abs(acct.Get(Assets.CRC) - before - got) < 1e-6 && bk.PosOf(m.Id, acct.Address) == null, "回到账户");
|
||||
Check(acct.Taint < 400 && acct.Taint > 359.2, "卖回时污点按退回的比例回来");
|
||||
// 持仓上限
|
||||
var big = new Wallet { Address = "x" }; big.Add(Assets.CRC, 1e7);
|
||||
@@ -1103,7 +1103,7 @@ internal static class Program
|
||||
acct.Add(Assets.CRC, 100000);
|
||||
var bk = new PredictBook();
|
||||
// 观测:第一晚没有 Prev,不算 Started
|
||||
bk.Night(4, new[] { "oxymoreWave" }, m => null, acct, rng);
|
||||
bk.Night(4, new[] { "oxymoreWave" }, m => null, _ => acct, rng);
|
||||
Check(!bk.Started.ContainsKey(4), "第一晚没有对照,不记新出现的事件");
|
||||
var win = PredictMarket.Create(++bk.Seq, PredictKind.Event, "powerShortage", "停电", 0, 4, 5, 6, 0.2);
|
||||
var lose = PredictMarket.Create(++bk.Seq, PredictKind.Event, "blackout", "x", 0, 4, 5, 6, 0.2);
|
||||
@@ -1113,9 +1113,9 @@ internal static class Program
|
||||
bk.Buy(acct, lose, true, 51, 4, pr, false, out _);
|
||||
bk.Buy(acct, voided, true, 51, 4, pr, false, out _);
|
||||
double cash = acct.Get(Assets.CRC);
|
||||
bk.Night(5, new[] { "oxymoreWave", "powerShortage" }, bk.Happened, acct, rng);
|
||||
bk.Night(5, new[] { "oxymoreWave", "powerShortage" }, bk.Happened, _ => acct, rng);
|
||||
Check(win.Outcome < 0 && lose.Outcome < 0, "窗口没结束不结算");
|
||||
var evs = bk.Night(6, new[] { "oxymoreWave", "powerShortage" }, bk.Happened, acct, rng);
|
||||
var evs = bk.Night(6, new[] { "oxymoreWave", "powerShortage" }, bk.Happened, _ => acct, rng);
|
||||
Check(win.Outcome == -1 || bk.Markets.All(x => x.Id != win.Id), "到期的盘口移出列表");
|
||||
Check(evs.Any(e => e.Kind == "win" && e.Title == "停电" && Math.Abs(e.Amount - sw) < 1e-6), "押中兑付份数");
|
||||
Check(evs.Any(e => e.Kind == "lose" && e.Title == "x"), "押错没收");
|
||||
@@ -1123,7 +1123,7 @@ internal static class Program
|
||||
Check(bk.Markets.Count == 1 && bk.Markets[0].Id == voided.Id, "后面的窗口还没到");
|
||||
// 缺观测:8 号之前 7、8 的记录缺,到期作废退本金
|
||||
double c2 = acct.Get(Assets.CRC);
|
||||
var ev2 = bk.Night(9, new string[0], bk.Happened, acct, rng);
|
||||
var ev2 = bk.Night(9, new string[0], bk.Happened, _ => acct, rng);
|
||||
Check(ev2.Any(e => e.Kind == "void") && Math.Abs(acct.Get(Assets.CRC) - c2 - 50) < 1e-6, $"缺数据作废并退本金:{acct.Get(Assets.CRC) - c2:0.00}");
|
||||
// 内幕被查:持仓达到上限的 40% 就有概率;200 次里大约一半
|
||||
int caught = 0, wins = 0;
|
||||
@@ -1134,7 +1134,7 @@ internal static class Program
|
||||
double target = Tuning.PredictInsiderShare * mk.ShareCap * 1.05, spend = 0;
|
||||
spend = (mk.BuyCost(true, target)) * (1 + Tuning.PredictFee);
|
||||
b2.Buy(a2, mk, true, spend, 4, pr, true, out _);
|
||||
var e = b2.Night(5, new string[0], mm => true, a2, new Rng((ulong)(i + 1)));
|
||||
var e = b2.Night(5, new string[0], mm => true, _ => a2, new Rng((ulong)(i + 1)));
|
||||
if (e[0].Kind == "caught") { caught++; Check(e[0].Fraud > 0 && e[0].Fraud <= Tuning.PredictFraudCap, "罪证有上限"); }
|
||||
else wins++;
|
||||
}
|
||||
@@ -1143,7 +1143,7 @@ internal static class Program
|
||||
var b3 = new PredictBook(); var a3 = new Wallet { Address = "p" }; a3.Add(Assets.CRC, 1e6);
|
||||
var m3 = PredictMarket.Create(++b3.Seq, PredictKind.Event, "e", "t", 0, 4, 5, 5, 0.1); b3.Markets.Add(m3);
|
||||
b3.Buy(a3, m3, true, m3.BuyCost(true, 0.2 * m3.ShareCap) * 1.02, 4, pr, true, out _);
|
||||
Check(b3.Night(5, new string[0], mm => true, a3, new Rng(1))[0].Kind == "win", "小额内幕安全");
|
||||
Check(b3.Night(5, new string[0], mm => true, _ => a3, new Rng(1))[0].Kind == "win", "小额内幕安全");
|
||||
// 被查:只退本金
|
||||
var b4 = new PredictBook(); var a4 = new Wallet { Address = "p" }; a4.Add(Assets.CRC, 1e6);
|
||||
var m4 = PredictMarket.Create(++b4.Seq, PredictKind.Event, "e", "t", 0, 4, 5, 5, 0.1); b4.Markets.Add(m4);
|
||||
@@ -1152,14 +1152,44 @@ internal static class Program
|
||||
double c4 = a4.Get(Assets.CRC);
|
||||
for (ulong sd = 1; sd < 50; sd++)
|
||||
{
|
||||
var bb = new PredictBook(); bb.Markets.Add(m4); bb.Positions.AddRange(b4.Positions.Select(x => new PredictPos { Market = x.Market, Yes = x.Yes, Shares = x.Shares, Cost = x.Cost, Insider = x.Insider }));
|
||||
var bb = new PredictBook(); bb.Markets.Add(m4); bb.Positions.AddRange(b4.Positions.Select(x => new PredictPos { Market = x.Market, Wallet = x.Wallet, Yes = x.Yes, Shares = x.Shares, Cost = x.Cost, Insider = x.Insider }));
|
||||
var aa = new Wallet { Address = "p" };
|
||||
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; }
|
||||
}
|
||||
});
|
||||
|
||||
Test("预测市场:多钱包持仓各回各的钱包,限额与内幕按盘口合计", () =>
|
||||
{
|
||||
Func<string, double> pr = a => 1;
|
||||
var w1 = new Wallet { Address = "0xa" }; var w2 = new Wallet { Address = "0xb" };
|
||||
w1.Add(Assets.CRC, 1e6); w2.Add(Assets.CRC, 1e6);
|
||||
Func<string, Wallet> pick = ad => ad == "0xa" ? w1 : w2;
|
||||
var bk = new PredictBook();
|
||||
var m = PredictMarket.Create(++bk.Seq, PredictKind.Event, "e", "t", 0, 4, 5, 5, 0.1); bk.Markets.Add(m);
|
||||
double half = Tuning.PredictInsiderShare * m.ShareCap * 0.6;
|
||||
Check(bk.Buy(w1, m, true, m.BuyCost(true, half) * 1.02, 4, pr, true, out _) == PredictResult.Ok, "钱包 A 买入");
|
||||
Check(bk.Buy(w2, m, false, 10, 4, pr, false, out _) == PredictResult.Opposite, "另一个钱包也不能买对面");
|
||||
Check(bk.Buy(w2, m, true, m.BuyCost(true, half) * 1.02, 4, pr, true, out _) == PredictResult.Ok, "钱包 B 买入同一边");
|
||||
Check(bk.PosAll(m.Id).Count == 2 && bk.PosOf(m.Id, "0xa") != null && bk.PosOf(m.Id, "0xb") != null, "每个钱包各一个持仓");
|
||||
Check(bk.SellAll(w2, m, 4, out double got) == PredictResult.Ok && got > 0 && bk.PosOf(m.Id, "0xb") == null && bk.PosOf(m.Id, "0xa") != null, "卖出只动自己钱包的持仓");
|
||||
Check(bk.Buy(w2, m, true, m.BuyCost(true, half) * 1.02, 4, pr, true, out _) == PredictResult.Ok, "再买");
|
||||
// 两边各 0.6×查处线,合计超线:拆钱包躲不过
|
||||
int caught = 0;
|
||||
for (ulong sd = 1; sd <= 60; sd++)
|
||||
{
|
||||
var b2 = new PredictBook(); b2.Markets.Add(new PredictMarket { Id = m.Id, Kind = m.Kind, Key = m.Key, Title = m.Title, FromDay = 5, ToDay = 5, P0 = m.P0, B = m.B, QYes = m.QYes, QNo = m.QNo });
|
||||
foreach (var p in bk.Positions) b2.Positions.Add(new PredictPos { Market = p.Market, Wallet = p.Wallet, Yes = p.Yes, Shares = p.Shares, Cost = p.Cost, Insider = p.Insider });
|
||||
double a0 = w1.Get(Assets.CRC), b0 = w2.Get(Assets.CRC);
|
||||
var ev = b2.Night(5, new string[0], x => true, pick, new Rng(sd));
|
||||
if (ev[0].Kind == "caught") caught++;
|
||||
else Check(w1.Get(Assets.CRC) > a0 && w2.Get(Assets.CRC) > b0, "赢了各自的钱包都收到兑付");
|
||||
w1.Balances[Assets.CRC] = a0; w2.Balances[Assets.CRC] = b0;
|
||||
}
|
||||
Check(caught > 15 && caught < 45, $"分到两个钱包的内幕持仓合计后约一半被查:{caught}/60");
|
||||
});
|
||||
|
||||
Test("预测市场:先验概率", () =>
|
||||
{
|
||||
Check(Math.Abs(PredictMath.PurityAtLeast(8500, 8000, 8999) - 0.5) < 1e-9, "纯度 8500 以上一半");
|
||||
|
||||
Reference in new issue
Block a user