Aggiunta Bootstrap 5.3.3 (CSS, JS, RTL, mappe) al progetto
Sono stati aggiunti tutti i file principali di Bootstrap 5.3.3, inclusi CSS, JavaScript (bundle, ESM, UMD, minificati), versioni RTL, utility, reboot, griglia e relative mappe delle sorgenti. Questi file abilitano un sistema di design moderno, responsive e accessibile, con supporto per layout LTR e RTL, debugging avanzato tramite source map e tutte le funzionalità di Bootstrap per lo sviluppo dell’interfaccia utente. Nessuna modifica ai file esistenti.
This commit is contained in:
209
TradingBot/Services/SimulatedMarketDataService.cs
Normal file
209
TradingBot/Services/SimulatedMarketDataService.cs
Normal file
@@ -0,0 +1,209 @@
|
||||
using TradingBot.Models;
|
||||
|
||||
namespace TradingBot.Services;
|
||||
|
||||
public class SimulatedMarketDataService : IMarketDataService
|
||||
{
|
||||
private readonly Dictionary<string, SimulatedAsset> _assets = new();
|
||||
private readonly Random _random = new();
|
||||
private readonly Timer _updateTimer;
|
||||
private readonly object _lock = new();
|
||||
|
||||
public event Action? OnPriceUpdated;
|
||||
|
||||
public SimulatedMarketDataService()
|
||||
{
|
||||
InitializeAssets();
|
||||
_updateTimer = new Timer(UpdatePrices, null, TimeSpan.Zero, TimeSpan.FromSeconds(2));
|
||||
}
|
||||
|
||||
private void InitializeAssets()
|
||||
{
|
||||
var assets = new[]
|
||||
{
|
||||
new { Symbol = "BTC", Name = "Bitcoin", BasePrice = 45000m, Volatility = 0.02m, TrendBias = 0.0002m },
|
||||
new { Symbol = "ETH", Name = "Ethereum", BasePrice = 2500m, Volatility = 0.025m, TrendBias = 0.0003m },
|
||||
new { Symbol = "BNB", Name = "Binance Coin", BasePrice = 350m, Volatility = 0.03m, TrendBias = 0.0001m },
|
||||
new { Symbol = "SOL", Name = "Solana", BasePrice = 100m, Volatility = 0.035m, TrendBias = 0.0004m },
|
||||
new { Symbol = "ADA", Name = "Cardano", BasePrice = 0.45m, Volatility = 0.028m, TrendBias = 0.0002m },
|
||||
new { Symbol = "XRP", Name = "Ripple", BasePrice = 0.65m, Volatility = 0.032m, TrendBias = 0.0001m },
|
||||
new { Symbol = "DOT", Name = "Polkadot", BasePrice = 6.5m, Volatility = 0.03m, TrendBias = 0.0003m },
|
||||
new { Symbol = "AVAX", Name = "Avalanche", BasePrice = 35m, Volatility = 0.038m, TrendBias = 0.0005m },
|
||||
new { Symbol = "MATIC", Name = "Polygon", BasePrice = 0.85m, Volatility = 0.033m, TrendBias = 0.0002m },
|
||||
new { Symbol = "LINK", Name = "Chainlink", BasePrice = 15m, Volatility = 0.029m, TrendBias = 0.0003m },
|
||||
new { Symbol = "UNI", Name = "Uniswap", BasePrice = 6.5m, Volatility = 0.031m, TrendBias = 0.0001m },
|
||||
new { Symbol = "ATOM", Name = "Cosmos", BasePrice = 10m, Volatility = 0.03m, TrendBias = 0.0004m },
|
||||
new { Symbol = "LTC", Name = "Litecoin", BasePrice = 75m, Volatility = 0.025m, TrendBias = 0.0001m },
|
||||
new { Symbol = "ALGO", Name = "Algorand", BasePrice = 0.25m, Volatility = 0.032m, TrendBias = 0.0003m },
|
||||
new { Symbol = "VET", Name = "VeChain", BasePrice = 0.03m, Volatility = 0.035m, TrendBias = 0.0002m }
|
||||
};
|
||||
|
||||
foreach (var asset in assets)
|
||||
{
|
||||
_assets[asset.Symbol] = new SimulatedAsset
|
||||
{
|
||||
Symbol = asset.Symbol,
|
||||
Name = asset.Name,
|
||||
CurrentPrice = asset.BasePrice,
|
||||
BasePrice = asset.BasePrice,
|
||||
Volatility = asset.Volatility,
|
||||
TrendBias = asset.TrendBias,
|
||||
LastUpdate = DateTime.UtcNow
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdatePrices(object? state)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
foreach (var asset in _assets.Values)
|
||||
{
|
||||
// Calculate time-based factors
|
||||
var timeSinceStart = (now - asset.LastUpdate).TotalSeconds;
|
||||
|
||||
// Generate random walk with trend
|
||||
var randomChange = (_random.NextDouble() - 0.5) * 2 * (double)asset.Volatility;
|
||||
var trendComponent = (double)asset.TrendBias;
|
||||
|
||||
// Add market cycles (sine wave for realistic market behavior)
|
||||
var cycleComponent = Math.Sin((double)asset.PriceUpdateCount / 100.0) * 0.001;
|
||||
|
||||
// Combine all factors
|
||||
var totalChange = randomChange + trendComponent + cycleComponent;
|
||||
|
||||
// Update price
|
||||
var newPrice = asset.CurrentPrice * (1 + (decimal)totalChange);
|
||||
|
||||
// Keep price within reasonable bounds (50% to 200% of base price)
|
||||
newPrice = Math.Max(asset.BasePrice * 0.5m, Math.Min(asset.BasePrice * 2.0m, newPrice));
|
||||
|
||||
// Calculate change and volume
|
||||
var priceChange = newPrice - asset.CurrentPrice;
|
||||
var changePercentage = asset.CurrentPrice > 0 ? (priceChange / asset.CurrentPrice) * 100 : 0;
|
||||
|
||||
// Simulate volume based on volatility and price change
|
||||
var baseVolume = asset.BasePrice * 1000000m;
|
||||
var volumeVariation = (decimal)(_random.NextDouble() * 0.5 + 0.75); // 75% to 125%
|
||||
var volumeFromVolatility = Math.Abs(changePercentage) * 100000m;
|
||||
|
||||
asset.CurrentPrice = newPrice;
|
||||
asset.Change24h = changePercentage;
|
||||
asset.Volume24h = (baseVolume + volumeFromVolatility) * volumeVariation;
|
||||
asset.LastUpdate = now;
|
||||
asset.PriceUpdateCount++;
|
||||
|
||||
// Add to history
|
||||
asset.PriceHistory.Add(new MarketPrice
|
||||
{
|
||||
Symbol = asset.Symbol,
|
||||
Price = newPrice,
|
||||
Change24h = changePercentage,
|
||||
Volume24h = asset.Volume24h,
|
||||
Timestamp = now
|
||||
});
|
||||
|
||||
// Keep history limited to last 500 points
|
||||
if (asset.PriceHistory.Count > 500)
|
||||
{
|
||||
asset.PriceHistory.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
OnPriceUpdated?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public Task<List<MarketPrice>> GetMarketPricesAsync(List<string> symbols)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
var prices = new List<MarketPrice>();
|
||||
|
||||
foreach (var symbol in symbols)
|
||||
{
|
||||
if (_assets.TryGetValue(symbol, out var asset))
|
||||
{
|
||||
prices.Add(new MarketPrice
|
||||
{
|
||||
Symbol = asset.Symbol,
|
||||
Price = asset.CurrentPrice,
|
||||
Change24h = asset.Change24h,
|
||||
Volume24h = asset.Volume24h,
|
||||
Timestamp = asset.LastUpdate
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return Task.FromResult(prices);
|
||||
}
|
||||
}
|
||||
|
||||
public Task<MarketPrice?> GetPriceAsync(string symbol)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (_assets.TryGetValue(symbol, out var asset))
|
||||
{
|
||||
return Task.FromResult<MarketPrice?>(new MarketPrice
|
||||
{
|
||||
Symbol = asset.Symbol,
|
||||
Price = asset.CurrentPrice,
|
||||
Change24h = asset.Change24h,
|
||||
Volume24h = asset.Volume24h,
|
||||
Timestamp = asset.LastUpdate
|
||||
});
|
||||
}
|
||||
|
||||
return Task.FromResult<MarketPrice?>(null);
|
||||
}
|
||||
}
|
||||
|
||||
public List<MarketPrice> GetPriceHistory(string symbol, int count = 100)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (_assets.TryGetValue(symbol, out var asset))
|
||||
{
|
||||
return asset.PriceHistory
|
||||
.Skip(Math.Max(0, asset.PriceHistory.Count - count))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
return new List<MarketPrice>();
|
||||
}
|
||||
}
|
||||
|
||||
public List<string> GetAvailableSymbols()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _assets.Keys.OrderBy(s => s).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<string, string> GetAssetNames()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _assets.ToDictionary(a => a.Key, a => a.Value.Name);
|
||||
}
|
||||
}
|
||||
|
||||
private class SimulatedAsset
|
||||
{
|
||||
public string Symbol { get; set; } = string.Empty;
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public decimal CurrentPrice { get; set; }
|
||||
public decimal BasePrice { get; set; }
|
||||
public decimal Change24h { get; set; }
|
||||
public decimal Volume24h { get; set; }
|
||||
public decimal Volatility { get; set; }
|
||||
public decimal TrendBias { get; set; }
|
||||
public DateTime LastUpdate { get; set; }
|
||||
public int PriceUpdateCount { get; set; }
|
||||
public List<MarketPrice> PriceHistory { get; set; } = new();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user