Mokaam's historic market data

This site is intended as a supplement to Adam4eve, Fuzzwork, and the ESI from CCP. It provides an easy way to pull data based on the historic market data from The Forge, Domain and Sinq Laison in EVE online without making a query for every item.

The API was made with the Oz community trading sheet in mind so the implementation is heavily based on how Fuzzwork implements his API in Google Sheet. The Oz community sheet can be found on Oz's discord under #faq.

It is a project created as a learning experience for myself and is running on my own server, so if the response times are slow or the site doesn't work, the reason can be the hardware, the code, or anything in between and is most likely due to n00bishness from my side.

Huge thanks to Steve from Fuzzwork as well as Shikkoken and Bonsailinse from the Oz community for invaluable help, discussions, and advice.
Also Big thanks to Phaelim O'Neil (Lanarion on discord) from the trading community on Oz's discord, for writing the guide on calling the API from Excel and creating the examples.

Data returned from API:

typeid last_data vol_{time} avg_price_{time}
item ID of the item Last time CCP data was updated, returns date of the newest entry, "Null" if no data from market, "Itemid not found" or "ERROR: {error_code}" if update from CCP gave an error Median volume of market for {time} = yesterday, last week, month, quarter, or year respectively Median average price for {time} = yesterday, last week, month, quarter, or year respectively
order_count_{time} size_{time} high_{time} ab_high_{time}
Median number of orders fulfilled for {time} = yesterday, last week, month, quarter, or year respectively Median size of market for {time} = yesterday, last week, month, quarter, or year respectively Median highest price traded for {time} = yesterday, last week, month, quarter, or year respectively Highest traded price within 4 standard deviations for {time} = yesterday, last week, month, quarter, or year respectively
low_{time} ab_low_{time} spread_{time} vwap_{time}
Median lowest price traded for {time} = yesterday, last week, month, quarter, or year respectively Lowest traded price within 4 standard deviations for {time} = yesterday, last week, month, quarter, or year respectively Median spread of market for {time} = yesterday, last week, month, quarter, or year respectively Volume weighted average price for {time} = last week, month, quarter, or year respectively
_52w_{high/low} std_dev_{time}
52 week highest or lowest average price traded respectively Standard deviation on average traded price for {time} = last week, month, quarter, or year respectively

How to format calls

There are currently 3 regions available:
The Forge with region id: 10000002
Sinq Laison with region id: 10000032
Domain with region id: 10000043

Requests can be formated to call data for one or more items from a region with:

https://mokaam.dk/API/market/items?regionid=10000002&typeid=28425,28441

Requests can be formated to call all data from a region. Be carefull not to use this call in Google Sheet as it will return too much data for Google Sheet to handle

https://mokaam.dk/API/market/all?regionid=10000002

How to call the API in Google Sheet

The API is called in Google Sheet in the same way as Fuzzwork calls his. Below is a script function to implement in Google Sheet to pull data. I highly suggest to only parse the data you need into Google Sheet

