Updates market averages
This commit is contained in:
parent
d3390892af
commit
2f6256756a
|
@ -15,8 +15,7 @@
|
|||
|
||||
public class MarketAverage
|
||||
{
|
||||
public int NumberOfFinished { get; set; }
|
||||
public int TimeRangeSeconds { get; set; }
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public float Price { get; set; }
|
||||
public float Size { get; set; }
|
||||
public float Duration { get; set; }
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using BiblioTech.Options;
|
||||
using DiscordRewards;
|
||||
using System.Globalization;
|
||||
using Utils;
|
||||
|
||||
namespace BiblioTech.Commands
|
||||
{
|
||||
|
@ -31,13 +30,7 @@ namespace BiblioTech.Commands
|
|||
|
||||
private string[] GetInsight(MarketAverage avg)
|
||||
{
|
||||
var timeRange = TimeSpan.FromSeconds(avg.TimeRangeSeconds);
|
||||
var headerLine = $"[Last {Time.FormatDuration(timeRange)}] ({avg.NumberOfFinished} Contracts finished)";
|
||||
|
||||
if (avg.NumberOfFinished == 0)
|
||||
{
|
||||
return new[] { headerLine };
|
||||
}
|
||||
var headerLine = $"[{avg.Title}]";
|
||||
|
||||
return new[]
|
||||
{
|
||||
|
|
|
@ -19,9 +19,6 @@ namespace TestNetRewarder
|
|||
[Uniform("check-history", "ch", "CHECKHISTORY", true, "Unix epoc timestamp of a moment in history on which processing begins. Required for hosting rewards. Should be 'launch of the testnet'.")]
|
||||
public int CheckHistoryTimestamp { get; set; } = 0;
|
||||
|
||||
[Uniform("market-insights", "mi", "MARKETINSIGHTS", false, "Semi-colon separated integers. Each represents a multiple of intervals, for which a market insights average will be generated.")]
|
||||
public string MarketInsights { get; set; } = "1;96";
|
||||
|
||||
[Uniform("events-overview", "eo", "EVENTSOVERVIEW", false, "When greater than zero, chain event summary will be generated. (default 1)")]
|
||||
public int CreateChainEventsOverview { get; set; } = 1;
|
||||
|
||||
|
|
|
@ -6,66 +6,47 @@ namespace TestNetRewarder
|
|||
{
|
||||
public class MarketTracker
|
||||
{
|
||||
private readonly List<ChainState> buffer = new List<ChainState>();
|
||||
private readonly MarketAverage MostRecent = new MarketAverage
|
||||
{
|
||||
Title = "Most recent"
|
||||
};
|
||||
private readonly MarketAverage Irf = new MarketAverage
|
||||
{
|
||||
Title = "Recent average"
|
||||
};
|
||||
|
||||
public MarketAverage[] ProcessChainState(ChainState chainState)
|
||||
{
|
||||
var intervalCounts = GetInsightCounts();
|
||||
if (!intervalCounts.Any()) return Array.Empty<MarketAverage>();
|
||||
UpdateMostRecent(chainState);
|
||||
UpdateIrf(chainState);
|
||||
|
||||
UpdateBuffer(chainState, intervalCounts.Max());
|
||||
var result = intervalCounts
|
||||
.Select(GenerateMarketAverage)
|
||||
.Where(a => a != null)
|
||||
.Cast<MarketAverage>()
|
||||
.ToArray();
|
||||
|
||||
if (!result.Any()) result = Array.Empty<MarketAverage>();
|
||||
return result;
|
||||
}
|
||||
|
||||
private void UpdateBuffer(ChainState chainState, int maxNumberOfIntervals)
|
||||
return new[]
|
||||
{
|
||||
buffer.Add(chainState);
|
||||
while (buffer.Count > maxNumberOfIntervals)
|
||||
{
|
||||
buffer.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
private MarketAverage? GenerateMarketAverage(int numberOfIntervals)
|
||||
{
|
||||
var states = SelectStates(numberOfIntervals);
|
||||
return CreateAverage(states);
|
||||
}
|
||||
|
||||
private ChainState[] SelectStates(int numberOfIntervals)
|
||||
{
|
||||
if (numberOfIntervals < 1) return Array.Empty<ChainState>();
|
||||
if (numberOfIntervals > buffer.Count) return Array.Empty<ChainState>();
|
||||
return buffer.TakeLast(numberOfIntervals).ToArray();
|
||||
}
|
||||
|
||||
private MarketAverage? CreateAverage(ChainState[] states)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new MarketAverage
|
||||
{
|
||||
NumberOfFinished = CountNumberOfFinishedRequests(states),
|
||||
TimeRangeSeconds = GetTotalTimeRange(states),
|
||||
Price = Average(states, s => s.Request.Ask.Reward),
|
||||
Duration = Average(states, s => s.Request.Ask.Duration),
|
||||
Size = Average(states, s => GetTotalSize(s.Request.Ask)),
|
||||
Collateral = Average(states, s => s.Request.Ask.Collateral),
|
||||
ProofProbability = Average(states, s => s.Request.Ask.ProofProbability)
|
||||
MostRecent,
|
||||
Irf
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
private void UpdateIrf(ChainState chainState)
|
||||
{
|
||||
Program.Log.Error($"Exception in CreateAverage: {ex}");
|
||||
return null;
|
||||
if (!chainState.FinishedRequests.Any()) return;
|
||||
|
||||
MostRecent.Price = GetIrf(MostRecent.Price, chainState, s => s.Request.Ask.Reward);
|
||||
MostRecent.Duration = GetIrf(MostRecent.Duration, chainState, s => s.Request.Ask.Duration);
|
||||
MostRecent.Size = GetIrf(MostRecent.Size, chainState, s => GetTotalSize(s.Request.Ask));
|
||||
MostRecent.Collateral = GetIrf(MostRecent.Collateral, chainState, s => s.Request.Ask.Collateral);
|
||||
MostRecent.ProofProbability = GetIrf(MostRecent.ProofProbability, chainState, s => s.Request.Ask.ProofProbability);
|
||||
}
|
||||
|
||||
private void UpdateMostRecent(ChainState chainState)
|
||||
{
|
||||
if (!chainState.FinishedRequests.Any()) return;
|
||||
|
||||
MostRecent.Price = Average(chainState, s => s.Request.Ask.Reward);
|
||||
MostRecent.Duration = Average(chainState, s => s.Request.Ask.Duration);
|
||||
MostRecent.Size = Average(chainState, s => GetTotalSize(s.Request.Ask));
|
||||
MostRecent.Collateral = Average(chainState, s => s.Request.Ask.Collateral);
|
||||
MostRecent.ProofProbability = Average(chainState, s => s.Request.Ask.ProofProbability);
|
||||
}
|
||||
|
||||
private int GetTotalSize(Ask ask)
|
||||
|
@ -75,50 +56,40 @@ namespace TestNetRewarder
|
|||
return nSlots * slotSize;
|
||||
}
|
||||
|
||||
private float Average(ChainState[] states, Func<StorageRequest, BigInteger> getValue)
|
||||
private float Average(ChainState state, Func<StorageRequest, BigInteger> getValue)
|
||||
{
|
||||
return Average(states, s => Convert.ToInt32(getValue(s)));
|
||||
return Average(state, s => Convert.ToInt32(getValue(s)));
|
||||
}
|
||||
|
||||
private float Average(ChainState[] states, Func<StorageRequest, int> getValue)
|
||||
private float GetIrf(float current, ChainState state, Func<StorageRequest, BigInteger> getValue)
|
||||
{
|
||||
return GetIrf(current, state, s => Convert.ToInt32(getValue(s)));
|
||||
}
|
||||
|
||||
private float Average(ChainState state, Func<StorageRequest, int> getValue)
|
||||
{
|
||||
var sum = 0.0f;
|
||||
var count = 0.0f;
|
||||
foreach (var state in states)
|
||||
{
|
||||
foreach (var finishedRequest in state.FinishedRequests)
|
||||
{
|
||||
sum += getValue(finishedRequest);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count < 1.0f) return 0.0f;
|
||||
return sum / count;
|
||||
}
|
||||
|
||||
private int GetTotalTimeRange(ChainState[] states)
|
||||
private float GetIrf(float current, ChainState state, Func<StorageRequest, int> getValue)
|
||||
{
|
||||
return Convert.ToInt32((Program.Config.Interval * states.Length).TotalSeconds);
|
||||
var result = current;
|
||||
foreach (var finishedRequest in state.FinishedRequests)
|
||||
{
|
||||
float v = getValue(finishedRequest);
|
||||
result = (result + v) / 2.0f;
|
||||
}
|
||||
|
||||
private int CountNumberOfFinishedRequests(ChainState[] states)
|
||||
{
|
||||
return states.Sum(s => s.FinishedRequests.Length);
|
||||
}
|
||||
|
||||
private int[] GetInsightCounts()
|
||||
{
|
||||
try
|
||||
{
|
||||
var tokens = Program.Config.MarketInsights.Split(';').ToArray();
|
||||
return tokens.Select(t => Convert.ToInt32(t)).ToArray();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Log.Error($"Exception when parsing MarketInsights config parameters: {ex}");
|
||||
}
|
||||
return Array.Empty<int>();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue