getHistoricalData method
Fetches historical OHLCV bars for the specified symbol and timeframe.
Optionally pass before to fetch candles older than that timestamp (for pagination).
Implementation
@override
Future<List<Candle>> getHistoricalData({
required String symbol,
required Timeframe timeframe,
int count = 500,
DateTime? before,
}) async {
final candles = <Candle>[];
final symbolBasePrice = defaultPrices[symbol] ?? initialPrice;
initialPrice = symbolBasePrice;
// If 'before' is provided, start from there; otherwise align from now
final anchor = before != null
? timeframe.alignTimestamp(before)
: timeframe.alignTimestamp(DateTime.now());
// Generate 'count' candles backwards from anchor
var price = symbolBasePrice;
final tempList = <Candle>[];
var currentTimestamp = anchor.subtract(timeframe.duration * count);
for (int i = 0; i < count; i++) {
final drift = 0.00005;
final shock = (_random.nextDouble() - 0.49) * 2.0;
final deltaPercent = drift + (volatility * shock);
final open = price;
final close = price * (1.0 + deltaPercent);
final maxOC = math.max(open, close);
final minOC = math.min(open, close);
final highExtension = (_random.nextDouble() * volatility * 1.2) * price;
final lowExtension = (_random.nextDouble() * volatility * 1.2) * price;
final high = maxOC + highExtension;
final low = math.max(0.01, minOC - lowExtension);
final isSpike = _random.nextDouble() < 0.08;
final baseVolume = 1500.0 + (_random.nextDouble() * 4000.0);
final volume = isSpike ? baseVolume * 3.5 : baseVolume;
tempList.add(Candle(
timestamp: currentTimestamp,
open: double.parse(open.toStringAsFixed(2)),
high: double.parse(high.toStringAsFixed(2)),
low: double.parse(low.toStringAsFixed(2)),
close: double.parse(close.toStringAsFixed(2)),
volume: double.parse(volume.toStringAsFixed(0)),
));
price = close;
currentTimestamp = currentTimestamp.add(timeframe.duration);
}
if (before == null) _currentPrice = price;
candles.addAll(tempList);
return candles;
}