Bisq markets: Volume and other fixes.

This commit is contained in:
softsimon 2021-03-10 23:02:55 +07:00
parent d99fd5d59a
commit 1d4ed85d50
No known key found for this signature in database
GPG Key ID: 488D7DCFB5A430D7
9 changed files with 57 additions and 26 deletions

View File

@ -457,8 +457,8 @@ class BisqMarketsApi {
} }
} }
get24hVolumes(): MarketVolume[] { getVolumesByTime(time: number): MarketVolume[] {
const timestamp_from = new Date().getTime() / 1000 - 86400; const timestamp_from = new Date().getTime() / 1000 - time;
const timestamp_to = new Date().getTime() / 1000; const timestamp_to = new Date().getTime() / 1000;
const trades = this.getTradesByCriteria(undefined, timestamp_to, timestamp_from, const trades = this.getTradesByCriteria(undefined, timestamp_to, timestamp_from,

View File

@ -203,7 +203,7 @@ class Server {
.get(config.MEMPOOL.API_URL_PREFIX + 'bisq/markets/ticker', routes.getBisqMarketTicker.bind(routes)) .get(config.MEMPOOL.API_URL_PREFIX + 'bisq/markets/ticker', routes.getBisqMarketTicker.bind(routes))
.get(config.MEMPOOL.API_URL_PREFIX + 'bisq/markets/trades', routes.getBisqMarketTrades.bind(routes)) .get(config.MEMPOOL.API_URL_PREFIX + 'bisq/markets/trades', routes.getBisqMarketTrades.bind(routes))
.get(config.MEMPOOL.API_URL_PREFIX + 'bisq/markets/volumes', routes.getBisqMarketVolumes.bind(routes)) .get(config.MEMPOOL.API_URL_PREFIX + 'bisq/markets/volumes', routes.getBisqMarketVolumes.bind(routes))
.get(config.MEMPOOL.API_URL_PREFIX + 'bisq/markets/24hvolumes', routes.getBisqMarket24hVolumes.bind(routes)) .get(config.MEMPOOL.API_URL_PREFIX + 'bisq/markets/volumes/7d', routes.getBisqMarketVolumes7d.bind(routes))
; ;
} }

View File

@ -401,12 +401,12 @@ class Routes {
} }
} }
public getBisqMarket24hVolumes(req: Request, res: Response) { public getBisqMarketVolumes7d(req: Request, res: Response) {
const result = bisqMarket.get24hVolumes(); const result = bisqMarket.getVolumesByTime(604800);
if (result) { if (result) {
res.json(result); res.json(result);
} else { } else {
res.status(500).json(this.getBisqMarketErrorResponse('getBisqMarket24hVolumes error')); res.status(500).json(this.getBisqMarketErrorResponse('getBisqMarketVolumes7d error'));
} }
} }

View File

@ -64,7 +64,7 @@ export class BisqApiService {
return this.httpClient.get<any[]>(API_BASE_URL + '/markets/offers?market=' + market); return this.httpClient.get<any[]>(API_BASE_URL + '/markets/offers?market=' + market);
} }
getMarket24hVolumes$(): Observable<any[]> { getMarketVolumesByTime$(period: string): Observable<any[]> {
return this.httpClient.get<any[]>(API_BASE_URL + '/markets/24hvolumes'); return this.httpClient.get<any[]>(API_BASE_URL + '/markets/volumes/' + period);
} }
} }

View File

@ -8,13 +8,13 @@
<th i18n>Currency</th> <th i18n>Currency</th>
<th i18n>Pair</th> <th i18n>Pair</th>
<th i18n>Price</th> <th i18n>Price</th>
<th i18n>Volume (24h)</th> <th i18n>Volume (7d)</th>
<th i18n>Trades (24h)</th> <th i18n>Trades (7d)</th>
</thead> </thead>
<tbody *ngIf="tickers.value; else loadingTmpl"> <tbody *ngIf="tickers.value; else loadingTmpl">
<tr *ngFor="let ticker of tickers.value; trackBy: trackByFn; let i = index"> <tr *ngFor="let ticker of tickers.value; trackBy: trackByFn; let i = index">
<td>{{ i + 1 }}</td> <td>{{ i + 1 }}</td>
<td>{{ ticker.market.lname }}</td> <td>{{ ticker.market.rtype === 'crypto' ? ticker.market.lname : ticker.market.rname }}</td>
<td><a [routerLink]="['/market' | relativeUrl, ticker.pair_url]">{{ ticker.pair }}</a></td> <td><a [routerLink]="['/market' | relativeUrl, ticker.pair_url]">{{ ticker.pair }}</a></td>
<td> <td>
<app-fiat *ngIf="ticker.market.rtype === 'crypto'; else fiat" [value]="ticker.last * 100000000"></app-fiat> <app-fiat *ngIf="ticker.market.rtype === 'crypto'; else fiat" [value]="ticker.last * 100000000"></app-fiat>

View File

