DCA redraw hacks

This commit is contained in:
Tim
2024-04-17 22:18:34 -04:00
parent 45a3d09e2b
commit 1579060024
6 changed files with 248 additions and 58 deletions

View File

@@ -1,7 +1,10 @@
<template>
<rung-builder name='DCA' :order="order" :builder="builder"
v-model:value-a="absTimeA" v-model:value-b="absTimeB" :mode="1" :shape="VLine"
:get-model-value="getModelValue" :set-model-value="setModelValue" :set-values="setValues"
v-model:value-a="absTimeA" v-model:value-b="absTimeB" :mode="1" :flip="flipped"
:shape="VLine"
:get-model-value="getModelValue" :set-model-value="setModelValue"
:get-points-value="getPointsValue"
:set-values="setValues" :set-weights="setWeights"
:std-width="stdWidth" :build-tranches="buildTranches">
<v-list style="background-color: inherit">
<v-list-item v-for="t in absoluteTimes">{{t}}</v-list-item>
@@ -17,7 +20,8 @@ import {useTheme} from "vuetify";
import {useOrderStore, useStore} from "@/store/store.js";
import {DISTANT_FUTURE, MAX_FRACTION, newTranche} from "@/blockchain/orderlib.js";
import RungBuilder from "@/components/chart/RungBuilder.vue";
import {computed, ref} from "vue";
import {computed, ref, watchEffect} from "vue";
import {chart, dragging} from "@/charts/chart.js";
const s = useStore()
const os = useOrderStore()
@@ -25,7 +29,8 @@ const co = useChartOrderStore()
const theme = useTheme().current
const props = defineProps(['order', 'builder'])
const stdWidth = computed(()=>10 * co.intervalSecs)
const minWidth = computed(()=>co.intervalSecs)
const stdWidth = computed(()=>10 * minWidth.value)
function computeDefaultColor() {
const index = props.order.builders.indexOf(props.builder)
@@ -46,6 +51,8 @@ builderDefaults(props.builder, {
})
const rawTimes = ref([])
const weights = ref([])
const times = computed(()=>rawTimes.value.map((t)=>Math.round(t)))
const endTimes = computed(()=>{
if (props.builder.rungs === 1)
@@ -55,27 +62,49 @@ const endTimes = computed(()=>{
return ts.map((t)=>t+window)
})
const absoluteTimes = computed(()=>{
console.log('absoluteTimes', props.builder.relative, times.value)
// console.log('absoluteTimes', props.builder.relative, times.value)
if (!props.builder.relative)
return times.value
const now = s.clock
return times.value.map((t)=>now+t)
})
watchEffect(()=>{
// auto scroll
if (!dragging && absoluteTimes.value.length) {
const endTime = absoluteTimes.value[absoluteTimes.value.length-1]
const range = chart.getVisibleRange()
const width = range.to - range.from
const now = s.clock
const extra = (Math.max(0,endTime - now) + minWidth.value) / width
// console.log('visrange', range, width, absV)
if (range.to < endTime) {
// console.log('scrolling')
chart.setVisibleRange({from: now - width, to: now}, {
percentRightMargin: Math.round(100 * extra),
applyDefaultRightMargin: false
})
}
}
})
const absTimeA = computed({
get() {
let result = props.builder.timeA
if (props.builder.relative)
result += s.clock
console.log('absTimeA', result)
// console.log('absTimeA', result)
return result
},
set(v) {
console.log('set absTimeA', props.builder.timeA, v)
// console.log('set absTimeA', props.builder.timeA, v)
if (props.builder.relative)
v -= s.clock
props.builder.timeA = v
console.log('absTimeA=',props.builder.timeA)
// console.log('absTimeA=',props.builder.timeA)
scroll()
}
})
const absTimeB = computed({
@@ -83,15 +112,57 @@ const absTimeB = computed({
let result = props.builder.timeB
if (props.builder.relative)
result += s.clock
console.log('absTimeB', result)
// console.log('absTimeB', result)
return result
},
set(v) {
console.log('set absTimeB', props.builder.timeB, v)
// console.log('set absTimeB', props.builder.timeB, v)
const absV = v
if ( v !== null && props.builder.relative )
v -= s.clock
props.builder.timeB = v
console.log('absTimeB=',props.builder.timeB)
const maxA = v - minWidth.value;
if (props.builder.timeA > maxA)
props.builder.timeA = maxA
// console.log('absTimeB=',props.builder.timeB)
scroll()
}
})
const flipped = computed(()=>{
const a = props.builder.timeA
const b = props.builder.timeB
return a !== null && b !== null && a > b
})
const higherIndex = computed(()=>flipped.value ? 0 : weights.value.length-1)
const lowerIndex = computed(()=>!flipped.value ? 0 : weights.value.length-1)
const innerIndexes = computed(()=>{
const n = times.value.length
const f = flipped.value
const result = []
for (let i=1; i<n-1; i++)
result.push(f?i:n-1-i)
return result
})
const earlierTime = computed({
get() { return !flipped.value ? props.builder.timeA : props.builder.timeB },
set(v) {
if (!flipped.value)
props.builder.timeA = v
else
props.builder.timeB = v
}
})
const laterTime = computed({
get() { return !flipped.value ? props.builder.timeA : props.builder.timeB },
set(v) {
if (!flipped.value)
props.builder.timeA = v
else
props.builder.timeB = v
}
})
@@ -124,11 +195,15 @@ function getModelValue(model) {
return model.time
}
function getPointsValue(points) {
return points[0].price
}
function setModelValue(model, value) {
console.log('DCA set model value', model, value)
// console.log('DCA set model value', model, value)
const v = value === null ? null : props.builder.relative ? s.clock + Math.round(value) : Math.round(value)
if (model.time !== v) {
console.log('DCA do set time', v)
// console.log('DCA do set time', v)
model.time = v
}
}
@@ -138,18 +213,11 @@ function setValues(values) {
rawTimes.value = values
else {
const now = s.clock
const vs = []
for (let i = 0; i < values.length; i++)
vs.push(values[i] - now)
rawTimes.value = vs
rawTimes.value = values.map((v)=>v-now)
}
}
function valueFromPoints(points) {
const result = points[0].time;
console.log('valueFromPoints', points, result);
return result
}
function setWeights(ws) { weights.value = ws }
</script>

View File

@@ -1,7 +1,9 @@
<template>
<rung-builder :name="prices.length>1?'Ladder':'Limit'" :order="order" :builder="builder"
v-model:value-a="priceA" v-model:value-b="priceB" :mode="0" :shape="HLine"
v-model:value-a="priceA" v-model:value-b="priceB" :mode="0" :flip="flipped"
:shape="HLine"
:get-model-value="getModelValue" :set-model-value="setModelValue"
:get-points-value="getPointsValue"
:set-values="setPrices" :set-weights="setWeights"
:std-width="stdWidth" :build-tranches="buildTranches">
<table>
@@ -131,9 +133,9 @@ const higherPrice = computed({
const higherIndex = computed(()=>flipped.value ? 0 : weights.value.length-1)
const lowerIndex = computed(()=>!flipped.value ? 0 : weights.value.length-1)
const innerIndexes = computed(()=>{
const result = []
const n = prices.value.length
const f = flipped.value
const result = []
for (let i=1; i<n-1; i++)
result.push(f?i:n-1-i)
return result
@@ -210,6 +212,10 @@ function getModelValue(model) {
return model.price
}
function getPointsValue(points) {
return points[0].price
}
function setModelValue(model, value) {
// console.log('setModelValue->', {...model}, value)
if (model.price !== value)
@@ -220,12 +226,6 @@ function setModelValue(model, value) {
</script>
<style scoped lang="scss">
:deep(.v-slider.v-input--vertical > .v-input__control) {
min-height: 5em !important;
}
:deep(.v-slider.no-slider-bg .v-slider-track__fill) {
background-color: inherit !important;
}
td.weight {
padding-left: 0.5em;
padding-right: 0.5em;

View File

@@ -36,12 +36,12 @@
<script setup>
import BuilderPanel from "@/components/chart/BuilderPanel.vue";
import {useOrderStore} from "@/store/store.js";
import {allocationText, deleteBuilder, linearWeights, useChartOrderStore, weightColors} from "@/orderbuild.js";
import {deleteBuilder, linearWeights, useChartOrderStore} from "@/orderbuild.js";
import {useTheme} from "vuetify";
import {linspace, sideColor} from "@/misc.js";
import {computed, onUnmounted, watchEffect} from "vue";
import Color from "color";
import {cancelDrawing} from "@/charts/chart.js";
import {cancelDrawing, chart} from "@/charts/chart.js";
const os = useOrderStore()
const co = useChartOrderStore()
@@ -56,14 +56,15 @@ const props = defineProps({
stdWidth: Number,
shape: Function, // shape() -> Shape
mode: { type: Number, default: 0 }, // rung addition mode: 0 = split, 1 = extend
flip: { type: Boolean, default: false }, // if true, the skew slider is flipped upside-down
getModelValue: Function, // getModelValue(model) -> value
setModelValue: Function, // setModelValue(model,value) -> void
getPointsValue: Function, // getValueFromPoints(points) -> value
setValues: Function, // setValues(values:Array) -> void
setWeights: Function, // setValues(values:Array) -> void
})
const flipped = computed(() => valueA.value !== null && valueB.value !== null && valueA.value > valueB.value)
const flippedSign = computed(()=>flipped.value?-1:1)
const flippedSign = computed(()=>props.flip?-1:1)
const skew100 = computed( {
get() {return flippedSign.value*props.builder.skew*100},
@@ -73,9 +74,9 @@ const skew100 = computed( {
// validity checks
watchEffect(()=>{
const rungs = props.builder.rungs
const prev = props.builder.valid
// const prev = props.builder.valid
props.builder.valid = rungs >= 1 && valueA.value && (rungs < 2 || valueB.value)
console.log('valid?', prev, props.builder.valid, rungs, valueA.value, valueB.value)
// console.log('valid?', prev, props.builder.valid, rungs, valueA.value, valueB.value)
})
@@ -138,7 +139,7 @@ const values = computed(()=>{
const weights = computed(() => {
// const skew = flipped.value ? -props.builder.skew : props.builder.skew
// const skew = props.flip ? -props.builder.skew : props.builder.skew
const ws = linearWeights(props.builder.rungs, -props.builder.skew)
if (props.setWeights)
props.setWeights(ws)
@@ -184,6 +185,7 @@ function createShape(value, model, onModel, onDelete) {
function translateOnDrag(shape) {
const oldOnPoints = shape.onPoints
shape.onPoints = function (points) {
// console.log('translateOnDrag', this.beingDragged(), shape.ourPoints)
if (!this.beingDragged()) {
oldOnPoints.call(this, points)
return
@@ -192,6 +194,7 @@ function translateOnDrag(shape) {
oldOnPoints.call(this, points)
const cur = props.getModelValue(this.model)
const delta = cur - prev
// console.log('delta', points, shape.ourPoints, prev, cur, delta)
if (delta !== 0) {
valueA.value += delta
valueB.value += delta
@@ -199,6 +202,28 @@ function translateOnDrag(shape) {
}
}
// function translateOnDrag(shape) {
// const oldOnPoints = shape.onPoints
// shape.onPoints = function (points) {
// console.log('translateOnDrag', this.beingDragged(), shape.ourPoints)
// if (!this.beingDragged()) {
// oldOnPoints.call(this, points)
// return
// }
//
// // todo vectorize
// const prev = props.getPointsValue(shape.ourPoints)
// const cur = props.getPointsValue(points)
// const delta = cur - prev
// console.log('delta', points, shape.ourPoints, prev, cur, delta)
// if (delta !== 0) {
// valueA.value += delta
// valueB.value += delta
// }
// oldOnPoints.call(this, points)
// }
// }
const shapeA = createShape(valueA.value, {color: defaultColor},
function (model) {
@@ -258,10 +283,42 @@ function makeModel(index) {
return result
}
let group = null
function adjustShapes() {
// this is where all the shapes are created or adjusted
// console.log('adjustShapes()', valueA.value, valueB.value)
const vs = values.value
//
//
// const selection = []
// if (shapeA.id !== null)
// selection.push(shapeA.id)
// if (shapeB.id !== null)
// selection.push(shapeB.id)
// for( const s of interiorShapes ) {
// if (s.id !== null)
// selection.push(s.id)
// }
// if (group===null) {
// if (selection.length) {
// const gc = chart.shapesGroupController();
// group = gc.createGroupFromSelection(selection)
// }
// }
// else {
// const gc = chart.shapesGroupController();
// const shapes = gc.shapesInGroup(group)
//
// console.log('shapes', group, shapes)
// for (const s of selection)
// if (!shapes.includes(s)) {
// console.log('add shape to group', group, s)
// gc.addShapeToGroup(group, s)
// }
// }
//
//
if (vs.length)
cancelDrawing()
// shape properties
@@ -306,10 +363,13 @@ function adjustShapes() {
}
function deleteSelf() {
if (valueA.value===null)
cancelDrawing()
deleteBuilder(props.order, props.builder);
}
function deleteShapes() {
cancelDrawing()
shapeA.delete()
shapeB.delete()
for (const shape of interiorShapes)
@@ -325,5 +385,10 @@ if (!valueA.value)
</script>
<style scoped lang="scss">
</style>
:deep(.v-slider.v-input--vertical > .v-input__control) {
min-height: 5em !important;
}
:deep(.v-slider.no-slider-bg .v-slider-track__fill) {
background-color: inherit !important;
}
</style>