trigger price fixes (inverted test)
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user