@ -24,7 +24,7 @@ export class BisqDashboardComponent implements OnInit {
this.tickers$ = combineLatest([ this.tickers$ = combineLatest([
this.bisqApiService.getMarketsTicker$(), this.bisqApiService.getMarketsTicker$(),
this.bisqApiService.getMarkets$(), this.bisqApiService.getMarkets$(),
this.bisqApiService.getMarket24hVolumes$(), this.bisqApiService.getMarketVolumesByTime$('7d'),
]) ])
.pipe( .pipe(
map(([tickers, markets, volumes]) => { map(([tickers, markets, volumes]) => {
@ -37,7 +37,7 @@ export class BisqDashboardComponent implements OnInit {
newTickers.push(tickers[t]); newTickers.push(tickers[t]);
} }
newTickers.sort((a, b) => (b.volume && b.volume.volume || 0) - (a.volume && a.volume.volume || 0)); newTickers.sort((a, b) => (b.volume && b.volume.num_trades || 0) - (a.volume && a.volume.num_trades || 0));
return newTickers; return newTickers;
}) })

View File

@ -6,16 +6,13 @@
<h1>{{ currency.market.lname }} - {{ currency.pair }}</h1> <h1>{{ currency.market.lname }} - {{ currency.pair }}</h1>
<div class="float-left"> <div class="float-left">
<span class="priceheader"> <span class="priceheader">
<ng-container *ngIf="currency.market.rtype === 'fiat'; else headerPriceCrypto"><span class="green-color">{{ hlocData[hlocData.length - 1].close | currency: currency.market.rsymbol }}</span></ng-container> <ng-container *ngIf="currency.market.rtype === 'fiat'; else headerPriceCrypto"><span class="green-color">{{ hlocData.hloc[hlocData.hloc.length - 1].close | currency: currency.market.rsymbol }}</span></ng-container>
<ng-template #headerPriceCrypto>{{ hlocData[hlocData.length - 1].close | number: '1.' + currency.market.rprecision + '-' + currency.market.rprecision }} {{ currency.market.rsymbol }}</ng-template> <ng-template #headerPriceCrypto>{{ hlocData.hloc[hlocData.hloc.length - 1].close | number: '1.' + currency.market.rprecision + '-' + currency.market.rprecision }} {{ currency.market.rsymbol }}</ng-template>
</span> </span>
</div> </div>
<form [formGroup]="radioGroupForm" class="mb-3 float-right"> <form [formGroup]="radioGroupForm" class="mb-3 float-right">
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="interval"> <div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="interval">
<label ngbButtonLabel class="btn-primary btn-sm">
<input ngbButton type="radio" [value]="'minute'"> 1M
</label>
<label ngbButtonLabel class="btn-primary btn-sm"> <label ngbButtonLabel class="btn-primary btn-sm">
<input ngbButton type="radio" [value]="'half_hour'"> 30M <input ngbButton type="radio" [value]="'half_hour'"> 30M
</label> </label>
@ -43,7 +40,9 @@
</div> </div>
</form> </form>
<app-lightweight-charts [data]="hlocData"></app-lightweight-charts> <app-lightweight-charts [data]="hlocData.hloc" [volumeData]="hlocData.volume" [precision]="currency.market.rtype === 'crypto' ? currency.market.lprecision : currency.market.rprecision"></app-lightweight-charts>
<div class="float-right small mt-2">Powered by <a href="https://www.tradingview.com/" target="_blank">Tradingview</a></div>
<br> <br>

View File

@ -46,11 +46,8 @@ export class BisqMarketComponent implements OnInit, OnDestroy {
this.offers$ = this.route.paramMap this.offers$ = this.route.paramMap
.pipe( .pipe(
map(routeParams => routeParams.get('pair')), map(routeParams => routeParams.get('pair')),
tap((marketPair) => this.websocketService.startTrackBisqMarket(marketPair)),
switchMap((marketPair) => this.bisqApiService.getMarketOffers$(marketPair)), switchMap((marketPair) => this.bisqApiService.getMarketOffers$(marketPair)),
map((offers) => { map((offers) => offers[Object.keys(offers)[0]])
return offers[Object.keys(offers)[0]];
})
); );
this.hlocData$ = combineLatest([ this.hlocData$ = combineLatest([
@ -62,11 +59,21 @@ export class BisqMarketComponent implements OnInit, OnDestroy {
const pair = routeParams.get('pair'); const pair = routeParams.get('pair');
return this.bisqApiService.getMarketsHloc$(pair, interval); return this.bisqApiService.getMarketsHloc$(pair, interval);
}), }),
map((hloc) => { map((hlocData) => {
return hloc.map((h) => { hlocData = hlocData.map((h) => {
h.time = h.period_start; h.time = h.period_start;
return h; return h;
}); });
return {
hloc: hlocData,
volume: hlocData.map((h) => {
return {
time: h.time,
value: h.volume_right,
color: h.close > h.avg ? 'rgba(0, 150, 136, 0.8)' : 'rgba(255,82,82, 0.8)',
};
})
};
}), }),
); );
} }

View File

@ -9,7 +9,11 @@ import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, Input, O
}) })
export class LightweightChartsComponent implements AfterViewInit, OnChanges, OnDestroy { export class LightweightChartsComponent implements AfterViewInit, OnChanges, OnDestroy {
@Input() data: any; @Input() data: any;
@Input() volumeData: any;
@Input() precision: number;
lineSeries: any; lineSeries: any;
volumeSeries: any;
chart: any; chart: any;
constructor( constructor(
@ -36,6 +40,18 @@ export class LightweightChartsComponent implements AfterViewInit, OnChanges, OnD
}, },
}); });
this.lineSeries = this.chart.addCandlestickSeries(); this.lineSeries = this.chart.addCandlestickSeries();
this.volumeSeries = this.chart.addHistogramSeries({
color: '#26a69a',
priceFormat: {
type: 'volume',
},
priceScaleId: '',
scaleMargins: {
top: 0.8,
bottom: 0,
},
});
} }
ngAfterViewInit(): void { ngAfterViewInit(): void {
@ -60,6 +76,15 @@ export class LightweightChartsComponent implements AfterViewInit, OnChanges, OnD
return; return;
} }
this.lineSeries.setData(this.data); this.lineSeries.setData(this.data);
this.volumeSeries.setData(this.volumeData);
this.lineSeries.applyOptions({
priceFormat: {
type: 'price',
precision: this.precision,
minMove: 0.0000001,
},
});
} }
ngOnDestroy() { ngOnDestroy() {