public async Task TryGetCachedResponse() { const int count = 15; // Clear cache var cache = Factory.Services.GetRequiredService <Wivuu.GlobalCache.IGlobalCache>(); await cache.InvalidateAsync(CacheId.ForCategory("weather")); using var client = Factory.CreateClient(); for (var tries = 0; tries < 3; ++tries) { var resp = await client.GetAsync($"weather/us?days={count}"); if (client.DefaultRequestHeaders.TryGetValues("If-None-Match", out _)) { // Expect the response to be empty and not modified Assert.Equal(304, (int)resp.StatusCode); } else { var respBody = await resp.Content.ReadAsStringAsync(); var data = JsonConvert.DeserializeAnonymousType(respBody, new [] { new { Date = default(DateTimeOffset), TemperatureC = default(decimal) } }); Assert.NotNull(data); Assert.Equal(count, data.Length); Assert.NotEqual(default, data[0].Date);
/// <summary> /// Calculate Pearson Correlation Coefficient. /// <see href="https://en.wikipedia.org/wiki/Pearson_correlation_coefficient"/> /// </summary> /// <param name="series">this time series</param> /// <param name="other">other time series</param> /// <param name="n">number of bars</param> /// <param name="subSample">distance between bars</param> /// <param name="parentId">caller cache id, optional</param> /// <param name="memberName">caller's member name, optional</param> /// <param name="lineNumber">caller line number, optional</param> /// <returns>correlation coefficient time series</returns> public static ITimeSeries <double> Correlation(this ITimeSeries <double> series, ITimeSeries <double> other, int n, int subSample = 1, CacheId parentId = null, [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0) { var cacheId = new CacheId(parentId, memberName, lineNumber, series.GetHashCode(), other.GetHashCode(), n); var x = series; var y = other; double sum = n / 2.0 * (n + 1.0); return(IndicatorsBasic.BufferedLambda( (v) => { var avgX = Enumerable.Range(0, n) .Average(t => x[t * subSample]); var avgY = Enumerable.Range(0, n) .Average(t => y[t * subSample]); var covXY = Enumerable.Range(0, n) .Sum(t => (x[t * subSample] - avgX) * (y[t * subSample] - avgY)) / n; var varX = Enumerable.Range(0, n) .Sum(t => Math.Pow(x[t * subSample] - avgX, 2.0)) / n; var varY = Enumerable.Range(0, n) .Sum(t => Math.Pow(y[t * subSample] - avgY, 2.0)) / n; var corr = covXY / Math.Max(1e-99, Math.Sqrt(varX) * Math.Sqrt(varY)); return corr; }, 0.0, cacheId)); }
/// <summary> /// Create time series based on lambda, with lambda being executed once for /// every call to the indexer method. Use this for leight-weight lambdas. /// </summary> /// <param name="lambda">lambda, taking bars back as parameter and returning time series value</param> /// <param name="parentId">cache id used to identify functor</param> /// <param name="memberName">caller's member name, optional</param> /// <param name="lineNumber">caller line number, optional</param> /// <returns>lambda time series</returns> public static ITimeSeries <double> Lambda(Func <int, double> lambda, CacheId parentId = null, [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0) { // NOTE: // this can be instantiated without parent cache id. As we don't have any data series // to go from, this will blow up when running multiple instances in the optimizer // a possible idea to fix this, would be to add the thread id... food for thought. #if false // CAUTION: // lambda.GetHashCode() might not work w/ .Net Core // there are alternatives, see here: // https://stackoverflow.com/questions/283537/most-efficient-way-to-test-equality-of-lambda-expressions // however, we might not need to hash the lambda, as it is reasonably safe to assume // that for a different lambda, the call stack would also be different var cacheId = new CacheId(parentId, memberName, lineNumber, lambda.GetHashCode()); #else var cacheId = new CacheId(parentId, memberName, lineNumber); #endif var functor = Cache <FunctorLambda> .GetData( cacheId, () => new FunctorLambda(lambda)); return(functor); }
/// <summary> /// Calculate Covariance. /// <see href="https://en.wikipedia.org/wiki/Covariance"/> /// </summary> /// <param name="series">this time series</param> /// <param name="other">other time series</param> /// <param name="n">number of bars</param> /// <param name="subSample">distance between bars</param> /// <param name="parentId">caller cache id, optional</param> /// <param name="memberName">caller's member name, optional</param> /// <param name="lineNumber">caller line number, optional</param> /// <returns>covariance time series</returns> public static ITimeSeries <double> Covariance(this ITimeSeries <double> series, ITimeSeries <double> other, int n, int subSample = 1, CacheId parentId = null, [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0) { var cacheId = new CacheId(parentId, memberName, lineNumber, series.GetHashCode(), other.GetHashCode(), n); var x = series; var y = other; return(IndicatorsBasic.BufferedLambda( (v) => { var avgX = Enumerable.Range(0, n) .Average(t => x[t * subSample]); var avgY = Enumerable.Range(0, n) .Average(t => y[t * subSample]); var covXY = Enumerable.Range(0, n) .Sum(t => (x[t * subSample] - avgX) * (y[t * subSample] - avgY)) / (n - 1.0); return covXY; }, 0.0, cacheId)); }
/// <summary> /// Calculate Kaufman's Adaptive Moving Average, as described here: /// <see href="https://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:kaufman_s_adaptive_moving_average"/> /// </summary> /// <param name="series">input time series</param> /// <param name="erPeriod">period for efficiency ratio</param> /// <param name="fastEma">period for fast EMA</param> /// <param name="slowEma">period for slow EMA</param> /// <param name="parentId">caller cache id, optional</param> /// <param name="memberName">caller's member name, optional</param> /// <param name="lineNumber">caller line number, optional</param> /// <returns>KAMA as time series</returns> public static ITimeSeries <double> KAMA(this ITimeSeries <double> series, int erPeriod = 10, int fastEma = 2, int slowEma = 30, CacheId parentId = null, [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0) { var cacheId = new CacheId(parentId, memberName, lineNumber, series.GetHashCode(), erPeriod, fastEma, slowEma); // TODO: we should be able to remove the try/ catch blocks here return(IndicatorsBasic.BufferedLambda( (v) => { try { double scFast = 2.0 / (1.0 + fastEma); double scSlow = 2.0 / (1.0 + slowEma); double change = Math.Abs(series[0] - series[erPeriod]); double volatility = Enumerable.Range(0, erPeriod) .Sum(t => Math.Abs(series[t] - series[t + 1])); double efficiencyRatio = change / Math.Max(1e-10, volatility); double smoothingConstant = Math.Pow(efficiencyRatio * (scFast - scSlow) + scSlow, 2); double r = smoothingConstant * (series[0] - v) + v; return double.IsNaN(r) ? 0.0 : r; } catch (Exception) { // we get here when we access bars too far in the past return series[0]; } }, series[0], cacheId)); }
/// <nodoc /> public MemCache(CacheId cacheId, bool strictMetadataCasCoupling, bool isauthoritative) { m_cacheGuid = CacheDeterminism.NewCacheGuid(); m_cacheId = cacheId; IsAuthoritative = isauthoritative; m_strictMetadataCasCoupling = strictMetadataCasCoupling; }
/// <summary> /// Calculate Stochastic Oscillator, as described here: /// <see href="https://en.wikipedia.org/wiki/Stochastic_oscillator"/> /// </summary> /// <param name="series">input time series</param> /// <param name="n">oscillator period</param> /// <param name="parentId">caller cache id, optional</param> /// <param name="memberName">caller's member name, optional</param> /// <param name="lineNumber">caller line number, optional</param> /// <returns>Stochastic Oscillator as time series</returns> public static _StochasticOscillator StochasticOscillator(this ITimeSeries <double> series, int n = 14, CacheId parentId = null, [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0) { var cacheId = new CacheId(parentId, memberName, lineNumber, series.GetHashCode(), n); var container = Cache <_StochasticOscillator> .GetData( cacheId, () => new _StochasticOscillator()); double hh = series .Highest(n, cacheId)[0]; double ll = series .Lowest(n, cacheId)[0]; double price = series[0]; container.PercentK = IndicatorsBasic.BufferedLambda( v => 100.0 * (price - ll) / Math.Max(1e-10, hh - ll), 50.0, cacheId); container.PercentD = container.PercentK .SMA(3, cacheId); return(container); }
/// <summary> /// Calculate Money Flow Index indicator /// <see href="https://en.wikipedia.org/wiki/Money_flow_index"/> /// </summary> /// <param name="series">input time series</param> /// <param name="n">calculation period</param> /// <param name="parentId">caller cache id, optional</param> /// <param name="memberName">caller's member name, optional</param> /// <param name="lineNumber">caller line number, optional</param> /// <returns>MFI time series</returns> public static ITimeSeries <double> MoneyFlowIndex(this Instrument series, int n, CacheId parentId = null, [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0) { var cacheId = new CacheId(parentId, memberName, lineNumber, series.GetHashCode(), n); var typicalPrice = series.TypicalPrice(); var postiveMoneyFlow = IndicatorsBasic.BufferedLambda( prev => typicalPrice[0] > typicalPrice[1] ? typicalPrice[0] * series.Volume[0] : 0.0, 0.0, cacheId); var negativeMoneyFlow = IndicatorsBasic.BufferedLambda( prev => typicalPrice[0] < typicalPrice[1] ? typicalPrice[0] * series.Volume[0] : 0.0, 0.0, cacheId); return(postiveMoneyFlow .SMA(n, cacheId) .Divide( postiveMoneyFlow .SMA(n, cacheId) .Add( negativeMoneyFlow .SMA(n, cacheId), cacheId), cacheId) .Multiply(100.0, cacheId)); }
private async Task <Option <AfkCacheItem> > GetUserAfkThroughCache(ulong userId) { // This user was checked and didnt have AFK so we return that. This is to stop the DB being queried for // every single mention that didnt have an AFK set. if (_cacheService.Contains(CacheId.GetAfkCheckId(userId))) { return(Option.None <AfkCacheItem>()); } bool inCache = true; var cached = await _cacheService.TryGetOrSetAndGetAsync <Data.Models.SoraDb.Afk>( CacheId.GetAfkId(userId), async() => { var afk = await _afkRepo.GetUserAfk(userId).ConfigureAwait(false); inCache = false; return(!afk ? null : afk.Some()); }, AfkTtl); if (!cached) { // TODO this is not clean at all and pretty bad practice. I just can't be bothered rn to write some form of hasmap to store the checks since i would need to make this singleton. _cacheService.Set(CacheId.GetAfkCheckId(userId), new object(), AfkTtl); return(Option.None <AfkCacheItem>()); } return(new Option <AfkCacheItem>(new AfkCacheItem(cached.Some(), inCache))); }
public object Clone() { CachePortsConfigParameters config = new CachePortsConfigParameters(); config.CacheId = CacheId != null ? (string)CacheId.Clone() : null; config.MangementPort = this.MangementPort; return(config); }
private async Task RemoveOldAndSetNewMessage(IUserMessage msg, LavaPlayer player) { string msgId = CacheId.MusicCacheMessage(player.VoiceChannel.GuildId); var oldMsg = _cache.Get <IUserMessage>(msgId); await oldMsg.MatchSome(async message => await message.DeleteAsync()); _cache.Set(CacheId.MusicCacheMessage(player.VoiceChannel.GuildId), msg, TimeSpan.FromMinutes(_MSG_CACHE_TTL_MINS)); }
/// <summary> /// Normalize time series over number of bars; 1.0 being the average. /// </summary> /// <param name="series">input time series</param> /// <param name="n">normalizing period</param> /// <param name="parentId">caller cache id, optional</param> /// <param name="memberName">caller's member name, optional</param> /// <param name="lineNumber">caller line number, optional</param> /// <returns>normalized time series</returns> public static ITimeSeries <double> Normalize(this ITimeSeries <double> series, int n, CacheId parentId = null, [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0) { var cacheId = new CacheId(parentId, memberName, lineNumber, series.GetHashCode(), n); return(series.Divide(series.EMA(n, cacheId), cacheId)); }
private void AddOrUpdateRateLimit(ulong messageId, ulong userId) { _cache.AddOrUpdate(CacheId.StarboardUserMessageReactCountId(messageId, userId), new CacheItem(1, _userRatelimitTtl), (id, item) => { int amount = (int)item.Content; return(new CacheItem(amount + 1, _userRatelimitTtl)); // Let's refresh the TTL on update }); }
private async Task <Option <IUserMessage> > GetStarboardMessage(ulong messageId, ITextChannel starboardChannel) { return(await _cache.TryGetOrSetAndGetAsync( CacheId.GetMessageId(messageId), async() => await starboardChannel.GetMessageAsync(messageId, CacheMode.AllowDownload) .ConfigureAwait(false) as IUserMessage, _postedMsgTtl).ConfigureAwait(false)); }
private Task OnMessageDeleted(Cacheable <IMessage, ulong> message, ISocketMessageChannel channel) { // There's no need to dispatch an event yet internally so no need for async state machines // and threading. That's just overhead we dont need atm for just cleaning some caches. _cacheService.TryRemove(message.Id); _cacheService.TryRemove(CacheId.StarboardDoNotPostId(message.Id)); return(Task.CompletedTask); }
public void InexistentCachedRecovery() { using (CacheHandler cacheHandler = new CacheHandler(100, new TimeSpan(1, 0, 0))) { CacheId cacheId = new CacheId("prefix"); Assert.Null(cacheHandler.Get <string>(cacheId)); } }
public async Task TestGeneralCaching(Type serializerType, Type storageProviderType) { IServiceProvider services; { var collection = new ServiceCollection(); collection.AddWivuuGlobalCache(settings => { settings.RetryTimeout = TimeSpan.FromSeconds(5); if (!(Activator.CreateInstance(serializerType) is ISerializationProvider serializer)) { throw new Exception($"{serializerType} is not a serialization provider"); } settings.SerializationProvider = serializer; switch (storageProviderType.Name) { case nameof(BlobStorageProvider): var blobServiceClient = new BlobServiceClient("UseDevelopmentStorage=true"); var container = blobServiceClient.GetBlobContainerClient("globalcache"); container.CreateIfNotExists(); settings.StorageProvider = new BlobStorageProvider(container); break; case nameof(FileStorageProvider): settings.StorageProvider = new FileStorageProvider(); break; default: throw new NotSupportedException($"{nameof(storageProviderType)} is not supported"); } }); services = collection.BuildServiceProvider(); } using (var scope = services.CreateScope()) { var cache = scope.ServiceProvider.GetRequiredService <IGlobalCache>(); // Remove item await cache.InvalidateAsync(CacheId.ForCategory("cachetest")); // Get or create item var item = await cache.GetOrCreateAsync(new CacheId("cachetest", "item5"), () => { return(Task.FromResult(new { Item = 5 })); }); Assert.Equal(5, item.Item); } }
/// <summary> /// Calculate logarithmic return from the previous to the current value /// of the time series. /// </summary> /// <param name="series">input time series</param> /// <param name="parentId">caller cache id, optional</param> /// <param name="memberName">caller's member name, optional</param> /// <param name="lineNumber">caller line number, optional</param> /// <returns>logarithm of relative return</returns> public static ITimeSeries <double> LogReturn(this ITimeSeries <double> series, CacheId parentId = null, [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0) { var cacheId = new CacheId(parentId, memberName, lineNumber, series.GetHashCode()); return(Lambda( (t) => Math.Log(series[t] / series[t + 1]), cacheId)); }
/// <summary> /// Calculate logarithmic regression of time series. /// </summary> /// <param name="series">input time series</param> /// <param name="n">number of bars for regression</param> /// <param name="parentId">caller cache id, optional</param> /// <param name="memberName">caller's member name, optional</param> /// <param name="lineNumber">caller line number, optional</param> /// <returns>regression parameters as time series</returns> public static _Regression LogRegression(this ITimeSeries <double> series, int n, CacheId parentId = null, [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0) { var cacheId = new CacheId(parentId, memberName, lineNumber, series.GetHashCode(), n); return(series .Log(cacheId) .LinRegression(n, cacheId)); }
/// <summary> /// Calculate Typical Price as described here: /// <see href="https://en.wikipedia.org/wiki/Typical_price"/> /// </summary> /// <param name="series">input instrument</param> /// <param name="parentId">caller cache id, optional</param> /// <param name="memberName">caller's member name, optional</param> /// <param name="lineNumber">caller line number, optional</param> /// <returns>typical price as time series</returns> public static ITimeSeries <double> TypicalPrice(this Instrument series, CacheId parentId = null, [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0) { var cacheId = new CacheId(parentId, memberName, lineNumber, series.GetHashCode()); return(IndicatorsBasic.Lambda( (t) => (series.High[t] + series.Low[t] + series.Close[t]) / 3.0, cacheId)); }
/// <summary> /// Calculate addition of time series and constant value. /// </summary> /// <param name="series">time series</param> /// <param name="constValue">constant value</param> /// <param name="parentId">caller cache id, optional</param> /// <param name="memberName">caller's member name, optional</param> /// <param name="lineNumber">caller line number, optional</param> /// <returns>time series + constant value</returns> public static ITimeSeries <double> Add(this ITimeSeries <double> series, double constValue, CacheId parentId = null, [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0) { var cacheId = new CacheId(parentId, memberName, lineNumber, series.GetHashCode(), constValue.GetHashCode()); return(IndicatorsBasic.Lambda( (t) => series[t] + constValue, cacheId)); }
/// <summary> /// Calculate subtraction of two time series. /// </summary> /// <param name="series1">time series #1</param> /// <param name="parentId">caller cache id, optional</param> /// <param name="memberName">caller's member name, optional</param> /// <param name="lineNumber">caller line number, optional</param> /// <param name="series2">time series #2</param> /// <returns>time series #1 - time series #2</returns> public static ITimeSeries <double> Subtract(this ITimeSeries <double> series1, ITimeSeries <double> series2, CacheId parentId = null, [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0) { var cacheId = new CacheId(parentId, memberName, lineNumber, series1.GetHashCode(), series2.GetHashCode()); return(IndicatorsBasic.Lambda( (t) => series1[t] - series2[t], cacheId)); }
/// <summary> /// .ctor /// </summary> /// <param name="cacheSession">Backing CacheSession for content and fingerprint calls</param> /// <param name="cache">Backing cache.</param> /// <param name="cacheId">Id of the parent cache that spawned the session.</param> /// <param name="logger">Diagnostic logger</param> /// <param name="sessionId">Telemetry ID for the session.</param> /// <param name="replaceExistingOnPlaceFile">If true, replace existing file on placing file from cache.</param> public MemoizationStoreAdapterCacheCacheSession( BuildXL.Cache.MemoizationStore.Interfaces.Sessions.ICacheSession cacheSession, BuildXL.Cache.MemoizationStore.Interfaces.Caches.ICache cache, CacheId cacheId, ILogger logger, string sessionId = null, bool replaceExistingOnPlaceFile = false) : base(cacheSession, cache, cacheId, logger, sessionId, replaceExistingOnPlaceFile) { }
/// <summary> /// Calculate historical volatility, based on log-returns. /// </summary> /// <param name="series">input time series</param> /// <param name="n">length</param> /// <param name="parentId">caller cache id, optional</param> /// <param name="memberName">caller's member name, optional</param> /// <param name="lineNumber">caller line number, optional</param> /// <returns>volatility as time series</returns> public static ITimeSeries <double> Volatility(this ITimeSeries <double> series, int n = 10, CacheId parentId = null, [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0) { var cacheId = new CacheId(parentId, memberName, lineNumber, series.GetHashCode(), n); return(series .LogReturn(cacheId) .StandardDeviation(n, cacheId)); }
/// <summary> /// Cast time series to double /// </summary> /// <param name="series">input series of long</param> /// <param name="parentId">caller cache id, optional</param> /// <param name="memberName">caller's member name, optional</param> /// <param name="lineNumber">caller line number, optional</param> /// <returns>output series of double</returns> public static ITimeSeries <double> ToDouble(this ITimeSeries <long> series, CacheId parentId = null, [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0) { var cacheId = new CacheId(parentId, memberName, lineNumber, series.GetHashCode()); return(IndicatorsBasic.Lambda( (t) => (double)series[t], cacheId)); }
/// <summary> /// Delay time series by number of bars. /// </summary> /// <param name="series">input time series</param> /// <param name="delay">delay length</param> /// <param name="parentId">caller cache id, optional</param> /// <param name="memberName">caller's member name, optional</param> /// <param name="lineNumber">caller line number, optional</param> /// <returns>delayed time series</returns> public static ITimeSeries <double> Delay(this ITimeSeries <double> series, int delay, CacheId parentId = null, [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0) { var cacheId = new CacheId(parentId, memberName, lineNumber, series.GetHashCode(), delay); return(Lambda( (t) => series[t + delay], cacheId)); }
/// <summary> /// Return constant value time series. /// </summary> /// <param name="constantValue">value of time series</param> /// <param name="parentId">caller cache id, optional</param> /// <param name="memberName">caller's member name, optional</param> /// <param name="lineNumber">caller line number, optional</param> /// <returns>value as time series</returns> public static ITimeSeries <double> Const(double constantValue, CacheId parentId = null, [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0) { var cacheId = new CacheId(parentId, memberName, lineNumber, constantValue.GetHashCode()); return(Lambda( (t) => constantValue, cacheId)); }
/// <summary> /// Calculate Averaged True Range, as described here: /// <see href="https://en.wikipedia.org/wiki/Average_true_range"/>. /// </summary> /// <param name="series">input time series</param> /// <param name="n">averaging length</param> /// <param name="parentId">caller cache id, optional</param> /// <param name="memberName">caller's member name, optional</param> /// <param name="lineNumber">caller line number, optional</param> /// <returns>ATR time series</returns> public static ITimeSeries <double> AverageTrueRange(this Instrument series, int n, CacheId parentId = null, [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0) { var cacheId = new CacheId(parentId, memberName, lineNumber, series.GetHashCode(), n); return(series .TrueRange(cacheId) .SMA(n, cacheId)); }
public void ExistentCachedRecovery() { using (CacheHandler cacheHandler = new CacheHandler(100, new TimeSpan(1, 0, 0))) { CacheId cacheId = new CacheId("prefix"); cacheHandler.Set(cacheId, "cached"); Assert.Equal("cached", cacheHandler.Get <string>(cacheId)); } }
private bool UserRateLimitReached(ulong messageId, ulong userId) { var reactCount = _cache.Get <int>(CacheId.StarboardUserMessageReactCountId(messageId, userId)); if (reactCount.HasValue && reactCount.Some() >= 2) { return(true); } return(false); }