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 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.order import OrderKey, TrancheKey
from dexorder.base.orderlib import SwapOrderState, ElaboratedSwapOrderStatus, Fill
from dexorder.blockstate import BlockDict, BlockSet
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.util import json
from dexorder.vault_blockdata import vault_owners
@@ -193,7 +194,6 @@ class Order:
order_log.debug(f'updated order_filled: {new}')
Order.order_filled[self.key] = new
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 """
assert final_state in (SwapOrderState.Canceled, SwapOrderState.Expired, SwapOrderState.Filled, SwapOrderState.Error)

View File

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