SwapOrder.inverted

This commit is contained in:
tim
2024-10-28 13:23:06 -04:00
parent 8a34c55fe0
commit 5e91b0ff43
10 changed files with 64 additions and 48 deletions

View File

@@ -15,6 +15,7 @@ export const DISTANT_FUTURE = uint32max
// uint256 minFillAmount; // if a tranche has less than this amount available to fill, it is considered completed // uint256 minFillAmount; // if a tranche has less than this amount available to fill, it is considered completed
// bool amountIsInput; // bool amountIsInput;
// bool outputDirectlyToOwner; // bool outputDirectlyToOwner;
// bool inverted;
// uint64 conditionalOrder; // use NO_CONDITIONAL_ORDER for no chaining. conditionalOrder index must be < than this order's index for safety (written first) and conditionalOrder state must be Template // uint64 conditionalOrder; // use NO_CONDITIONAL_ORDER for no chaining. conditionalOrder index must be < than this order's index for safety (written first) and conditionalOrder state must be Template
// Tranche[] tranches; // Tranche[] tranches;
// } // }
@@ -22,7 +23,7 @@ export const DISTANT_FUTURE = uint32max
// Exchange exchange; // Exchange exchange;
// uint24 fee; // uint24 fee;
// } // }
export function newOrder(tokenIn, tokenOut, exchange, fee, amount, amountIsInput, tranches, export function newOrder(tokenIn, tokenOut, exchange, fee, amount, amountIsInput, inverted, tranches,
minFillAmount=null, outputDirectlyToOwner = false, conditionalOrder = NO_CONDITIONAL_ORDER) { minFillAmount=null, outputDirectlyToOwner = false, conditionalOrder = NO_CONDITIONAL_ORDER) {
amountIsInput = !!amountIsInput // force convert to bool amountIsInput = !!amountIsInput // force convert to bool
outputDirectlyToOwner = !!outputDirectlyToOwner // force convert to bool outputDirectlyToOwner = !!outputDirectlyToOwner // force convert to bool
@@ -34,7 +35,7 @@ export function newOrder(tokenIn, tokenOut, exchange, fee, amount, amountIsInput
return { return {
tokenIn, tokenOut, route:{exchange, fee}, tokenIn, tokenOut, route:{exchange, fee},
amount, minFillAmount, amountIsInput, amount, minFillAmount, amountIsInput,
outputDirectlyToOwner, conditionalOrder, tranches outputDirectlyToOwner, inverted, conditionalOrder, tranches
} }
} }
@@ -186,6 +187,7 @@ export function parseOrder(order) {
minFillAmount, minFillAmount,
amountIsInput, amountIsInput,
outputDirectlyToOwner, outputDirectlyToOwner,
inverted,
conditionalOrder, conditionalOrder,
tranches, tranches,
] = order ] = order
@@ -194,7 +196,7 @@ export function parseOrder(order) {
minFillAmount = BigInt(minFillAmount) minFillAmount = BigInt(minFillAmount)
tranches = tranches.map(parseTranche) tranches = tranches.map(parseTranche)
return { return {
tokenIn, tokenOut, route, amount, minFillAmount, amountIsInput, outputDirectlyToOwner, conditionalOrder, tranches tokenIn, tokenOut, route, amount, minFillAmount, amountIsInput, outputDirectlyToOwner, inverted, conditionalOrder, tranches
} }
} }

View File

