import {DISTANT_FUTURE, DISTANT_PAST} from "@/blockchain/orderlib.js"; import {DLine, HLine} from "@/charts/shape.js"; import {createShape, deleteShapeId} from "@/charts/chart.js"; import {allocationText} from "@/orderbuild.js"; import {timestamp} from "@/misc.js"; export class OrderShapes { constructor(symbol, orderStatus) { this.symbol = symbol this.status = orderStatus this.trancheShapes = []; this.update(orderStatus) } update(orderStatus) { // todo delete old shapes 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)); // todo TV shape group } 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) { 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 inverted = buy === symbol.inverted const time = f.time const out = Number(f.filledOut) / (1-this.status.order.route.fee/1000000) let price = out / Number(f.filledIn) if (inverted) price = 1/price price *= scale // console.log('price', price) const channel = buy?'low':'high'; const text = (buy ? 'Buy ' : 'Sell ') + allocationText(null, f.filled, '') 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) { 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 const inverted = buy === symbol.inverted const color = buy ? 'green' : 'red' if (intercept !== 0 || slope !== 0) { // console.log('tranche line', intercept, slope) // line active if (slope === 0) { let price = intercept if (inverted) price = 1/price price *= scale // horizontal line // console.log('hline', price, inverted) const s = new HLine({price, color, // todo allocation maxAllocation amount amountSymbol }, null, null, null, true) this.shapes.push(s) } else { // diagonal line let startTime = t.startTime // noinspection EqualityComparisonWithCoercionJS if (startTime == DISTANT_PAST) startTime = 1231006505 // use Bitcoin genesis as the drawing point's start time. unnecessary. let endTime = t.endTime // noinspection EqualityComparisonWithCoercionJS if (endTime == DISTANT_FUTURE) endTime = timestamp() // use "now" as the drawing point's time let startPrice = (intercept + slope * startTime); let endPrice = (intercept + slope * endTime); if (inverted) { startPrice = 1/startPrice endPrice = 1/endPrice } startPrice *= scale endPrice *= scale // console.log('dline', startTime, endTime, DISTANT_FUTURE, startPrice, endPrice) const s = new DLine({ pointA: {time: t.startTime, price: startPrice}, pointB: {time: t.endTime, price: endPrice}, extendLeft: t.startTime === DISTANT_PAST, extendRight: t.endTime === DISTANT_FUTURE, color, // todo allocation maxAllocation amount amountSymbol }, 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) } }