Files
PineSript/Simulator/Services/SimState.cs

90 lines
3.3 KiB
C#
Raw Normal View History

2026-04-27 17:45:32 +09:00
namespace Simulator.Services
{
/// <summary>
/// 시뮬레이션 인메모리 상태.
/// 잔고, 포지션, 거래 내역을 관리합니다.
/// </summary>
public class SimState
{
private int _nextOrderId = 1000;
public double Balance { get; set; }
public SimPosition? LongPosition { get; set; }
public SimPosition? ShortPosition { get; set; }
public List<SimTrade> TradeHistory { get; } = new();
public SimState(double initialBalance)
{
Balance = initialBalance;
}
public string NextOrderId() => $"SIM{_nextOrderId++:D6}";
/// <summary>모든 포지션을 Bitget all-position 응답 형식 목록으로 반환합니다.</summary>
public List<object> GetAllPositions(string symbol, string productType, double currentPrice)
{
var result = new List<object>();
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; }
}
}