diff --git a/src/blockchain/contract.js b/src/blockchain/contract.js index 3c74cdc..dba6138 100644 --- a/src/blockchain/contract.js +++ b/src/blockchain/contract.js @@ -31,7 +31,7 @@ export async function queryHelperContract(helper, provider) { // use newContract(addr, 'IVaultImpl', provider, 'IVault') to get the ABI from IVault.sol/IVaultImpl.json export async function newContract(addr, name, provider) { const abi = await abiCache.get(name) - console.log(`${name} ABI`, abi) + // console.log(`${name} ABI`, abi) return new ethers.Contract(addr, abi, provider) } diff --git a/src/blockchain/orderlib.js b/src/blockchain/orderlib.js index 62785d5..f019451 100644 --- a/src/blockchain/orderlib.js +++ b/src/blockchain/orderlib.js @@ -1,5 +1,6 @@ import {uint32max, uint64max} from "@/misc.js"; import {decodeIEE754, encodeIEE754} from "@/common.js"; +import order from "@/components/Order.vue"; export const MAX_FRACTION = 65535; export const NO_CONDITIONAL_ORDER = uint64max; @@ -151,10 +152,11 @@ export function parseOrderStatus(chainId, status) { order = parseOrder(order) filledIn = BigInt(filledIn) filledOut = BigInt(filledOut) - trancheStatus = trancheStatus.map((obj)=>parseTrancheStatus(obj)) + const filled = order.amountIsInput ? filledIn : filledOut + trancheStatus = trancheStatus.map((obj)=>parseTrancheStatus(obj, order.amountIsInput)) const result = { chainId, order, fillFeeHalfBps, state, startTime, startPrice, ocoGroup, - filledIn, filledOut, trancheStatus, + filledIn, filledOut, filled, trancheStatus, }; console.log('SwapOrderStatus', result) return result @@ -162,20 +164,23 @@ export function parseOrderStatus(chainId, status) { function parseFill(obj) { let [tx, time, filledIn, filledOut, fee] = obj + time = new Date(time * 1000) filledIn = BigInt(filledIn) filledOut = BigInt(filledOut) + const filled = obj.amountIsInput ? filledIn : filledOut fee = BigInt(fee) - return {tx, time, filledIn, filledOut, fee} + return {tx, time, filledIn, filledOut, filled, fee} } -function parseTrancheStatus(obj) { +function parseTrancheStatus(obj, amountIsInput) { let [filledIn, filledOut, activationTime, startTime, endTime, rawFills,] = obj filledIn = BigInt(filledIn) filledOut = BigInt(filledOut) const fills = [] for (const fill of rawFills) - fills.push(parseFill(fill)) - return {filledIn, filledOut, activationTime, startTime, endTime, fills} + fills.push(parseFill(fill, amountIsInput)) + const filled = amountIsInput ? filledIn : filledOut + return {filledIn, filledOut, filled, activationTime, startTime, endTime, fills} } export function parseOrder(order) { diff --git a/src/charts/datafeed.js b/src/charts/datafeed.js index 373e3e1..3966f7a 100644 --- a/src/charts/datafeed.js +++ b/src/charts/datafeed.js @@ -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 diff --git a/src/charts/ordershapes.js b/src/charts/ordershapes.js index 6a78a4c..7f6c279 100644 --- a/src/charts/ordershapes.js +++ b/src/charts/ordershapes.js @@ -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 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 } diff --git a/src/common.js b/src/common.js index b5c0205..b58acc0 100644 --- a/src/common.js +++ b/src/common.js @@ -133,3 +133,11 @@ export function abiPath(name) { } +export function parseFill(obj) { + let [tx, time, filledIn, filledOut, fee] = obj + time = new Date(time * 1000) + filledIn = BigInt(filledIn) + filledOut = BigInt(filledOut) + fee = BigInt(fee) + return {tx, time, filledIn, filledOut, fee} +} diff --git a/src/components/LimitPrice.vue b/src/components/LimitPrice.vue index 7d6ede2..d86a66a 100644 --- a/src/components/LimitPrice.vue +++ b/src/components/LimitPrice.vue @@ -17,12 +17,12 @@ - -