breakout orders
This commit is contained in:
@@ -98,13 +98,13 @@ class TrancheShapes {
|
|||||||
const amountSymbol = buy ? this.symbol.base.s : this.symbol.quote.s
|
const amountSymbol = buy ? this.symbol.base.s : this.symbol.quote.s
|
||||||
const color = buy ? 'green' : 'red'
|
const color = buy ? 'green' : 'red'
|
||||||
if (intercept !== 0 || slope !== 0) {
|
if (intercept !== 0 || slope !== 0) {
|
||||||
console.log('tranche line', intercept, slope)
|
// console.log('tranche line', intercept, slope)
|
||||||
// line active
|
// line active
|
||||||
if (slope === 0) {
|
if (slope === 0) {
|
||||||
let price = intercept
|
let price = intercept
|
||||||
price *= scale
|
price *= scale
|
||||||
// horizontal line
|
// horizontal line
|
||||||
console.log('hline', price)
|
// console.log('hline', price)
|
||||||
const model = {price, color, maxAllocation: status.order.amount, amount, amountSymbol};
|
const model = {price, color, maxAllocation: status.order.amount, amount, amountSymbol};
|
||||||
const s = new HLine(model, null, null, null, true)
|
const s = new HLine(model, null, null, null, true)
|
||||||
this.shapes.push(s)
|
this.shapes.push(s)
|
||||||
@@ -120,7 +120,7 @@ class TrancheShapes {
|
|||||||
let endPrice = (intercept + slope * endTime);
|
let endPrice = (intercept + slope * endTime);
|
||||||
startPrice *= scale
|
startPrice *= scale
|
||||||
endPrice *= scale
|
endPrice *= scale
|
||||||
console.log('dline', startTime, endTime, DISTANT_FUTURE, startPrice, endPrice)
|
// console.log('dline', startTime, endTime, DISTANT_FUTURE, startPrice, endPrice)
|
||||||
// noinspection EqualityComparisonWithCoercionJS
|
// noinspection EqualityComparisonWithCoercionJS
|
||||||
const model = {
|
const model = {
|
||||||
pointA: {time: startTime, price: startPrice},
|
pointA: {time: startTime, price: startPrice},
|
||||||
|
|||||||
@@ -108,6 +108,8 @@ export class Shape {
|
|||||||
// both amount and amountSymbol must be set in order to display amount text
|
// both amount and amountSymbol must be set in order to display amount text
|
||||||
this.model.amount = null
|
this.model.amount = null
|
||||||
this.model.amountSymbol = null
|
this.model.amountSymbol = null
|
||||||
|
this.model.extraText = null
|
||||||
|
this.model.textLocation = 'above'
|
||||||
|
|
||||||
// LEAF SUBCLASSES MUST CALL setModel(model) AFTER ALL CONSTRUCTION.
|
// LEAF SUBCLASSES MUST CALL setModel(model) AFTER ALL CONSTRUCTION.
|
||||||
}
|
}
|
||||||
@@ -127,6 +129,10 @@ export class Shape {
|
|||||||
this.model.amount = model.amount
|
this.model.amount = model.amount
|
||||||
if (model.amountSymbol)
|
if (model.amountSymbol)
|
||||||
this.model.amountSymbol = model.amountSymbol
|
this.model.amountSymbol = model.amountSymbol
|
||||||
|
if (model.extraText)
|
||||||
|
this.model.extraText = model.extraText
|
||||||
|
if (model.textLocation)
|
||||||
|
this.model.textLocation = model.textLocation
|
||||||
|
|
||||||
const newProps = {}
|
const newProps = {}
|
||||||
|
|
||||||
@@ -152,12 +158,18 @@ export class Shape {
|
|||||||
|
|
||||||
// text label
|
// text label
|
||||||
let text = allocationText(this.model.allocation, this.model.amount, this.model.amountSymbol)
|
let text = allocationText(this.model.allocation, this.model.amount, this.model.amountSymbol)
|
||||||
|
if (this.model.extraText)
|
||||||
|
text += ' '+this.model.extraText
|
||||||
if (this.debug) text = `${this.id} ` + text
|
if (this.debug) text = `${this.id} ` + text
|
||||||
if (!text.length)
|
if (!text.length)
|
||||||
newProps.showLabel = false
|
newProps.showLabel = false
|
||||||
else {
|
else {
|
||||||
newProps.text = text
|
newProps.text = text
|
||||||
newProps.showLabel = true
|
newProps.showLabel = true
|
||||||
|
newProps.textLocation = this.model.textLocation
|
||||||
|
newProps.vertLabelsAlign =
|
||||||
|
this.model.textLocation === 'above' ? 'bottom' :
|
||||||
|
this.model.textLocation === 'below' ? 'top' : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.debug && this.id)
|
if (this.debug && this.id)
|
||||||
@@ -612,7 +624,7 @@ export class DLine extends Line {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/* todo tim
|
||||||
pointsToTvOhlcStart(points, periodSeconds = null) {
|
pointsToTvOhlcStart(points, periodSeconds = null) {
|
||||||
if (points === null) return null
|
if (points === null) return null
|
||||||
const [v,w] = points
|
const [v,w] = points
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<span v-if="b||m">
|
<span v-if="b||m">
|
||||||
{{description}}
|
{{description}}<br/>
|
||||||
<suspense>
|
<suspense>
|
||||||
<pair-price :base="base" :quote="quote" :value="price" :show-btn="showBtn"/>
|
<pair-price :base="base" :quote="quote" :value="price" :show-btn="showBtn"/>
|
||||||
</suspense>
|
</suspense>
|
||||||
@@ -13,7 +13,7 @@ import PairPrice from "@/components/PairPrice.vue";
|
|||||||
import {computed} from "vue";
|
import {computed} from "vue";
|
||||||
import {useStore} from "@/store/store.js";
|
import {useStore} from "@/store/store.js";
|
||||||
|
|
||||||
const props = defineProps(['base', 'quote', 'm', 'b', 'isMin', 'showBtn', 'buy'])
|
const props = defineProps(['base', 'quote', 'm', 'b', 'isBreakout', 'showBtn', 'buy'])
|
||||||
const s = useStore()
|
const s = useStore()
|
||||||
|
|
||||||
|
|
||||||
@@ -25,9 +25,10 @@ const price = computed(()=>{
|
|||||||
})
|
})
|
||||||
|
|
||||||
const description = computed(()=>{
|
const description = computed(()=>{
|
||||||
|
let msg = props.isBreakout ? 'breakout' : 'limit'
|
||||||
if( props.m !== 0 )
|
if( props.m !== 0 )
|
||||||
return 'diagonal'
|
msg += ' diagonal'
|
||||||
return props.isBreakout ? 'breakout' : 'limit'
|
return msg
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,6 @@
|
|||||||
<template v-for="(t, i) in item.order.tranches">
|
<template v-for="(t, i) in item.order.tranches">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="text-right" colspan="2">
|
<td class="text-right" colspan="2">
|
||||||
Tranche {{ i + 1 }}
|
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<div v-if="s.clock < item.trancheStatus[i].startTime">
|
<div v-if="s.clock < item.trancheStatus[i].startTime">
|
||||||
Activates {{ timestampString(item.trancheStatus[i].startTime) }}
|
Activates {{ timestampString(item.trancheStatus[i].startTime) }}
|
||||||
@@ -368,7 +367,8 @@ const orders = computed(()=>{
|
|||||||
}
|
}
|
||||||
st.base = st.order.inverted ? high : low;
|
st.base = st.order.inverted ? high : low;
|
||||||
st.quote = st.order.inverted ? low : high;
|
st.quote = st.order.inverted ? low : high;
|
||||||
st.minIsLimit = buy !== st.order.inverted // whether limit/breakout is flipped
|
st.minIsLimit = buy === st.order.inverted // whether limit/breakout is flipped
|
||||||
|
// console.log('buy/inverted/minIsLimit', buy, st.order.inverted, st.minIsLimit)
|
||||||
// console.log('elaborated', st)
|
// console.log('elaborated', st)
|
||||||
}
|
}
|
||||||
result.sort((a,b)=>b.startTime-a.startTime)
|
result.sort((a,b)=>b.startTime-a.startTime)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {builderFuncs, deleteBuilder, useChartOrderStore} from "@/orderbuild.js";
|
import {builderFuncs, deleteBuilder} from "@/orderbuild.js";
|
||||||
import ColorBand from "@/components/chart/ColorBand.vue";
|
import ColorBand from "@/components/chart/ColorBand.vue";
|
||||||
import RowBar from "@/components/chart/RowBar.vue";
|
import RowBar from "@/components/chart/RowBar.vue";
|
||||||
import {onBeforeUnmount, onMounted, onUnmounted, onUpdated, watchEffect} from "vue";
|
import {onBeforeUnmount, onMounted, onUnmounted, onUpdated, watchEffect} from "vue";
|
||||||
@@ -31,7 +31,6 @@ const props = defineProps({
|
|||||||
deleteShapes: {type: Function, default: null},
|
deleteShapes: {type: Function, default: null},
|
||||||
})
|
})
|
||||||
const emit = defineEmits(['update:builder'])
|
const emit = defineEmits(['update:builder'])
|
||||||
const co = useChartOrderStore()
|
|
||||||
|
|
||||||
|
|
||||||
let lastId = props.builder.id
|
let lastId = props.builder.id
|
||||||
|
|||||||
@@ -29,18 +29,34 @@
|
|||||||
</template>
|
</template>
|
||||||
<div class="my-3">
|
<div class="my-3">
|
||||||
<div v-if="order.builders.length===0"> <!--todo remove gralpha limitation of one builder-->
|
<div v-if="order.builders.length===0"> <!--todo remove gralpha limitation of one builder-->
|
||||||
<v-btn :color="color" variant="text" prepend-icon="mdi-clock-outline" @click="build(order,'DCABuilder')">DCA</v-btn>
|
<v-tooltip text="Spread order across time" location="top">
|
||||||
<v-btn :color="color" variant="text" prepend-icon="mdi-ray-vertex" @click="build(order,'LimitBuilder')">Limit</v-btn>
|
|
||||||
<v-btn :color="color" variant="text" prepend-icon="mdi-vector-line" @click="build(order,'DiagonalBuilder')">Diagonal</v-btn>
|
|
||||||
<!--
|
|
||||||
<v-tooltip text="Coming Soon!" location="top">
|
|
||||||
<template v-slot:activator="{ props }">
|
<template v-slot:activator="{ props }">
|
||||||
<span v-bind="props">
|
<span v-bind="props">
|
||||||
<v-btn :color="color" variant="text" prepend-icon="mdi-information-outline">New Thing!</v-btn>
|
<v-btn :color="color" variant="text" prepend-icon="mdi-clock-outline" @click="build(order,'DCABuilder')">DCA</v-btn>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</v-tooltip>
|
||||||
|
<v-tooltip text="Trade a price level" location="top">
|
||||||
|
<template v-slot:activator="{ props }">
|
||||||
|
<span v-bind="props">
|
||||||
|
<v-btn :color="color" variant="text" prepend-icon="mdi-ray-vertex" @click="build(order,'LimitBuilder')">Limit</v-btn>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</v-tooltip>
|
||||||
|
<v-tooltip text="Trade trends and channels" location="top">
|
||||||
|
<template v-slot:activator="{ props }">
|
||||||
|
<span v-bind="props">
|
||||||
|
<v-btn :color="color" variant="text" prepend-icon="mdi-vector-line" @click="build(order,'DiagonalBuilder')">Diagonal</v-btn>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</v-tooltip>
|
||||||
|
<v-tooltip text="Coming Soon! Stoplosses and Takeprofits" location="top">
|
||||||
|
<template v-slot:activator="{ props }">
|
||||||
|
<span v-bind="props">
|
||||||
|
<v-btn :color="color" variant="text" prepend-icon="mdi-plus-minus" disabled>Stoploss</v-btn>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</v-tooltip>
|
</v-tooltip>
|
||||||
-->
|
|
||||||
<!-- mdi-ray-start-end mdi-vector-polyline -->
|
<!-- mdi-ray-start-end mdi-vector-polyline -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<rung-builder name="Diagonal" :order="order" :builder="builder" v-model="endpoints"
|
<rung-builder :name="name" :description="description"
|
||||||
|
:order="order" :builder="builder" v-model="endpoints"
|
||||||
:shape="DLine" :mode="0"
|
:shape="DLine" :mode="0"
|
||||||
:get-model-value="getModelValue" :set-model-value="setModelValue"
|
:get-model-value="getModelValue" :set-model-value="setModelValue"
|
||||||
:set-values="setLines" :set-weights="setWeights"
|
:set-values="setLines" :set-weights="setWeights"
|
||||||
@@ -122,6 +123,7 @@ builderDefaults(props.builder, {
|
|||||||
extendRight: true,
|
extendRight: true,
|
||||||
rungs: 1,
|
rungs: 1,
|
||||||
skew: 0,
|
skew: 0,
|
||||||
|
breakout: false,
|
||||||
color: defaultColor,
|
color: defaultColor,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -150,9 +152,11 @@ function buildTranches() {
|
|||||||
// console.log('tranche start/end',
|
// console.log('tranche start/end',
|
||||||
// t.startTime === DISTANT_PAST ? 'PAST' : t.startTime,
|
// t.startTime === DISTANT_PAST ? 'PAST' : t.startTime,
|
||||||
// t.endTime === DISTANT_FUTURE ? 'FUTURE' : t.endTime)
|
// t.endTime === DISTANT_FUTURE ? 'FUTURE' : t.endTime)
|
||||||
applyLinePoints(t, symbol, order.buy, ...line)
|
applyLinePoints(t, symbol, order.buy, ...line, builder.breakout)
|
||||||
tranches.push(t)
|
tranches.push(t)
|
||||||
}
|
}
|
||||||
|
// if( flipped.value )
|
||||||
|
// tranches.reverse()
|
||||||
return tranches
|
return tranches
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,6 +399,13 @@ function dirtyLine(a, b) {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const name = computed(()=>(props.builder.breakout?'Breakout':'Limit')+' Diagonal'+(weights.value.length>1?'s':''))
|
||||||
|
|
||||||
|
const description = computed(()=>{
|
||||||
|
const buy = props.order.buy
|
||||||
|
const above = buy === props.builder.breakout
|
||||||
|
return (buy?'Buy ':'Sell ')+(above?'above':'below')+' the line'
|
||||||
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<rung-builder :name="prices.length>1?'Ladder':'Limit'" :order="order" :builder="builder"
|
<rung-builder :name="(builder.breakout?'Breakout':'Limit')+(prices.length>1?' Ladder':'')"
|
||||||
|
:description="description"
|
||||||
|
:order="order" :builder="builder"
|
||||||
v-model="priceEndpoints" :mode="0" :flip="flipped"
|
v-model="priceEndpoints" :mode="0" :flip="flipped"
|
||||||
:shape="HLine"
|
:shape="HLine"
|
||||||
:get-model-value="getModelValue" :set-model-value="setModelValue"
|
:get-model-value="getModelValue" :set-model-value="setModelValue"
|
||||||
@@ -70,6 +72,7 @@ builderDefaults(props.builder, {
|
|||||||
priceB: null,
|
priceB: null,
|
||||||
rungs: 1,
|
rungs: 1,
|
||||||
skew: 0,
|
skew: 0,
|
||||||
|
breakout: false,
|
||||||
color: defaultColor,
|
color: defaultColor,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -81,7 +84,7 @@ function buildTranches() {
|
|||||||
console.log('buildTranches', builder, order, tranches)
|
console.log('buildTranches', builder, order, tranches)
|
||||||
const ps = prices.value
|
const ps = prices.value
|
||||||
const ws = weights.value
|
const ws = weights.value
|
||||||
for(let i=ps.length-1; i>=0; i--) { // reverse
|
for(let i=0; i<ps.length; i++) {
|
||||||
let p = ps[i]
|
let p = ps[i]
|
||||||
const w = ws[i]
|
const w = ws[i]
|
||||||
const t = newTranche({
|
const t = newTranche({
|
||||||
@@ -90,9 +93,11 @@ function buildTranches() {
|
|||||||
})
|
})
|
||||||
const symbol = co.selectedSymbol
|
const symbol = co.selectedSymbol
|
||||||
console.log('symbol', symbol, p)
|
console.log('symbol', symbol, p)
|
||||||
applyLinePoint(t, symbol, order.buy, p)
|
applyLinePoint(t, symbol, order.buy, p, builder.breakout)
|
||||||
tranches.push(t)
|
tranches.push(t)
|
||||||
}
|
}
|
||||||
|
if (!flipped.value)
|
||||||
|
tranches.reverse()
|
||||||
return tranches
|
return tranches
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,11 +196,13 @@ function setWeights(ws) { weights.value = ws }
|
|||||||
|
|
||||||
const amountSymbol = computed(()=>props.order.amountIsTokenA ? co.selectedSymbol.base.s : co.selectedSymbol.quote.s )
|
const amountSymbol = computed(()=>props.order.amountIsTokenA ? co.selectedSymbol.base.s : co.selectedSymbol.quote.s )
|
||||||
const allocationTexts = computed(()=>weights.value.map((w)=>allocationText(w, w*props.order.amount, amountSymbol.value)))
|
const allocationTexts = computed(()=>weights.value.map((w)=>allocationText(w, w*props.order.amount, amountSymbol.value)))
|
||||||
|
|
||||||
const color = computed(()=>props.builder.color ? props.builder.color : defaultColor)
|
const color = computed(()=>props.builder.color ? props.builder.color : defaultColor)
|
||||||
|
|
||||||
const stdWidth = computed(()=>co.meanRange)
|
const stdWidth = computed(()=>co.meanRange)
|
||||||
|
const description = computed(()=>{
|
||||||
|
const buy = props.order.buy
|
||||||
|
const above = buy === props.builder.breakout
|
||||||
|
return (buy?'Buy ':'Sell ')+(above?'above':'below')+' the line'
|
||||||
|
})
|
||||||
|
|
||||||
function getModelValue(model) {
|
function getModelValue(model) {
|
||||||
if(!model)
|
if(!model)
|
||||||
|
|||||||
@@ -3,7 +3,10 @@
|
|||||||
:adjust-shapes="adjustShapes" :delete-shapes="deleteShapes">
|
:adjust-shapes="adjustShapes" :delete-shapes="deleteShapes">
|
||||||
<div style="min-width: 4em; font-size: larger" :style="colorStyle"
|
<div style="min-width: 4em; font-size: larger" :style="colorStyle"
|
||||||
class="d-flex flex-column align-self-start ml-2">
|
class="d-flex flex-column align-self-start ml-2">
|
||||||
<span class="w-100 text-center">{{ name }}</span>
|
<div class="flex-row align-items-center">
|
||||||
|
<v-btn variant="outlined" @click="props.builder.breakout=!props.builder.breakout">{{ name }}</v-btn>
|
||||||
|
<div class="description">{{description}}</div>
|
||||||
|
</div>
|
||||||
<v-text-field type="number" v-model="rungs"
|
<v-text-field type="number" v-model="rungs"
|
||||||
density="compact" hide-details class="mx-1 my-2" variant="outlined"
|
density="compact" hide-details class="mx-1 my-2" variant="outlined"
|
||||||
label="Rungs"
|
label="Rungs"
|
||||||
@@ -55,6 +58,7 @@ const co = useChartOrderStore()
|
|||||||
const endpoints = defineModel('modelValue') // 2-item list of points/values
|
const endpoints = defineModel('modelValue') // 2-item list of points/values
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
name: String,
|
name: String,
|
||||||
|
description: String,
|
||||||
order: Object,
|
order: Object,
|
||||||
builder: Object,
|
builder: Object,
|
||||||
buildTranches: Function,
|
buildTranches: Function,
|
||||||
@@ -309,12 +313,18 @@ function removeInteriorShape() {
|
|||||||
function makeModel(index) {
|
function makeModel(index) {
|
||||||
const ws = weights.value
|
const ws = weights.value
|
||||||
const alloc = props.builder.allocation * ws[index];
|
const alloc = props.builder.allocation * ws[index];
|
||||||
|
const buy = props.order.buy
|
||||||
|
const above = buy === props.builder.breakout
|
||||||
const result = {
|
const result = {
|
||||||
color: color.value,
|
color: color.value,
|
||||||
allocation: alloc,
|
allocation: alloc,
|
||||||
maxAllocation: Math.max(...weights.value),
|
maxAllocation: Math.max(...weights.value),
|
||||||
amount: props.order.amount * alloc,
|
amount: props.order.amount * alloc,
|
||||||
amountSymbol: amountSymbol.value,
|
amountSymbol: amountSymbol.value,
|
||||||
|
textLocation: above ? 'above' : 'below',
|
||||||
|
extraText: !props.builder.breakout ? ' ' :
|
||||||
|
// (above ? '↑ Breakout ↑' : '↓ Breakout ↓')
|
||||||
|
(above ? '▲ Breakout ▲' : '▼ Breakout ▼')
|
||||||
}
|
}
|
||||||
setModelValue(result, values.value[index])
|
setModelValue(result, values.value[index])
|
||||||
return result
|
return result
|
||||||
@@ -411,4 +421,7 @@ if (!endpoints.value[0])
|
|||||||
min-width: 9em;
|
min-width: 9em;
|
||||||
max-width: 12em;
|
max-width: 12em;
|
||||||
}
|
}
|
||||||
|
.description {
|
||||||
|
font-size: 0.6em;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user