@@ -265,7 +265,8 @@ export const PendingOrderState = {
Sent: -102, // tx is awaiting blockchain mining Sent: -102, // tx is awaiting blockchain mining
} }
const placementFeeSelector = 'placementFee((address,address,(uint8,uint24),uint256,uint256,bool,bool,uint64,(uint16,bool,bool,bool,bool,bool,bool,bool,bool,uint16,uint24,uint32,uint32,(uint32,uint32),(uint32,uint32))[]),(uint8,uint8,uint8,uint8,uint8))' // single order placement selector
const placementFeeSelector = 'placementFee((address,address,(uint8,uint24),uint256,uint256,bool,bool,bool,uint64,(uint16,bool,bool,bool,bool,bool,bool,bool,bool,uint16,uint24,uint32,uint32,(uint32,uint32),(uint32,uint32))[]),(uint8,uint8,uint8,uint8,uint8))'
export async function placementFee(vault, order, window=300) { export async function placementFee(vault, order, window=300) {
// If the fees are about to change within `window` seconds of now, we send the higher native amount of the two fees. // If the fees are about to change within `window` seconds of now, we send the higher native amount of the two fees.

View File

@@ -86,7 +86,11 @@ const feeGroups = {} // keyed by ticker without the final fee field. values are
// symbol is keyed by the `ticker` which is defined as 'chain_id|pool_addr' for absolute uniqueness. // symbol is keyed by the `ticker` which is defined as 'chain_id|pool_addr' for absolute uniqueness.
export function tickerForOrder(chainId, order) { export function tickerForOrder(chainId, order) {
return tickerKey(chainId, order.route.exchange, order.tokenIn, order.tokenOut, order.route.fee, true) let [base, quote] = [order.tokenIn, order.tokenOut]
const inv = base > quote
if (inv !== order.inverted)
[base, quote] = [quote, base]
return tickerKey(chainId, order.route.exchange, base, quote, order.route.fee, false)
} }
export function tickerKey(chainId, exchange, tokenAddrA, tokenAddrB, fee, chooseInversion=false ) { export function tickerKey(chainId, exchange, tokenAddrA, tokenAddrB, fee, chooseInversion=false ) {

View File

@@ -2,6 +2,7 @@ import {DISTANT_FUTURE, DISTANT_PAST} from "@/blockchain/orderlib.js";
import {allocationText, DLine, HLine} from "@/charts/shape.js"; import {allocationText, DLine, HLine} from "@/charts/shape.js";
import {createShape, deleteShapeId} from "@/charts/chart.js"; import {createShape, deleteShapeId} from "@/charts/chart.js";
import {timestamp} from "@/misc.js"; import {timestamp} from "@/misc.js";
import {useChartOrderStore} from "@/orderbuild.js";
export class OrderShapes { export class OrderShapes {
constructor(symbol, orderStatus) { constructor(symbol, orderStatus) {
@@ -30,6 +31,11 @@ export class OrderShapes {
class TrancheShapes { class TrancheShapes {
constructor(symbol, orderStatus, trancheIndex) { 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.symbol = symbol
this.status = orderStatus this.status = orderStatus
this.trancheIndex = trancheIndex this.trancheIndex = trancheIndex
@@ -68,18 +74,18 @@ class TrancheShapes {
* 10 ** -(amountIsBase ? this.symbol.base.d : this.symbol.quote.d) * 10 ** -(amountIsBase ? this.symbol.base.d : this.symbol.quote.d)
const weight = Number(filledAmount) / Number(this.status.order.amount) const weight = Number(filledAmount) / Number(this.status.order.amount)
const amountSymbol = amountIsBase ? this.symbol.base.s : this.symbol.quote.s 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 time = f.time
const out = Number(f.filledOut) / (1-this.status.order.route.fee/1000000) const out = Number(f.filledOut) / (1-this.status.order.route.fee/1000000)
let price = out / Number(f.filledIn) let price = out / Number(f.filledIn)
if (buy) if (buy)
price = 1/price price = 1/price
price *= scale price *= scale
// console.log('price', price) console.log('price', price)
const channel = buy?'low':'high'; const channel = buy?'low':'high';
const text = (buy ? 'Buy ' : 'Sell ') + allocationText(weight, amount, amountSymbol, '\n') const text = (buy ? 'Buy ' : 'Sell ') + allocationText(weight, amount, amountSymbol, '\n')
const s = createShape(buy?'arrow_up':'arrow_down', {time, price}, {channel,text,lock:true}) 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) this.fills.push(s)
} }
@@ -89,21 +95,18 @@ class TrancheShapes {
const symbol = this.symbol const symbol = this.symbol
const scale = 10**symbol.decimals; const scale = 10**symbol.decimals;
const buy = status.order.tokenIn === this.symbol.quote.a const buy = status.order.tokenIn === this.symbol.quote.a
const inverted = buy
amount = Number(amount) amount = Number(amount)
* 10 ** -(buy ? this.symbol.base.d : this.symbol.quote.d) * 10 ** -(buy ? this.symbol.base.d : this.symbol.quote.d)
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
if (inverted)
price = 1/price
price *= scale price *= scale
// horizontal line // horizontal line
// console.log('hline', price, inverted) 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)
@@ -111,16 +114,12 @@ class TrancheShapes {
// diagonal line // diagonal line
let startTime = t.startTime let startTime = t.startTime
if (startTime === DISTANT_PAST) if (startTime === DISTANT_PAST)
startTime = 1231006505 // use Bitcoin genesis as the drawing point's start time. unnecessary. startTime = timestamp() - useChartOrderStore().intervalSecs * 20 // 20 bars ago
let endTime = t.endTime let endTime = t.endTime
if (endTime === DISTANT_FUTURE) if (endTime === DISTANT_FUTURE)
endTime = timestamp() // use "now" as the drawing point's time endTime = timestamp() // use "now" as the drawing point's time
let startPrice = (intercept + slope * startTime); let startPrice = (intercept + slope * startTime);
let endPrice = (intercept + slope * endTime); let endPrice = (intercept + slope * endTime);
if (inverted) {
startPrice = 1/startPrice
endPrice = 1/endPrice
}
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)

View File

@@ -68,7 +68,7 @@ const FAUCET_CONFIG = {
USXD: 0, USXD: 0,
WETH: 0, WETH: 0,
ARB: 0, ARB: 0,
USDC: 10000, USDC: 1000000,
} }
function gib() { function gib() {

View File

@@ -20,14 +20,14 @@ const s = useStore()
const price = computed(()=>{ const price = computed(()=>{
if (props.m === 0) if (props.m === 0)
return props.b === 0 ? null : props.b return props.b === 0 ? null : props.b
console.log('raw line price', props.b + props.m * s.clock) // console.log('raw line price', props.b + props.m * s.clock)
return props.b + props.m * s.clock return props.b + props.m * s.clock
}) })
const description = computed(()=>{ const description = computed(()=>{
if( props.m !== 0 ) if( props.m !== 0 )
return 'diagonal' return 'diagonal'
return props.isMin ? 'limit' : 'dont-chase' return props.isBreakout ? 'breakout' : 'limit'
}) })

View File

@@ -46,7 +46,7 @@ function placeOrder() {
const amt = FixedNumber.fromString(os.totalAmount.toString(), {decimals: os.amountToken.decimals}).value const amt = FixedNumber.fromString(os.totalAmount.toString(), {decimals: os.amountToken.decimals}).value
const ts = props.tranches() const ts = props.tranches()
console.log('new order', symbol) console.log('new order', symbol)
const order = newOrder(tokenIn, tokenOut, symbol.e, symbol.fee, amt, os.amountIsInput, ts) // todo: minAmount, outputToOwner, conditionalOrder const order = newOrder(tokenIn, tokenOut, symbol.e, symbol.fee, amt, os.amountIsInput, symbol.inverted, ts) // todo: minAmount, outputToOwner, conditionalOrder
pendOrder(order) pendOrder(order)
} }

View File

@@ -95,12 +95,12 @@
<div> <div>
<div class="mx-3" v-if="t.marketOrder">market order</div> <div class="mx-3" v-if="t.marketOrder">market order</div>
<line-price class="mx-3" v-if="!t.marketOrder" <line-price class="mx-3" v-if="!t.marketOrder"
:base="item.order.tokenIn" :quote="item.order.tokenOut" :base="item.base" :quote="item.quote"
:b="t.minLine.intercept" :m="t.minLine.slope" :is-min="true" :b="t.minLine.intercept" :m="t.minLine.slope" :is-breakout="!item.minIsLimit"
:show-btn="true"/> :show-btn="true"/>
<line-price class="mx-3" v-if="!t.marketOrder" <line-price class="mx-3" v-if="!t.marketOrder"
:base="item.order.tokenIn" :quote="item.order.tokenOut" :base="item.base" :quote="item.quote"
:b="t.maxLine.intercept" :m="t.maxLine.slope" :is-min="false" :b="t.maxLine.intercept" :m="t.maxLine.slope" :is-breakout="item.minIsLimit"
:show-btn="true"/> :show-btn="true"/>
</div> </div>
@@ -181,6 +181,7 @@ const props = defineProps(['vault'])
const vaultAddr = computed(()=>props.vault?props.vault:s.vault) const vaultAddr = computed(()=>props.vault?props.vault:s.vault)
const selected = ref([]) const selected = ref([])
// Draw Shapes
watch(selected, async ()=>{ watch(selected, async ()=>{
const statusIndex = {} const statusIndex = {}
for (const order of orders.value) for (const order of orders.value)
@@ -335,6 +336,24 @@ const orders = computed(()=>{
} }
} }
} }
// elaborate
for (const st of result) {
let low, high;
console.log('elab', st.order)
const buy = st.order.tokenIn > st.order.tokenOut;
if (buy) {
low = st.order.tokenOut
high = st.order.tokenIn
}
else {
low = st.order.tokenIn
high = st.order.tokenOut
}
st.base = st.order.inverted ? high : low;
st.quote = st.order.inverted ? low : high;
st.minIsLimit = buy !== st.order.inverted // whether limit/breakout is flipped
console.log('elaborated', st.order)
}
result.sort((a,b)=>b.startTime-a.startTime) result.sort((a,b)=>b.startTime-a.startTime)
// console.log('orders', result) // console.log('orders', result)
return result return result

View File

@@ -125,7 +125,7 @@ function buildOrder() {
tranches = [...tranches, ...ts] tranches = [...tranches, ...ts]
} }
return newOrder(tokenIn.value.a, tokenOut.value.a, symbol.exchangeId, symbol.fee, amount, amountIsInput, tranches) return newOrder(tokenIn.value.a, tokenOut.value.a, symbol.exchangeId, symbol.fee, amount, amountIsInput, symbol.inverted, tranches)
} }

View File

@@ -138,36 +138,27 @@ export function linePointsValue(time0, price0, time1, price1, unixTime = null) {
} }
export function applyLinePoint(tranche, symbol, buy, price0) { export function applyLinePoint(tranche, symbol, buy, price0, breakout=false) {
const orig = price0 applyLine(tranche, symbol, buy, price0, 0, breakout)
price0 *= 10 ** -symbol.decimals
if (buy)
price0 = 1/price0
console.log('applyLinePoint', buy?'BUY':'SELL', symbol, orig, price0)
applyLine(tranche, symbol, buy, price0, 0)
} }
export function applyLinePoints(tranche, symbol, buy, time0, price0, time1, price1) { export function applyLinePoints(tranche, symbol, buy, time0, price0, time1, price1, breakout=false) {
const scale = 10 ** -symbol.decimals
price0 *= scale
price1 *= scale
if (buy) {
price0 = 1/price0
price1 = 1/price1
}
const [intercept, slope] = computeInterceptSlope(time0, price0, time1, price1); const [intercept, slope] = computeInterceptSlope(time0, price0, time1, price1);
applyLine(tranche, symbol, buy, intercept, slope) applyLine(tranche, symbol, buy, intercept, slope, breakout)
} }
function applyLine(tranche, symbol, buy, intercept, slope, isMaximum=false) { function applyLine(tranche, symbol, buy, intercept, slope=0, breakout=false) {
let m = slope const scale = 10 ** -symbol.decimals
let b = intercept let m = slope * scale
console.log('applyLine current line value', isMaximum?'max':'min', m*timestamp()+b, 1./(m*timestamp()+b)) let b = intercept * scale
m = encodeIEE754(m) m = encodeIEE754(m)
b = encodeIEE754(b) b = encodeIEE754(b)
if (isMaximum) { const isMax = (buy !== symbol.inverted) !== breakout // buy XOR inverted XOR breakout
console.log('apply line point isMax?', buy?'buy':'sell', symbol.inverted, breakout, isMax)
console.log('applyLine current line value', isMax?'max':'min', m*timestamp()+b, 1./(m*timestamp()+b))
if (isMax) {
tranche.maxLine.intercept = b; tranche.maxLine.intercept = b;
tranche.maxLine.slope = m; tranche.maxLine.slope = m;
} else { } else {