post-order line draw improvements
This commit is contained in:
@@ -240,7 +240,6 @@ function invertTicker(ticker) {
|
||||
}
|
||||
|
||||
export function lookupSymbol(ticker) { // lookup by ticker which is "0xbaseAddress/0xquoteAddress"
|
||||
// todo tim lookup default base/quote pool
|
||||
const symbols = getAllSymbols();
|
||||
if (!(ticker in symbols)) {
|
||||
// check the inverted symbol
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {DISTANT_FUTURE, DISTANT_PAST} from "@/blockchain/orderlib.js";
|
||||
import {DISTANT_FUTURE, DISTANT_PAST, MAX_FRACTION} from "@/blockchain/orderlib.js";
|
||||
import {allocationText, DLine, HLine} from "@/charts/shape.js";
|
||||
import {createShape, deleteShapeId} from "@/charts/chart.js";
|
||||
import {timestamp} from "@/misc.js";
|
||||
import {sideColor, timestamp} from "@/misc.js";
|
||||
import {useChartOrderStore} from "@/orderbuild.js";
|
||||
|
||||
export class OrderShapes {
|
||||
@@ -16,9 +16,10 @@ export class OrderShapes {
|
||||
for (const old of this.trancheShapes)
|
||||
old.delete()
|
||||
this.status = orderStatus
|
||||
this.trancheShapes = [];
|
||||
this.trancheShapes = []
|
||||
const maxAllocation = Math.max(...orderStatus.order.tranches.map((ts)=>ts.fraction)) / MAX_FRACTION
|
||||
for (let i = 0; i < orderStatus.trancheStatus.length; i++)
|
||||
this.trancheShapes.push(new TrancheShapes(this.symbol, this.status, i));
|
||||
this.trancheShapes.push(new TrancheShapes(this.symbol, this.status, i, maxAllocation));
|
||||
}
|
||||
|
||||
show() {for (const t of this.trancheShapes) t.show();}
|
||||
@@ -28,8 +29,7 @@ export class OrderShapes {
|
||||
|
||||
|
||||
class TrancheShapes {
|
||||
constructor(symbol, orderStatus, trancheIndex) {
|
||||
// todo validate base/quote
|
||||
constructor(symbol, orderStatus, trancheIndex, maxAllocation) {
|
||||
if (symbol.inverted !== orderStatus.order.inverted) {
|
||||
console.log('OrderShapes.createLine(): symbol has wrong inverson for this order')
|
||||
return
|
||||
@@ -38,14 +38,16 @@ class TrancheShapes {
|
||||
this.status = orderStatus
|
||||
this.trancheIndex = trancheIndex
|
||||
this.tranche = orderStatus.order.tranches[trancheIndex]
|
||||
this.trancheStatus = orderStatus.trancheStatus[trancheIndex]
|
||||
this.shapes = []
|
||||
this.fills = []
|
||||
this.createShapes();
|
||||
this.maxAllocation = maxAllocation
|
||||
this.createShapes()
|
||||
}
|
||||
|
||||
createShapes() {
|
||||
// todo amounts
|
||||
const t = this.tranche
|
||||
|
||||
// console.log('create tranche shapes', t)
|
||||
if (t.marketOrder) {
|
||||
if (t.startTime !== DISTANT_PAST) {
|
||||
@@ -53,8 +55,10 @@ class TrancheShapes {
|
||||
}
|
||||
} else {
|
||||
// check lines
|
||||
this.createLine(t.minLine.slope, t.minLine.intercept);
|
||||
this.createLine(t.maxLine.slope, t.maxLine.intercept);
|
||||
const amount = this.status.order.amount * BigInt(t.fraction) / BigInt(MAX_FRACTION)
|
||||
const buy = this.status.order.tokenIn === this.symbol.quote.a
|
||||
this.createLine(t.minLine.slope, t.minLine.intercept, amount, buy);
|
||||
this.createLine(t.maxLine.slope, t.maxLine.intercept, amount, !buy);
|
||||
}
|
||||
for (const f of this.status.trancheStatus[this.trancheIndex].fills)
|
||||
this.createFillPoint(f)
|
||||
@@ -72,67 +76,78 @@ class TrancheShapes {
|
||||
* 10 ** -(amountIsBase ? this.symbol.base.d : this.symbol.quote.d)
|
||||
const weight = Number(filledAmount) / Number(this.status.order.amount)
|
||||
const amountSymbol = amountIsBase ? this.symbol.base.s : this.symbol.quote.s
|
||||
console.log('fillpoint', buy, filledAmount, this.status.order, this.symbol)
|
||||
// console.log('fillpoint', buy, filledAmount, this.status.order, this.symbol)
|
||||
const time = f.time
|
||||
const out = Number(f.filledOut) / (1-this.status.order.route.fee/1000000)
|
||||
let price = out / Number(f.filledIn)
|
||||
if (buy)
|
||||
price = 1/price
|
||||
price *= scale
|
||||
console.log('price', price)
|
||||
// console.log('price', price)
|
||||
const channel = buy?'low':'high';
|
||||
const text = (buy ? 'Buy ' : 'Sell ') + allocationText(weight, amount, amountSymbol, '\n')
|
||||
const s = createShape(buy?'arrow_up':'arrow_down', {time, price}, {channel,text,lock:true})
|
||||
console.log('created fill shape at', time, price)
|
||||
// console.log('created fill shape at', time, price)
|
||||
this.fills.push(s)
|
||||
}
|
||||
|
||||
createLine(slope, intercept, amount) {
|
||||
createLine(slope, intercept, amountBigInt, breakout) {
|
||||
if (intercept === 0 && slope === 0) return
|
||||
const t = this.tranche
|
||||
const status = this.status
|
||||
const symbol = this.symbol
|
||||
const scale = 10**symbol.decimals;
|
||||
const buy = status.order.tokenIn === this.symbol.quote.a
|
||||
amount = Number(amount)
|
||||
* 10 ** -(buy ? this.symbol.base.d : this.symbol.quote.d)
|
||||
const decimals = buy ? this.symbol.base.d : this.symbol.quote.d;
|
||||
amountBigInt = BigInt(amountBigInt)
|
||||
const amount = Number(amountBigInt) * 10 ** - decimals
|
||||
const amountSymbol = buy ? this.symbol.base.s : this.symbol.quote.s
|
||||
const color = buy ? 'green' : 'red'
|
||||
if (intercept !== 0 || slope !== 0) {
|
||||
// console.log('tranche line', intercept, slope)
|
||||
// line active
|
||||
if (slope === 0) {
|
||||
let price = intercept
|
||||
price *= scale
|
||||
// horizontal line
|
||||
// console.log('hline', price)
|
||||
const model = {price, color, maxAllocation: status.order.amount, amount, amountSymbol};
|
||||
const s = new HLine(model, null, null, null, true)
|
||||
this.shapes.push(s)
|
||||
} else {
|
||||
// diagonal line
|
||||
let startTime = t.startTime
|
||||
if (startTime === DISTANT_PAST)
|
||||
startTime = timestamp() - useChartOrderStore().intervalSecs * 20 // 20 bars ago
|
||||
let endTime = t.endTime
|
||||
if (endTime === DISTANT_FUTURE)
|
||||
endTime = timestamp() // use "now" as the drawing point's time
|
||||
let startPrice = (intercept + slope * startTime);
|
||||
let endPrice = (intercept + slope * endTime);
|
||||
startPrice *= scale
|
||||
endPrice *= scale
|
||||
// console.log('dline', startTime, endTime, DISTANT_FUTURE, startPrice, endPrice)
|
||||
// noinspection EqualityComparisonWithCoercionJS
|
||||
const model = {
|
||||
pointA: {time: startTime, price: startPrice},
|
||||
pointB: {time: endTime, price: endPrice},
|
||||
extendLeft: t.startTime === DISTANT_PAST,
|
||||
extendRight: t.endTime === DISTANT_FUTURE,
|
||||
color,
|
||||
maxAllocation: status.order.amount, amount, amountSymbol,
|
||||
};
|
||||
const s = new DLine(model, null, null, null, true)
|
||||
this.shapes.push(s)
|
||||
const color = sideColor(buy)
|
||||
const maxAllocation = this.maxAllocation
|
||||
const allocation = t.fraction / MAX_FRACTION
|
||||
const ts = this.trancheStatus
|
||||
let sum = 0n
|
||||
for (let i=0; i<ts.fills.length; i++)
|
||||
sum += ts.fills[i].filled
|
||||
const completed = (amountBigInt - sum) < status.order.minFillAmount
|
||||
const extraText = completed ? '✓' : null
|
||||
const textLocation = breakout === buy ? 'above' : 'below'
|
||||
// line active
|
||||
if (slope === 0) {
|
||||
let price = intercept
|
||||
price *= scale
|
||||
// horizontal line
|
||||
// console.log('hline', price)
|
||||
const model = {
|
||||
price, breakout, color, extraText, textLocation,
|
||||
allocation, maxAllocation, amount, amountSymbol,
|
||||
}
|
||||
const s = new HLine(model, null, null, null, true)
|
||||
this.shapes.push(s)
|
||||
} else {
|
||||
// diagonal line
|
||||
let startTime = t.startTime
|
||||
if (startTime === DISTANT_PAST)
|
||||
startTime = timestamp() - useChartOrderStore().intervalSecs * 20 // 20 bars ago
|
||||
let endTime = t.endTime
|
||||
if (endTime === DISTANT_FUTURE)
|
||||
endTime = timestamp() // use "now" as the drawing point's time
|
||||
let startPrice = (intercept + slope * startTime);
|
||||
let endPrice = (intercept + slope * endTime);
|
||||
startPrice *= scale
|
||||
endPrice *= scale
|
||||
// console.log('dline', startTime, endTime, DISTANT_FUTURE, startPrice, endPrice)
|
||||
// noinspection EqualityComparisonWithCoercionJS
|
||||
const model = {
|
||||
pointA: {time: startTime, price: startPrice},
|
||||
pointB: {time: endTime, price: endPrice},
|
||||
extendLeft: t.startTime === DISTANT_PAST,
|
||||
extendRight: t.endTime === DISTANT_FUTURE,
|
||||
breakout, color, extraText, textLocation,
|
||||
allocation, maxAllocation, amount, amountSymbol,
|
||||
}
|
||||
const s = new DLine(model, null, null, null, true)
|
||||
this.shapes.push(s)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import {invokeCallback, mixin} from "@/common.js";
|
||||
import {chart, createShape, deleteShapeId, dragging, draggingShapeIds, drawShape, widget} from "@/charts/chart.js";
|
||||
import Color from "color";
|
||||
import {dirtyItems, dirtyPoints, nearestOhlcStart} from "@/charts/chart-misc.js";
|
||||
import {computeInterceptSlope} from "@/misc.js";
|
||||
import {defined} from "@/misc.js";
|
||||
|
||||
|
||||
//
|
||||
@@ -40,6 +40,7 @@ export const ShapeType = {
|
||||
|
||||
|
||||
export function allocationText(weight, amount, symbol, separator = ' ') {
|
||||
// set breakout=true for a buy breakout and breakout=false for a sell breakout
|
||||
const hasAmount = amount !== null && amount !== undefined && amount > 0
|
||||
if (hasAmount)
|
||||
amount = Number(amount)
|
||||
@@ -109,7 +110,7 @@ export class Shape {
|
||||
this.model.amount = null
|
||||
this.model.amountSymbol = null
|
||||
this.model.extraText = null
|
||||
this.model.textLocation = 'above'
|
||||
this.model.textLocation = null // defaults to 'above' if not set
|
||||
|
||||
// LEAF SUBCLASSES MUST CALL setModel(model) AFTER ALL CONSTRUCTION.
|
||||
}
|
||||
@@ -119,19 +120,21 @@ export class Shape {
|
||||
//
|
||||
|
||||
setModel(model) {
|
||||
if (model.color)
|
||||
if (defined(model.color))
|
||||
this.model.color = model.color
|
||||
if (model.allocation !== null && model.allocation !== undefined)
|
||||
if (defined(model.allocation))
|
||||
this.model.allocation = model.allocation
|
||||
if (model.maxAllocation !== null && model.maxAllocation !== undefined)
|
||||
if (defined(model.maxAllocation))
|
||||
this.model.maxAllocation = model.maxAllocation
|
||||
if (model.amount !== null && model.amount !== undefined)
|
||||
if (defined(model.amount))
|
||||
this.model.amount = model.amount
|
||||
if (model.amountSymbol)
|
||||
if (defined(model.amountSymbol))
|
||||
this.model.amountSymbol = model.amountSymbol
|
||||
if (model.extraText)
|
||||
if (defined(model.extraText))
|
||||
this.model.extraText = model.extraText
|
||||
if (model.textLocation)
|
||||
if (defined(model.breakout))
|
||||
this.model.breakout = model.breakout
|
||||
if (defined(model.textLocation))
|
||||
this.model.textLocation = model.textLocation
|
||||
|
||||
const newProps = {}
|
||||
@@ -141,7 +144,7 @@ export class Shape {
|
||||
newProps.textcolor = color
|
||||
|
||||
// line color
|
||||
if (this.model.allocation && this.model.maxAllocation) {
|
||||
if (defined(this.model.allocation) && defined(this.model.maxAllocation)) {
|
||||
const w = this.model.allocation / this.model.maxAllocation
|
||||
if (!w)
|
||||
newProps.linecolor = 'rgba(0,0,0,0)'
|
||||
@@ -158,6 +161,8 @@ export class Shape {
|
||||
|
||||
// text label
|
||||
let text = allocationText(this.model.allocation, this.model.amount, this.model.amountSymbol)
|
||||
if (this.model.breakout)
|
||||
text += ' ' + (this.model.textLocation==='above' ? '▲Breakout▲' : '▼Breakout▼')
|
||||
if (this.model.extraText)
|
||||
text += ' '+this.model.extraText
|
||||
if (this.debug) text = `${this.id} ` + text
|
||||
@@ -199,10 +204,13 @@ export class Shape {
|
||||
const p = this.type.drawingProp
|
||||
const lc = this.model.lineColor ? this.model.lineColor : this.model.color;
|
||||
const tc = this.model.textColor ? this.model.textColor : this.model.color;
|
||||
const tl = this.model.textLocation ? this.model.textLocation : 'above';
|
||||
if (lc)
|
||||
o[p+".linecolor"] = lc
|
||||
if (tc)
|
||||
o[p+".textcolor"] = tc
|
||||
if (tl)
|
||||
o[p+".textlocation"] = tl
|
||||
return o
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user