Allow selection of Multiple bots for Dashboard View

This commit is contained in:
Matthias 2022-05-04 20:43:14 +02:00
parent 5cdbd8c8e6
commit f493b25d5a
6 changed files with 69 additions and 31 deletions

View File

@ -8,6 +8,16 @@
:items="tableItems" :items="tableItems"
:fields="tableFields" :fields="tableFields"
> >
<template #cell(botName)="row">
<div class="d-flex flex-row">
<b-form-checkbox
v-if="row.item.botId && botStore.botCount > 1"
v-model="botStore.botStores[row.item.botId].isSelected"
title="Show bot in Dashboard"
/>
<span>{{ row.value }}</span>
</div>
</template>
<template #cell(profitOpen)="row"> <template #cell(profitOpen)="row">
<profit-pill <profit-pill
v-if="row.item.profitOpen && row.item.botId != 'Summary'" v-if="row.item.profitOpen && row.item.botId != 'Summary'"
@ -47,7 +57,7 @@ import ProfitPill from '@/components/general/ProfitPill.vue';
import { formatPrice } from '@/shared/formatters'; import { formatPrice } from '@/shared/formatters';
import { defineComponent, computed } from '@vue/composition-api'; import { defineComponent, computed } from '@vue/composition-api';
import { useBotStore } from '@/stores/ftbotwrapper'; import { useBotStore } from '@/stores/ftbotwrapper';
import { ProfitInterface } from '@/types'; import { ProfitInterface, ComparisonTableItems } from '@/types';
export default defineComponent({ export default defineComponent({
name: 'BotComparisonList', name: 'BotComparisonList',
@ -56,7 +66,7 @@ export default defineComponent({
const botStore = useBotStore(); const botStore = useBotStore();
const tableFields: Record<string, string | Function>[] = [ const tableFields: Record<string, string | Function>[] = [
{ key: 'botId', label: 'Bot' }, { key: 'botName', label: 'Bot' },
{ key: 'trades', label: 'Trades' }, { key: 'trades', label: 'Trades' },
{ key: 'profitOpen', label: 'Open Profit' }, { key: 'profitOpen', label: 'Open Profit' },
{ key: 'profitClosed', label: 'Closed Profit' }, { key: 'profitClosed', label: 'Closed Profit' },
@ -66,9 +76,10 @@ export default defineComponent({
const tableItems = computed(() => { const tableItems = computed(() => {
console.log('tableItems called'); console.log('tableItems called');
const val: any[] = []; const val: ComparisonTableItems[] = [];
const summary = { const summary: ComparisonTableItems = {
botId: 'Summary', botId: undefined,
botName: 'Summary',
profitClosed: 0, profitClosed: 0,
profitClosedRatio: 0, profitClosedRatio: 0,
profitOpen: 0, profitOpen: 0,
@ -87,7 +98,8 @@ export default defineComponent({
// TODO: handle one inactive bot ... // TODO: handle one inactive bot ...
val.push({ val.push({
botId: botStore.availableBots[k].botName, botId: k,
botName: botStore.availableBots[k].botName,
trades: `${botStore.allOpenTradeCount[k]} / ${ trades: `${botStore.allOpenTradeCount[k]} / ${
botStore.allBotState[k]?.max_open_trades || 'N/A' botStore.allBotState[k]?.max_open_trades || 'N/A'
}`, }`,
@ -117,6 +129,7 @@ export default defineComponent({
formatPrice, formatPrice,
tableFields, tableFields,
tableItems, tableItems,
botStore,
}; };
}, },
}); });

View File

@ -44,7 +44,7 @@ import {
TradeResponse, TradeResponse,
ClosedTrade, ClosedTrade,
} from '@/types'; } from '@/types';
import axios, { AxiosInstance, AxiosResponse } from 'axios'; import axios, { AxiosResponse } from 'axios';
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { showAlert } from './alerts'; import { showAlert } from './alerts';
@ -55,6 +55,7 @@ export function createBotSubStore(botId: string, botName: string) {
const useBotStore = defineStore(botId, { const useBotStore = defineStore(botId, {
state: () => { state: () => {
return { return {
isSelected: true,
ping: '', ping: '',
botStatusAvailable: false, botStatusAvailable: false,
isBotOnline: false, isBotOnline: false,

View File

@ -14,7 +14,6 @@ import {
RenameBotPayload, RenameBotPayload,
Trade, Trade,
} from '@/types'; } from '@/types';
import { AxiosInstance } from 'axios';
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { createBotSubStore } from './ftbot'; import { createBotSubStore } from './ftbot';
const AUTH_SELECTED_BOT = 'ftSelectedBot'; const AUTH_SELECTED_BOT = 'ftSelectedBot';
@ -89,36 +88,42 @@ export const useBotStore = defineStore('wrapper', {
return result; return result;
}, },
allOpenTradesAllBots: (state): Trade[] => { allOpenTradesSelectedBots: (state): Trade[] => {
const result: Trade[] = []; const result: Trade[] = [];
Object.entries(state.botStores).forEach(([, botStore]) => { Object.entries(state.botStores).forEach(([, botStore]) => {
result.push(...botStore.openTrades); if (botStore.isSelected) {
result.push(...botStore.openTrades);
}
}); });
return result; return result;
}, },
allTradesAllBots: (state): ClosedTrade[] => { allTradesSelectedBots: (state): ClosedTrade[] => {
const result: ClosedTrade[] = []; const result: ClosedTrade[] = [];
Object.entries(state.botStores).forEach(([, botStore]) => { Object.entries(state.botStores).forEach(([, botStore]) => {
result.push(...botStore.trades); if (botStore.isSelected) {
result.push(...botStore.trades);
}
}); });
return result; return result;
}, },
allDailyStatsAllBots: (state): DailyReturnValue => { allDailyStatsSelectedBots: (state): DailyReturnValue => {
// Return aggregated daily stats for all bots - sorted ascending. // Return aggregated daily stats for all bots - sorted ascending.
const resp: Record<string, DailyRecord> = {}; const resp: Record<string, DailyRecord> = {};
Object.entries(state.botStores).forEach(([, botStore]) => { Object.entries(state.botStores).forEach(([, botStore]) => {
botStore.dailyStats?.data?.forEach((d) => { if (botStore.isSelected) {
if (!resp[d.date]) { botStore.dailyStats?.data?.forEach((d) => {
resp[d.date] = { ...d }; if (!resp[d.date]) {
} else { resp[d.date] = { ...d };
// eslint-disable-next-line @typescript-eslint/camelcase } else {
resp[d.date].abs_profit += d.abs_profit; // eslint-disable-next-line @typescript-eslint/camelcase
// eslint-disable-next-line @typescript-eslint/camelcase resp[d.date].abs_profit += d.abs_profit;
resp[d.date].fiat_value += d.fiat_value; // eslint-disable-next-line @typescript-eslint/camelcase
// eslint-disable-next-line @typescript-eslint/camelcase resp[d.date].fiat_value += d.fiat_value;
resp[d.date].trade_count += d.trade_count; // eslint-disable-next-line @typescript-eslint/camelcase
} resp[d.date].trade_count += d.trade_count;
}); }
});
}
}); });
const dailyReturn: DailyReturnValue = { const dailyReturn: DailyReturnValue = {

View File

@ -0,0 +1,14 @@
export interface ComparisonTableItems {
botId: string | undefined;
botName: string;
trades?: string;
profitClosed: number;
profitClosedRatio: number;
profitOpen: number;
profitOpenRatio: number;
stakeCurrency: string;
wins: number;
losses: number;
balance?: number;
stakeCurrencyDecimals?: number;
}

View File

@ -1,7 +1,8 @@
export * from './auth'; export * from './auth';
export * from './balance';
export * from './backtest'; export * from './backtest';
export * from './balance';
export * from './blacklist'; export * from './blacklist';
export * from './botComparison';
export * from './chart'; export * from './chart';
export * from './daily'; export * from './daily';
export * from './locks'; export * from './locks';

View File

@ -26,8 +26,8 @@
> >
<DraggableContainer :header="`Daily Profit ${botStore.botCount > 1 ? 'combined' : ''}`"> <DraggableContainer :header="`Daily Profit ${botStore.botCount > 1 ? 'combined' : ''}`">
<DailyChart <DailyChart
v-if="botStore.allDailyStatsAllBots" v-if="botStore.allDailyStatsSelectedBots"
:daily-stats="botStore.allDailyStatsAllBots" :daily-stats="botStore.allDailyStatsSelectedBots"
:show-title="false" :show-title="false"
/> />
</DraggableContainer> </DraggableContainer>
@ -57,7 +57,11 @@
drag-allow-from=".drag-header" drag-allow-from=".drag-header"
> >
<DraggableContainer header="Open Trades"> <DraggableContainer header="Open Trades">
<trade-list :active-trades="true" :trades="botStore.allOpenTradesAllBots" multi-bot-view /> <trade-list
:active-trades="true"
:trades="botStore.allOpenTradesSelectedBots"
multi-bot-view
/>
</DraggableContainer> </DraggableContainer>
</GridItem> </GridItem>
<GridItem <GridItem
@ -71,7 +75,7 @@
drag-allow-from=".drag-header" drag-allow-from=".drag-header"
> >
<DraggableContainer header="Cumulative Profit"> <DraggableContainer header="Cumulative Profit">
<CumProfitChart :trades="botStore.allTradesAllBots" :show-title="false" /> <CumProfitChart :trades="botStore.allTradesSelectedBots" :show-title="false" />
</DraggableContainer> </DraggableContainer>
</GridItem> </GridItem>
<GridItem <GridItem
@ -85,7 +89,7 @@
drag-allow-from=".drag-header" drag-allow-from=".drag-header"
> >
<DraggableContainer header="Trades Log"> <DraggableContainer header="Trades Log">
<TradesLogChart :trades="botStore.allTradesAllBots" :show-title="false" /> <TradesLogChart :trades="botStore.allTradesSelectedBots" :show-title="false" />
</DraggableContainer> </DraggableContainer>
</GridItem> </GridItem>
</GridLayout> </GridLayout>