diff --git a/DiscordClient/Graphing/GraphDrawer.cs b/DiscordClient/Graphing/GraphDrawer.cs
index eb8679e..a5dd56d 100644
--- a/DiscordClient/Graphing/GraphDrawer.cs
+++ b/DiscordClient/Graphing/GraphDrawer.cs
@@ -5,6 +5,7 @@
using SixLabors.ImageSharp.Drawing;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Formats.Png;
+using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using Path = System.IO.Path;
@@ -12,10 +13,16 @@ namespace DiscordClient.Graphing;
public static class GraphDrawer
{
+ private enum GraphTimePeriod
+ {
+ DAY,
+ MONTH
+ }
+
private static readonly string GraphBackgroundPath;
private static readonly Pen GraphingPenLow;
private static readonly Pen GraphingPenHigh;
- private static readonly Pen Last6HPen;
+ private static readonly Pen HighlightingPen;
private static readonly Font Font;
@@ -23,18 +30,18 @@ static GraphDrawer()
{
const string fontPath = @"assets\fonts\runescape_uf.ttf";
const string graphBackgroundPath = @"assets\textures\graph_background.png";
-
+
string executingAssemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? string.Empty;
GraphBackgroundPath = Path.Combine(executingAssemblyPath, graphBackgroundPath);
- string fontPath1 = Path.Combine(executingAssemblyPath, fontPath);
-
+ string fPath = Path.Combine(executingAssemblyPath, fontPath);
+
FontCollection fontCollection = new();
- FontFamily family = fontCollection.Add(fontPath1);
+ FontFamily family = fontCollection.Add(fPath);
Font = new Font(family, 14, FontStyle.Regular);
-
+
GraphingPenLow = new SolidPen(new SolidBrush(Color.Chartreuse), 1f);
GraphingPenHigh = new SolidPen(new SolidBrush(Color.Orange), 1f);
- Last6HPen = new SolidPen(new SolidBrush(Color.Brown), 3f);
+ HighlightingPen = new SolidPen(new SolidBrush(Color.CadetBlue), 3f);
}
@@ -42,14 +49,67 @@ static GraphDrawer()
/// Draws a price graph from the price history of an item.
///
/// Item price history, in 5min intervals. Should contain at least 288x 5min data-points = 24h.
- public static async Task DrawGraph(ItemPriceHistory history5MinIntervals)
+ /// Item price history, in 6h intervals. May be null if not available.
+ /// Latest buy price.
+ /// Latest sell price.
+ public static async Task DrawGraph(
+ ItemPriceHistory history5MinIntervals,
+ ItemPriceHistory? history6HourIntervals,
+ int latestBuy,
+ int latestSell)
{
- if (history5MinIntervals.Data.Count < 288)
+ const int graphPointsPerDay = 288; // Assuming 5min intervals.
+
+ if (history5MinIntervals.Data.Count < graphPointsPerDay)
throw new ArgumentException("The price history must contain at least 288x 5min data-points = 24h.", nameof(history5MinIntervals));
- List dataPoints = history5MinIntervals.Data.TakeLast(288).ToList();
+ List dataPointsDay = history5MinIntervals.Data.TakeLast(graphPointsPerDay).ToList();
+ dataPointsDay.Add(
+ new ItemPriceHistoryEntry
+ {
+ AvgHighPrice = latestBuy,
+ AvgLowPrice = latestSell
+ });
+
+ Image dayGraph = await CreateGraph(dataPointsDay, GraphTimePeriod.DAY);
+ Image? monthGraph = null;
+
+ if (history6HourIntervals != null)
+ {
+ List dataPointsMonth = history6HourIntervals.Data.TakeLast(120).ToList();
+ dataPointsMonth.Add(
+ new ItemPriceHistoryEntry
+ {
+ AvgHighPrice = latestBuy,
+ AvgLowPrice = latestSell
+ });
+
+ monthGraph = await CreateGraph(dataPointsMonth, GraphTimePeriod.MONTH);
+ }
+
+ int width = Math.Max(dayGraph.Width, monthGraph?.Width ?? 0);
+ int height = dayGraph.Height + (monthGraph?.Height ?? 0);
+ Image combinedImage = new Image(width, height);
+ combinedImage.Mutate(ctx => ctx.DrawImage(dayGraph, new Point(0, 0), 1f));
+ if (monthGraph != null)
+ combinedImage.Mutate(ctx => ctx.DrawImage(monthGraph, new Point(0, dayGraph.Height), 1f));
+
+ MemoryStream ms = new();
+ await combinedImage.SaveAsync(ms, new PngEncoder());
+ ms.Position = 0;
+
+ combinedImage.Dispose();
+
+ return ms;
+ }
+
+
+ private static async Task CreateGraph(List dataPoints, GraphTimePeriod timePeriod)
+ {
+ const int graphPadding = 15;
+
// 460x80 pixels.
- using Image img = await Image.LoadAsync(GraphBackgroundPath);
+ Image img = await Image.LoadAsync(GraphBackgroundPath);
int imageWidth = img.Width;
int imageHeight = img.Height;
@@ -62,73 +122,128 @@ public static async Task DrawGraph(ItemPriceHistory history5MinInt
continue;
if ((int)entry.LowestPrice < minValue)
minValue = (int)entry.LowestPrice;
-
+
if (entry.HighestPrice == null)
continue;
if ((int)entry.HighestPrice > maxValue)
maxValue = (int)entry.HighestPrice;
}
+ // Determine required values.
+ float periodHighlightStartPoint = imageWidth - (imageWidth - graphPadding) / 4f;
+ int periodCount;
+ int periodCountForStartPoint;
+ string periodText;
+ string lastPeriodText;
+ switch (timePeriod)
+ {
+ case GraphTimePeriod.DAY:
+ periodCount = 288;
+ periodCountForStartPoint = 72;
+ periodText = "last 24h";
+ lastPeriodText = "last 6h ->";
+ break;
+ case GraphTimePeriod.MONTH:
+ periodCount = 120;
+ periodCountForStartPoint = 4;
+ periodText = "last 30d";
+ lastPeriodText = "last day ->";
+ break;
+ default:
+ throw new ArgumentOutOfRangeException(nameof(timePeriod), timePeriod, null);
+ }
+
+ // Construct the graph points.
List graphPointsLow = new();
List graphPointsHigh = new();
-
- float last6HStartPoint = imageWidth - (imageWidth - 15) / 4f;
for (int i = 0; i < dataPoints.Count; i++)
{
- if (dataPoints[i].LowestPrice != null)
+ if (dataPoints[i].AvgLowPrice != null)
{
- PointF point = NormalizedPointFromValues(i, (int)dataPoints[i].LowestPrice!, imageWidth, imageHeight, 15, 15, dataPoints.Count, minValue, maxValue);
+ PointF point = NormalizedPointFromValues(
+ i,
+ (int)dataPoints[i].AvgLowPrice!,
+ imageWidth,
+ imageHeight,
+ graphPadding,
+ graphPadding,
+ dataPoints.Count,
+ minValue,
+ maxValue);
- if (i == 288 - 72)
- last6HStartPoint = point.X;
+ if (i == periodCount - periodCountForStartPoint)
+ periodHighlightStartPoint = point.X;
graphPointsLow.Add(point);
}
-
- if (dataPoints[i].HighestPrice != null)
+
+ if (dataPoints[i].AvgHighPrice != null)
{
- PointF point = NormalizedPointFromValues(i, (int)dataPoints[i].HighestPrice!, imageWidth, imageHeight, 15, 15, dataPoints.Count, minValue, maxValue);
+ PointF point = NormalizedPointFromValues(
+ i,
+ (int)dataPoints[i].AvgHighPrice!,
+ imageWidth,
+ imageHeight,
+ graphPadding,
+ graphPadding,
+ dataPoints.Count,
+ minValue,
+ maxValue);
+
+ if (i == periodCount - periodCountForStartPoint)
+ periodHighlightStartPoint = point.X;
- if (i == 288 - 72)
- last6HStartPoint = point.X;
-
graphPointsHigh.Add(point);
}
}
-
+
+ // Construct the graph paths.
PathBuilder graphPathLow = new();
PathBuilder graphPathHigh = new();
graphPathLow.AddLines(graphPointsLow.ToArray());
graphPathHigh.AddLines(graphPointsHigh.ToArray());
-
+
// Draw the graphs.
img.Mutate(ctx => ctx.Draw(GraphingPenLow, graphPathLow.Build()));
img.Mutate(ctx => ctx.Draw(GraphingPenHigh, graphPathHigh.Build()));
-
- // Construct points for the 6h helper line.
- List last6HPoints = new();
- int targetHeight6H = imageHeight - 15;
- int latestPoint = imageWidth - 15;
-
- last6HPoints.Add(new PointF(last6HStartPoint, targetHeight6H));
- last6HPoints.Add(new PointF(latestPoint, targetHeight6H));
- // Draw the 6h helper line
+ // Construct points for the helper line.
+ List highlightedPeriodPoints = new();
+ int targetHeightPeriod = imageHeight - graphPadding;
+ int latestPoint = imageWidth - graphPadding;
+
+ // Add the last period points.
+ highlightedPeriodPoints.Add(new PointF(periodHighlightStartPoint, targetHeightPeriod));
+ highlightedPeriodPoints.Add(new PointF(latestPoint, targetHeightPeriod));
+
+ // Draw the helper line
PathBuilder helperPath = new();
- helperPath.AddLines(last6HPoints.ToArray());
- img.Mutate(ctx => ctx.Draw(Last6HPen, helperPath.Build()));
-
- // Draw the "last 6h ->" text.
- img.Mutate(ctx => ctx.DrawText("last 6h ->", Font, Color.Wheat, new PointF(last6HStartPoint - 60, imageHeight - 20)));
+ helperPath.AddLines(highlightedPeriodPoints.ToArray());
+ img.Mutate(ctx => ctx.Draw(HighlightingPen, helperPath.Build()));
- MemoryStream ms = new();
- await img.SaveAsync(ms, new PngEncoder());
- ms.Position = 0;
- return ms;
+ // Draw the "last period ->" text.
+ img.Mutate(ctx => ctx.DrawText(lastPeriodText, Font, Color.Wheat, new PointF(periodHighlightStartPoint - 60, imageHeight - graphPadding - 5)));
+
+ // Add the "period" text.
+ img.Mutate(ctx => ctx.DrawText(periodText, Font, Color.Wheat, new PointF(10, 5)));
+
+ return img;
}
- private static PointF NormalizedPointFromValues(int pointIndex, int pointValue, int imageWidth, int imageHeight, int widthPadding, int heightPadding, int pointsCount, int lowestValue, int highestValue)
+ ///
+ /// Normalizes a data point to a point on the graph.
+ ///
+ private static PointF NormalizedPointFromValues(
+ int pointIndex,
+ int pointValue,
+ int imageWidth,
+ int imageHeight,
+ int widthPadding,
+ int heightPadding,
+ int pointsCount,
+ int lowestValue,
+ int highestValue)
{
float normalizedX = pointIndex * (imageWidth - widthPadding - widthPadding) / (float)(pointsCount - 1) + widthPadding;
float normalizedY = (pointValue - lowestValue) * (imageHeight - heightPadding - heightPadding) / (float)(highestValue - lowestValue) + heightPadding;
diff --git a/DiscordClient/Program.cs b/DiscordClient/Program.cs
index 4210fc4..950777a 100644
--- a/DiscordClient/Program.cs
+++ b/DiscordClient/Program.cs
@@ -89,7 +89,7 @@ private static async void OnDumpsUpdated()
foreach (SocketTextChannel channel in channels)
{
// Get the graph image.
- MemoryStream memStream = await GraphDrawer.DrawGraph(dump.PriceHistory);
+ MemoryStream memStream = await GraphDrawer.DrawGraph(dump.PriceHistory5Min, dump.PriceHistory6Hour, dump.InstaBuyPrice, dump.InstaSellPrice);
FileAttachment graphAttachment = new(memStream, "graph.png");
RestUserMessage msg = await channel.SendFileAsync(graphAttachment);
string graphUrl = msg.Attachments.First().Url;
@@ -97,6 +97,7 @@ private static async void OnDumpsUpdated()
Embed embed = DumpEmbedBuilder.BuildEmbed(dump, graphUrl);
await channel.SendMessageAsync(embed: embed);
await msg.DeleteAsync();
+ await Task.Delay(2000);
}
}
catch (Exception e)
diff --git a/OsrsFlipper/Api/OsrsApiController.cs b/OsrsFlipper/Api/OsrsApiController.cs
index cdf916d..e82514c 100644
--- a/OsrsFlipper/Api/OsrsApiController.cs
+++ b/OsrsFlipper/Api/OsrsApiController.cs
@@ -1,5 +1,4 @@
-using System.Diagnostics;
-using OsrsFlipper.Data.Mapping;
+using OsrsFlipper.Data.Mapping;
using OsrsFlipper.Data.Price.Average;
using OsrsFlipper.Data.Price.Latest;
using OsrsFlipper.Data.TimeSeries;
@@ -103,7 +102,7 @@ public async Task GetItemMapping()
}
- public async Task GetPriceHistory(ItemData item, TimeSeriesApi.TimeSeriesTimeStep timestep)
+ public async Task GetPriceHistory(ItemData item, TimeSeriesTimeStep timestep)
{
return await _timeSeriesApi.GetPriceHistory(_client, item, timestep);
}
diff --git a/OsrsFlipper/Api/TimeSeriesApi.cs b/OsrsFlipper/Api/TimeSeriesApi.cs
index 3e53314..4a2b5c1 100644
--- a/OsrsFlipper/Api/TimeSeriesApi.cs
+++ b/OsrsFlipper/Api/TimeSeriesApi.cs
@@ -6,13 +6,6 @@ namespace OsrsFlipper.Api;
public class TimeSeriesApi : OsrsApi
{
- public enum TimeSeriesTimeStep
- {
- FiveMinutes,
- Hour,
- SixHours,
- Day
- }
private readonly RestRequest _request;
diff --git a/OsrsFlipper/Api/TimeSeriesTimeStep.cs b/OsrsFlipper/Api/TimeSeriesTimeStep.cs
new file mode 100644
index 0000000..acb5e12
--- /dev/null
+++ b/OsrsFlipper/Api/TimeSeriesTimeStep.cs
@@ -0,0 +1,9 @@
+namespace OsrsFlipper.Api;
+
+public enum TimeSeriesTimeStep
+{
+ FiveMinutes,
+ Hour,
+ SixHours,
+ Day
+}
\ No newline at end of file
diff --git a/OsrsFlipper/Caching/CacheEntry.cs b/OsrsFlipper/Caching/CacheEntry.cs
index 82bfa73..1536e2e 100644
--- a/OsrsFlipper/Caching/CacheEntry.cs
+++ b/OsrsFlipper/Caching/CacheEntry.cs
@@ -54,6 +54,12 @@ public class CacheEntry
public readonly AveragedPriceData Price24HourAverage = new();
+ ///
+ /// Potential maximum amount that can be bought in 4 hours.
+ ///
+ public int MaxBuyAmount => Math.Min(Item.GeBuyLimit, Price24HourAverage.TotalVolume);
+
+
public CacheEntry(ItemData item)
{
Item = item;
diff --git a/OsrsFlipper/Filtering/FilterCollection.cs b/OsrsFlipper/Filtering/FilterCollection.cs
index 3da56c8..31a89c8 100644
--- a/OsrsFlipper/Filtering/FilterCollection.cs
+++ b/OsrsFlipper/Filtering/FilterCollection.cs
@@ -54,4 +54,18 @@ public bool PassesFlipTest(CacheEntry itemData, ItemPriceHistory history)
return true;
}
+
+
+ public void DebugFilters()
+ {
+ foreach (PruneFilter filter in _pruneFilters)
+ {
+ Logger.Verbose($"Prune filter {filter.GetType().Name} block count: {filter.ItemsFailed} / {filter.ItemsChecked}");
+ }
+
+ foreach (FlipFilter filter in _flipFilters)
+ {
+ Logger.Verbose($"Flip filter {filter.GetType().Name} block count: {filter.ItemsFailed} / {filter.ItemsChecked}");
+ }
+ }
}
\ No newline at end of file
diff --git a/OsrsFlipper/Filtering/Filters/PruneFilters/InsufficientDataFilter.cs b/OsrsFlipper/Filtering/Filters/PruneFilters/InsufficientDataFilter.cs
new file mode 100644
index 0000000..a5f2b03
--- /dev/null
+++ b/OsrsFlipper/Filtering/Filters/PruneFilters/InsufficientDataFilter.cs
@@ -0,0 +1,50 @@
+using OsrsFlipper.Caching;
+
+namespace OsrsFlipper.Filtering.Filters.PruneFilters;
+
+///
+/// Checks if the item has valid price data.
+/// If any of the price data is insufficient, the item is not considered for flipping.
+///
+internal class InsufficientDataFilter : PruneFilter
+{
+ protected override bool CanPassFilter(CacheEntry itemData)
+ {
+ bool latestValid = itemData.PriceLatest.IsValid;
+ bool average5MinValid = itemData.Price5MinAverage.IsValid;
+ bool average5MinOffsetValid = itemData.Price5MinAverageOffset.IsValid;
+ bool average10MinValid = itemData.Price10MinAverage.IsValid;
+ bool average30MinValid = itemData.Price30MinAverage.IsValid;
+ bool average1HValid = itemData.Price1HourAverage.IsValid;
+ bool average6HValid = itemData.Price6HourAverage.IsValid;
+ bool average24HValid = itemData.Price24HourAverage.IsValid;
+
+ bool allDataValid = latestValid &&
+ average5MinValid &&
+ average5MinOffsetValid &&
+ average10MinValid &&
+ average30MinValid &&
+ average1HValid &&
+ average6HValid &&
+ average24HValid;
+
+ /*if (!latestValid)
+ Logger.Verbose($"Item {itemData.Item} has invalid latest data.");
+ if (!average5MinValid)
+ Logger.Verbose($"Item {itemData.Item} has invalid 5min average data.");
+ if (!average5MinOffsetValid)
+ Logger.Verbose($"Item {itemData.Item} has invalid 5min average offset data.");
+ if (!average10MinValid)
+ Logger.Verbose($"Item {itemData.Item} has invalid 10min average data.");
+ if (!average30MinValid)
+ Logger.Verbose($"Item {itemData.Item} has invalid 30min average data.");
+ if (!average1HValid)
+ Logger.Verbose($"Item {itemData.Item} has invalid 1h average data.");
+ if (!average6HValid)
+ Logger.Verbose($"Item {itemData.Item} has invalid 6h average data.");
+ if (!average24HValid)
+ Logger.Verbose($"Item {itemData.Item} has invalid 24h average data.");*/
+
+ return allDataValid;
+ }
+}
\ No newline at end of file
diff --git a/OsrsFlipper/Filtering/Filters/PruneFilters/PotentialProfitFilter.cs b/OsrsFlipper/Filtering/Filters/PruneFilters/PotentialProfitFilter.cs
index d1745e9..33c366c 100644
--- a/OsrsFlipper/Filtering/Filters/PruneFilters/PotentialProfitFilter.cs
+++ b/OsrsFlipper/Filtering/Filters/PruneFilters/PotentialProfitFilter.cs
@@ -35,7 +35,7 @@ protected override bool CanPassFilter(CacheEntry itemData)
// The price the item should be bought at to make a profit.
int priceToBuyAt = itemData.PriceLatest.LowestPrice;
// The price the item should be sold at to make a profit.
- int priceToSellAt = itemData.Price1HourAverage.HighestPrice; // NOTE: Possibly use Price1HourAverage.AveragePrice instead of Price1HourAverage.HighestPrice?
+ int priceToSellAt = itemData.Price1HourAverage.HighestPrice;
// Calculate the margin.
int margin = priceToSellAt - priceToBuyAt;
@@ -45,7 +45,7 @@ protected override bool CanPassFilter(CacheEntry itemData)
margin = (int)(margin * 0.99);
// Calculate the potential profit.
- int potentialProfit = margin * Math.Min(itemData.Item.GeBuyLimit, itemData.Price24HourAverage.TotalVolume);
+ int potentialProfit = margin * itemData.MaxBuyAmount;
// Check if the potential profit is above the minimum required.
return potentialProfit >= _minPotentialProfit;
diff --git a/OsrsFlipper/Filtering/Filters/PruneFilters/ValidDataFilter.cs b/OsrsFlipper/Filtering/Filters/PruneFilters/ValidDataFilter.cs
deleted file mode 100644
index 8cb061d..0000000
--- a/OsrsFlipper/Filtering/Filters/PruneFilters/ValidDataFilter.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using OsrsFlipper.Caching;
-
-namespace OsrsFlipper.Filtering.Filters.PruneFilters;
-
-///
-/// Checks if the item has valid price data.
-/// If any of the price data is invalid, the item is not considered for flipping.
-///
-internal class ValidDataFilter : PruneFilter
-{
- protected override bool CanPassFilter(CacheEntry itemData)
- {
- return itemData.PriceLatest.IsValid &&
- itemData.Price5MinAverageOffset.IsValid &&
- itemData.Price5MinAverage.IsValid &&
- itemData.Price10MinAverage.IsValid &&
- itemData.Price30MinAverage.IsValid &&
- itemData.Price1HourAverage.IsValid &&
- itemData.Price6HourAverage.IsValid &&
- itemData.Price24HourAverage.IsValid;
- }
-}
\ No newline at end of file
diff --git a/OsrsFlipper/Flipper.cs b/OsrsFlipper/Flipper.cs
index 2283465..6b39347 100644
--- a/OsrsFlipper/Flipper.cs
+++ b/OsrsFlipper/Flipper.cs
@@ -5,13 +5,14 @@
using OsrsFlipper.Data.Price.Latest;
using OsrsFlipper.Data.TimeSeries;
using OsrsFlipper.Filtering;
-using OsrsFlipper.Filtering.Filters;
using OsrsFlipper.Filtering.Filters.PruneFilters;
namespace OsrsFlipper;
public sealed class Flipper : IDisposable
{
+ private const bool DEBUG_FILTERS = false;
+
///
/// The API controller used to fetch data from the OSRS API.
///
@@ -47,7 +48,7 @@ private Flipper(OsrsApiController apiController, ItemCache cache, int cooldownMi
// Add wanted filters to the filter collection.
// Prune filters are used to quickly discard items that are not worth considering, and to avoid fetching additional API data for them.
_filterCollection
- .AddPruneFilter(new ValidDataFilter()) // Skip items with invalid data.
+ //.AddPruneFilter(new InsufficientDataFilter()) // Skip items with invalid data.
.AddPruneFilter(new ItemCooldownFilter(_cooldownManager)) // Skip items that are on a cooldown.
.AddPruneFilter(new Item24HAveragePriceFilter(50, 50_000_000)) // Skip items with a 24-hour average price outside the range X - Y.
.AddPruneFilter(new PotentialProfitFilter(500_000, true)) // Skip items with a potential profit less than X.
@@ -103,26 +104,36 @@ public async Task> FindDumps()
}
// Check if the item passes all pruning filters.
+ // DEBUG-TEST: if (entry.Item.Id != 2)
if (!_filterCollection.PassesPruneTest(entry))
continue;
itemsPassedPruneCount++;
// Get the price history for the item.
- ItemPriceHistory? history = await GetPriceHistory(entry.Item, TimeSeriesApi.TimeSeriesTimeStep.FiveMinutes);
- if (history == null)
+ ItemPriceHistory? history5Min = await GetPriceHistory(entry.Item, TimeSeriesTimeStep.FiveMinutes);
+ if (history5Min == null)
continue;
// Check if the item passes all flip filters.
- if (!_filterCollection.PassesFlipTest(entry, history))
+ // DEBUG-TEST: if (entry.Item.Id != 2)
+ if (!_filterCollection.PassesFlipTest(entry, history5Min))
continue;
- ItemDump dump = ConstructDumpObject(entry, history);
+ // Get the additional 6-hour price history for the item.
+ ItemPriceHistory? history6Hour = await GetPriceHistory(entry.Item, TimeSeriesTimeStep.SixHours);
+
+ ItemDump dump = ConstructDumpObject(entry, history5Min, history6Hour);
// Add the flip to the list and set the item on cooldown.
flips.Add(dump);
_cooldownManager.SetCooldown(entry.Item.Id, TimeSpan.FromMinutes(_cooldownMinutes));
}
Logger.Verbose($"{itemsPassedPruneCount} items passed all pruning filters.");
+
+ if (DEBUG_FILTERS)
+ {
+ _filterCollection.DebugFilters();
+ }
return flips;
}
@@ -131,7 +142,7 @@ public async Task> FindDumps()
///
/// Constructs an from the given .
///
- private static ItemDump ConstructDumpObject(CacheEntry entry, ItemPriceHistory history)
+ private static ItemDump ConstructDumpObject(CacheEntry entry, ItemPriceHistory history5Min, ItemPriceHistory? history6Hour)
{
// The price the item should be bought at to make a profit.
int priceToBuyAt = entry.PriceLatest.LowestPrice;
@@ -157,7 +168,8 @@ private static ItemDump ConstructDumpObject(CacheEntry entry, ItemPriceHistory h
entry.PriceLatest.LastSellTime,
entry.Price30MinAverage.AveragePrice,
entry.Price6HourAverage.AveragePrice,
- history);
+ history5Min,
+ history6Hour);
}
@@ -222,7 +234,7 @@ public async Task RefreshCache()
}
- private async Task GetPriceHistory(ItemData item, TimeSeriesApi.TimeSeriesTimeStep timestep)
+ private async Task GetPriceHistory(ItemData item, TimeSeriesTimeStep timestep)
{
return await _apiController.GetPriceHistory(item, timestep);
}
diff --git a/OsrsFlipper/ItemDump.cs b/OsrsFlipper/ItemDump.cs
index 71d0db7..cab3757 100644
--- a/OsrsFlipper/ItemDump.cs
+++ b/OsrsFlipper/ItemDump.cs
@@ -13,7 +13,17 @@ public class ItemDump
public readonly DateTime LastInstaSellTime;
public readonly int AveragePrice30Min;
public readonly int AveragePrice6Hour;
- public readonly ItemPriceHistory PriceHistory;
+
+ ///
+ /// Price history with 5-minute intervals, with up to 365 data points.
+ ///
+ public readonly ItemPriceHistory PriceHistory5Min;
+
+ ///
+ /// Price history with 6-hour intervals, with up to 365 data points.
+ ///
+ public readonly ItemPriceHistory? PriceHistory6Hour;
+
// Calculated values:
public readonly int? PotentialProfit;
public readonly double RoiPercentage;
@@ -29,7 +39,8 @@ public ItemDump(ItemData item,
DateTime lastInstaSellTime,
int averagePrice30Min,
int averagePrice6Hour,
- ItemPriceHistory priceHistory)
+ ItemPriceHistory priceHistory5Min,
+ ItemPriceHistory? priceHistory6Hour)
{
Item = item;
PotentialProfit = potentialProfit;
@@ -41,7 +52,8 @@ public ItemDump(ItemData item,
LastInstaSellTime = lastInstaSellTime;
AveragePrice30Min = averagePrice30Min;
AveragePrice6Hour = averagePrice6Hour;
- PriceHistory = priceHistory;
+ PriceHistory5Min = priceHistory5Min;
+ PriceHistory6Hour = priceHistory6Hour;
}
diff --git a/OsrsFlipper/Utils.cs b/OsrsFlipper/Utils.cs
index 23abdb6..5082c71 100644
--- a/OsrsFlipper/Utils.cs
+++ b/OsrsFlipper/Utils.cs
@@ -21,14 +21,14 @@ public static long DateTimeToUnixTime(DateTime dateTime)
}
- public static string AsString(this TimeSeriesApi.TimeSeriesTimeStep timeStep)
+ public static string AsString(this TimeSeriesTimeStep timeStep)
{
return timeStep switch
{
- TimeSeriesApi.TimeSeriesTimeStep.FiveMinutes => "5m",
- TimeSeriesApi.TimeSeriesTimeStep.Hour => "1h",
- TimeSeriesApi.TimeSeriesTimeStep.SixHours => "6h",
- TimeSeriesApi.TimeSeriesTimeStep.Day => "24h",
+ TimeSeriesTimeStep.FiveMinutes => "5m",
+ TimeSeriesTimeStep.Hour => "1h",
+ TimeSeriesTimeStep.SixHours => "6h",
+ TimeSeriesTimeStep.Day => "24h",
_ => throw new ArgumentOutOfRangeException(nameof(timeStep), timeStep, null)
};
}