import {DISTANT_FUTURE, DISTANT_PAST} 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 {useChartOrderStore} from "@/orderbuild.js"; export class OrderShapes { constructor(symbol, orderStatus) { this.symbol = symbol this.status = orderStatus this.trancheShapes = []; this.update(orderStatus) } update(orderStatus) { for (const old of this.trancheShapes) old.delete() this.status = orderStatus this.trancheShapes = []; for (let i = 0; i < orderStatus.trancheStatus.length; i++) this.trancheShapes.push(new TrancheShapes(this.symbol, this.status, i)); } show() {for (const t of this.trancheShapes) t.show();} hide() {for (const t of this.trancheShapes) t.hide();} delete() {for (const t of this.trancheShapes) t.delete(); this.shapes=[]} } class TrancheShapes { constructor(symbol, orderStatus, trancheIndex) { // todo validate base/quote if (symbol.inverted !== orderStatus.order.inverted) { console.log('OrderShapes.createLine(): symbol has wrong inverson for this order') return } this.symbol = symbol this.status = orderStatus this.trancheIndex = trancheIndex this.tranche = orderStatus.order.tranches[trancheIndex] this.shapes = [] this.fills = [] this.createShapes(); } createShapes() { // todo amounts const t = this.tranche // console.log('create tranche shapes', t) if (t.marketOrder) { if (t.startTime !== DISTANT_PAST) { // todo vertical line } } else { // check lines this.createLine(t.minLine.slope, t.minLine.intercept); this.createLine(t.maxLine.slope, t.maxLine.intercept); } for (const f of this.status.trancheStatus[this.trancheIndex].fills) this.createFillPoint(f) } createFillPoint(f) { // console.log('draw fill', f, this.symbol) const order = this.status.order; const symbol = this.symbol const scale = 10**symbol.decimals; const buy = order.tokenIn === this.symbol.quote.a const amountIsBase = buy !== this.status.order.amountIsInput const filledAmount = this.status.order.amountIsInput ? f.filledIn : f.filledOut; const amount = Number(filledAmount) * 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) 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) 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) this.fills.push(s) } createLine(slope, intercept, amount) { 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 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) } } } // todo like this? show() {for (const s of this.shapes) s.show();} hide() {for (const s of this.shapes) s.hide();} delete() { for (const s of this.shapes) s.delete(); this.shapes=[] for (const s of this.fills) deleteShapeId(s) } }