Created
January 8, 2020 20:53
-
-
Save MrMeison/aa68d3677d5443035fcbc3aa4a12a946 to your computer and use it in GitHub Desktop.
Скрипт для Google Sheets для получения данных индекса, акциях и облигациях
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var MicexApi = {}; | |
// список id разных типов ЦБ | |
var BOARD_ID = { | |
STOCK: 'TQBR', | |
ETF: 'TQTF', | |
BONDS: 'EQOB' | |
}; | |
(function(App) { | |
var MICEX_ENTRYPOINT = 'https://iss.moex.com/iss/'; | |
var MICEX_REQ_PARAMS = { | |
'iss.meta': 'off' | |
}; | |
var DEFAULT_SHARES_PARAMS = { | |
'iss.only': 'marketdata' | |
}; | |
var DEFAULT_BONDS_PARAMS = { | |
'iss.only': 'marketdata,securities' | |
}; | |
var DEFAULT_SHARES_OPTIONS = { | |
columns: { | |
marketdata: ['SECID', 'LAST'] | |
}, | |
mapping: { | |
marketdata: { | |
'SECID': 'ticker', | |
'LAST': 'price' | |
}, | |
} | |
}; | |
var DEFAULT_BOND_OPTIONS = { | |
columns: { | |
marketdata: ['SECID', 'LAST'], | |
securities: ['LOTVALUE'] | |
}, | |
mapping: { | |
marketdata: { | |
'SECID': 'ticker', | |
'LAST': 'price' | |
}, | |
securities: { | |
'LOTVALUE': 'lot' | |
} | |
} | |
}; | |
function getPageIndexs(cursor) { | |
var fieldsMap = { | |
'INDEX': 'index', | |
'TOTAL': 'total', | |
'PAGESIZE': 'pageSize' | |
}; | |
var pages = []; | |
var currentCursor = { | |
index: undefined, | |
total: undefined, | |
pageSize: undefined | |
}; | |
var columns = cursor.columns; | |
var cursorData = cursor.data[0]; | |
for(var i = 0; i < columns.length; i++) { | |
if(fieldsMap.hasOwnProperty(columns[i])) { | |
currentCursor[fieldsMap[columns[i]]] = cursorData[i]; | |
} | |
} | |
var nextPageIndex = currentCursor.index + currentCursor.pageSize; | |
while(nextPageIndex && nextPageIndex < currentCursor.total) { | |
pages.push(nextPageIndex); | |
nextPageIndex += currentCursor.pageSize; | |
} | |
return pages; | |
} | |
function convertToObject(columns, rows, map) { | |
return rows.map(function(row) { | |
return row.reduce(function(acc, cell, index) { | |
if (map) { | |
acc[map[columns[index]]] = cell; | |
} else { | |
acc[columns[index]] = cell; | |
} | |
return acc; | |
}, {}); | |
}); | |
} | |
App.getIndexTickersMeta = function(indexTicker) { | |
var INDEX_PARAMS = { | |
'analytics.columns': 'ticker,weight', | |
'start': 0 | |
}; | |
var getUrl = function(params) { | |
return MICEX_ENTRYPOINT + 'statistics/engines/stock/markets/index/analytics/'+ indexTicker + '.json' + CGI.buildQueryParams(params); | |
}; | |
var params = Object.assign({}, MICEX_REQ_PARAMS, INDEX_PARAMS); | |
var response = UrlFetchApp.fetch(getUrl(params)).getContentText(); | |
var data = JSON.parse(response); | |
var pages = getPageIndexs(data['analytics.cursor']); | |
var tickersMeta = convertToObject(data['analytics']['columns'], data['analytics']['data']); | |
if (pages) { | |
var urls = pages.map(function(page) { | |
return getUrl(Object.assign({}, MICEX_REQ_PARAMS, INDEX_PARAMS, { start: page })) | |
}); | |
tickersMeta = UrlFetchApp.fetchAll(urls).reduce(function(acc, response) { | |
var data = JSON.parse(response); | |
return acc.concat(convertToObject(data['analytics']['columns'], data['analytics']['data'])); | |
}, tickersMeta); | |
} | |
return tickersMeta; | |
}; | |
App.getMarketData = function(ids, marketType, boardId, params, options) { | |
var queryParams = {}; | |
var url = MICEX_ENTRYPOINT + 'engines/stock/markets/'+ marketType; | |
if (boardId) { | |
url += '/boards/'+ boardId; | |
} | |
for (var nodeKey in options.mapping) { | |
queryParams[nodeKey + '.columns'] = options.columns[nodeKey].join(); | |
} | |
queryParams = Object.assign({}, MICEX_REQ_PARAMS, queryParams, { 'securities': ids.join() }); | |
url += '/securities.json' + CGI.buildQueryParams(queryParams); | |
var response = UrlFetchApp.fetch(url).getContentText(); | |
var data = JSON.parse(response); | |
var result = []; | |
for (var nodeKey in options.mapping) { | |
var additionalData = convertToObject(data[nodeKey]['columns'], data[nodeKey]['data'], options.mapping[nodeKey]); | |
if (result.length) { | |
result.forEach(function(item, index) { | |
Object.assign(item, additionalData[index]); | |
}); | |
} else { | |
result = additionalData; | |
} | |
} | |
return result; | |
}; | |
App.getPriceByTickers = function(tickers, boardId) { | |
var params = Object.assign({}, MICEX_REQ_PARAMS, DEFAULT_SHARES_PARAMS); | |
return App.getMarketData(tickers, 'shares', boardId, params, DEFAULT_SHARES_OPTIONS); | |
}; | |
App.getPriceByISINs = function(isins, boardId) { | |
var params = Object.assign({}, MICEX_REQ_PARAMS, DEFAULT_BONDS_PARAMS); | |
return App.getMarketData(isins, 'bonds', boardId, params, DEFAULT_BOND_OPTIONS); | |
}; | |
})(MicexApi); | |
function getIndex(ticker) { | |
return MicexApi.getIndexTickersMeta(ticker); | |
} | |
function getPriceByTickers(tickers, boardId) { | |
return MicexApi.getPriceByTickers(tickers, boardId); | |
} | |
function getPriceByISINs(isins, boardId) { | |
return MicexApi.getPriceByISINs(isins, boardId); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment