2020-07-26 11:44:34 +00:00
|
|
|
<template>
|
2021-07-04 17:57:19 +00:00
|
|
|
<div class="container-fluid" style="max-height: calc(100vh - 60px)">
|
2021-07-04 14:08:43 +00:00
|
|
|
<div class="container-fluid">
|
|
|
|
<div class="row mb-2"></div>
|
2022-04-19 05:05:34 +00:00
|
|
|
<p v-if="!botStore.activeBot.canRunBacktest">
|
|
|
|
Bot must be in webserver mode to enable Backtesting.
|
|
|
|
</p>
|
2021-07-04 14:08:43 +00:00
|
|
|
<div class="row w-100">
|
|
|
|
<h2 class="col-4 col-lg-3">Backtesting</h2>
|
|
|
|
<div
|
2021-12-01 05:40:25 +00:00
|
|
|
class="col-12 col-lg-order-last col-lg-6 mx-md-5 d-flex flex-wrap justify-content-md-center justify-content-between mb-4"
|
2020-12-05 15:32:44 +00:00
|
|
|
>
|
2022-04-12 05:18:35 +00:00
|
|
|
<b-form-radio
|
2022-04-19 05:05:34 +00:00
|
|
|
v-if="botStore.activeBot.botApiVersion >= 2.15"
|
2022-04-12 05:18:35 +00:00
|
|
|
v-model="btFormMode"
|
|
|
|
name="bt-form-radios"
|
|
|
|
button
|
|
|
|
class="mx-1 flex-samesize-items"
|
|
|
|
value="historicResults"
|
2022-04-19 05:05:34 +00:00
|
|
|
:disabled="!botStore.activeBot.canRunBacktest"
|
2022-04-12 05:18:35 +00:00
|
|
|
>Load Results</b-form-radio
|
|
|
|
>
|
2021-07-04 14:08:43 +00:00
|
|
|
<b-form-radio
|
|
|
|
v-model="btFormMode"
|
|
|
|
name="bt-form-radios"
|
|
|
|
button
|
|
|
|
class="mx-1 flex-samesize-items"
|
|
|
|
value="run"
|
2022-04-19 05:05:34 +00:00
|
|
|
:disabled="!botStore.activeBot.canRunBacktest"
|
2021-07-04 14:08:43 +00:00
|
|
|
>Run backtest</b-form-radio
|
|
|
|
>
|
|
|
|
<b-form-radio
|
2022-04-13 17:55:27 +00:00
|
|
|
id="bt-analyze-btn"
|
2021-07-04 14:08:43 +00:00
|
|
|
v-model="btFormMode"
|
|
|
|
name="bt-form-radios"
|
|
|
|
button
|
|
|
|
class="mx-1 flex-samesize-items"
|
|
|
|
value="results"
|
|
|
|
:disabled="!hasBacktestResult"
|
|
|
|
>Analyze result</b-form-radio
|
|
|
|
>
|
|
|
|
<b-form-radio
|
|
|
|
v-model="btFormMode"
|
|
|
|
name="bt-form-radios"
|
|
|
|
button
|
|
|
|
class="mx-1 flex-samesize-items"
|
|
|
|
value="visualize-summary"
|
|
|
|
:disabled="!hasBacktestResult"
|
|
|
|
>Visualize summary</b-form-radio
|
|
|
|
>
|
|
|
|
<b-form-radio
|
|
|
|
v-model="btFormMode"
|
|
|
|
name="bt-form-radios"
|
|
|
|
button
|
|
|
|
class="mx-1 flex-samesize-items"
|
|
|
|
value="visualize"
|
|
|
|
:disabled="!hasBacktestResult"
|
|
|
|
>Visualize result</b-form-radio
|
|
|
|
>
|
|
|
|
</div>
|
2022-04-19 05:05:34 +00:00
|
|
|
<small
|
|
|
|
v-show="botStore.activeBot.backtestRunning"
|
2022-10-30 13:26:23 +00:00
|
|
|
class="text-end bt-running-label col-8 col-lg-3"
|
2022-04-19 05:05:34 +00:00
|
|
|
>Backtest running: {{ botStore.activeBot.backtestStep }}
|
|
|
|
{{ formatPercent(botStore.activeBot.backtestProgress, 2) }}</small
|
2020-12-05 15:32:44 +00:00
|
|
|
>
|
|
|
|
</div>
|
2021-03-11 18:17:09 +00:00
|
|
|
</div>
|
2021-06-25 18:00:40 +00:00
|
|
|
|
2021-05-23 14:25:31 +00:00
|
|
|
<div class="d-md-flex">
|
2021-03-11 18:17:09 +00:00
|
|
|
<!-- Left bar -->
|
|
|
|
<div
|
2022-11-18 18:48:15 +00:00
|
|
|
:class="`${showLeftBar ? 'col-md-3' : ''} sticky-top sticky-offset me-3 d-flex flex-column`"
|
2021-03-11 18:17:09 +00:00
|
|
|
>
|
|
|
|
<b-button
|
2021-06-25 18:00:40 +00:00
|
|
|
v-if="btFormMode !== 'visualize'"
|
2021-03-11 18:17:09 +00:00
|
|
|
class="align-self-start"
|
|
|
|
aria-label="Close"
|
|
|
|
size="sm"
|
|
|
|
@click="showLeftBar = !showLeftBar"
|
|
|
|
>{{ showLeftBar ? '<' : '>' }}</b-button
|
|
|
|
>
|
2021-06-24 18:46:24 +00:00
|
|
|
<transition name="fade" mode="in-out">
|
|
|
|
<BacktestResultSelect
|
|
|
|
v-if="btFormMode !== 'visualize' && showLeftBar"
|
2022-04-19 05:05:34 +00:00
|
|
|
:backtest-history="botStore.activeBot.backtestHistory"
|
|
|
|
:selected-backtest-result-key="botStore.activeBot.selectedBacktestResultKey"
|
2023-04-13 04:34:39 +00:00
|
|
|
@selection-change="botStore.activeBot.setBacktestResultKey"
|
2021-06-24 18:46:24 +00:00
|
|
|
/>
|
|
|
|
</transition>
|
2021-03-11 18:17:09 +00:00
|
|
|
</div>
|
|
|
|
<!-- End Left bar -->
|
2022-04-12 05:18:35 +00:00
|
|
|
<div
|
|
|
|
v-if="btFormMode == 'historicResults'"
|
|
|
|
class="flex-fill row d-flex flex-column bt-config"
|
|
|
|
>
|
|
|
|
<backtest-history-load />
|
|
|
|
</div>
|
2021-07-06 04:56:41 +00:00
|
|
|
<div v-if="btFormMode == 'run'" class="flex-fill row d-flex flex-column bt-config">
|
2023-07-22 09:24:24 +00:00
|
|
|
<backtest-run />
|
2020-09-25 04:22:34 +00:00
|
|
|
</div>
|
2021-03-11 18:17:09 +00:00
|
|
|
<BacktestResultView
|
|
|
|
v-if="hasBacktestResult && btFormMode == 'results'"
|
2022-04-19 05:05:34 +00:00
|
|
|
:backtest-result="botStore.activeBot.selectedBacktestResult"
|
2021-03-11 18:17:09 +00:00
|
|
|
class="flex-fill"
|
2020-11-01 12:58:16 +00:00
|
|
|
/>
|
2021-03-11 18:17:09 +00:00
|
|
|
|
2023-07-22 09:27:01 +00:00
|
|
|
<BacktestGraphs
|
2021-03-11 18:17:09 +00:00
|
|
|
v-if="hasBacktestResult && btFormMode == 'visualize-summary'"
|
2022-09-15 18:16:06 +00:00
|
|
|
:trades="botStore.activeBot.selectedBacktestResult.trades"
|
|
|
|
/>
|
2020-11-01 12:58:16 +00:00
|
|
|
</div>
|
2021-03-11 18:17:09 +00:00
|
|
|
|
2020-12-05 16:42:22 +00:00
|
|
|
<div
|
|
|
|
v-if="hasBacktestResult && btFormMode == 'visualize'"
|
2021-06-25 18:00:40 +00:00
|
|
|
class="container-fluid text-center w-100 mt-2"
|
2020-12-05 16:42:22 +00:00
|
|
|
>
|
2022-10-30 11:55:14 +00:00
|
|
|
<BacktestResultChart
|
|
|
|
:timeframe="timeframe"
|
2023-07-22 09:11:07 +00:00
|
|
|
:strategy="btStore.strategy"
|
2023-07-22 09:15:17 +00:00
|
|
|
:timerange="btStore.timerange"
|
2022-10-30 11:55:14 +00:00
|
|
|
:pairlist="botStore.activeBot.selectedBacktestResult.pairlist"
|
|
|
|
:trades="botStore.activeBot.selectedBacktestResult.trades"
|
2023-07-22 09:16:13 +00:00
|
|
|
:freqai-model="btStore.freqAI.enabled ? btStore.freqAI.model : undefined"
|
2022-10-30 11:55:14 +00:00
|
|
|
/>
|
2020-07-26 17:35:56 +00:00
|
|
|
</div>
|
2020-07-26 11:44:34 +00:00
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
2022-12-20 06:02:47 +00:00
|
|
|
<script setup lang="ts">
|
2023-07-22 09:27:01 +00:00
|
|
|
import BacktestGraphs from '@/components/ftbot/BacktestGraphs.vue';
|
2023-07-22 09:24:24 +00:00
|
|
|
import BacktestHistoryLoad from '@/components/ftbot/BacktestHistoryLoad.vue';
|
2022-10-30 11:02:48 +00:00
|
|
|
import BacktestResultChart from '@/components/ftbot/BacktestResultChart.vue';
|
2023-07-22 09:24:24 +00:00
|
|
|
import BacktestResultSelect from '@/components/ftbot/BacktestResultSelect.vue';
|
|
|
|
import BacktestResultView from '@/components/ftbot/BacktestResultView.vue';
|
|
|
|
import BacktestRun from '@/components/ftbot/BacktestRun.vue';
|
2020-07-27 05:19:45 +00:00
|
|
|
|
2021-01-14 07:04:28 +00:00
|
|
|
import { formatPercent } from '@/shared/formatters';
|
2023-07-22 09:11:07 +00:00
|
|
|
import { useBtStore } from '@/stores/btStore';
|
2023-07-22 09:24:24 +00:00
|
|
|
import { useBotStore } from '@/stores/ftbotwrapper';
|
|
|
|
import { computed, onMounted, ref, watch } from 'vue';
|
2020-07-26 11:44:34 +00:00
|
|
|
|
2022-12-20 06:02:47 +00:00
|
|
|
const botStore = useBotStore();
|
2023-07-22 09:11:07 +00:00
|
|
|
const btStore = useBtStore();
|
2022-04-16 12:30:33 +00:00
|
|
|
|
2022-12-20 06:02:47 +00:00
|
|
|
const hasBacktestResult = computed(() =>
|
|
|
|
botStore.activeBot.backtestHistory
|
|
|
|
? Object.keys(botStore.activeBot.backtestHistory).length !== 0
|
|
|
|
: false,
|
|
|
|
);
|
|
|
|
const timeframe = computed((): string => {
|
|
|
|
try {
|
|
|
|
return botStore.activeBot.selectedBacktestResult.timeframe;
|
|
|
|
} catch (err) {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
});
|
2022-04-16 12:30:33 +00:00
|
|
|
|
2022-12-20 06:02:47 +00:00
|
|
|
const showLeftBar = ref(false);
|
2023-07-22 09:18:04 +00:00
|
|
|
|
2022-12-20 06:02:47 +00:00
|
|
|
const btFormMode = ref('run');
|
|
|
|
const pollInterval = ref<number | null>(null);
|
2022-04-16 12:30:33 +00:00
|
|
|
|
2022-12-20 06:02:47 +00:00
|
|
|
const selectBacktestResult = () => {
|
|
|
|
// Set parameters for this result
|
2023-07-22 09:11:07 +00:00
|
|
|
btStore.strategy = botStore.activeBot.selectedBacktestResult.strategy_name;
|
|
|
|
botStore.activeBot.getStrategy(btStore.strategy);
|
2023-07-22 09:13:35 +00:00
|
|
|
btStore.selectedTimeframe = botStore.activeBot.selectedBacktestResult.timeframe;
|
|
|
|
btStore.selectedDetailTimeframe =
|
|
|
|
botStore.activeBot.selectedBacktestResult.timeframe_detail || '';
|
2023-04-10 16:20:09 +00:00
|
|
|
// TODO: maybe this should not use timerange, but the actual backtest start/end results instead?
|
2023-07-22 09:15:17 +00:00
|
|
|
btStore.timerange = botStore.activeBot.selectedBacktestResult.timerange;
|
2022-12-20 06:02:47 +00:00
|
|
|
};
|
2022-09-14 18:44:29 +00:00
|
|
|
|
2022-12-20 06:02:47 +00:00
|
|
|
watch(
|
|
|
|
() => botStore.activeBot.selectedBacktestResultKey,
|
|
|
|
() => {
|
|
|
|
selectBacktestResult();
|
|
|
|
},
|
|
|
|
);
|
2021-02-17 19:37:30 +00:00
|
|
|
|
2022-12-20 06:02:47 +00:00
|
|
|
onMounted(() => botStore.activeBot.getState());
|
|
|
|
watch(
|
|
|
|
() => botStore.activeBot.backtestRunning,
|
|
|
|
() => {
|
|
|
|
if (botStore.activeBot.backtestRunning === true) {
|
|
|
|
pollInterval.value = window.setInterval(botStore.activeBot.pollBacktest, 1000);
|
|
|
|
} else if (pollInterval.value) {
|
|
|
|
clearInterval(pollInterval.value);
|
|
|
|
pollInterval.value = null;
|
|
|
|
}
|
2022-04-16 12:30:33 +00:00
|
|
|
},
|
2022-12-20 06:02:47 +00:00
|
|
|
);
|
2020-07-26 11:44:34 +00:00
|
|
|
</script>
|
|
|
|
|
2021-05-24 09:34:48 +00:00
|
|
|
<style lang="scss" scoped>
|
2021-01-21 06:47:51 +00:00
|
|
|
.bt-running-label {
|
|
|
|
position: absolute;
|
|
|
|
right: 2em;
|
|
|
|
margin-top: 1em;
|
|
|
|
}
|
2021-03-11 18:17:09 +00:00
|
|
|
|
|
|
|
.sticky-offset {
|
|
|
|
top: 2em;
|
|
|
|
}
|
2021-05-24 09:34:48 +00:00
|
|
|
.flex-samesize-items {
|
|
|
|
flex: 1 1 0;
|
|
|
|
@media md {
|
|
|
|
flex: unset;
|
|
|
|
}
|
|
|
|
}
|
2021-06-24 18:46:24 +00:00
|
|
|
|
|
|
|
.fade-enter-active,
|
|
|
|
.fade-leave-active {
|
|
|
|
transition: all 0.2s;
|
|
|
|
}
|
|
|
|
|
|
|
|
.fade-enter,
|
|
|
|
.fade-leave-to {
|
|
|
|
opacity: 0;
|
|
|
|
}
|
2021-07-06 04:56:41 +00:00
|
|
|
|
|
|
|
.bt-config {
|
|
|
|
@media (min-width: 992px) {
|
|
|
|
margin-left: auto;
|
|
|
|
margin-right: auto;
|
|
|
|
max-width: 75vw;
|
|
|
|
}
|
|
|
|
}
|
2020-09-16 18:28:48 +00:00
|
|
|
</style>
|