Candles and volume for every traded asset, chart asset switcher

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:51:31 +08:00
1 parent b8308e1010
commit e1390a6921
9 files changed
+105 -27

No files matched your search

+3
View File
@@ -4,6 +4,9 @@
### 行情图 ### 行情图
- 所有可交易资产都有日 K 和成交量:PSC、SPARK、CRT、CRA、CRC、Ponero。开门时每个币开一根(开盘接昨天收盘),夜间结算在价格更新前收盘;稳定币和 SPARK 的价格在夜里变,变动算进第二天那根。成交量:市场的量 = 主池深度 × 各币比例(PSC 12%、CRC 10%、CRT 6%、CRA 4%、SPARK 3%、Ponero 1%)×(1 + 8 × 当天的涨跌与振幅)× 0.6–1.4 的随机,波动越大成交越多;你的量包括 Poinbase / DEX 兑换(两边的币都算)、SPARK 铸销(SPARK 和 CRA)、Ponero 兑换、永续开平仓(按名义价值,计入 PSC 或 SPARK)。
- 图上方加一排币种按钮(Poinbase 现货页、Web3 交易页各自记住选的币,Ponero 要黑市解锁后才出现);永续页显示当前选中的品种;预测页仍是 PSC。均线改为先画,蜡烛盖在上面,贴着锚的稳定币不会被均线遮住。
- 游戏内验证:Web3 交易页切换 PSC / SPARK / CRT 都正常,SPARK 有完整的蜡烛和放量,CRT 在锚上是一条线(30 天里没脱锚)。没有在游戏里验证:脱锚时稳定币的图、Ponero、玩家各类成交计入量柱(只看过 PSC 现货的青色柱)。
- PSC 日 K:存档里新增逐日 K 线历史(`CandleBook`,保留 60 天)。开盘接前一天的收盘价(币是全天候交易的,夜里的回归和开门波动算进当天这根,没有跳空);最高 / 最低只取白天真实发生过的价格(开门波动、NPC 大户、插针、玩家在 Poinbase 的大单),不编造日内走势;收盘是夜间结算前、插针回去之后的价格。成交量分大户和玩家两份。旧存档没有历史,从接入当天开始记录。 - PSC 日 K:存档里新增逐日 K 线历史(`CandleBook`,保留 60 天)。开盘接前一天的收盘价(币是全天候交易的,夜里的回归和开门波动算进当天这根,没有跳空);最高 / 最低只取白天真实发生过的价格(开门波动、NPC 大户、插针、玩家在 Poinbase 的大单),不编造日内走势;收盘是夜间结算前、插针回去之后的价格。成交量分大户和玩家两份。旧存档没有历史,从接入当天开始记录。
- K 线图:运行时画在一张 188×97 的纹理上,点采样放大 2 倍显示,和游戏的像素风格一致。最近 30 根,涨绿跌红、影线、黄色 7 日均线(永续资金费按它算),下方成交量柱(灰 大户 / 青 你的成交),当天还没收盘的蜡烛画成空心;上方一行写最高、最低、收盘和涨跌幅。出现在 Poinbase 现货页、永续页,以及预测页选中 PSC 价格盘时(加一条蓝色阈值虚线)。 - K 线图:运行时画在一张 188×97 的纹理上,点采样放大 2 倍显示,和游戏的像素风格一致。最近 30 根,涨绿跌红、影线、黄色 7 日均线(永续资金费按它算),下方成交量柱(灰 大户 / 青 你的成交),当天还没收盘的蜡烛画成空心;上方一行写最高、最低、收盘和涨跌幅。出现在 Poinbase 现货页、永续页,以及预测页选中 PSC 价格盘时(加一条蓝色阈值虚线)。
- 调试入口"Chart: run market 30 days":用真实的行情过程往前跑 30 天并记录蜡烛(会改动这一局的 PSC 价格,只在测试存档用)。 - 调试入口"Chart: run market 30 days":用真实的行情过程往前跑 30 天并记录蜡烛(会改动这一局的 PSC 价格,只在测试存档用)。
+4
View File
@@ -65,6 +65,10 @@ namespace Decentralized.Domain
Today(asset, day, price).Closed = true; Today(asset, day, price).Closed = true;
} }
/// <summary>NPC 当天的成交额(信用点):基础量随池深,波动越大成交越多。</summary>
public static double NpcVolume(double depth, double share, double absMove, Rng rng) =>
depth * share * (1 + Tuning.ChartVolMove * absMove) * rng.Range(0.6, 1.4);
/// <summary>收盘价的 n 日均线(不足 n 根时用已有的);每根蜡烛一个值。</summary> /// <summary>收盘价的 n 日均线(不足 n 根时用已有的);每根蜡烛一个值。</summary>
public static List<double> Ma(IList<Candle> s, int n) public static List<double> Ma(IList<Candle> s, int n)
{ {
+3
View File
@@ -235,6 +235,9 @@ namespace Decentralized.Domain
public const double FakeSupportChance = 0.04, FakeTransferShare = 0.08; public const double FakeSupportChance = 0.04, FakeTransferShare = 0.08;
public const int ScamMinDay = 10; public const int ScamMinDay = 10;
/// <summary>行情图的 NPC 成交量:每天的基础量占主池深度的比例(按币种),价格波动越大成交越多(|涨跌幅| × 倍数),再乘 0.6–1.4 的随机。</summary>
public const double ChartVolPsc = 0.12, ChartVolCrc = 0.10, ChartVolCrt = 0.06, ChartVolCra = 0.04, ChartVolSpark = 0.03, ChartVolPonero = 0.01, ChartVolMove = 8;
/// <summary>主交易对(信用点一侧)的深度随天数增长。</summary> /// <summary>主交易对(信用点一侧)的深度随天数增长。</summary>
public static double PoolDepth(int day) => PoolDepth0 * (1 + day / 60.0); public static double PoolDepth(int day) => PoolDepth0 * (1 + day / 60.0);
} }
+67 -7
View File
@@ -13,6 +13,49 @@ namespace Decentralized
/// </summary> /// </summary>
public static class CandleChart public static class CandleChart
{ {
/// <summary>画图的币种:全部可交易资产。</summary>
public static readonly string[] ChartAssets = { Assets.PSC, Assets.SPARK, Assets.CRT, Assets.CRA, Assets.CRC, Assets.Ponero };
private static double VolShare(string a) =>
a == Assets.PSC ? Tuning.ChartVolPsc : a == Assets.CRC ? Tuning.ChartVolCrc : a == Assets.CRT ? Tuning.ChartVolCrt :
a == Assets.CRA ? Tuning.ChartVolCra : a == Assets.SPARK ? Tuning.ChartVolSpark : Tuning.ChartVolPonero;
/// <summary>开门:每个币开一根蜡烛(开盘接昨天收盘,夜里的价格变化算进来)。</summary>
public static void Morning(SaveData d, int day)
{
foreach (var a in ChartAssets) d.Candles.Open(a, day, Session.Price(a));
}
/// <summary>白天价格变了(不计成交)。</summary>
public static void Touch(SaveData d, int day, params string[] assets)
{
foreach (var a in assets) d.Candles.Tick(a, day, Session.Price(a));
}
/// <summary>玩家的一笔成交:按信用点计进这个币当天的成交量。</summary>
public static void Trade(string asset, double credits)
{
var d = Session.Data;
if (d == null || Array.IndexOf(ChartAssets, asset) < 0 || credits <= 0) return;
d.Candles.Tick(asset, StoreStation.GetDayCounter(), Session.Price(asset), credits, true);
}
/// <summary>夜间结算:补上当天 NPC 的成交量,收盘。在价格的夜间更新之前调用。</summary>
public static void Close(SaveData d, int day)
{
double depth = Tuning.PoolDepth(day);
foreach (var a in ChartAssets)
{
double p = Session.Price(a);
var c = d.Candles.Today(a, day, p);
double move = c.O > 0 ? Math.Abs(p / c.O - 1) + (c.H - c.L) / c.O : 0;
d.Candles.Tick(a, day, p, CandleBook.NpcVolume(depth, VolShare(a), move, d.Rng));
d.Candles.Close(a, day, p);
}
}
private static readonly Dictionary<string, string> Picked = new Dictionary<string, string>();
public const int Days = 30, Step = 6, Body = 5, PriceH = 70, Gap = 3, VolH = 16, Pad = 2; public const int Days = 30, Step = 6, Body = 5, PriceH = 70, Gap = 3, VolH = 16, Pad = 2;
public const int W = Days * Step + Pad * 2, H = PriceH + Gap + VolH + Pad * 2; public const int W = Days * Step + Pad * 2, H = PriceH + Gap + VolH + Pad * 2;
public const float Scale = 2f; public const float Scale = 2f;
@@ -49,6 +92,8 @@ namespace Decentralized
Func<double, int> y = p => priceY0 + (int)Math.Round((p - lo) / span * (PriceH - 1)); Func<double, int> y = p => priceY0 + (int)Math.Round((p - lo) / span * (PriceH - 1));
double vmax = Math.Max(1, c.Max(x => x.VolPlayer + x.VolNpc)); double vmax = Math.Max(1, c.Max(x => x.VolPlayer + x.VolNpc));
int x0 = Pad + (Days - c.Count) * Step; // 不足 30 根时靠右 int x0 = Pad + (Days - c.Count) * Step; // 不足 30 根时靠右
// 均线先画,蜡烛盖在上面(贴着锚的稳定币不会被均线遮住)
for (int i = 1; i < ma.Count; i++) Line(px, x0 + (i - 1) * Step + Body / 2, y(ma[i - 1]), x0 + i * Step + Body / 2, y(ma[i]), Ma);
for (int i = 0; i < c.Count; i++) for (int i = 0; i < c.Count; i++)
{ {
var k = c[i]; var k = c[i];
@@ -69,7 +114,6 @@ namespace Decentralized
if (hm > 0) VLine(px, xx, volY0 + hn, volY0 + hn + hm - 1, VolMe); if (hm > 0) VLine(px, xx, volY0 + hn, volY0 + hn + hm - 1, VolMe);
} }
} }
for (int i = 1; i < ma.Count; i++) Line(px, x0 + (i - 1) * Step + Body / 2, y(ma[i - 1]), x0 + i * Step + Body / 2, y(ma[i]), Ma);
if (threshold > 0) { int ty = y(threshold); for (int xx = Pad; xx < W - Pad; xx++) if ((xx / 3) % 2 == 0) Set(px, xx, ty, Thr); } if (threshold > 0) { int ty = y(threshold); for (int xx = Pad; xx < W - Pad; xx++) if ((xx / 3) % 2 == 0) Set(px, xx, ty, Thr); }
} }
s.Tex.SetPixels32(px); s.Tex.SetPixels32(px);
@@ -78,13 +122,13 @@ namespace Decentralized
} }
/// <summary>图上方的一行说明:最高、最低、最新收盘,涨跌。</summary> /// <summary>图上方的一行说明:最高、最低、最新收盘,涨跌。</summary>
public static string Caption(IList<Candle> all) public static string Caption(string asset, IList<Candle> all)
{ {
var c = all.Skip(Math.Max(0, all.Count - Days)).ToList(); var c = all.Skip(Math.Max(0, all.Count - Days)).ToList();
if (c.Count == 0) return L.T("chart.empty"); if (c.Count == 0) return L.T("chart.empty", asset);
var last = c[c.Count - 1]; var last = c[c.Count - 1];
double prev = c.Count > 1 ? c[c.Count - 2].C : last.O, chg = prev > 0 ? last.C / prev - 1 : 0; double prev = c.Count > 1 ? c[c.Count - 2].C : last.O, chg = prev > 0 ? last.C / prev - 1 : 0;
return L.T("chart.caption", c.Count, Fmt.Num(c.Max(x => x.H)), Fmt.Num(c.Min(x => x.L)), Fmt.Num(last.C), (chg * 100).ToString("+0.0;-0.0;0.0", CultureInfo.InvariantCulture)); return L.T("chart.caption", asset, c.Count, Fmt.Num(c.Max(x => x.H)), Fmt.Num(c.Min(x => x.L)), Fmt.Num(last.C), (chg * 100).ToString("+0.0;-0.0;0.0", CultureInfo.InvariantCulture));
} }
private static void Set(Color32[] px, int x, int y, Color32 c) { if (x >= 0 && x < W && y >= 0 && y < H) px[y * W + x] = c; } private static void Set(Color32[] px, int x, int y, Color32 c) { if (x >= 0 && x < W && y >= 0 && y < H) px[y * W + x] = c; }
@@ -104,12 +148,28 @@ namespace Decentralized
} }
} }
/// <summary>把图放进界面:说明一行、图、图例一行。</summary> /// <summary>把一个币的图放进界面:说明一行、图、图例一行。</summary>
public static void Add(CustomUIBuilder b, string key, IList<Candle> all, double threshold = 0) public static void Add(CustomUIBuilder b, string key, string asset, double threshold = 0)
{ {
b.AddLabel(Caption(all)); var all = Session.Data.Candles.Of(asset);
b.AddLabel(Caption(asset, all));
b.AddImage(Render(key, all, threshold), W * Scale, H * Scale); b.AddImage(Render(key, all, threshold), W * Scale, H * Scale);
b.AddLabel(L.T(threshold > 0 ? "chart.legend.thr" : "chart.legend")); b.AddLabel(L.T(threshold > 0 ? "chart.legend.thr" : "chart.legend"));
} }
/// <summary>带币种切换的图:上面一排币种按钮(选中的加方括号),切换后重画。</summary>
public static void AddPicker(CustomUIBuilder b, string key, string fallback, Action refresh)
{
var list = ChartAssets.Where(a => a != Assets.Ponero || Unlock.BlackUnlocked).ToList();
if (!Picked.TryGetValue(key, out var cur) || !list.Contains(cur)) cur = fallback;
b.BeginRow(4f);
foreach (var a in list)
{
string asset = a;
b.AddButton(asset == cur ? "[" + asset + "]" : asset, () => { Picked[key] = asset; refresh(); });
}
b.End();
Add(b, key, cur);
}
} }
} }
+6 -5
View File
@@ -118,17 +118,18 @@ namespace Decentralized
{ {
// 用真实的行情过程往前跑 30 天,记录蜡烛(会改动这一局的 PSC 价格,只在测试存档用) // 用真实的行情过程往前跑 30 天,记录蜡烛(会改动这一局的 PSC 价格,只在测试存档用)
var d = Session.Data; int day0 = StoreStation.GetDayCounter() - 30; var none = new List<MarketEvent>(); var d = Session.Data; int day0 = StoreStation.GetDayCounter() - 30; var none = new List<MarketEvent>();
d.Candles.Series.Remove(Assets.PSC); d.Candles.Series.Clear();
for (int k = day0; k < day0 + 30; k++) for (int k = day0; k < day0 + 30; k++)
{ {
d.Market.Open(none, d.Rng, k); d.Candles.Open(Assets.PSC, k, d.Market.Price); d.Market.Open(none, d.Rng, k); CandleChart.Morning(d, k);
double wh = d.Market.Whale(d.Rng); d.Candles.Tick(Assets.PSC, k, d.Market.Price, wh); double wh = d.Market.Whale(d.Rng); d.Candles.Tick(Assets.PSC, k, d.Market.Price, wh);
if (d.Market.TryWick(d.Rng, k) != 0) d.Candles.Tick(Assets.PSC, k, d.Market.Price); if (d.Market.TryWick(d.Rng, k) != 0) CandleChart.Touch(d, k, Assets.PSC, Assets.Ponero);
if (d.Rng.Chance(0.3)) { double v = d.Rng.Range(500.0, 4000.0); bool buy = d.Rng.Chance(0.5); if (buy) d.Market.Main.BuyBase(v); else d.Market.Main.SellBase(v / d.Market.Price); d.Candles.Tick(Assets.PSC, k, d.Market.Price, v, true); } if (d.Rng.Chance(0.3)) { double v = d.Rng.Range(500.0, 4000.0); bool buy = d.Rng.Chance(0.5); if (buy) d.Market.Main.BuyBase(v); else d.Market.Main.SellBase(v / d.Market.Price); d.Candles.Tick(Assets.PSC, k, d.Market.Price, v, true); }
d.Market.UndoWick(k); d.Candles.Close(Assets.PSC, k, d.Market.Price); d.Market.UndoWick(k); CandleChart.Close(d, k);
d.Stable.Night(k, d.Rng, d.Staking.Earning);
d.Market.Night(none, d.Rng, k, Session.Price); d.Market.UpdateSupply(k); d.Market.Night(none, d.Rng, k, Session.Price); d.Market.UpdateSupply(k);
} }
d.Candles.Open(Assets.PSC, day0 + 30, d.Market.Price); CandleChart.Morning(d, day0 + 30);
Log.Info($"测试:K 线 {d.Candles.Of(Assets.PSC).Count} 根,PSC {d.Market.Price:0.00}"); Log.Info($"测试:K 线 {d.Candles.Of(Assets.PSC).Count} 根,PSC {d.Market.Price:0.00}");
})); }));
ModHelper.AddDebugFunction(ModInfo.Id, ModInfo.Name, "Predict: window = tomorrow (test)", () => { foreach (var m in Session.Data.Predict.Markets) { m.FromDay = m.ToDay = StoreStation.GetDayCounter() + 1; } Log.Info("测试:所有盘口窗口改成明天"); }); ModHelper.AddDebugFunction(ModInfo.Id, ModInfo.Name, "Predict: window = tomorrow (test)", () => { foreach (var m in Session.Data.Predict.Markets) { m.FromDay = m.ToDay = StoreStation.GetDayCounter() + 1; } Log.Info("测试:所有盘口窗口改成明天"); });
@@ -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
@@ -727,7 +727,7 @@ predict.kind.Cra,CRA warning
predict.kind.Era,ASIC era predict.kind.Era,ASIC era
nightlog.predict.move,"Prediction ""{0}"" moved {1} -> {2}" nightlog.predict.move,"Prediction ""{0}"" moved {1} -> {2}"
nightlog.predict.why, ({0}) nightlog.predict.why, ({0})
chart.empty,PSC daily chart: no history yet; recording from today. chart.empty,{0} daily chart: no history yet; recording from today.
chart.caption,PSC daily ({0} days) H {1} L {2} C {3} ({4}%) chart.caption,{0} daily H {2} L {3} C {4} ({5}%)
chart.legend,"<size=80%>green up, red down; yellow 7-day MA; bars: grey whales / cyan you</size>" chart.legend,"<size=80%>green up, red down; yellow 7-day MA; bars: grey market / cyan you</size>"
chart.legend.thr,"<size=80%>green up, red down; yellow 7-day MA; blue dashes threshold</size>" chart.legend.thr,"<size=80%>green up, red down; yellow 7-day MA; blue dashes threshold</size>"
@@ -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,签收
@@ -726,7 +726,7 @@ predict.kind.Cra,CRA 预警
predict.kind.Era,矿机时代 predict.kind.Era,矿机时代
nightlog.predict.move,预测盘「{0}」价格 {1} → {2} nightlog.predict.move,预测盘「{0}」价格 {1} → {2}
nightlog.predict.why,({0}) nightlog.predict.why,({0})
chart.empty,PSC 日 K:还没有历史,从今天开始记录。 chart.empty,{0} 日 K:还没有历史,从今天开始记录。
chart.caption,PSC 日 K({0} 天) 高 {1} 低 {2} 收 {3}({4}%) chart.caption,{0} 日K 高 {2} 低 {3} 收 {4}({5}%)
chart.legend,<size=80%>绿涨红跌 黄线 7 日均线 柱:灰 大户 / 青 你的成交</size> chart.legend,<size=80%>绿涨红跌 黄线 7 日均线 柱:灰 市场 / 青 你的成交</size>
chart.legend.thr,<size=80%>绿涨红跌 黄线 7 日均线 蓝虚线 阈值</size> chart.legend.thr,<size=80%>绿涨红跌 黄线 7 日均线 蓝虚线 阈值</size>
+3 -3
View File
@@ -55,11 +55,11 @@ namespace Decentralized
var d = Session.Data; var d = Session.Data;
int day = StoreStation.GetDayCounter(); int day = StoreStation.GetDayCounter();
d.Market.Open(ActiveEvents(), d.Rng, day); d.Market.Open(ActiveEvents(), d.Rng, day);
d.Candles.Open(Assets.PSC, day, d.Market.Price); CandleChart.Morning(d, day);
double whale = d.Market.Whale(d.Rng); double whale = d.Market.Whale(d.Rng);
d.Candles.Tick(Assets.PSC, day, d.Market.Price, whale); d.Candles.Tick(Assets.PSC, day, d.Market.Price, whale);
if (day >= Tuning.ScamMinDay) { double wk = d.Market.TryWick(d.Rng, day); if (wk != 0) Log.Info($"插针 {wk:+0.000;-0.000},当晚回去 {d.Market.WickBack:0.00}"); } if (day >= Tuning.ScamMinDay) { double wk = d.Market.TryWick(d.Rng, day); if (wk != 0) Log.Info($"插针 {wk:+0.000;-0.000},当晚回去 {d.Market.WickBack:0.00}"); }
d.Candles.Tick(Assets.PSC, day, d.Market.Price); CandleChart.Touch(d, day, Assets.PSC, Assets.Ponero);
PredictGame.Morning(d, day); PredictGame.Morning(d, day);
if (!d.OpeningNewsShown) if (!d.OpeningNewsShown)
{ {
@@ -190,7 +190,7 @@ namespace Decentralized
// 预测市场:先登记今晚的观测再结算到期的盘口;行情盘读夜间更新之前的价格 // 预测市场:先登记今晚的观测再结算到期的盘口;行情盘读夜间更新之前的价格
double pscMark = d.Market.Mark; double pscMark = d.Market.Mark;
d.Market.UndoWick(day); d.Market.UndoWick(day);
d.Candles.Close(Assets.PSC, day, d.Market.Price); CandleChart.Close(d, day);
PredictGame.ClosePrice = d.Market.Price; PredictGame.CloseGas = d.Gas; PredictGame.ClosePush = d.Market.PlayerPush; PredictGame.ClosePrice = d.Market.Price; PredictGame.CloseGas = d.Gas; PredictGame.ClosePush = d.Market.PlayerPush;
// 永续:用今天的标记价(当日均价)结算,要在今晚的价格更新之前 // 永续:用今天的标记价(当日均价)结算,要在今晚的价格更新之前
var perpEvents = d.Perps.Night(day, new Dictionary<string, double> { ["PSC"] = pscMark, ["SPARK"] = d.Stable.Spark }, d.Poinbase, Session.Price); var perpEvents = d.Perps.Night(day, new Dictionary<string, double> { ["PSC"] = pscMark, ["SPARK"] = d.Stable.Spark }, d.Poinbase, Session.Price);
+11 -4
View File
@@ -246,7 +246,7 @@ namespace Decentralized
if (_poinTab == PoinTab.Perp) { PerpPage(b); return; } if (_poinTab == PoinTab.Perp) { PerpPage(b); return; }
Columns(b, l => Columns(b, l =>
{ {
CandleChart.Add(l, "poin", d.Candles.Of(Assets.PSC)); CandleChart.AddPicker(l, "poin", Assets.PSC, Open);
l.AddSeparator(); l.AddSeparator();
l.AddHeader(L.T("poin.account.h")); l.AddHeader(L.T("poin.account.h"));
Holdings(l, w, a => true); Holdings(l, w, a => true);
@@ -313,7 +313,7 @@ namespace Decentralized
l.AddLabel(L.T("perp.rate", p, Fmt.Num(PerpSpot(p)), (bk.Rate(p) * 100).ToString("+0.00;-0.00;0.00", CultureInfo.InvariantCulture))); l.AddLabel(L.T("perp.rate", p, Fmt.Num(PerpSpot(p)), (bk.Rate(p) * 100).ToString("+0.00;-0.00;0.00", CultureInfo.InvariantCulture)));
l.AddLabel(L.T("perp.fund", Fmt.Credits(bk.InsuranceFund))); l.AddLabel(L.T("perp.fund", Fmt.Credits(bk.InsuranceFund)));
l.AddSeparator(); l.AddSeparator();
CandleChart.Add(l, "perp", d.Candles.Of(Assets.PSC)); CandleChart.Add(l, "perp", _perpProduct);
}, r => }, r =>
{ {
r.AddHeader(L.T("perp.open")); r.AddHeader(L.T("perp.open"));
@@ -613,7 +613,7 @@ namespace Decentralized
l.AddLabel(L.T("predict.acct", WalletWindow.NameOf(w), Fmt.Num(w.Avail(Assets.CRC)))); l.AddLabel(L.T("predict.acct", WalletWindow.NameOf(w), Fmt.Num(w.Avail(Assets.CRC))));
l.AddSeparator(); l.AddSeparator();
// 选中 PSC 价格盘时,在列表上方画日 K 和阈值线 // 选中 PSC 价格盘时,在列表上方画日 K 和阈值线
if (sel != null && sel.Kind == PredictKind.Price) { CandleChart.Add(l, "predict", d.Candles.Of(Assets.PSC), sel.Param); l.AddSeparator(); } if (sel != null && sel.Kind == PredictKind.Price) { CandleChart.Add(l, "predict", Assets.PSC, sel.Param); l.AddSeparator(); }
if (open.Count == 0) l.AddLabel(L.T("predict.none")); if (open.Count == 0) l.AddLabel(L.T("predict.none"));
foreach (var m in open) foreach (var m in open)
{ {
@@ -827,6 +827,7 @@ namespace Decentralized
if (!ReadAmount(out double v)) return; if (!ReadAmount(out double v)) return;
var d = Session.Data; var d = Session.Data;
var res = d.Perps.Open(d.Poinbase, _perpProduct, _perpLong, v, _perpLev, PerpSpot(_perpProduct), StoreStation.GetDayCounter(), Session.Price); var res = d.Perps.Open(d.Poinbase, _perpProduct, _perpLong, v, _perpLev, PerpSpot(_perpProduct), StoreStation.GetDayCounter(), Session.Price);
if (res == PerpResult.Ok) CandleChart.Trade(_perpProduct, v * _perpLev);
_message = res == PerpResult.Ok ? L.T("perp.opened", _perpProduct, L.T(_perpLong ? "perp.long" : "perp.short"), Fmt.Num(v), _perpLev) : PerpErr(res); _message = res == PerpResult.Ok ? L.T("perp.opened", _perpProduct, L.T(_perpLong ? "perp.long" : "perp.short"), Fmt.Num(v), _perpLev) : PerpErr(res);
if (res == PerpResult.Ok) Session.Save(); if (res == PerpResult.Ok) Session.Save();
Open(); Open();
@@ -848,6 +849,7 @@ namespace Decentralized
var pos = d.Perps.Of(_perpProduct); var pos = d.Perps.Of(_perpProduct);
if (pos == null) { _message = PerpErr(PerpResult.NoPosition); Open(); return; } if (pos == null) { _message = PerpErr(PerpResult.NoPosition); Open(); return; }
double margin = pos.Margin; double margin = pos.Margin;
CandleChart.Trade(_perpProduct, pos.Notional(PerpSpot(_perpProduct)));
double paid = d.Perps.Close(d.Poinbase, _perpProduct, PerpSpot(_perpProduct), StoreStation.GetDayCounter(), out double deficit); double paid = d.Perps.Close(d.Poinbase, _perpProduct, PerpSpot(_perpProduct), StoreStation.GetDayCounter(), out double deficit);
// 操纵:平仓盈利,而且盈利方向和玩家自己推价的方向一致,按推价幅度被查:盈利没收,记诈骗罪证,永续账户冻结几天 // 操纵:平仓盈利,而且盈利方向和玩家自己推价的方向一致,按推价幅度被查:盈利没收,记诈骗罪证,永续账户冻结几天
double push = d.Market.PlayerPush, profit = paid - margin; double push = d.Market.PlayerPush, profit = paid - margin;
@@ -1008,6 +1010,8 @@ namespace Decentralized
l.AddLabel(L.T("wallet.total", Fmt.Credits(w.Value(Session.Price)))); l.AddLabel(L.T("wallet.total", Fmt.Credits(w.Value(Session.Price))));
if (w.Taint > 0.5) l.AddLabel(L.T("wallet.taint", Fmt.Credits(w.Taint))); if (w.Taint > 0.5) l.AddLabel(L.T("wallet.taint", Fmt.Credits(w.Taint)));
StableTable(l); StableTable(l);
l.AddSeparator();
CandleChart.AddPicker(l, "web3", Assets.PSC, Open);
}, r => }, r =>
{ {
r.AddHeader(L.T("trade.h")); r.AddHeader(L.T("trade.h"));
@@ -1453,6 +1457,7 @@ namespace Decentralized
int day = StoreStation.GetDayCounter(); int day = StoreStation.GetDayCounter();
double got = _deskIn ? d.Black.ToPonero(pw, _deskAsset, v, day, Session.Price) : d.Black.FromPonero(pw, _deskAsset, v, day, Session.Price); double got = _deskIn ? d.Black.ToPonero(pw, _deskAsset, v, day, Session.Price) : d.Black.FromPonero(pw, _deskAsset, v, day, Session.Price);
if (got < 0) { _message = L.T("black.desk.fail"); Open(); return; } if (got < 0) { _message = L.T("black.desk.fail"); Open(); return; }
{ double cr = v * Session.Price(_deskIn ? _deskAsset : Assets.Ponero); CandleChart.Trade(Assets.Ponero, cr); CandleChart.Trade(_deskAsset, cr); }
// 从 Ponero 出来的币来源不明:出金审查按"来自混币器"加重 // 从 Ponero 出来的币来源不明:出金审查按"来自混币器"加重
if (!_deskIn) d.Mixer.LastReturnDay = day; if (!_deskIn) d.Mixer.LastReturnDay = day;
_message = _deskIn ? L.T("msg.trade", Fmt.Num(v), _deskAsset, Fmt.Num(got), Assets.Ponero) : L.T("msg.trade", Fmt.Num(v), Assets.Ponero, Fmt.Num(got), _deskAsset); _message = _deskIn ? L.T("msg.trade", Fmt.Num(v), _deskAsset, Fmt.Num(got), Assets.Ponero) : L.T("msg.trade", Fmt.Num(v), Assets.Ponero, Fmt.Num(got), _deskAsset);
@@ -1622,6 +1627,7 @@ namespace Decentralized
Execute = pw => Execute = pw =>
{ {
double got = mint ? d.Stable.Mint(pw, v) : d.Stable.Burn(pw, v); double got = mint ? d.Stable.Mint(pw, v) : d.Stable.Burn(pw, v);
if (got >= 0) { double cr = v * Session.Price(pay); CandleChart.Trade(Assets.SPARK, cr); CandleChart.Trade(Assets.CRA, cr); }
_message = got < 0 ? L.T("msg.balance") : L.T("msg.trade", Fmt.Num(v), pay, Fmt.Num(got), get); _message = got < 0 ? L.T("msg.balance") : L.T("msg.trade", Fmt.Num(v), pay, Fmt.Num(got), get);
Session.Save(); Session.Save();
Open(); Open();
@@ -1713,8 +1719,9 @@ namespace Decentralized
if (w.Avail(pay) + 1e-9 < v) { _message = L.T(frozenPay(w, pay) ? "msg.frozen" : "msg.balance"); Open(); return; } if (w.Avail(pay) + 1e-9 < v) { _message = L.T(frozenPay(w, pay) ? "msg.frozen" : "msg.balance"); Open(); return; }
double before = p.Price; double before = p.Price;
double got = buy ? p.BuyBase(v) : p.SellBase(v); double got = buy ? p.BuyBase(v) : p.SellBase(v);
if (p == Session.Data.Market.Main) { Session.Data.Market.PlayerPush += Math.Log(p.Price / before); Session.Data.Candles.Tick(Assets.PSC, StoreStation.GetDayCounter(), p.Price, v * Session.Price(pay), true); Log.Info($"现货推价:累计 {Session.Data.Market.PlayerPush:0.000}"); } if (p == Session.Data.Market.Main) { Session.Data.Market.PlayerPush += Math.Log(p.Price / before); Log.Info($"现货推价:累计 {Session.Data.Market.PlayerPush:0.000}"); }
double spent = v * Session.Price(pay); double spent = v * Session.Price(pay);
CandleChart.Trade(pay, spent); CandleChart.Trade(get, spent);
w.Add(pay, -v); w.Add(pay, -v);
w.Add(get, got); w.Add(get, got);
w.RecordBuy(get, got, spent); w.RecordBuy(get, got, spent);