mirror of
https://github.com/freqtrade/frequi.git
synced 2024-11-26 13:05:15 +00:00
Allow selection of Multiple bots for Dashboard View
This commit is contained in:
parent
5cdbd8c8e6
commit
f493b25d5a
|
@ -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,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
14
src/types/botComparison.ts
Normal file
14
src/types/botComparison.ts
Normal 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;
|
||||||
|
}
|
|
@ -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';
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user