2020-08-17 19:16:27 +00:00
|
|
|
<template>
|
2020-08-29 09:38:43 +00:00
|
|
|
<GridLayout
|
|
|
|
class="h-100 w-100"
|
|
|
|
:row-height="50"
|
2021-08-20 18:16:16 +00:00
|
|
|
:layout.sync="gridLayout"
|
2020-08-25 17:45:35 +00:00
|
|
|
:vertical-compact="false"
|
2020-12-21 18:39:55 +00:00
|
|
|
:margin="[5, 5]"
|
2021-08-20 18:16:16 +00:00
|
|
|
:responsive-layouts="responsiveGridLayouts"
|
|
|
|
:is-resizable="!isLayoutLocked"
|
|
|
|
:is-draggable="!isLayoutLocked"
|
|
|
|
:responsive="true"
|
|
|
|
:prevent-collision="true"
|
|
|
|
@layout-updated="layoutUpdated"
|
|
|
|
@breakpoint-changed="breakpointChanged"
|
2020-08-29 09:38:43 +00:00
|
|
|
>
|
2020-09-03 04:58:06 +00:00
|
|
|
<GridItem
|
|
|
|
:i="gridLayoutKPI.i"
|
|
|
|
:x="gridLayoutKPI.x"
|
|
|
|
:y="gridLayoutKPI.y"
|
|
|
|
:w="gridLayoutKPI.w"
|
|
|
|
:h="gridLayoutKPI.h"
|
|
|
|
:min-w="3"
|
|
|
|
:min-h="4"
|
|
|
|
drag-allow-from=".drag-header"
|
|
|
|
>
|
|
|
|
<DraggableContainer header="Bot KPI">
|
2020-09-03 05:17:00 +00:00
|
|
|
<b-card-group deck>
|
|
|
|
<b-card header="Open / Total trades">
|
|
|
|
<b-card-text>
|
|
|
|
<span class="text-primary">{{ openTrades.length }}</span> /
|
2020-12-29 09:38:11 +00:00
|
|
|
<span class="text">{{ profit.trade_count }}</span>
|
2020-09-03 05:17:00 +00:00
|
|
|
</b-card-text>
|
|
|
|
</b-card>
|
|
|
|
<b-card header="Won / lost trades">
|
|
|
|
<b-card-text>
|
2021-09-04 09:20:55 +00:00
|
|
|
<span class="text-profit">{{ profit.winning_trades }}</span> /
|
|
|
|
<span class="text-loss">{{ profit.losing_trades }}</span>
|
2020-09-03 05:17:00 +00:00
|
|
|
</b-card-text>
|
|
|
|
</b-card>
|
|
|
|
<b-card header="Last trade">
|
|
|
|
<b-card-text>{{ profit.latest_trade_date }}</b-card-text>
|
|
|
|
</b-card>
|
|
|
|
</b-card-group>
|
|
|
|
<b-card-group deck class="mt-2">
|
|
|
|
<b-card header="Best performing">
|
|
|
|
<b-card-text>{{ profit.best_pair }}</b-card-text>
|
|
|
|
</b-card>
|
|
|
|
<b-card header="Total Balance">
|
|
|
|
<b-card-text
|
2021-09-01 04:35:59 +00:00
|
|
|
>{{
|
|
|
|
formatPrice(balance.total, botState ? botState.stake_currency_decimals || 8 : 8)
|
|
|
|
}}
|
2021-06-26 18:45:41 +00:00
|
|
|
{{ dailyStats.stake_currency }}</b-card-text
|
2020-09-03 05:17:00 +00:00
|
|
|
>
|
|
|
|
</b-card>
|
|
|
|
<b-card v-if="profit.profit_closed_fiat" header="Total profit">
|
|
|
|
<b-card-text
|
2021-06-26 18:45:41 +00:00
|
|
|
>{{ formatPrice(profit.profit_closed_fiat, 2) }}
|
2020-09-03 05:17:00 +00:00
|
|
|
{{ dailyStats.fiat_display_currency }}</b-card-text
|
|
|
|
>
|
|
|
|
</b-card>
|
|
|
|
</b-card-group>
|
2020-09-03 04:58:06 +00:00
|
|
|
</DraggableContainer>
|
|
|
|
</GridItem>
|
2020-08-18 05:05:40 +00:00
|
|
|
<GridItem
|
2020-08-31 15:48:08 +00:00
|
|
|
:i="gridLayoutDaily.i"
|
|
|
|
:x="gridLayoutDaily.x"
|
|
|
|
:y="gridLayoutDaily.y"
|
|
|
|
:w="gridLayoutDaily.w"
|
|
|
|
:h="gridLayoutDaily.h"
|
2020-08-31 15:47:26 +00:00
|
|
|
:min-w="3"
|
|
|
|
:min-h="4"
|
|
|
|
drag-allow-from=".drag-header"
|
2020-08-18 05:05:40 +00:00
|
|
|
>
|
2020-08-31 15:47:26 +00:00
|
|
|
<DraggableContainer header="Daily Profit">
|
|
|
|
<DailyChart v-if="dailyStats.data" :daily-stats="dailyStats" :show-title="false" />
|
|
|
|
</DraggableContainer>
|
2020-08-18 05:05:40 +00:00
|
|
|
</GridItem>
|
|
|
|
<GridItem
|
2020-08-31 15:48:08 +00:00
|
|
|
:i="gridLayoutHourly.i"
|
|
|
|
:x="gridLayoutHourly.x"
|
|
|
|
:y="gridLayoutHourly.y"
|
|
|
|
:w="gridLayoutHourly.w"
|
|
|
|
:h="gridLayoutHourly.h"
|
2020-08-31 15:47:26 +00:00
|
|
|
:min-w="3"
|
|
|
|
:min-h="4"
|
|
|
|
drag-allow-from=".drag-header"
|
2020-08-18 05:05:40 +00:00
|
|
|
>
|
2020-08-31 15:47:26 +00:00
|
|
|
<DraggableContainer header="Hourly Profit">
|
|
|
|
<HourlyChart :trades="closedTrades" :show-title="false" />
|
|
|
|
</DraggableContainer>
|
2020-08-18 05:05:40 +00:00
|
|
|
</GridItem>
|
|
|
|
<GridItem
|
2020-08-31 15:48:08 +00:00
|
|
|
:i="gridLayoutCumChart.i"
|
|
|
|
:x="gridLayoutCumChart.x"
|
|
|
|
:y="gridLayoutCumChart.y"
|
|
|
|
:w="gridLayoutCumChart.w"
|
|
|
|
:h="gridLayoutCumChart.h"
|
2020-08-31 15:47:26 +00:00
|
|
|
:min-w="3"
|
|
|
|
:min-h="4"
|
|
|
|
drag-allow-from=".drag-header"
|
2020-08-18 05:05:40 +00:00
|
|
|
>
|
2020-08-31 15:47:26 +00:00
|
|
|
<DraggableContainer header="Cumulative Profit">
|
2021-09-04 14:41:44 +00:00
|
|
|
<CumProfitChart :trades="allTradesAllBots" :show-title="false" />
|
2020-08-31 15:47:26 +00:00
|
|
|
</DraggableContainer>
|
2020-08-18 05:05:40 +00:00
|
|
|
</GridItem>
|
2021-01-05 18:29:47 +00:00
|
|
|
<GridItem
|
|
|
|
:i="gridLayoutTradesLogChart.i"
|
|
|
|
:x="gridLayoutTradesLogChart.x"
|
|
|
|
:y="gridLayoutTradesLogChart.y"
|
|
|
|
:w="gridLayoutTradesLogChart.w"
|
|
|
|
:h="gridLayoutTradesLogChart.h"
|
|
|
|
:min-w="3"
|
|
|
|
:min-h="4"
|
|
|
|
drag-allow-from=".drag-header"
|
|
|
|
>
|
|
|
|
<DraggableContainer header="Trades Log">
|
|
|
|
<TradesLogChart :trades="closedTrades" :show-title="false" />
|
|
|
|
</DraggableContainer>
|
|
|
|
</GridItem>
|
2020-08-18 05:05:40 +00:00
|
|
|
</GridLayout>
|
2020-08-17 19:16:27 +00:00
|
|
|
</template>
|
|
|
|
|
|
|
|
<script lang="ts">
|
2020-08-24 20:27:03 +00:00
|
|
|
import { formatPrice } from '@/shared/formatters';
|
|
|
|
|
2020-08-17 19:16:27 +00:00
|
|
|
import { Component, Vue } from 'vue-property-decorator';
|
|
|
|
import { namespace } from 'vuex-class';
|
2020-08-29 09:38:43 +00:00
|
|
|
import { GridLayout, GridItem, GridItemData } from 'vue-grid-layout';
|
2020-08-17 19:16:27 +00:00
|
|
|
|
|
|
|
import DailyChart from '@/components/charts/DailyChart.vue';
|
|
|
|
import HourlyChart from '@/components/charts/HourlyChart.vue';
|
2020-08-24 17:28:46 +00:00
|
|
|
import CumProfitChart from '@/components/charts/CumProfitChart.vue';
|
2021-01-05 18:29:47 +00:00
|
|
|
import TradesLogChart from '@/components/charts/TradesLog.vue';
|
2020-08-31 15:47:26 +00:00
|
|
|
import DraggableContainer from '@/components/layout/DraggableContainer.vue';
|
2020-08-17 19:16:27 +00:00
|
|
|
|
2020-10-06 05:59:05 +00:00
|
|
|
import {
|
|
|
|
DashboardLayout,
|
|
|
|
findGridLayout,
|
|
|
|
LayoutActions,
|
|
|
|
LayoutGetters,
|
|
|
|
} from '@/store/modules/layout';
|
2021-06-26 18:45:41 +00:00
|
|
|
import {
|
|
|
|
Trade,
|
|
|
|
DailyReturnValue,
|
|
|
|
BalanceInterface,
|
|
|
|
ProfitInterface,
|
|
|
|
DailyPayload,
|
|
|
|
BotState,
|
2021-09-04 08:35:00 +00:00
|
|
|
ClosedTrade,
|
2021-06-26 18:45:41 +00:00
|
|
|
} from '@/types';
|
2021-08-26 18:35:33 +00:00
|
|
|
import { BotStoreGetters } from '@/store/modules/ftbot';
|
2021-09-02 18:04:48 +00:00
|
|
|
import { MultiBotStoreGetters } from '@/store/modules/botStoreWrapper';
|
2020-08-17 19:16:27 +00:00
|
|
|
|
|
|
|
const ftbot = namespace('ftbot');
|
2020-08-18 06:29:40 +00:00
|
|
|
const layoutNs = namespace('layout');
|
2020-08-17 19:16:27 +00:00
|
|
|
|
|
|
|
@Component({
|
|
|
|
components: {
|
2020-08-29 09:38:43 +00:00
|
|
|
GridLayout,
|
|
|
|
GridItem,
|
2020-08-17 19:16:27 +00:00
|
|
|
DailyChart,
|
|
|
|
HourlyChart,
|
2020-08-24 17:28:46 +00:00
|
|
|
CumProfitChart,
|
2021-01-05 18:29:47 +00:00
|
|
|
TradesLogChart,
|
2020-08-31 15:47:26 +00:00
|
|
|
DraggableContainer,
|
2020-08-17 19:16:27 +00:00
|
|
|
},
|
|
|
|
})
|
2020-08-18 06:29:40 +00:00
|
|
|
export default class Dashboard extends Vue {
|
2020-08-29 15:47:05 +00:00
|
|
|
@ftbot.Getter closedTrades!: Trade[];
|
2020-08-17 19:16:27 +00:00
|
|
|
|
2021-09-04 14:41:44 +00:00
|
|
|
@ftbot.Getter [MultiBotStoreGetters.allTradesAllBots]!: ClosedTrade[];
|
2021-09-02 18:04:48 +00:00
|
|
|
|
2021-08-28 09:39:03 +00:00
|
|
|
@ftbot.Getter [BotStoreGetters.dailyStats]!: DailyReturnValue;
|
2020-08-17 19:16:27 +00:00
|
|
|
|
2021-08-28 09:39:03 +00:00
|
|
|
@ftbot.Getter [BotStoreGetters.openTrades]!: Array<Trade>;
|
2020-08-24 20:27:03 +00:00
|
|
|
|
2021-08-28 09:39:03 +00:00
|
|
|
@ftbot.Getter [BotStoreGetters.balance]!: BalanceInterface;
|
2020-08-24 20:27:03 +00:00
|
|
|
|
2021-08-26 18:35:33 +00:00
|
|
|
@ftbot.Getter [BotStoreGetters.botState]?: BotState;
|
2021-06-26 18:45:41 +00:00
|
|
|
|
2021-08-28 09:39:03 +00:00
|
|
|
@ftbot.Getter [BotStoreGetters.profit]!: ProfitInterface;
|
2020-08-24 20:27:03 +00:00
|
|
|
|
2021-08-28 09:39:03 +00:00
|
|
|
@ftbot.Getter [BotStoreGetters.performanceStats]!: PerformanceEntry[];
|
2020-08-24 20:27:03 +00:00
|
|
|
|
|
|
|
@ftbot.Action getPerformance;
|
|
|
|
|
2020-09-08 13:45:01 +00:00
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
2020-09-03 05:10:08 +00:00
|
|
|
@ftbot.Action getDaily!: (payload?: DailyPayload) => void;
|
2020-08-17 19:16:27 +00:00
|
|
|
|
|
|
|
@ftbot.Action getTrades;
|
|
|
|
|
2021-08-20 18:16:16 +00:00
|
|
|
@layoutNs.Getter [LayoutGetters.getDashboardLayoutSm]!: GridItemData[];
|
|
|
|
|
2020-10-06 05:59:05 +00:00
|
|
|
@layoutNs.Getter [LayoutGetters.getDashboardLayout]!: GridItemData[];
|
2020-08-18 06:29:40 +00:00
|
|
|
|
2020-10-06 05:59:05 +00:00
|
|
|
@layoutNs.Action [LayoutActions.setDashboardLayout];
|
2020-08-18 06:29:40 +00:00
|
|
|
|
2021-05-28 17:07:34 +00:00
|
|
|
@layoutNs.Getter [LayoutGetters.getLayoutLocked]: boolean;
|
|
|
|
|
2020-08-24 20:27:03 +00:00
|
|
|
@ftbot.Action getOpenTrades;
|
|
|
|
|
|
|
|
@ftbot.Action getBalance;
|
|
|
|
|
|
|
|
@ftbot.Action getProfit;
|
|
|
|
|
|
|
|
formatPrice = formatPrice;
|
|
|
|
|
2021-08-20 18:16:16 +00:00
|
|
|
localGridLayout: GridItemData[] = [];
|
|
|
|
|
|
|
|
currentBreakpoint = '';
|
|
|
|
|
|
|
|
get isLayoutLocked() {
|
|
|
|
return this.getLayoutLocked || !this.isResizableLayout;
|
|
|
|
}
|
|
|
|
|
|
|
|
get isResizableLayout() {
|
|
|
|
return ['', 'md', 'lg', 'xl'].includes(this.currentBreakpoint);
|
|
|
|
}
|
|
|
|
|
2020-08-31 15:48:08 +00:00
|
|
|
get gridLayout() {
|
2021-08-20 18:16:16 +00:00
|
|
|
if (this.isResizableLayout) {
|
|
|
|
return this.getDashboardLayout;
|
|
|
|
}
|
|
|
|
return this.localGridLayout;
|
|
|
|
}
|
|
|
|
|
|
|
|
set gridLayout(newLayout) {
|
|
|
|
// Dummy setter to make gridLayout happy. Updates happen through layoutUpdated.
|
|
|
|
}
|
|
|
|
|
|
|
|
layoutUpdated(newLayout) {
|
|
|
|
// Frozen layouts for small screen sizes.
|
|
|
|
if (this.isResizableLayout) {
|
|
|
|
console.log('newlayout', newLayout);
|
|
|
|
console.log('saving dashboard');
|
|
|
|
this.setDashboardLayout(newLayout);
|
|
|
|
}
|
2020-08-18 06:29:40 +00:00
|
|
|
}
|
2020-08-18 05:05:40 +00:00
|
|
|
|
2020-09-03 04:58:06 +00:00
|
|
|
get gridLayoutKPI(): GridItemData {
|
|
|
|
return findGridLayout(this.gridLayout, DashboardLayout.KPI);
|
|
|
|
}
|
|
|
|
|
2020-08-31 15:48:08 +00:00
|
|
|
get gridLayoutDaily(): GridItemData {
|
2020-08-29 14:43:50 +00:00
|
|
|
return findGridLayout(this.gridLayout, DashboardLayout.dailyChart);
|
2020-08-31 15:48:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
get gridLayoutHourly(): GridItemData {
|
2020-08-29 14:43:50 +00:00
|
|
|
return findGridLayout(this.gridLayout, DashboardLayout.hourlyChart);
|
2020-08-31 15:48:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
get gridLayoutCumChart(): GridItemData {
|
2020-08-29 14:43:50 +00:00
|
|
|
return findGridLayout(this.gridLayout, DashboardLayout.cumChartChart);
|
2020-08-31 15:48:08 +00:00
|
|
|
}
|
|
|
|
|
2021-01-05 18:29:47 +00:00
|
|
|
get gridLayoutTradesLogChart(): GridItemData {
|
|
|
|
return findGridLayout(this.gridLayout, DashboardLayout.tradesLogChart);
|
|
|
|
}
|
|
|
|
|
2021-08-20 18:16:16 +00:00
|
|
|
get responsiveGridLayouts() {
|
|
|
|
return {
|
|
|
|
sm: this.getDashboardLayoutSm,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-08-17 19:16:27 +00:00
|
|
|
mounted() {
|
2020-09-03 05:10:08 +00:00
|
|
|
this.getDaily({ timescale: 30 });
|
2020-08-17 19:16:27 +00:00
|
|
|
this.getTrades();
|
2020-08-24 20:27:03 +00:00
|
|
|
this.getOpenTrades();
|
|
|
|
this.getBalance();
|
|
|
|
this.getPerformance();
|
|
|
|
this.getProfit();
|
2021-08-20 18:16:16 +00:00
|
|
|
this.localGridLayout = [...this.getDashboardLayoutSm];
|
2020-08-17 19:16:27 +00:00
|
|
|
}
|
2020-08-29 09:38:43 +00:00
|
|
|
|
2021-08-20 18:16:16 +00:00
|
|
|
breakpointChanged(newBreakpoint) {
|
|
|
|
// console.log('breakpoint:', newBreakpoint);
|
|
|
|
this.currentBreakpoint = newBreakpoint;
|
2020-08-29 09:38:43 +00:00
|
|
|
}
|
2020-08-17 19:16:27 +00:00
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped></style>
|