182 lines
4.9 KiB
Vue
182 lines
4.9 KiB
Vue
<template>
|
|
<rung-builder name="Diagonal" :order="order" :builder="builder" v-model="endpoints"
|
|
:shape="DLine" :mode="0"
|
|
:get-model-value="getModelValue" :set-model-value="setModelValue"
|
|
:get-points-value="getPointsValue"
|
|
:set-values="setLines" :set-weights="setWeights"
|
|
:std-width="stdWidth" :build-tranches="buildTranches">
|
|
<table>
|
|
<tbody>
|
|
<template v-if="prices.length>1">
|
|
<tr>
|
|
<td>
|
|
<v-text-field type="number" v-model="higherPrice" min="0"
|
|
density="compact" hide-details class="mx-1 my-2" variant="outlined"
|
|
label="Price"
|
|
:color="color" :base-color="color"
|
|
style="flex: 6em"
|
|
/>
|
|
</td>
|
|
<td class="weight">{{ allocationText(weights[higherIndex]) }}</td>
|
|
</tr>
|
|
<tr v-for="i in innerIndexes" class="ml-5">
|
|
<td class="pl-5">{{ prices[i] }}</td>
|
|
<td class="weight">{{ allocationText(weights[i]) }}</td>
|
|
</tr>
|
|
</template>
|
|
<tr>
|
|
<td>
|
|
<v-text-field type="number" v-model="lowerPrice" min="0"
|
|
density="compact" hide-details class="mx-1 my-2" variant="outlined"
|
|
label="Price"
|
|
:color="color" :base-color="color"
|
|
style="flex: 6em"
|
|
/>
|
|
</td>
|
|
<td class="weight">{{ weights.length ? allocationText(weights[lowerIndex]) : '' }}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</rung-builder>
|
|
</template>
|
|
|
|
<script setup>
|
|
import {allocationText, applyLine, applyLinePoints, builderDefaults, useChartOrderStore} from "@/orderbuild.js";
|
|
import {interpolate, sideColor} from "@/misc.js";
|
|
import {useOrderStore, useStore} from "@/store/store.js";
|
|
import {MAX_FRACTION, newTranche} from "@/blockchain/orderlib.js";
|
|
import RungBuilder from "@/components/chart/RungBuilder.vue";
|
|
import {computed, ref} from "vue";
|
|
import {DLine} from "@/charts/shape.js";
|
|
import {vectorInterpolate} from "@/vector.js";
|
|
|
|
const s = useStore()
|
|
const os = useOrderStore()
|
|
const co = useChartOrderStore()
|
|
const props = defineProps(['order', 'builder'])
|
|
const emit = defineEmits(['update:builder'])
|
|
|
|
function computeDefaultColor() {
|
|
const index = props.order.builders.indexOf(props.builder)
|
|
return sideColor(props.order.buy, index)
|
|
}
|
|
|
|
const defaultColor = computeDefaultColor()
|
|
|
|
// Fields must be defined in order to be reactive
|
|
builderDefaults(props.builder, {
|
|
lineA: [null, null], // [{time, price}, {time, price}]
|
|
lineB: [null, null],
|
|
rungs: 1,
|
|
skew: 0,
|
|
color: defaultColor,
|
|
})
|
|
|
|
|
|
function buildTranches() {
|
|
throw Error('unimplemented') // todo
|
|
const order = props.order
|
|
const builder = props.builder
|
|
const tranches = []
|
|
|
|
console.log('buildTranches', builder, order, tranches)
|
|
const la = buildLine(_endpoints[0])
|
|
const lb = buildLine(_endpoints[1])
|
|
const ws = weights.value
|
|
for (let i = 0; i < ws.length; i++) {
|
|
const w = ws[i]
|
|
const line = vectorInterpolate(la, lb, i/(ws.length-1))
|
|
const t = newTranche({fraction: w * MAX_FRACTION})
|
|
const symbol = co.selectedSymbol
|
|
console.log('symbol', symbol)
|
|
applyLinePoints(t, order.buy, ...line, symbol.decimals, symbol.inverted)
|
|
tranches.push(t)
|
|
}
|
|
return tranches
|
|
}
|
|
|
|
|
|
function flattenLine(l) {
|
|
return l === null ? [null, null, null, null] : [l[0].time, l[0].price, l[1].time, l[1].price]
|
|
}
|
|
|
|
|
|
function buildLine(f) {
|
|
return f[0] === null ? null : [{time: f[0], price: f[1]}, {time: f[2], price: f[3]}]
|
|
}
|
|
|
|
const _endpoints = ref([flattenLine(props.builder.lineA), flattenLine(props.builder.lineB)])
|
|
const endpoints = computed({
|
|
get() {
|
|
return _endpoints.value
|
|
},
|
|
set(v) {
|
|
const [a, b] = v
|
|
update(a, b)
|
|
}
|
|
})
|
|
|
|
function update(a, b) { // a and b are lines of two points
|
|
_endpoints.value = [flattenLine(a), flattenLine(b)]
|
|
const newBuilder = {...props.builder}
|
|
newBuilder.lineA = a
|
|
newBuilder.lineB = b
|
|
emit('update:builder', newBuilder)
|
|
}
|
|
|
|
|
|
const innerIndexes = computed(() => {
|
|
const n = flatLines.value.length
|
|
const result = []
|
|
for (let i = 1; i < n - 1; i++)
|
|
result.push(n - 1 - i)
|
|
return result
|
|
})
|
|
|
|
|
|
const flatLines = ref([])
|
|
const weights = ref([])
|
|
|
|
function setLines(ls) {
|
|
flatLines.value = ls
|
|
}
|
|
|
|
function setWeights(ws) {
|
|
weights.value = ws
|
|
}
|
|
|
|
|
|
const color = computed(() => props.builder.color ? props.builder.color : defaultColor)
|
|
|
|
const stdWidth = [2 * co.meanRange, 2 * co.meanRange]
|
|
|
|
|
|
function getModelValue(model) {
|
|
if (!model)
|
|
return null
|
|
return [flattenLine(model.lineA), flattenLine(model.lineB)]
|
|
}
|
|
|
|
function getPointsValue(points) {
|
|
return points[0].price
|
|
}
|
|
|
|
function setModelValue(model, value) {
|
|
// console.log('setModelValue->', model.price, value)
|
|
if (model.price !== value)
|
|
model.price = value
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
td.weight {
|
|
width: 11em;
|
|
padding-left: 0.5em;
|
|
padding-right: 0.5em;
|
|
text-align: right;
|
|
}
|
|
</style>
|
|
|