Add plotconfig selector

This commit is contained in:
Matthias 2020-08-08 15:57:36 +02:00
parent 25cce25fc1
commit 1886e3328f
6 changed files with 77 additions and 51 deletions

View File

@ -8,7 +8,7 @@
import { Component, Vue, Prop, Watch } from 'vue-property-decorator';
import ECharts from 'vue-echarts';
import * as echarts from 'echarts';
import { Trade, PairHistory, PlotConfig } from '@/store/types';
import { Trade, PairHistory, PlotConfig } from '@/types';
import randomColor from '@/shared/randomColor';
import { roundTimeframe } from '@/shared/timemath';
import { timestampms } from '@/shared/formatters';

View File

@ -7,16 +7,22 @@
hide-backdrop
button-size="sm"
>
<PlotConfigurator :columns="datasetColumns" v-model="plotConfig" />
<PlotConfigurator v-model="plotConfig" :columns="datasetColumns" />
</b-modal>
<div class="row ml-auto">
<div class="col-mb-2 mr-2">
<b-select
v-model="plotConfigName"
:options="availablePlotConfigNames"
@change="plotConfigChanged"
>
</b-select>
</div>
<div class="col-mb-2 mr-2">
<b-checkbox v-model="useUTC" title="Use UTC for graph">useUtc</b-checkbox>
</div>
<div class="col-mb-2 mr-3">
<b-button @click="showConfigurator" size="sm" title="Plot configurator">
&#9881;
</b-button>
<b-button size="sm" title="Plot configurator" @click="showConfigurator"> &#9881; </b-button>
</div>
</div>
<CandleChart
@ -24,7 +30,7 @@
:timeframems="timeframems"
:dataset="dataset"
:trades="trades"
:plotConfig="plotConfig"
:plot-config="plotConfig"
>
</CandleChart>
</div>
@ -32,10 +38,13 @@
<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator';
import { Trade, PairHistory, EMPTY_PLOTCONFIG, PlotConfig } from '@/store/types';
import { namespace } from 'vuex-class';
import { Trade, PairHistory, EMPTY_PLOTCONFIG, PlotConfig } from '@/types';
import CandleChart from '@/components/charts/CandleChart.vue';
import PlotConfigurator from '@/components/charts/PlotConfigurator.vue';
import { loadCustomPlotConfig, loadPlotConfigName } from '../../shared/storage';
import { getCustomPlotConfig, getPlotConfigName } from '@/shared/storage';
const ftbot = namespace('ftbot');
@Component({ components: { CandleChart, PlotConfigurator } })
export default class CandleChartContainer extends Vue {
@ -51,12 +60,21 @@ export default class CandleChartContainer extends Vue {
plotConfig: PlotConfig = { ...EMPTY_PLOTCONFIG };
plotConfigName = '';
@ftbot.State availablePlotConfigNames!: Array<string>;
get datasetColumns() {
return this.dataset ? this.dataset.columns : [];
}
mounted() {
this.plotConfig = loadCustomPlotConfig(loadPlotConfigName());
this.plotConfigName = getPlotConfigName();
this.plotConfig = getCustomPlotConfig(this.plotConfigName);
}
plotConfigChanged() {
this.plotConfig = getCustomPlotConfig(this.plotConfigName);
}
showConfigurator() {

View File

@ -2,28 +2,28 @@
<div v-if="columns">
<div class="col-mb-3 ml-2">
<b-form-radio-group
class="w-100"
v-model="plotOption"
class="w-100"
:options="plotOptions"
buttons
button-variant="outline-primary"
>
</b-form-radio-group>
</div>
<div class="col-mb-3" v-if="plotOption == 'subplots'">
<div v-if="plotOption == 'subplots'" class="col-mb-3">
<hr />
<b-form-group label="Subplot" label-for="FieldSel">
<b-form-select id="FieldSel" :options="subplots" v-model="selSubPlot" :select-size="4">
<b-form-select id="FieldSel" v-model="selSubPlot" :options="subplots" :select-size="4">
</b-form-select>
</b-form-group>
</div>
<b-form-group v-if="plotOption == 'subplots'" label="New subplot" label-for="newSubplot">
<b-input-group size="sm">
<b-form-input class="addPlot" id="newSubplot" v-model="newSubplotName"></b-form-input>
<b-form-input id="newSubplot" v-model="newSubplotName" class="addPlot"></b-form-input>
<b-input-group-append>
<b-button @click="addSubplot">+</b-button>
<b-button @click="delSubplot" v-if="selSubPlot">-</b-button>
<b-button v-if="selSubPlot" @click="delSubplot">-</b-button>
</b-input-group-append>
</b-input-group>
</b-form-group>
@ -31,8 +31,8 @@
<b-form-group label="Used indicators" label-for="selectedIndicators">
<b-form-select
id="selectedIndicators"
:options="usedColumns"
v-model="selIndicator"
:options="usedColumns"
:select-size="4"
>
</b-form-select>
@ -40,15 +40,15 @@
<b-form-group label="Add indicator" label-for="indicatorSelector">
<b-form-select
id="indicatorSelector"
:options="columns"
v-model="selAvailableIndicator"
:options="columns"
:select-size="4"
>
</b-form-select>
</b-form-group>
<b-form-group label="Choose type" label-for="plotTypeSelector">
<b-form-select id="plotTypeSelector" :options="availableGraphTypes" v-model="graphType">
<b-form-select id="plotTypeSelector" v-model="graphType" :options="availableGraphTypes">
</b-form-select>
</b-form-group>
<hr />
@ -56,78 +56,78 @@
<b-form-group label="Color" label-for="colsel" size="sm">
<b-input-group>
<b-input-group-prepend>
<div v-bind:style="{ 'background-color': selColor }" class="colorbox mr-2"></div>
<div :style="{ 'background-color': selColor }" class="colorbox mr-2"></div>
</b-input-group-prepend>
<b-form-input id="colsel" v-model="selColor" size="sm"> </b-form-input>
<b-input-group-append>
<b-button variant="primary" @click="newColor" size="sm">&#x21bb;</b-button>
<b-button variant="primary" size="sm" @click="newColor">&#x21bb;</b-button>
</b-input-group-append>
</b-input-group>
</b-form-group>
<hr />
<b-form-group label="Plot config name" label-for="idPlotConfigName">
<b-form-input id="idPlotConfigName" :options="availableGraphTypes" v-model="plotConfigName">
<b-form-input id="idPlotConfigName" v-model="plotConfigName" :options="availableGraphTypes">
</b-form-input>
</b-form-group>
<div class="row">
<b-button
class="ml-1"
variant="primary"
@click="addIndicator"
title="Add indicator to plot"
size="sm"
:disabled="!selAvailableIndicator"
@click="addIndicator"
>
Add
</b-button>
<b-button
class="ml-1"
variant="primary"
@click="removeIndicator"
title="Remove indicator to plot"
size="sm"
:disabled="!selIndicator"
@click="removeIndicator"
>
Remove
</b-button>
<b-button class="ml-1" variant="primary" @click="loadPlotConfig" size="sm">Load</b-button>
<b-button class="ml-1" variant="primary" @click="loadPlotConfigFromStrategy" size="sm">
<b-button class="ml-1" variant="primary" size="sm" @click="loadPlotConfig">Load</b-button>
<b-button class="ml-1" variant="primary" size="sm" @click="loadPlotConfigFromStrategy">
Load from strategy
</b-button>
<b-button
class="ml-1"
variant="primary"
@click="savePlotConfig"
size="sm"
data-toggle="tooltip"
title="Save configuration"
@click="savePlotConfig"
>Save</b-button
>
<b-button
class="ml-1"
id="showButton"
class="ml-1"
variant="primary"
@click="showConfig = !showConfig"
size="sm"
title="Show configuration for easy transfer to a strategy"
@click="showConfig = !showConfig"
>Show</b-button
>
<b-button
v-if="showConfig"
class="ml-1"
variant="primary"
@click="loadConfigFromString"
size="sm"
v-if="showConfig"
title="Load configuration from text box below"
@click="loadConfigFromString"
>Load from String</b-button
>
</div>
<div class="col-mb-5 ml-2 mt-2" v-if="showConfig">
<div v-if="showConfig" class="col-mb-5 ml-2 mt-2">
<b-textarea
id="TextArea"
class="textArea"
v-model="plotConfigJson"
class="textArea"
size="sm"
:state="tempPlotConfigValid"
>
@ -139,9 +139,9 @@
<script lang="ts">
import { Component, Vue, Prop, Emit } from 'vue-property-decorator';
import { namespace } from 'vuex-class';
import { PlotConfig, EMPTY_PLOTCONFIG } from '@/store/types';
import { PlotConfig, EMPTY_PLOTCONFIG } from '@/types';
import randomColor from '@/shared/randomColor';
import { loadCustomPlotConfig } from '@/shared/storage';
import { getCustomPlotConfig } from '@/shared/storage';
const ftbot = namespace('ftbot');
@ -302,7 +302,7 @@ export default class PlotConfigurator extends Vue {
}
loadPlotConfig() {
this.plotConfig = loadCustomPlotConfig(this.plotConfigName);
this.plotConfig = getCustomPlotConfig(this.plotConfigName);
console.log(this.plotConfig);
console.log('loading config');
this.emitPlotConfig();

View File

@ -3,7 +3,7 @@ import { PlotConfig, EMPTY_PLOTCONFIG, PlotConfigStorage } from '@/types';
const PLOT_CONFIG = 'ft_custom_plot_config';
const PLOT_CONFIG_NAME = 'ft_selected_plot_config';
export function loadPlotConfigName(): string {
export function getPlotConfigName(): string {
return localStorage.getItem(PLOT_CONFIG_NAME) || 'default';
}
@ -11,17 +11,21 @@ export function storePlotConfigName(plotConfigName: string): void {
localStorage.setItem(PLOT_CONFIG_NAME, plotConfigName);
}
export function loadAllCustomPlotConfig(): PlotConfig {
export function getAllCustomPlotConfig(): PlotConfig {
return JSON.parse(localStorage.getItem(PLOT_CONFIG) || '{}');
}
export function loadCustomPlotConfig(configName: string): PlotConfig {
const configs = loadAllCustomPlotConfig();
export function getAllPlotConfigNames(): Array<string> {
return Object.keys(getAllCustomPlotConfig());
}
export function getCustomPlotConfig(configName: string): PlotConfig {
const configs = getAllCustomPlotConfig();
return configName in configs ? configs[configName] : { ...EMPTY_PLOTCONFIG };
}
export function storeCustomPlotConfig(plotConfig: PlotConfigStorage) {
const existingConfig = loadAllCustomPlotConfig();
const existingConfig = getAllCustomPlotConfig();
// Merge existing with new config
const finalPlotConfig = { ...existingConfig, ...plotConfig };

View File

@ -15,7 +15,12 @@ import {
PlotConfigStorage,
} from '@/types';
import { storeCustomPlotConfig, loadPlotConfigName, storePlotConfigName } from '@/shared/storage';
import {
storeCustomPlotConfig,
getPlotConfigName,
getAllPlotConfigNames,
storePlotConfigName,
} from '@/shared/storage';
import { showAlert } from './alerts';
export enum BotStoreGetters {
@ -47,7 +52,8 @@ export default {
history: {},
strategyPlotConfig: {},
customPlotConfig: { ...EMPTY_PLOTCONFIG },
plotConfigName: loadPlotConfigName(),
plotConfigName: getPlotConfigName(),
availablePlotConfigNames: getAllPlotConfigNames(),
strategyList: [],
pairlist: [],
},
@ -128,12 +134,14 @@ export default {
state.strategyPlotConfig = plotConfig;
},
updatePlotConfigName(state, plotConfigName: string) {
// Set default plot config name
state.plotConfigName = plotConfigName;
storePlotConfigName(plotConfigName);
},
saveCustomPlotConfig(state, plotConfig: PlotConfigStorage) {
state.customPlotConfig = plotConfig;
storeCustomPlotConfig(plotConfig);
state.availablePlotConfigNames = getAllPlotConfigNames();
},
},
actions: {

View File

@ -8,17 +8,13 @@
<b-button @click="refresh">&#x21bb;</b-button>
</div>
<div class="col-mb-2">
<b-form-select
:options="historicView ? pairlist : whitelist"
v-model="pair"
@change="refresh"
>
</b-form-select>
<b-select v-model="pair" :options="historicView ? pairlist : whitelist" @change="refresh">
</b-select>
</div>
</div>
<div class="mt-2 row" v-if="historicView">
<TimeRangeSelect class="col-md-4 mr-2" v-model="timerange"></TimeRangeSelect>
<StrategyList class="col-md-2" v-model="strategy"></StrategyList>
<div v-if="historicView" class="mt-2 row">
<TimeRangeSelect v-model="timerange" class="col-md-4 mr-2"></TimeRangeSelect>
<StrategyList v-model="strategy" class="col-md-2"></StrategyList>
</div>
<div class="row">
@ -40,7 +36,7 @@ import { namespace } from 'vuex-class';
import CandleChartContainer from '@/components/charts/CandleChartContainer.vue';
import TimeRangeSelect from '@/components/ftbot/TimeRangeSelect.vue';
import StrategyList from '@/components/ftbot/StrategyList.vue';
import { AvailablePairPayload, PairCandlePayload, PairHistoryPayload } from '@/store/types';
import { AvailablePairPayload, PairCandlePayload, PairHistoryPayload } from '@/types';
const ftbot = namespace('ftbot');