function loadmarkethistory(priceIDs,regionID){ if (typeof regionID == 'undefined'){ regionID=10000002; } if (typeof priceIDs == 'undefined'){ throw 'Need a list of typeids'; } var prices = new Array(); var dirtyTypeIds = new Array(); var cleanTypeIds = new Array(); var url="https://www.mokaam.dk/API/market/items?regionid="+regionID+"&typeid=" priceIDs.forEach (function (row) { row.forEach ( function (cell) { if (typeof(cell) === 'number' ) { dirtyTypeIds.push(cell); } }); }); cleanTypeIds = dirtyTypeIds.filter(function(v,i,a) { return a.indexOf(v)===i; }); prices.push([ 'TypeID', 'Last updated', 'Vol. yesterday', 'Median vol. last week', 'Median vol. last month', 'Median vol. last quarter', 'Median vol. last year', 'Avg. price yesterday', 'Median avg. price last week', 'Median avg. price last month', 'Median avg. price last quarter', 'Median avg. price last year', 'Order count yesterday', 'Order count last week', 'Order count last month', 'Order count last quarter', 'Order count last year', 'Size yesterday', 'Median size last week', 'Median size last month', 'Median size last quarter', 'Median size last year', 'Highest price yesterday', 'Median highest price last week', 'Median highest price last month', 'Median highest price last quarter', 'Median highest price last year', 'Highest price yesterday', 'Higest price last week', 'Highest price last month', 'Highest price last quarter', 'Highest price last year', 'Lowest price yesterday', 'Median lowest price last week', 'Median lowest price last month', 'Median lowest price last quarter', 'Median lowest price last year', 'Lowest price yesterday', 'Lowest price last week', 'Lowest price last month', 'Lowest price last quarter', 'Lowest price last year', 'Spread yesterday', 'Median spread last week', 'Median spread last month', 'Median spread last quarter', 'Median spread last year', 'VWAP last week', 'VWAP last month', 'VWAP last quarter', 'VWAP last year', '52 week low', '52 week high', 'Std dev week', 'Std dev month', 'Std dev quarter', 'Std dev year']) var parameters = {method : "get", payload : ""}; var o,j,temparray,chunk = 100; for (o=0,j=cleanTypeIds.length; o < j; o+=chunk) { temparray = cleanTypeIds.slice(o,o+chunk); Utilities.sleep(100); var types=temparray.join(",").replace(/,$/,'') var jsonFeed = UrlFetchApp.fetch(url+types, parameters).getContentText(); var json = JSON.parse(jsonFeed); if(json) { for(i in json) { var price=[parseInt(i), json[i].last_data, parseFloat(json[i].vol_yesterday), parseFloat(json[i].vol_week), parseFloat(json[i].vol_month), parseFloat(json[i].vol_quarter), parseFloat(json[i].vol_year), parseFloat(json[i].avg_price_yesterday), parseFloat(json[i].avg_price_week), parseFloat(json[i].avg_price_month), parseFloat(json[i].avg_price_quarter), parseFloat(json[i].avg_price_year), parseFloat(json[i].order_count_yesterday), parseFloat(json[i].order_count_week), parseFloat(json[i].order_count_month), parseFloat(json[i].order_count_quarter), parseFloat(json[i].order_count_year), parseFloat(json[i].size_yesterday), parseFloat(json[i].size_week), parseFloat(json[i].size_month), parseFloat(json[i].size_quarter), parseFloat(json[i].size_year), parseFloat(json[i].high_yesterday), parseFloat(json[i].high_week), parseFloat(json[i].high_month), parseFloat(json[i].high_quarter), parseFloat(json[i].high_year), parseFloat(json[i].ab_high_yesterday), parseFloat(json[i].ab_high_week), parseFloat(json[i].ab_high_month), parseFloat(json[i].ab_high_quarter), parseFloat(json[i].ab_high_year), parseFloat(json[i].low_yesterday), parseFloat(json[i].low_week), parseFloat(json[i].low_month), parseFloat(json[i].low_quarter), parseFloat(json[i].low_year), parseFloat(json[i].ab_low_yesterday), parseFloat(json[i].ab_low_week), parseFloat(json[i].ab_low_month), parseFloat(json[i].ab_low_quarter), parseFloat(json[i].ab_low_year), parseFloat(json[i].spread_yesterday), parseFloat(json[i].spread_week), parseFloat(json[i].spread_month), parseFloat(json[i].spread_quarter), parseFloat(json[i].spread_year), parseFloat(json[i].vwap_week), parseFloat(json[i].vwap_month), parseFloat(json[i].vwap_quarter), parseFloat(json[i].vwap_year), parseFloat(json[i]._52w_low), parseFloat(json[i]._52w_high), parseFloat(json[i].std_dev_week), parseFloat(json[i].std_dev_month), parseFloat(json[i].std_dev_quarter), parseFloat(json[i].std_dev_year)]; prices.push(price); } } } return prices; }

How to call the API in Excel

The API is called from Excel by using Power Query. It requires either Excel 365 or PowerBI for the following guide to work. I will use an example so all codes should be modified with your own cells, names and ranges. Before we get started a few steps has to be done in Excel to ready the data for Power Query. First create a column with itemids (or use the one you have in your current sheet) and a cell with the regionid of the region to get data from. Then in a new cell join the itemids:

=TEXTJOIN(",",TRUE,!A2:A10)

This returns a concatenated, comma seperated text string that represents all the itemids. Now either format the cell with the regionid as text or create a new cell to convert the regionid from a number to text by using:

=TEXT(C2,0)

Preparation of Excel for Power Query

