19 using System.Threading.Tasks;
21 using System.Collections.Generic;
22 using System.Globalization;
36 private string _ticker;
37 private bool _scheduledCleanup;
38 private Dictionary<DateTime, ShortableData> _shortableDataPerDate;
62 if (symbol !=
null && GetCacheData(symbol).TryGetValue(localTime.Date, out var result))
64 return result.FeeRate;
79 if (symbol !=
null && GetCacheData(symbol).TryGetValue(localTime.Date, out var result))
81 return result.RebateFee;
95 if (symbol !=
null && GetCacheData(symbol).TryGetValue(localTime.Date, out var result))
97 return result.ShortableQuantity;
107 private Dictionary<DateTime, ShortableData> GetCacheData(
Symbol symbol)
109 var result = _shortableDataPerDate;
110 if (_ticker == symbol.
Value)
115 if (!_scheduledCleanup)
118 _scheduledCleanup =
true;
123 _ticker = symbol.
Value;
124 result = _shortableDataPerDate =
new();
128 "shortable",
Brokerage,
"symbols", $
"{_ticker.ToLowerInvariant()}.csv");
130 foreach (var line
in DataProvider.ReadLines(shortableSymbolFile))
132 if (
string.IsNullOrEmpty(line) || line.StartsWith(
"#"))
139 var csv = line.Split(
',');
140 var date = Parse.DateTimeExact(csv[0],
"yyyyMMdd");
141 var lenght = csv.Length;
142 var shortableQuantity = csv[1].IfNotNullOrEmpty(s =>
long.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture));
143 var rebateRate = csv.Length > 2 ? csv[2].IfNotNullOrEmpty(s => decimal.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture)) : 0;
144 var feeRate = csv.Length > 3 ? csv[3].IfNotNullOrEmpty(s => decimal.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture)) : 0;
145 result[date] =
new ShortableData(shortableQuantity, rebateRate / 100, feeRate / 100);
154 private void ClearCache()
156 var now = DateTime.UtcNow;
157 var tomorrowMidnight = now.Date.AddDays(1);
158 var delayToClean = tomorrowMidnight - now;
160 Task.Delay(delayToClean).ContinueWith((_) =>
164 _shortableDataPerDate =
new();