trigger price fixes (inverted test)

This commit is contained in:
tim
2024-09-21 01:57:31 -04:00
parent 04a9d963ea
commit 1014cb2bda
2 changed files with 31 additions and 20 deletions

View File

@@ -3,12 +3,13 @@ import logging
from dataclasses import dataclass from dataclasses import dataclass
from typing import overload from typing import overload
from dexorder import DELETE, db, order_log from dexorder import DELETE, db, order_log, dec
from dexorder.base.chain import current_chain from dexorder.base.chain import current_chain
from dexorder.base.order import OrderKey, TrancheKey from dexorder.base.order import OrderKey, TrancheKey
from dexorder.base.orderlib import SwapOrderState, ElaboratedSwapOrderStatus, Fill from dexorder.base.orderlib import SwapOrderState, ElaboratedSwapOrderStatus, Fill
from dexorder.blockstate import BlockDict, BlockSet from dexorder.blockstate import BlockDict, BlockSet
from dexorder.database.model.orderindex import OrderIndex from dexorder.database.model.orderindex import OrderIndex
from dexorder.pools import get_pool, ensure_pool_price, pool_prices
from dexorder.routing import pool_address from dexorder.routing import pool_address
from dexorder.util import json from dexorder.util import json
from dexorder.vault_blockdata import vault_owners from dexorder.vault_blockdata import vault_owners
@@ -193,7 +194,6 @@ class Order:
order_log.debug(f'updated order_filled: {new}') order_log.debug(f'updated order_filled: {new}')
Order.order_filled[self.key] = new Order.order_filled[self.key] = new
def complete(self, final_state: SwapOrderState): def complete(self, final_state: SwapOrderState):
""" updates the static order record with its final values, then deletes all its dynamic blockstate and removes the Order from the actives list """ """ updates the static order record with its final values, then deletes all its dynamic blockstate and removes the Order from the actives list """
assert final_state in (SwapOrderState.Canceled, SwapOrderState.Expired, SwapOrderState.Filled, SwapOrderState.Error) assert final_state in (SwapOrderState.Canceled, SwapOrderState.Expired, SwapOrderState.Filled, SwapOrderState.Error)

View File

