namespace Simulator.Services { /// /// 시뮬레이션 인메모리 상태. /// 잔고, 포지션, 거래 내역을 관리합니다. /// public class SimState { private int _nextOrderId = 1000; public double Balance { get; set; } public SimPosition? LongPosition { get; set; } public SimPosition? ShortPosition { get; set; } public List TradeHistory { get; } = new(); public SimState(double initialBalance) { Balance = initialBalance; } public string NextOrderId() => $"SIM{_nextOrderId++:D6}"; /// 모든 포지션을 Bitget all-position 응답 형식 목록으로 반환합니다. public List GetAllPositions(string symbol, string productType, double currentPrice) { var result = new List(); if (LongPosition != null) result.Add(BuildPositionObject(LongPosition, symbol, productType, currentPrice)); if (ShortPosition != null) result.Add(BuildPositionObject(ShortPosition, symbol, productType, currentPrice)); return result; } private static object BuildPositionObject( SimPosition pos, string symbol, string productType, double currentPrice) { double unrealized = pos.Side == "long" ? (currentPrice - pos.AvgPrice) * pos.Size : (pos.AvgPrice - currentPrice) * pos.Size; return new { symbol = symbol, productType = productType, marginMode = "crossed", holdSide = pos.Side, openDelegateSize = pos.Size.ToString("F4"), margin = "0", available = pos.Size.ToString("F4"), locked = "0", total = pos.Size.ToString("F4"), leverage = pos.Leverage.ToString(), achievedProfits = "0", openPriceAvg = pos.AvgPrice.ToString("F6"), posMode = "hedge_mode", unrealizedPL = unrealized.ToString("F4"), liquidationPrice = "0", keepMarginRate = "0.004", markPrice = currentPrice.ToString("F6"), marginRatio = "0", cTime = pos.OpenTime.ToUnixTimeMilliseconds().ToString(), uTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString(), }; } } public class SimPosition { public string Side { get; set; } = ""; // "long" | "short" public double Size { get; set; } public double AvgPrice { get; set; } public double Leverage { get; set; } = 10; public DateTimeOffset OpenTime { get; set; } = DateTimeOffset.UtcNow; } public class SimTrade { public DateTimeOffset Time { get; set; } public string Side { get; set; } = ""; public string Action { get; set; } = ""; public double Size { get; set; } public double Price { get; set; } public double Pnl { get; set; } } }