Merge branch 'dev' of https://github.com/shirsig/Aux-Addon into dev
This commit is contained in:
+39
-150
@@ -1,4 +1,4 @@
|
||||
private, public = {}, {}
|
||||
local private, public = {}, {}
|
||||
Aux.stat_average = public
|
||||
|
||||
private.PUSH_INTERVAL = 57600
|
||||
@@ -19,171 +19,60 @@ function private.process_auction(auction_info)
|
||||
end
|
||||
|
||||
local item_record = private.load_data()[get_item_key(auction_info)] or {
|
||||
auction_count = 0,
|
||||
unit_count = 0,
|
||||
daily_auction_count = 0,
|
||||
daily_unit_count = 0,
|
||||
accumulated_buyout_price = 0,
|
||||
seen_days = 0,
|
||||
EMA3 = 0,
|
||||
EMA7 = 0,
|
||||
EMA14 = 0,
|
||||
average_min_buyout = 0,
|
||||
}
|
||||
|
||||
|
||||
item_record.auction_count = item_record.auction_count + 1
|
||||
item_record.unit_count = item_record.unit_count + auction_info.count
|
||||
item_record.daily_auction_count = item_record.daily_auction_count + 1
|
||||
item_record.daily_unit_count = item_record.daily_unit_count + auction_info.count
|
||||
item_record.accumulated_buyout_price = item_record.accumulated_buyout_price + auction_info.buyout_price
|
||||
|
||||
|
||||
--[[ data = {
|
||||
[1] = total buyout,
|
||||
[2] = seen count,
|
||||
[3] = today's minimum buyout,
|
||||
[4] = auctions count, (only recorded if different from seen count)
|
||||
}--]]
|
||||
|
||||
|
||||
if data0 then
|
||||
local aucs = data0[4]
|
||||
if aucs then
|
||||
data0[4] = aucs + 1
|
||||
elseif stack > 1 then
|
||||
-- no recorded auctions count, so auctions count must have been equal to seen count up to this point
|
||||
data0[4] = data0[2] + 1
|
||||
end
|
||||
local mbo = data0[3]
|
||||
if mbo == 0 or buyoutper < mbo then
|
||||
data0[3] = buyoutper
|
||||
end
|
||||
data0[2] = data0[2] + stack
|
||||
data0[1] = data0[1] + buyout
|
||||
end
|
||||
|
||||
if dataP then
|
||||
local aucs = dataP[4]
|
||||
if aucs then
|
||||
dataP[4] = aucs + 1
|
||||
elseif stack > 1 then
|
||||
-- no recorded auctions count, so auctions count must have been equal to seen count up to this point
|
||||
dataP[4] = dataP[2] + 1
|
||||
end
|
||||
local mbo = dataP[3]
|
||||
if mbo == 0 or buyoutper < mbo then
|
||||
dataP[3] = buyoutper
|
||||
end
|
||||
dataP[2] = dataP[2] + stack
|
||||
dataP[1] = dataP[1] + buyout
|
||||
end
|
||||
|
||||
private.WriteItemData(serverKey, storeID, storeProperty)
|
||||
item_record.daily_min_buyout_price = item_record.daily_min_buyout_price and min(item_record.daily_min_buyout_price, auction_info.buyout_price / auction_info.count) or auction_info.buyout_price / auction_info.count
|
||||
end
|
||||
|
||||
function private.push_data()
|
||||
local realmdata = SSRealmData[serverKey]
|
||||
if not realmdata then return end
|
||||
local daily, means = realmdata.daily, realmdata.means
|
||||
local lookupmeansdata, lookupmeansindex = {}, {}
|
||||
local data = private.load_data()
|
||||
|
||||
for storeID, itemstring in pairs(daily) do
|
||||
-- find the means data for this storeID, and build lookup tables to help cross-index
|
||||
-- we leave the last (DATA_DIVIDER) level of the data as strings for now; later we will fully unpack only the ones we need
|
||||
local itemstoremeans
|
||||
if means[storeID] then
|
||||
itemstoremeans = {strsplit(ITEM_DIVIDER, means[storeID])}
|
||||
else
|
||||
itemstoremeans = {}
|
||||
end
|
||||
for index, propertystring in ipairs(itemstoremeans) do
|
||||
local prop, datastringmeans = strsplit(PROPERTY_DIVIDER, propertystring)
|
||||
lookupmeansdata[prop] = datastringmeans
|
||||
lookupmeansindex[prop] = index -- remember where we got datastringmeans from, so we can put the revised datastring back in the same place
|
||||
end
|
||||
for item_key, item_record in pairs(data) do
|
||||
|
||||
local itemsdaily = {strsplit(ITEM_DIVIDER, itemstring)}
|
||||
for index, propertystring in ipairs(itemsdaily) do
|
||||
-- extract daily data entries for this itemID & property
|
||||
local prop, datastringdaily = strsplit(PROPERTY_DIVIDER, propertystring)
|
||||
local dailybuy, dailyseen, dailymbo, dailyauctions = strsplit(DATA_DIVIDER, datastringdaily)
|
||||
dailybuy, dailyseen, dailymbo, dailyauctions = tonumber(dailybuy), tonumber(dailyseen), tonumber(dailymbo), tonumber(dailyauctions)
|
||||
local dailyavg = dailybuy
|
||||
-- dailyseen may be 0 for certain unusual items which do not modify property "0"
|
||||
-- our database format requires that there must always be a property "0" (which must always be at index 1)
|
||||
-- if no items of that base type with property "0" were seen today, the entry will be empty (all 0)
|
||||
if dailyseen > 0 then
|
||||
dailyavg = dailyavg / dailyseen
|
||||
end
|
||||
if item_record.daily_auction_count > 0 then
|
||||
|
||||
local daily_average = item_record.daily_accumulated_buyout / item_record.daily_unit_count
|
||||
|
||||
-- look for existing means data for this property
|
||||
local datastringmeans = lookupmeansdata[prop]
|
||||
if datastringmeans then
|
||||
if dailyseen > 0 then
|
||||
datameans = {strsplit(DATA_DIVIDER, datastringmeans)} -- seendays, seencount, EMA3, EMA7, EMA14, avgminbuy [, seenauctions]
|
||||
for k, v in ipairs(datameans) do
|
||||
datameans[k] = tonumber(v)
|
||||
end
|
||||
|
||||
-- update means data for this entry
|
||||
local seendays = datameans[1]
|
||||
local newseendays = seendays + 1
|
||||
datameans[1] = newseendays
|
||||
datameans[2] = datameans[2] + dailyseen
|
||||
local seenauctions = datameans[7]
|
||||
if seenauctions then
|
||||
datameans[7] = seenauctions + (dailyauctions or dailyseen)
|
||||
else
|
||||
datameans[7] = dailyauctions -- may be nil
|
||||
end
|
||||
|
||||
if seendays < 3 then
|
||||
-- for first 3 days perform plain average insead of EMAs
|
||||
datameans[3] = numberformat((datameans[3] * seendays + dailyavg) / newseendays) -- EMA3
|
||||
datameans[6] = numberformat((datameans[6] * seendays + dailymbo) / newseendays) -- average minimum buyout
|
||||
if newseendays == 3 then
|
||||
-- this is the third day, prep other EMAs for next time
|
||||
datameans[4] = datameans[3]
|
||||
datameans[5] = datameans[3]
|
||||
end
|
||||
else
|
||||
-- do normal EMA calculations
|
||||
datameans[3] = numberformat((datameans[3] * 2 + dailyavg) / 3) -- EMA3
|
||||
datameans[4] = numberformat((datameans[4] * 6 + dailyavg) / 7) -- EMA7
|
||||
datameans[5] = numberformat((datameans[5] * 13 + dailyavg) / 14) -- EMA14
|
||||
|
||||
local avgmbo = datameans[6] -- average minimum buyout
|
||||
if avgmbo < 1 then
|
||||
datameans[6] = dailymbo
|
||||
else
|
||||
if dailymbo >= 1 then
|
||||
if avgmbo < dailymbo then
|
||||
if (avgmbo*10/dailymbo) < 9 then
|
||||
datameans[6] = numberformat((avgmbo+dailymbo)/2)
|
||||
else
|
||||
datameans[6] = numberformat((avgmbo*7+dailymbo)/8)
|
||||
end
|
||||
else
|
||||
if (dailymbo*10/avgmbo) < 9 then
|
||||
datameans[6] = numberformat((avgmbo+dailymbo)/2)
|
||||
else
|
||||
datameans[6] = numberformat((avgmbo*7+dailymbo)/8)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
itemstoremeans[lookupmeansindex[prop]] = prop..PROPERTY_DIVIDER..tconcat(datameans, DATA_DIVIDER)
|
||||
end
|
||||
if item_record.seen_days < 3 then
|
||||
-- for first 3 days perform plain average instead of EMAs
|
||||
item_record.EMA3 = (item_record.EMA3 * item_record.seen_days + daily_average) / (item_record.seen_days + 1)
|
||||
item_record.average_min_buyout = (item_record.average_min_buyout * item_record.seen_days + item_record.daily_min_buyout) / (item_record.seen_days + 1)
|
||||
item_record.EMA7 = item_record.EMA3
|
||||
item_record.EMA14 = item_record.EMA3
|
||||
else
|
||||
-- this property has not been seen before, create a new entry for it
|
||||
-- we don't need to use an intermediate table, we can build the datastring directly
|
||||
-- there is no need to update lookupmeansdata[prop] or lookupmeansindex[prop], as each prop should only occur once for each storeID
|
||||
if dailyauctions then
|
||||
tinsert(itemstoremeans, newstringtemplate7:format(prop, dailyseen, dailyavg, dailymbo, dailyauctions)) -- represents data table with 7 entries
|
||||
-- do normal EMA calculations
|
||||
item_record.EMA3 = (item_record.EMA3 * 2 + daily_average) / 3)
|
||||
item_record.EMA7 = (item_record.EMA7 * 6 + daily_average) / 7)
|
||||
item_record.EMA14 = (item_record.EMA14 * 13 + daily_average) / 14)
|
||||
|
||||
if item_record.daily_min_buyout / item_record.average_min_buyout < 0.9 then
|
||||
item_record.average_min_buyout = (item_record.average_min_buyout + item_record.daily_min_buyout) / 2
|
||||
else
|
||||
tinsert(itemstoremeans, newstringtemplate6:format(prop, dailyseen, dailyavg, dailymbo)) -- represents data table with 6 entries (missing seenauctions)
|
||||
item_record.average_min_buyout = (item_record.average_min_buyout * 7 + item_record.daily_min_buyout) / 8
|
||||
end
|
||||
end
|
||||
|
||||
item_record.count = item_record.unit_count + item_record.daily_unit_count
|
||||
item_record.count = item_record.auction_count + item_record.daily_auction_count
|
||||
item_record.seen_days = item_record.seen_days + 1
|
||||
|
||||
item_record.daily_auction_count = 0
|
||||
item_record.daily_unit_count = 0
|
||||
item_record.daily_min_buyout = nil
|
||||
item_record.daily_accumulated_buyout = 0
|
||||
end
|
||||
|
||||
means[storeID] = tconcat(itemstoremeans, ITEM_DIVIDER)
|
||||
wipe(lookupmeansdata)
|
||||
wipe(lookupmeansindex)
|
||||
end
|
||||
|
||||
realmdata.dailypush = time() + PUSHTIME
|
||||
wipe(daily)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user