@@ -48,7 +48,9 @@ class OrderTriggers:
@staticmethod @staticmethod
async def create(order: Order): async def create(order: Order):
triggers = await asyncio.gather(*[TrancheTrigger.create(order, tk) for tk in order.tranche_keys]) pool = await get_pool(order.pool_address)
await ensure_pool_price(pool)
triggers = await asyncio.gather(*[TrancheTrigger.create(order, tk, pool) for tk in order.tranche_keys])
return OrderTriggers(order, triggers) return OrderTriggers(order, triggers)
def __init__(self, order: Order, triggers: Sequence['TrancheTrigger']): def __init__(self, order: Order, triggers: Sequence['TrancheTrigger']):
@@ -315,21 +317,23 @@ class PriceLineTrigger (Trigger):
by_pool: dict[str,set['PriceLineTrigger']] = defaultdict(set) by_pool: dict[str,set['PriceLineTrigger']] = defaultdict(set)
@staticmethod @staticmethod
async def create(tk: TrancheKey, line: Line, is_min: bool, is_barrier: bool): def create(tk: TrancheKey, scale: dec, inverted: bool, price: dec, line: Line, is_min: bool, is_barrier: bool):
if line.intercept == 0 and line.slope == 0: if line.intercept == 0 and line.slope == 0:
return None # no constraint (deactivated) return None # no constraint (deactivated)
pool = await get_pool(Order.of(tk).pool_address) return PriceLineTrigger(tk, scale, inverted, line, is_min, is_barrier, price)
await ensure_pool_price(pool)
price_now = pool_prices[pool['address']] * dec(10) ** dec(-pool['decimals']) # adjust for pool decimals to get onchain price
return PriceLineTrigger(tk, line, is_min, is_barrier, price_now)
def __init__(self, tk: TrancheKey, line: Line, is_min: bool, is_barrier: bool, price_now: dec): def __init__(self, tk: TrancheKey, scale: dec, inverted: bool, line: Line, is_min: bool, is_barrier: bool, price_now: dec):
if is_barrier: if is_barrier:
log.warning('Barriers not supported') log.warning('Barriers not supported')
value_now = line.intercept + line.slope * current_clock.get().timestamp value_now = line.intercept + line.slope * current_clock.get().timestamp
if inverted:
price_now = 1/price_now
price_now *= scale
activated = value_now < price_now if is_min else value_now > price_now activated = value_now < price_now if is_min else value_now > price_now
log.debug(f'initial price line {value_now} {"<" if is_min else ">"} {price_now} {activated}') log.debug(f'initial price line {value_now} {"<" if is_min else ">"} {price_now} {activated}')
super().__init__(3 if is_min else 4, tk, activated) super().__init__(3 if is_min else 4, tk, activated)
self.scale = scale
self.inverted = inverted
self.line = line self.line = line
self.is_min = is_min self.is_min = is_min
self.is_barrier = is_barrier self.is_barrier = is_barrier
@@ -356,12 +360,16 @@ class PriceLineTrigger (Trigger):
PriceLineTrigger.triggers_set.clear() PriceLineTrigger.triggers_set.clear()
def update(self, price: float): def update(self, price: float):
# oldPrice = price
if self.inverted:
price = 1/price
log.debug(f'price trigger {price}')
if self not in PriceLineTrigger.triggers_set: if self not in PriceLineTrigger.triggers_set:
self.index = len(PriceLineTrigger.y) self.index = len(PriceLineTrigger.y)
PriceLineTrigger.y.append(price) PriceLineTrigger.y.append(price)
PriceLineTrigger.m.append(self.line.slope) PriceLineTrigger.m.append(self.line.slope)
PriceLineTrigger.b.append(self.line.intercept) PriceLineTrigger.b.append(self.line.intercept)
PriceLineTrigger.sign.append(-1 if self.is_min else 1) PriceLineTrigger.sign.append(1 if (self.is_min != self.inverted) else -1)
PriceLineTrigger.triggers.append(self) PriceLineTrigger.triggers.append(self)
PriceLineTrigger.triggers_set.add(self) PriceLineTrigger.triggers_set.add(self)
else: else:
@@ -376,8 +384,8 @@ class PriceLineTrigger (Trigger):
line_value = m * time + b line_value = m * time + b
price_diff = sign * (y - line_value) price_diff = sign * (y - line_value)
activated = price_diff > 0 activated = price_diff > 0
for price, line, s, a in zip(y, line_value, sign, activated): for price, line, s, a, diff in zip(y, line_value, sign, activated, price_diff):
log.debug(f'price: {line} {"<" if s == -1 else ">"} {price} {a}') log.debug(f'price: {line} {"<" if s == 1 else ">"} {price} {a} ({diff:+})')
for t, activated in zip(PriceLineTrigger.triggers, activated): for t, activated in zip(PriceLineTrigger.triggers, activated):
t.handle_result(activated) t.handle_result(activated)
PriceLineTrigger.clear_data() PriceLineTrigger.clear_data()
@@ -429,10 +437,10 @@ class TrancheState (Enum):
class TrancheTrigger: class TrancheTrigger:
all: dict[TrancheKey,'TrancheTrigger'] = {} all: dict[TrancheKey, 'TrancheTrigger'] = {}
@staticmethod @staticmethod
async def create(order: Order, tk: TrancheKey) -> 'TrancheTrigger': async def create(order: Order, tk: TrancheKey, pool: OldPoolDict) -> 'TrancheTrigger':
time = current_clock.get().timestamp time = current_clock.get().timestamp
tranche = order.order.tranches[tk.tranche_index] tranche = order.order.tranches[tk.tranche_index]
ts = order.status.trancheStatus[tk.tranche_index] ts = order.status.trancheStatus[tk.tranche_index]
@@ -443,12 +451,15 @@ class TrancheTrigger:
min_trigger = max_trigger = None min_trigger = max_trigger = None
else: else:
# tranche minLine and maxLine are relative to the pool and will be flipped from the orderspec if the # tranche minLine and maxLine are relative to the pool and will be flipped from the orderspec if the
# order is selling the base and buying the quote. # order is buying the base and selling the quote.
pool = await get_pool(order.pool_address) price = pool_prices[pool['address']]
buy = pool['base'] == order.order.tokenOut scale = 10 ** -pool['decimals']
min_trigger, max_trigger = await asyncio.gather( inverted = order.order.tokenIn != pool['base']
PriceLineTrigger.create(tk, tranche.minLine, True is buy, tranche.minIsBarrier), assert inverted and order.order.tokenIn == pool['quote'] or not inverted and order.order.tokenIn == pool['base']
PriceLineTrigger.create(tk, tranche.maxLine, False is buy, tranche.maxIsBarrier)) min_trigger = PriceLineTrigger.create(tk, scale, inverted, price, tranche.minLine, True,
tranche.minIsBarrier)
max_trigger = PriceLineTrigger.create(tk, scale, inverted, price, tranche.maxLine, False,
tranche.maxIsBarrier)
return TrancheTrigger(order, tk, balance_trigger, activation_trigger, expiration_trigger, min_trigger, max_trigger) return TrancheTrigger(order, tk, balance_trigger, activation_trigger, expiration_trigger, min_trigger, max_trigger)
def __init__(self, order: Order, tk: TrancheKey, def __init__(self, order: Order, tk: TrancheKey,