Define a name for the joined itemids and the regionid in the Name Manager. Go to Name Manager in the "Formula" tab. Press "New" and add the cells with the joined text and the regionid with each their name. I named my itemids "list" and my regionid "regionID".


Name Manager Location

Name Manager

From the "Data" tab choose "From Web" and enter the following URL into the URL field and press "OK":

https://mokaam.dk/API/market/items?regionid=10000002&typeid=4

From web Location

This should open the Power Query Editor, if it doesn't open, click "Queries & Connections" and double click the query. In the Power Query Editor you might have a warning about privacy, Click "Continue" and check "Ignore Privacy Levels.." and press "Save".

Privacy Warning

Privacy Setting

Go to the "Home" tab of the Power Query Editor and choose "Advanced Editor".

Advanced Editor

Replace all code with the following and click "Done" and then click "Close & Load" under the "Home" tab in the Power Query Editor.

let list=Excel.CurrentWorkbook(){[Name="list"]}[Content]{0}[Column1], region=Excel.CurrentWorkbook(){[Name="regionID"]}[Content]{0}[Column1], Source = Json.Document(Web.Contents("https://mokaam.dk/API/market/items?regionid="&region&"&typeid="&list&" ")), #"Converted to Table" = Record.ToTable(Source), #"Expanded Value" = Table.ExpandRecordColumn(#"Converted to Table", "Value", { "typeid", "last_data", "vol_yesterday", "vol_week", "vol_month", "vol_quarter", "vol_year", "avg_price_yesterday", "avg_price_week", "avg_price_month", "avg_price_quarter", "avg_price_year", "order_count_yesterday", "order_count_week", "order_count_month", "order_count_quarter", "order_count_year", "size_yesterday", "size_week", "size_month", "size_quarter", "size_year", "high_yesterday", "high_week", "high_month", "high_quarter", "high_year", "ab_high_yesterday", "ab_high_week", "ab_high_month", "ab_high_quarter", "ab_high_year", "low_yesterday", "low_week", "low_month", "low_quarter", "low_year", "ab_low_yesterday", "ab_low_week", "ab_low_month", "ab_low_quarter", "ab_low_year", "spread_yesterday", "spread_week", "spread_month", "spread_quarter", "spread_year", "vwap_week", "vwap_month", "vwap_quarter", "vwap_year", "_52w_low", "_52w_high", "std_dev_week", "std_dev_month", "std_dev_quarter", "std_dev_year"}, {"Value.typeid", "Value.last_data", "Value.vol_yesterday", "Value.vol_week", "Value.vol_month", "Value.vol_quarter", "Value.vol_year", "Value.avg_price_yesterday", "Value.avg_price_week", "Value.avg_price_month", "Value.avg_price_quarter", "Value.avg_price_year", "Value.order_count_yesterday", "Value.order_count_week", "Value.order_count_month", "Value.order_count_quarter", "Value.order_count_year", "Value.size_yesterday", "Value.size_week", "Value.size_month", "Value.size_quarter", "Value.size_year", "Value.high_yesterday", "Value.high_week", "Value.high_month", "Value.high_quarter", "Value.high_year", "Value.ab_high_yesterday", "Value.ab_high_week", "Value.ab_high_month", "Value.ab_high_quarter", "Value.ab_high_year", "Value.low_yesterday", "Value.low_week", "Value.low_month", "Value.low_quarter", "Value.low_year", "Value.ab_low_yesterday", "Value.ab_low_week", "Value.ab_low_month", "Value.ab_low_quarter", "Value.ab_low_year", "Value.spread_yesterday", "Value.spread_week", "Value.spread_month", "Value.spread_quarter", "Value.spread_year", "Value.vwap_week", "Value.vwap_month", "Value.vwap_quarter", "Value.vwap_year", "Value._52w_low", "Value._52w_high", "Value.std_dev_week", "Value.std_dev_month", "Value.std_dev_quarter", "Value.std_dev_year"}), #"Removed Columns" = Table.RemoveColumns(#"Expanded Value",{"Value.typeid"}), #"Filtered Rows" = Table.SelectRows(#"Removed Columns", each ( [Value.last_data] <> "ERROR: 404" and [Value.last_data] <> "ERROR: 502" and [Value.last_data] <> "Itemid not found" and [Value.last_data] <> "Null")) in #"Filtered Rows"