Skip to content

Instantly share code, notes, and snippets.

@MrMeison
Created January 8, 2020 20:53
Show Gist options
  • Save MrMeison/aa68d3677d5443035fcbc3aa4a12a946 to your computer and use it in GitHub Desktop.
Save MrMeison/aa68d3677d5443035fcbc3aa4a12a946 to your computer and use it in GitHub Desktop.
Скрипт для Google Sheets для получения данных индекса, акциях и облигациях
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