📄 aucstatistic.lua
字号:
--[[ Auctioneer Addon for World of Warcraft(tm). Version: 3.5.0.0917 (Platypus) Revision: $Id: AucStatistic.lua 872 2006-05-21 09:24:08Z luke1410 $ Auctioneer statistical functions. Functions to calculate various forms of statistics from the auction data. License: This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program(see GPL.txt); if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.]]--Local function prototypeslocal subtractPercent, addPercent, percentLessThan, getLowest, getMedian, getPercentile, getMeans, getItemSnapshotMedianBuyout, getItemHistoricalMedianBuyout, getUsableMedian, getCurrentBid, isBadResaleChoice, profitComparisonSort, roundDownTo95, findLowestAuctions, buildLowestCache, doLow, doMedian, doHSP, getBidBasedSellablePrice, getMarketPrice, getHSP, determinePrice-- Subtracts/Adds given percentage from/to a valuefunction subtractPercent(value, percentLess) --function subtractPercent(value, percentLess) return math.floor(value * ((100 - percentLess)/100));endfunction addPercent(value, percentMore) return math.floor(value * ((100 + percentMore)/100));end-- returns the integer representation of the percent less value2 is from value1-- example: value1=10, value2=7, percentLess=30function percentLessThan(value1, value2) if Auctioneer.Util.NullSafe(value1) > 0 and Auctioneer.Util.NullSafe(value2) < Auctioneer.Util.NullSafe(value1) then return 100 - math.floor((100 * Auctioneer.Util.NullSafe(value2))/Auctioneer.Util.NullSafe(value1)); else return 0; endendfunction getLowest(valuesTable) if (not valuesTable or table.getn(valuesTable) == 0) then return nil, nil; end local tableSize = table.getn(valuesTable); local lowest = tonumber(valuesTable[1]) or 0; local second = nil if (tableSize > 1) then for i=2, tableSize do second = tonumber(valuesTable[i]) or 0; if (second > lowest) then return lowest, second; end end end return lowest, nil;end-- Returns the median value of a given table one-dimentional tablefunction getMedian(valuesTable) return getPercentile(valuesTable, 0.5)end-- Return weighted average percentile such that returned value-- is larger than or equal to (100*pct)% of the table values-- 0 <= pct <= 1function getPercentile(valuesTable, pct) if (type(valuesTable) ~= "table") or (not tonumber(pct)) then return nil -- make valuesTable a required table argument end pct = math.min(math.max(pct, 0), 1) -- Make sure 0 <= pct <= 1 local _percentile = function(sortedTable, p, first, last) local f = (last - first) * p + first local i1, i2 = math.floor(f), math.ceil(f) f = f - i1 return sortedTable[i1] * (1 - f) + sortedTable[i2] * f end local tableSize = table.getn(valuesTable) or 0 if (tableSize == 0) then return 0, 0; -- if there is an empty table, returns median = 0, count = 0 elseif (tableSize == 1) then return tonumber(valuesTable[1]), 1 end -- The following calculations require a sorted table table.sort(valuesTable) -- Skip IQR calculations if table is too small to have outliers if tableSize <= 4 then return _percentile(valuesTable, pct, 1, tableSize), tableSize end -- REWORK by Karavirs to use IQR*1.5 to ignore outliers -- q1 is median 1st quartile q2 is median of set q3 is median of 3rd quartile iqr is q3 - q1 local q1 = _percentile(valuesTable, 0.25, 1, tableSize) local q3 = _percentile(valuesTable, 0.75, 1, tableSize) assert(q3 >= q1) local iqr = (q3 - q1) * 1.5 local iqlow, iqhigh = q1 - iqr, q3 + iqr -- Find first and last index to include in median calculation local first, last = 1, tableSize -- Skip low outliers while valuesTable[first] < iqlow do first = first + 1 end -- Skip high outliers while valuesTable[last] > iqhigh do last = last - 1 end assert(last >= first) return _percentile(valuesTable, pct, first, last), last - first + 1end-- Return all of the averages for an item-- Returns: avgMin,avgBuy,avgBid,bidPct,buyPct,avgQty,aCountfunction getMeans(itemKey, from) local auctionPriceItem = Auctioneer.Core.GetAuctionPriceItem(itemKey, from); if (not auctionPriceItem.data) then EnhTooltip.DebugPrint("Error, GetAuctionPriceItem", itemKey, from, "returns", auctionPriceItem); end local aCount,minCount,minPrice,bidCount,bidPrice,buyCount,buyPrice = Auctioneer.Core.GetAuctionPrices(auctionPriceItem.data); local avgMin,avgBuy,avgBid,bidPct,buyPct,avgQty; if aCount > 0 then avgQty = math.floor(minCount / aCount); avgMin = math.floor(minPrice / minCount); bidPct = math.floor(bidCount / minCount * 100); buyPct = math.floor(buyCount / minCount * 100); avgBid = 0; if (bidCount > 0) then avgBid = math.floor(bidPrice / bidCount); end avgBuy = 0; if (buyCount > 0) then avgBuy = math.floor(buyPrice / buyCount); end end return avgMin,avgBuy,avgBid,bidPct,buyPct,avgQty,aCount;end-- Returns the current snapshot median for an itemfunction getItemSnapshotMedianBuyout(itemKey, auctKey, buyoutPrices) if (not auctKey) then auctKey = Auctioneer.Util.GetAuctionKey() end local stat, count; if (AuctionConfig.stats and AuctionConfig.stats.snapmed and AuctionConfig.stats.snapmed[auctKey]) then stat = AuctionConfig.stats.snapmed[auctKey][itemKey]; count = AuctionConfig.stats.snapcount[auctKey][itemKey]; end if (not stat) or (not count) then if (not buyoutPrices) then local sbuy = Auctioneer.Core.GetSnapshotInfo(auctKey, itemKey); if (sbuy) then buyoutPrices = sbuy.buyoutPrices; end end if (buyoutPrices) then stat, count = getMedian(buyoutPrices); else stat, count = 0, 0; end -- save median to the savedvariablesfile Auctioneer.Storage.SetSnapMed(auctKey, itemKey, stat, count) end return stat, count;end-- Returns the historical median for an itemfunction getItemHistoricalMedianBuyout(itemKey, auctKey, buyoutHistoryTable) if (not auctKey) then auctKey = Auctioneer.Util.GetAuctionKey() end local stat, count; if (AuctionConfig.stats and AuctionConfig.stats.histmed and AuctionConfig.stats.histmed[auctKey]) then stat = AuctionConfig.stats.histmed[auctKey][itemKey]; count = AuctionConfig.stats.histcount[auctKey][itemKey]; end if (not stat) or (not count) then if (not buyoutHistoryTable) then buyoutHistoryTable = Auctioneer.Core.GetAuctionBuyoutHistory(itemKey, auctKey); end if (buyoutHistoryTable) then stat, count = getMedian(buyoutHistoryTable); else stat, count = 0, 0; end -- save median to the savedvariablesfile Auctioneer.Storage.SetHistMed(auctKey, itemKey, stat, count); end return stat, count;end-- this function returns the most accurate median possible,-- if an accurate median cannot be obtained based on min seen counts then nil is returnedfunction getUsableMedian(itemKey, realm, buyoutPrices) if not realm then realm = Auctioneer.Util.GetAuctionKey(); end --get snapshot median local snapshotMedian, snapCount = getItemSnapshotMedianBuyout(itemKey, realm, buyoutPrices) --get history median local historyMedian, histCount = getItemHistoricalMedianBuyout(itemKey, realm); local median, count if (histCount >= Auctioneer.Core.Constants.MinBuyoutSeenCount) then median, count = historyMedian, histCount; end if (snapCount >= Auctioneer.Core.Constants.MinBuyoutSeenCount) then if (histCount < snapCount) then -- History median isn't shown in tooltip if histCount < snapCount so use snap median in this case median, count = snapshotMedian, snapCount; elseif (snapshotMedian < 1.2 * historyMedian) then median, count = snapshotMedian, snapCount; end end return median, count;end-- Returns the current bid on an auctionfunction getCurrentBid(auctionSignature) local x,x,x, x, x,min,x,_ = Auctioneer.Core.GetItemSignature(auctionSignature); local auctKey = Auctioneer.Util.GetAuctionKey(); local itemCat = Auctioneer.Util.GetCatForSig(auctionSignature); local snap = Auctioneer.Core.GetSnapshot(auctKey, itemCat, auctionSignature); if (not snap) then return 0 end local currentBid = tonumber(snap.bidamount) or 0; if currentBid == 0 then currentBid = min end return currentBid;end-- This filter will return true if an auction is a bad choice for resellingfunction isBadResaleChoice(auctSig, auctKey) if (not auctKey) then auctKey = Auctioneer.Util.GetAuctionKey() end local isBadChoice = false; local id,rprop,enchant, name, count,min,buyout,uniq = Auctioneer.Core.GetItemSignature(auctSig); local itemKey = id..":"..rprop..":"..enchant; local itemCat = Auctioneer.Util.GetCatForKey(itemKey); local auctionItem = Auctioneer.Core.GetSnapshot(auctKey, itemCat, auctSig); local auctionPriceItem = Auctioneer.Core.GetAuctionPriceItem(itemKey, auctKey); local aCount,minCount,minPrice,bidCount,bidPrice,buyCount,buyPrice = Auctioneer.Core.GetAuctionPrices(auctionPriceItem.data); local bidPercent = math.floor(bidCount / minCount * 100); if (auctionItem) then local itemLevel = tonumber(auctionItem.level); local itemQuality = tonumber(auctionItem.quality); -- bad choice conditions if Auctioneer.Core.Constants.BidBasedCategories[auctionItem.category] and bidPercent < Auctioneer.Core.Constants.MinBidPercent then isBadChoice = true; -- bidbased items should have a minimum bid percent elseif (itemLevel >= 50 and itemQuality == Auctioneer.Core.Constants.Quality.Uncommon and bidPercent < Auctioneer.Core.Constants.MinBidPercent) then isBadChoice = true; -- level 50 and greater greens that do not have bids do not sell well elseif auctionItem.owner == UnitName("player") or auctionItem.highBidder then isBadChoice = true; -- don't display auctions that we own, or are high bidder on elseif itemQuality == Auctioneer.Core.Constants.Quality.Poor then isBadChoice = true; -- gray items are never a good choice end end return isBadChoice;end-- method to pass to table.sort() that sorts auctions by profit descendingfunction profitComparisonSort(a, b) local aid,arprop,aenchant, aName, aCount, x, aBuyout, x = Auctioneer.Core.GetItemSignature(a.signature); local bid,brprop,benchant, bName, bCount, x, bBuyout, x = Auctioneer.Core.GetItemSignature(b.signature); local aItemKey = aid .. ":" .. arprop..":"..aenchant; local bItemKey = bid .. ":" .. brprop..":"..benchant; local realm = Auctioneer.Util.GetAuctionKey() local aProfit = (getHSP(aItemKey, realm) * aCount) - aBuyout; local bProfit = (getHSP(bItemKey, realm) * bCount) - bBuyout; return (aProfit > bProfit)end-- this function takes copper and rounds to 5 silver below the the nearest gold if it is less than 15 silver above of an even gold-- example: this function changes 1g9s to 95s-- example: 1.5g will be unchanged and remain 1.5gfunction roundDownTo95(copper) local g,s,c = EnhTooltip.GetGSC(copper); if g > 0 and s < 10 then return (copper - ((s + 5) * 100)); -- subtract enough copper to round to 95 silver end return copper;end-- given an item name, find the lowest price for that item in the current AHSnapshot-- if the item does not exist in the snapshot or the snapshot does not exist-- a nil is returned.function findLowestAuctions(itemKey, auctKey) local itemID, itemRand, enchant = Auctioneer.Util.BreakItemKey(itemKey); if (itemID == nil) then return nil; end if (not auctKey) then auctKey = Auctioneer.Util.GetAuctionKey(); end if not (Auctioneer_Lowests and Auctioneer_Lowests[auctKey]) then buildLowestCache(auctKey) end local lowKey = itemID..":"..itemRand; local itemCat = nil; local lowSig = nil; local nextSig = nil;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -