mirror of
https://github.com/mempool/mempool.git
synced 2025-01-18 05:12:35 +01:00
* /volumes API
* /ticker API
This commit is contained in:
parent
bafe2db094
commit
a11135f358
@ -15,9 +15,9 @@
|
|||||||
"TX_PER_SECOND_SPAN_SECONDS": 150,
|
"TX_PER_SECOND_SPAN_SECONDS": 150,
|
||||||
"ELECTRS_API_URL": "http://localhost:50001",
|
"ELECTRS_API_URL": "http://localhost:50001",
|
||||||
"BISQ_ENABLED": false,
|
"BISQ_ENABLED": false,
|
||||||
|
"BISQ_BLOCKS_DATA_PATH": "/bisq/seednode-data/btc_mainnet/db/json",
|
||||||
"BISQ_MARKET_ENABLED": false,
|
"BISQ_MARKET_ENABLED": false,
|
||||||
"BSQ_BLOCKS_DATA_PATH": "/bisq/data",
|
"BISQ_MARKETS_DATA_PATH": "/bisq/seednode-data/btc_mainnet/db",
|
||||||
"BSQ_MARKETS_DATA_PATH": "/bisq-folder/Bisq",
|
|
||||||
"SSL": false,
|
"SSL": false,
|
||||||
"SSL_CERT_FILE_PATH": "/etc/letsencrypt/live/mysite/fullchain.pem",
|
"SSL_CERT_FILE_PATH": "/etc/letsencrypt/live/mysite/fullchain.pem",
|
||||||
"SSL_KEY_FILE_PATH": "/etc/letsencrypt/live/mysite/privkey.pem"
|
"SSL_KEY_FILE_PATH": "/etc/letsencrypt/live/mysite/privkey.pem"
|
||||||
|
@ -72,8 +72,8 @@ class Bisq {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private checkForBisqDataFolder() {
|
private checkForBisqDataFolder() {
|
||||||
if (!fs.existsSync(config.BSQ_BLOCKS_DATA_PATH + Bisq.BLOCKS_JSON_FILE_PATH)) {
|
if (!fs.existsSync(config.BISQ_BLOCKS_DATA_PATH + Bisq.BLOCKS_JSON_FILE_PATH)) {
|
||||||
console.log(config.BSQ_BLOCKS_DATA_PATH + Bisq.BLOCKS_JSON_FILE_PATH + ` doesn't exist. Make sure Bisq is running and the config is correct before starting the server.`);
|
console.log(config.BISQ_BLOCKS_DATA_PATH + Bisq.BLOCKS_JSON_FILE_PATH + ` doesn't exist. Make sure Bisq is running and the config is correct before starting the server.`);
|
||||||
return process.exit(1);
|
return process.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,7 +83,7 @@ class Bisq {
|
|||||||
this.topDirectoryWatcher.close();
|
this.topDirectoryWatcher.close();
|
||||||
}
|
}
|
||||||
let fsWait: NodeJS.Timeout | null = null;
|
let fsWait: NodeJS.Timeout | null = null;
|
||||||
this.topDirectoryWatcher = fs.watch(config.BSQ_BLOCKS_DATA_PATH, () => {
|
this.topDirectoryWatcher = fs.watch(config.BISQ_BLOCKS_DATA_PATH, () => {
|
||||||
if (fsWait) {
|
if (fsWait) {
|
||||||
clearTimeout(fsWait);
|
clearTimeout(fsWait);
|
||||||
}
|
}
|
||||||
@ -105,13 +105,13 @@ class Bisq {
|
|||||||
if (this.subdirectoryWatcher) {
|
if (this.subdirectoryWatcher) {
|
||||||
this.subdirectoryWatcher.close();
|
this.subdirectoryWatcher.close();
|
||||||
}
|
}
|
||||||
if (!fs.existsSync(config.BSQ_BLOCKS_DATA_PATH + Bisq.BLOCKS_JSON_FILE_PATH)) {
|
if (!fs.existsSync(config.BISQ_BLOCKS_DATA_PATH + Bisq.BLOCKS_JSON_FILE_PATH)) {
|
||||||
console.log(config.BSQ_BLOCKS_DATA_PATH + Bisq.BLOCKS_JSON_FILE_PATH + ` doesn't exist. Trying to restart sub directory watcher again in 3 minutes.`);
|
console.log(config.BISQ_BLOCKS_DATA_PATH + Bisq.BLOCKS_JSON_FILE_PATH + ` doesn't exist. Trying to restart sub directory watcher again in 3 minutes.`);
|
||||||
setTimeout(() => this.startSubDirectoryWatcher(), 180000);
|
setTimeout(() => this.startSubDirectoryWatcher(), 180000);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let fsWait: NodeJS.Timeout | null = null;
|
let fsWait: NodeJS.Timeout | null = null;
|
||||||
this.subdirectoryWatcher = fs.watch(config.BSQ_BLOCKS_DATA_PATH + '/all', () => {
|
this.subdirectoryWatcher = fs.watch(config.BISQ_BLOCKS_DATA_PATH + '/all', () => {
|
||||||
if (fsWait) {
|
if (fsWait) {
|
||||||
clearTimeout(fsWait);
|
clearTimeout(fsWait);
|
||||||
}
|
}
|
||||||
@ -243,10 +243,10 @@ class Bisq {
|
|||||||
|
|
||||||
private loadData(): Promise<string> {
|
private loadData(): Promise<string> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!fs.existsSync(config.BSQ_BLOCKS_DATA_PATH + Bisq.BLOCKS_JSON_FILE_PATH)) {
|
if (!fs.existsSync(config.BISQ_BLOCKS_DATA_PATH + Bisq.BLOCKS_JSON_FILE_PATH)) {
|
||||||
return reject(Bisq.BLOCKS_JSON_FILE_PATH + ` doesn't exist`);
|
return reject(Bisq.BLOCKS_JSON_FILE_PATH + ` doesn't exist`);
|
||||||
}
|
}
|
||||||
fs.readFile(config.BSQ_BLOCKS_DATA_PATH + Bisq.BLOCKS_JSON_FILE_PATH, 'utf8', (err, data) => {
|
fs.readFile(config.BISQ_BLOCKS_DATA_PATH + Bisq.BLOCKS_JSON_FILE_PATH, 'utf8', (err, data) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
}
|
}
|
||||||
|
@ -234,8 +234,8 @@ export interface TradesData {
|
|||||||
|
|
||||||
export interface MarketVolume {
|
export interface MarketVolume {
|
||||||
period_start: number;
|
period_start: number;
|
||||||
volume: string;
|
|
||||||
num_trades: number;
|
num_trades: number;
|
||||||
|
volume: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MarketsApiError {
|
export interface MarketsApiError {
|
||||||
@ -244,3 +244,15 @@ export interface MarketsApiError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type Interval = 'minute' | 'half_hour' | 'hour' | 'half_day' | 'day' | 'week' | 'month' | 'year' | 'auto';
|
export type Interval = 'minute' | 'half_hour' | 'hour' | 'half_day' | 'day' | 'week' | 'month' | 'year' | 'auto';
|
||||||
|
|
||||||
|
export interface SummarizedIntervals { [market: string]: SummarizedInterval; }
|
||||||
|
export interface SummarizedInterval {
|
||||||
|
'period_start': number;
|
||||||
|
'open': number;
|
||||||
|
'close': number;
|
||||||
|
'high': number;
|
||||||
|
'low': number;
|
||||||
|
'avg': number;
|
||||||
|
'volume_right': number;
|
||||||
|
'volume_left': number;
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Currencies, OffsersData, TradesData, Depth, Currency, Interval, HighLowOpenClose,
|
import { Currencies, OffsersData, TradesData, Depth, Currency, Interval, HighLowOpenClose,
|
||||||
Markets, Offers, Offer, BisqTrade, MarketVolume, Tickers } from './interfaces';
|
Markets, Offers, Offer, BisqTrade, MarketVolume, Tickers, Ticker, SummarizedIntervals, SummarizedInterval } from './interfaces';
|
||||||
|
|
||||||
import * as datetime from 'locutus/php/datetime';
|
import * as datetime from 'locutus/php/datetime';
|
||||||
|
|
||||||
@ -8,6 +8,8 @@ class BisqMarketsApi {
|
|||||||
private fiatCurrencyData: Currency[] = [];
|
private fiatCurrencyData: Currency[] = [];
|
||||||
private offersData: OffsersData[] = [];
|
private offersData: OffsersData[] = [];
|
||||||
private tradesData: TradesData[] = [];
|
private tradesData: TradesData[] = [];
|
||||||
|
private fiatCurrenciesIndexed: { [code: string]: true } = {};
|
||||||
|
private tradeDataByMarket: { [market: string]: TradesData[] } = {};
|
||||||
|
|
||||||
constructor() { }
|
constructor() { }
|
||||||
|
|
||||||
@ -17,10 +19,18 @@ class BisqMarketsApi {
|
|||||||
this.offersData = offers;
|
this.offersData = offers;
|
||||||
this.tradesData = trades;
|
this.tradesData = trades;
|
||||||
|
|
||||||
this.fiatCurrencyData.forEach((currency) => currency._type = 'fiat');
|
// Handle data for smarter memory caching
|
||||||
|
this.fiatCurrencyData.forEach((currency) => {
|
||||||
|
currency._type = 'fiat';
|
||||||
|
this.fiatCurrenciesIndexed[currency.code] = true;
|
||||||
|
});
|
||||||
this.cryptoCurrencyData.forEach((currency) => currency._type = 'crypto');
|
this.cryptoCurrencyData.forEach((currency) => currency._type = 'crypto');
|
||||||
this.tradesData.forEach((trade) => {
|
this.tradesData.forEach((trade) => {
|
||||||
trade._market = trade.currencyPair.toLowerCase().replace('/', '_');
|
trade._market = trade.currencyPair.toLowerCase().replace('/', '_');
|
||||||
|
if (!this.tradeDataByMarket[trade._market]) {
|
||||||
|
this.tradeDataByMarket[trade._market] = [];
|
||||||
|
}
|
||||||
|
this.tradeDataByMarket[trade._market].push(trade);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +163,7 @@ class BisqMarketsApi {
|
|||||||
sort: 'asc' | 'desc' = 'desc',
|
sort: 'asc' | 'desc' = 'desc',
|
||||||
): BisqTrade[] {
|
): BisqTrade[] {
|
||||||
limit = Math.min(limit, 2000);
|
limit = Math.min(limit, 2000);
|
||||||
const _market = market === 'all' ? null : market;
|
const _market = market === 'all' ? undefined : market;
|
||||||
|
|
||||||
if (!timestamp_from) {
|
if (!timestamp_from) {
|
||||||
timestamp_from = new Date('2016-01-01').getTime() / 1000;
|
timestamp_from = new Date('2016-01-01').getTime() / 1000;
|
||||||
@ -188,18 +198,149 @@ class BisqMarketsApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getVolumes(
|
getVolumes(
|
||||||
timestamp_from: number,
|
|
||||||
timestamp_to: number,
|
|
||||||
interval: Interval,
|
|
||||||
market?: string,
|
market?: string,
|
||||||
): MarketVolume[] {
|
timestamp_from?: number,
|
||||||
return [];
|
timestamp_to?: number,
|
||||||
|
interval: Interval = 'auto',
|
||||||
|
milliseconds?: boolean,
|
||||||
|
): MarketVolume[] {
|
||||||
|
if (milliseconds) {
|
||||||
|
timestamp_from = timestamp_from ? timestamp_from / 1000 : timestamp_from;
|
||||||
|
timestamp_to = timestamp_to ? timestamp_to / 1000 : timestamp_to;
|
||||||
|
}
|
||||||
|
if (!timestamp_from) {
|
||||||
|
timestamp_from = new Date('2016-01-01').getTime() / 1000;
|
||||||
|
}
|
||||||
|
if (!timestamp_to) {
|
||||||
|
timestamp_to = new Date().getTime() / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
const trades = this.getTradesByCriteria(market, timestamp_to, timestamp_from,
|
||||||
|
undefined, undefined, undefined, 'asc', Number.MAX_SAFE_INTEGER);
|
||||||
|
|
||||||
|
if (interval === 'auto') {
|
||||||
|
const range = timestamp_to - timestamp_from;
|
||||||
|
interval = this.getIntervalFromRange(range);
|
||||||
|
}
|
||||||
|
|
||||||
|
const intervals: any = {};
|
||||||
|
const marketVolumes: MarketVolume[] = [];
|
||||||
|
|
||||||
|
for (const trade of trades) {
|
||||||
|
const traded_at = trade['tradeDate'] / 1000;
|
||||||
|
const interval_start = this.intervalStart(traded_at, interval);
|
||||||
|
|
||||||
|
if (!intervals[interval_start]) {
|
||||||
|
intervals[interval_start] = {
|
||||||
|
'volume': 0,
|
||||||
|
'num_trades': 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const period = intervals[interval_start];
|
||||||
|
period['period_start'] = interval_start;
|
||||||
|
period['volume'] += this.fiatCurrenciesIndexed[trade.currency] ? trade._tradeAmount : trade._tradeVolume;
|
||||||
|
period['num_trades']++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const p in intervals) {
|
||||||
|
if (intervals.hasOwnProperty(p)) {
|
||||||
|
const period = intervals[p];
|
||||||
|
marketVolumes.push({
|
||||||
|
period_start: period['period_start'],
|
||||||
|
num_trades: period['num_trades'],
|
||||||
|
volume: this.intToBtc(period['volume']),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return intervals;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTicker(
|
getTicker(
|
||||||
market?: string,
|
market?: string,
|
||||||
): Tickers {
|
): Tickers | Ticker | null {
|
||||||
return {};
|
if (market) {
|
||||||
|
return this.getTickerFromMarket(market);
|
||||||
|
}
|
||||||
|
|
||||||
|
const allMarkets = this.getMarkets();
|
||||||
|
const tickers = {};
|
||||||
|
for (const m in allMarkets) {
|
||||||
|
if (allMarkets.hasOwnProperty(m)) {
|
||||||
|
tickers[allMarkets[m].pair] = this.getTickerFromMarket(allMarkets[m].pair);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tickers;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTickerFromMarket(market: string): Ticker | null {
|
||||||
|
let ticker: Ticker;
|
||||||
|
const timestamp_from = datetime.strtotime('-24 hour');
|
||||||
|
const timestamp_to = new Date().getTime() / 1000;
|
||||||
|
const trades = this.getTradesByCriteria(market, timestamp_to, timestamp_from,
|
||||||
|
undefined, undefined, undefined, 'asc', Number.MAX_SAFE_INTEGER);
|
||||||
|
|
||||||
|
const periods: SummarizedInterval[] = Object.values(this.getTradesSummarized(trades, timestamp_from));
|
||||||
|
|
||||||
|
const allCurrencies = this.getCurrencies();
|
||||||
|
const currencyRight = allCurrencies[market.split('_')[1].toUpperCase()];
|
||||||
|
|
||||||
|
if (periods[0]) {
|
||||||
|
ticker = {
|
||||||
|
'last': this.intToBtc(periods[0].close),
|
||||||
|
'high': this.intToBtc(periods[0].high),
|
||||||
|
'low': this.intToBtc(periods[0].low),
|
||||||
|
'volume_left': this.intToBtc(periods[0].volume_left),
|
||||||
|
'volume_right': this.intToBtc(periods[0].volume_right),
|
||||||
|
'buy': null,
|
||||||
|
'sell': null,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const lastTrade = this.tradeDataByMarket[market];
|
||||||
|
if (!lastTrade) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const tradePrice = lastTrade[0].primaryMarketTradePrice * Math.pow(10, 8 - currencyRight.precision);
|
||||||
|
|
||||||
|
const lastTradePrice = this.intToBtc(tradePrice);
|
||||||
|
ticker = {
|
||||||
|
'last': lastTradePrice,
|
||||||
|
'high': lastTradePrice,
|
||||||
|
'low': lastTradePrice,
|
||||||
|
'volume_left': '0',
|
||||||
|
'volume_right': '0',
|
||||||
|
'buy': null,
|
||||||
|
'sell': null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const timestampFromMilli = timestamp_from * 1000;
|
||||||
|
const timestampToMilli = timestamp_to * 1000;
|
||||||
|
|
||||||
|
const currencyPair = market.replace('_', '/').toUpperCase();
|
||||||
|
const offersData = this.offersData.slice().sort((a, b) => a.price - b.price);
|
||||||
|
|
||||||
|
const buy = offersData.find((offer) => offer.currencyPair === currencyPair
|
||||||
|
&& offer.primaryMarketDirection === 'BUY'
|
||||||
|
&& offer.date >= timestampFromMilli
|
||||||
|
&& offer.date <= timestampToMilli
|
||||||
|
);
|
||||||
|
const sell = offersData.find((offer) => offer.currencyPair === currencyPair
|
||||||
|
&& offer.primaryMarketDirection === 'SELL'
|
||||||
|
&& offer.date >= timestampFromMilli
|
||||||
|
&& offer.date <= timestampToMilli
|
||||||
|
);
|
||||||
|
|
||||||
|
if (buy) {
|
||||||
|
ticker.buy = this.intToBtc(buy.primaryMarketPrice * Math.pow(10, 8 - currencyRight.precision));
|
||||||
|
}
|
||||||
|
if (sell) {
|
||||||
|
ticker.sell = this.intToBtc(sell.primaryMarketPrice * Math.pow(10, 8 - currencyRight.precision));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ticker;
|
||||||
}
|
}
|
||||||
|
|
||||||
getHloc(
|
getHloc(
|
||||||
@ -220,53 +361,73 @@ class BisqMarketsApi {
|
|||||||
timestamp_to = new Date().getTime() / 1000;
|
timestamp_to = new Date().getTime() / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
const range = timestamp_to - timestamp_from;
|
|
||||||
|
|
||||||
const trades = this.getTradesByCriteria(market, timestamp_to, timestamp_from,
|
const trades = this.getTradesByCriteria(market, timestamp_to, timestamp_from,
|
||||||
undefined, undefined, undefined, 'asc', Number.MAX_SAFE_INTEGER);
|
undefined, undefined, undefined, 'asc', Number.MAX_SAFE_INTEGER);
|
||||||
|
|
||||||
if (interval === 'auto') {
|
if (interval === 'auto') {
|
||||||
// two days range loads minute data
|
const range = timestamp_to - timestamp_from;
|
||||||
if (range <= 3600) {
|
interval = this.getIntervalFromRange(range);
|
||||||
// up to one hour range loads minutely data
|
|
||||||
interval = 'minute';
|
|
||||||
} else if (range <= 1 * 24 * 3600) {
|
|
||||||
// up to one day range loads half-hourly data
|
|
||||||
interval = 'half_hour';
|
|
||||||
} else if (range <= 3 * 24 * 3600) {
|
|
||||||
// up to 3 day range loads hourly data
|
|
||||||
interval = 'hour';
|
|
||||||
} else if (range <= 7 * 24 * 3600) {
|
|
||||||
// up to 7 day range loads half-daily data
|
|
||||||
interval = 'half_day';
|
|
||||||
} else if (range <= 60 * 24 * 3600) {
|
|
||||||
// up to 2 month range loads daily data
|
|
||||||
interval = 'day';
|
|
||||||
} else if (range <= 12 * 31 * 24 * 3600) {
|
|
||||||
// up to one year range loads weekly data
|
|
||||||
interval = 'week';
|
|
||||||
} else if (range <= 12 * 31 * 24 * 3600) {
|
|
||||||
// up to 5 year range loads monthly data
|
|
||||||
interval = 'month';
|
|
||||||
} else {
|
|
||||||
// greater range loads yearly data
|
|
||||||
interval = 'year';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const hlocs = this.getTradesSummarized(trades, timestamp_from, interval);
|
const intervals = this.getTradesSummarized(trades, timestamp_from, interval);
|
||||||
|
|
||||||
return hlocs;
|
const hloc: HighLowOpenClose[] = [];
|
||||||
|
|
||||||
|
for (const p in intervals) {
|
||||||
|
if (intervals.hasOwnProperty(p)) {
|
||||||
|
const period = intervals[p];
|
||||||
|
hloc.push({
|
||||||
|
period_start: period['period_start'],
|
||||||
|
open: this.intToBtc(period['open']),
|
||||||
|
close: this.intToBtc(period['close']),
|
||||||
|
high: this.intToBtc(period['high']),
|
||||||
|
low: this.intToBtc(period['low']),
|
||||||
|
avg: this.intToBtc(period['avg']),
|
||||||
|
volume_right: this.intToBtc(period['volume_right']),
|
||||||
|
volume_left: this.intToBtc(period['volume_left']),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getTradesSummarized(trades: TradesData[], timestamp_from, interval: string): HighLowOpenClose[] {
|
private getIntervalFromRange(range: number): Interval {
|
||||||
|
// two days range loads minute data
|
||||||
|
if (range <= 3600) {
|
||||||
|
// up to one hour range loads minutely data
|
||||||
|
return 'minute';
|
||||||
|
} else if (range <= 1 * 24 * 3600) {
|
||||||
|
// up to one day range loads half-hourly data
|
||||||
|
return 'half_hour';
|
||||||
|
} else if (range <= 3 * 24 * 3600) {
|
||||||
|
// up to 3 day range loads hourly data
|
||||||
|
return 'hour';
|
||||||
|
} else if (range <= 7 * 24 * 3600) {
|
||||||
|
// up to 7 day range loads half-daily data
|
||||||
|
return 'half_day';
|
||||||
|
} else if (range <= 60 * 24 * 3600) {
|
||||||
|
// up to 2 month range loads daily data
|
||||||
|
return 'day';
|
||||||
|
} else if (range <= 12 * 31 * 24 * 3600) {
|
||||||
|
// up to one year range loads weekly data
|
||||||
|
return 'week';
|
||||||
|
} else if (range <= 12 * 31 * 24 * 3600) {
|
||||||
|
// up to 5 year range loads monthly data
|
||||||
|
return 'month';
|
||||||
|
} else {
|
||||||
|
// greater range loads yearly data
|
||||||
|
return 'year';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getTradesSummarized(trades: TradesData[], timestamp_from: number, interval?: string): SummarizedIntervals {
|
||||||
const intervals: any = {};
|
const intervals: any = {};
|
||||||
const intervals_prices: any = {};
|
const intervals_prices: any = {};
|
||||||
const one_period = false;
|
|
||||||
|
|
||||||
for (const trade of trades) {
|
for (const trade of trades) {
|
||||||
const traded_at = trade.tradeDate / 1000;
|
const traded_at = trade.tradeDate / 1000;
|
||||||
const interval_start = one_period ? timestamp_from : this.intervalStart(traded_at, interval);
|
const interval_start = !interval ? timestamp_from : this.intervalStart(traded_at, interval);
|
||||||
|
|
||||||
if (!intervals[interval_start]) {
|
if (!intervals[interval_start]) {
|
||||||
intervals[interval_start] = {
|
intervals[interval_start] = {
|
||||||
@ -306,30 +467,11 @@ class BisqMarketsApi {
|
|||||||
period['volume_right'] += trade._tradeVolume;
|
period['volume_right'] += trade._tradeVolume;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return intervals;
|
||||||
const hloc: HighLowOpenClose[] = [];
|
|
||||||
|
|
||||||
for (const p in intervals) {
|
|
||||||
if (intervals.hasOwnProperty(p)) {
|
|
||||||
const period = intervals[p];
|
|
||||||
hloc.push({
|
|
||||||
period_start: period['period_start'],
|
|
||||||
open: this.intToBtc(period['open']),
|
|
||||||
close: this.intToBtc(period['close']),
|
|
||||||
high: this.intToBtc(period['high']),
|
|
||||||
low: this.intToBtc(period['low']),
|
|
||||||
avg: this.intToBtc(period['avg']),
|
|
||||||
volume_right: this.intToBtc(period['volume_right']),
|
|
||||||
volume_left: this.intToBtc(period['volume_left']),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hloc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private getTradesByCriteria(
|
private getTradesByCriteria(
|
||||||
market: string | null,
|
market: string | undefined,
|
||||||
timestamp_to: number,
|
timestamp_to: number,
|
||||||
timestamp_from: number,
|
timestamp_from: number,
|
||||||
trade_id_to: string | undefined,
|
trade_id_to: string | undefined,
|
||||||
@ -422,7 +564,7 @@ class BisqMarketsApi {
|
|||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
private intervalStart(ts: number, interval: string) {
|
private intervalStart(ts: number, interval: string): number {
|
||||||
switch (interval) {
|
switch (interval) {
|
||||||
case 'minute':
|
case 'minute':
|
||||||
return (ts - (ts % 60));
|
return (ts - (ts % 60));
|
||||||
|
@ -4,7 +4,7 @@ import { OffsersData, TradesData, Currency } from './interfaces';
|
|||||||
import bisqMarket from './markets-api';
|
import bisqMarket from './markets-api';
|
||||||
|
|
||||||
class Bisq {
|
class Bisq {
|
||||||
private static MARKET_JSON_PATH = config.BSQ_MARKETS_DATA_PATH + '/btc_mainnet/db';
|
private static MARKET_JSON_PATH = config.BISQ_MARKETS_DATA_PATH + '/btc_mainnet/db';
|
||||||
private static MARKET_JSON_FILE_PATHS = {
|
private static MARKET_JSON_FILE_PATHS = {
|
||||||
cryptoCurrency: '/crypto_currency_list.json',
|
cryptoCurrency: '/crypto_currency_list.json',
|
||||||
fiatCurrency: '/fiat_currency_list.json',
|
fiatCurrency: '/fiat_currency_list.json',
|
||||||
|
@ -175,7 +175,7 @@ class Routes {
|
|||||||
|
|
||||||
const p = this.parseRequestParameters(req, constraints);
|
const p = this.parseRequestParameters(req, constraints);
|
||||||
if (p.error) {
|
if (p.error) {
|
||||||
res.status(501).json(this.getBisqMarketErrorResponse(p.error));
|
res.status(400).json(this.getBisqMarketErrorResponse(p.error));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +197,7 @@ class Routes {
|
|||||||
|
|
||||||
const p = this.parseRequestParameters(req, constraints);
|
const p = this.parseRequestParameters(req, constraints);
|
||||||
if (p.error) {
|
if (p.error) {
|
||||||
res.status(501).json(this.getBisqMarketErrorResponse(p.error));
|
res.status(400).json(this.getBisqMarketErrorResponse(p.error));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,7 +256,7 @@ class Routes {
|
|||||||
|
|
||||||
const p = this.parseRequestParameters(req, constraints);
|
const p = this.parseRequestParameters(req, constraints);
|
||||||
if (p.error) {
|
if (p.error) {
|
||||||
res.status(501).json(this.getBisqMarketErrorResponse(p.error));
|
res.status(400).json(this.getBisqMarketErrorResponse(p.error));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,7 +283,7 @@ class Routes {
|
|||||||
|
|
||||||
const p = this.parseRequestParameters(req, constraints);
|
const p = this.parseRequestParameters(req, constraints);
|
||||||
if (p.error) {
|
if (p.error) {
|
||||||
res.status(501).json(this.getBisqMarketErrorResponse(p.error));
|
res.status(400).json(this.getBisqMarketErrorResponse(p.error));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,7 +298,7 @@ class Routes {
|
|||||||
public getBisqMarketVolumes(req: Request, res: Response) {
|
public getBisqMarketVolumes(req: Request, res: Response) {
|
||||||
const constraints: RequiredSpec = {
|
const constraints: RequiredSpec = {
|
||||||
'market': {
|
'market': {
|
||||||
required: true,
|
required: false,
|
||||||
types: ['@string']
|
types: ['@string']
|
||||||
},
|
},
|
||||||
'interval': {
|
'interval': {
|
||||||
@ -313,15 +313,19 @@ class Routes {
|
|||||||
required: false,
|
required: false,
|
||||||
types: ['@number']
|
types: ['@number']
|
||||||
},
|
},
|
||||||
|
'milliseconds': {
|
||||||
|
required: false,
|
||||||
|
types: ['@boolean']
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const p = this.parseRequestParameters(req, constraints);
|
const p = this.parseRequestParameters(req, constraints);
|
||||||
if (p.error) {
|
if (p.error) {
|
||||||
res.status(501).json(this.getBisqMarketErrorResponse(p.error));
|
res.status(400).json(this.getBisqMarketErrorResponse(p.error));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = bisqMarket.getVolumes(p.timestamp_from, p.timestamp_to, p.interval, p.market);
|
const result = bisqMarket.getVolumes(p.market, p.timestamp_from, p.timestamp_to, p.interval, p.milliseconds);
|
||||||
if (result) {
|
if (result) {
|
||||||
res.json(result);
|
res.json(result);
|
||||||
} else {
|
} else {
|
||||||
@ -355,7 +359,7 @@ class Routes {
|
|||||||
|
|
||||||
const p = this.parseRequestParameters(req, constraints);
|
const p = this.parseRequestParameters(req, constraints);
|
||||||
if (p.error) {
|
if (p.error) {
|
||||||
res.status(501).json(this.getBisqMarketErrorResponse(p.error));
|
res.status(400).json(this.getBisqMarketErrorResponse(p.error));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,11 +381,11 @@ class Routes {
|
|||||||
|
|
||||||
const p = this.parseRequestParameters(req, constraints);
|
const p = this.parseRequestParameters(req, constraints);
|
||||||
if (p.error) {
|
if (p.error) {
|
||||||
res.status(501).json(this.getBisqMarketErrorResponse(p.error));
|
res.status(400).json(this.getBisqMarketErrorResponse(p.error));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = bisqMarket.getCurrencies(p.market);
|
const result = bisqMarket.getTicker(p.market);
|
||||||
if (result) {
|
if (result) {
|
||||||
res.json(result);
|
res.json(result);
|
||||||
} else {
|
} else {
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
"TX_PER_SECOND_SPAN_SECONDS": 150,
|
"TX_PER_SECOND_SPAN_SECONDS": 150,
|
||||||
"ELECTRS_API_URL": "http://[::1]:3000",
|
"ELECTRS_API_URL": "http://[::1]:3000",
|
||||||
"BISQ_ENABLED": true,
|
"BISQ_ENABLED": true,
|
||||||
"BSQ_BLOCKS_DATA_PATH": "/bisq/data",
|
"BISQ_BLOCKS_DATA_PATH": "/bisq/data",
|
||||||
"SSL": false,
|
"SSL": false,
|
||||||
"SSL_CERT_FILE_PATH": "/etc/letsencrypt/live/mysite/fullchain.pem",
|
"SSL_CERT_FILE_PATH": "/etc/letsencrypt/live/mysite/fullchain.pem",
|
||||||
"SSL_KEY_FILE_PATH": "/etc/letsencrypt/live/mysite/privkey.pem"
|
"SSL_KEY_FILE_PATH": "/etc/letsencrypt/live/mysite/privkey.pem"
|
||||||
|
Loading…
Reference in New Issue
Block a user