换币客户改在交易终端成交:按比例部分成交、买币随机出价、弹出钱包
- 对话只剩"到终端上谈 / 这单我不做":交易终端打开柜台交易页(标签"柜台",只在有客户时出现),客户在柜台前等着 - 柜台交易页:客户来意、数量、市值、出价/要价、单价、地址(卖币可"查地址"进浏览器),25/50/75/100% 或手输数量部分成交(Otc.Part),成交 / 放弃 - 买币客户随机出价(OtcBidMin −5% … OtcBidMax +30%),去掉三档报价与成交概率(OtcPremium、OtcAccept);成交后弹出 PLEDGER,账单 Prefill 填好客户地址 - 卖币:成交后付现金、币进已连接的钱包;客户说最后一句离开(DialogUIManager.StartDialogue) - 客户被打发或离开时交易作废;不再有"当晚未付作废" - 增量翻译:只是和已删旧键同文的新键照常翻译 - 实测:买币客户 25% 部分成交(先在 Web3 换出 CRA),PLEDGER 预填地址签名,到账 +668,客户离开;涡轮增压器作用于矿架立刻挖一轮 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2badc45a5a
commit
9d95e1f760
16 files changed
+455
-223
No files matched your search
@@ -1357,7 +1357,7 @@ internal static class Program
|
||||
Check(ps > 12 && ps < 20, $"夜里向 SPARK 参考价靠拢:{ps:0.00}");
|
||||
});
|
||||
|
||||
Test("换币客户:卖币的事件币种、污点比例与折扣、收下后的污点;买币的报价档;成交统计", () =>
|
||||
Test("换币客户:卖币的事件币种、污点比例与折扣、收下后的污点;买币的随机出价;部分成交;成交统计", () =>
|
||||
{
|
||||
Func<string, double> pr = a => a == Assets.Ponero ? 50 : 1;
|
||||
var none = new List<MarketEvent>();
|
||||
@@ -1397,16 +1397,19 @@ internal static class Program
|
||||
if (Otc.MakeSell(new List<MarketEvent> { MarketEvent.Crackdown }, false, pr, 500, rng).Sting) stingsCd++;
|
||||
}
|
||||
Check(stingsCd > stings * 2, $"镇压期间便衣更多:{stings} → {stingsCd}");
|
||||
// 买币:市值按房租,三档溢价,越高越难成交
|
||||
var ob = Otc.MakeBuy(pr, 500, new Rng(7));
|
||||
Check(Array.IndexOf(Otc.BuyAssets, ob.Asset) >= 0 && ob.Value >= 500 * Tuning.OtcBuyMinRents && ob.Value <= 500 * Tuning.OtcBuyMaxRents && Near(ob.Qty * pr(ob.Asset), ob.Value, 1e-6), "买币的币种与数量");
|
||||
Check(Otc.Quote(ob, 0) < Otc.Quote(ob, 1) && Otc.Quote(ob, 1) < Otc.Quote(ob, 2) && Otc.Quote(ob, 2) == (int)Math.Round(ob.Value * (1 + Tuning.OtcPremium[2])), "三档报价");
|
||||
for (int t = 0; t < 3; t++)
|
||||
// 买币:市值按房租,出价 = 市值 × (1 + 随机溢价),溢价在区间内
|
||||
for (int i = 0; i < 200; i++)
|
||||
{
|
||||
int ok = 0; var r = new Rng((ulong)(t + 11));
|
||||
for (int i = 0; i < 4000; i++) if (Otc.Accepts(t, r)) ok++;
|
||||
Check(Math.Abs(ok / 4000.0 - Tuning.OtcAccept[t]) < 0.03, $"第 {t + 1} 档成交概率:{ok}/4000");
|
||||
var ob = Otc.MakeBuy(pr, 500, rng);
|
||||
Check(Array.IndexOf(Otc.BuyAssets, ob.Asset) >= 0 && ob.Value >= 500 * Tuning.OtcBuyMinRents && ob.Value <= 500 * Tuning.OtcBuyMaxRents && Near(ob.Qty * pr(ob.Asset), ob.Value, 1e-6), "买币的币种与数量");
|
||||
Check(ob.Cash >= ob.Value * (1 + Tuning.OtcBidMin) - 1 && ob.Cash <= ob.Value * (1 + Tuning.OtcBidMax) + 1, $"出价在区间内:{ob.Cash} / {ob.Value:0}");
|
||||
}
|
||||
// 部分成交:现金、市值按数量比例折算,超过报价按全部算
|
||||
var whole = new OtcOffer { Side = OtcSide.Sell, Asset = Assets.PSC, Qty = 20, Value = 2000, TaintRatio = 0.5, Cash = 1200, Sting = true };
|
||||
var half = Otc.Part(whole, 10);
|
||||
Check(Near(half.Qty, 10, 1e-9) && Near(half.Value, 1000, 1e-9) && half.Cash == 600 && half.TaintRatio == 0.5 && half.Sting, "收一半:现金、市值减半,污点比例和便衣不变");
|
||||
Check(Near(Otc.Part(whole, 50).Qty, 20, 1e-9) && Otc.Part(whole, 50).Cash == 1200, "超过报价的数量按全部算");
|
||||
Check(Otc.Part(whole, 0) == null && Otc.Part(whole, -1) == null, "数量不合法");
|
||||
// 来历:脏的来源按污点比例出现,数量占比合计为 1
|
||||
var hist = Otc.History(new OtcOffer { TaintRatio = 1 }, new[] { "dirty" }, new[] { "clean" }, new Rng(2));
|
||||
Check(hist.Count >= 1 && hist.Count <= Tuning.OtcHistoryMax && hist.TrueForAll(kv => kv.Key == "dirty") && Near(hist.Sum(kv => kv.Value), 1, 1e-9), "全脏的币来历都是脏来源");
|
||||
|
||||
Reference in new issue
Block a user