Skip to content

Commit

Permalink
Merge pull request #81 from valory-xyz/fix/market_approval_logic
Browse files Browse the repository at this point in the history
Market approval fix
  • Loading branch information
jmoreira-valory authored Jan 3, 2024
2 parents b66f116 + ace158e commit 0dbae99
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 63 deletions.
8 changes: 4 additions & 4 deletions packages/packages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
"contract/valory/conditional_tokens/0.1.0": "bafybeifbhritgoqecuilj35uzrrokm2ngfmwkoafbmzxgvpa4q3wpi6i64",
"contract/valory/fpmm_deterministic_factory/0.1.0": "bafybeih5yb4df6plwsxicp4jtywvpqmjnvfw55zw35yuycwxrx7mehoowy",
"contract/valory/realtio/0.1.0": "bafybeihfdvkrjkhezqeaxj3eluv2v4syvnxni6jbuc3knqb4rawrcivcke",
"skill/valory/market_creation_manager_abci/0.1.0": "bafybeia6sk3zu5cwlxryqnl6jp73bplri32oyhodofzj4gyxu56l26ueuq",
"skill/valory/market_maker_abci/0.1.0": "bafybeihl5s3edflvboifkg44kipx54mk7oxpzeag7vzpgd4cpwjgcthrou",
"agent/valory/market_maker/0.1.0": "bafybeiftycxdzvw62ouvlohwsjl4mldtnihn4lsztdazra4ylrmydc6zoe",
"service/valory/market_maker/0.1.0": "bafybeiai5qv7pzpuuy7vnmogq6eyeqcs5e53im7b262xjhetibc2culfuq",
"skill/valory/market_creation_manager_abci/0.1.0": "bafybeie67exdnu5phmap5q7xfwgjhfitgyld7bgwvzr2z2nhe7apwwqlaa",
"skill/valory/market_maker_abci/0.1.0": "bafybeidfmvqcnzcd6zy6r56xek4rqjremlcfc37x6is6qggp4mdsblmpyq",
"agent/valory/market_maker/0.1.0": "bafybeialdamcroevqq7d77jiuxg7ga7sq6uzc23uqauiaa3hjskzga2hfu",
"service/valory/market_maker/0.1.0": "bafybeia4h3jxysymq3c7v6ri4lcq4ybchixgytlqw43s5ijgoocc4cadly",
"contract/valory/wxdai/0.1.0": "bafybeidalocwbhmbto6ii6adldtpcughtdt6j3v4tv36utevjk2wrdyqie",
"contract/valory/fpmm/0.1.0": "bafybeiai2ruj27nnglvn7yc5atojyojo3fkmofw6wrjgz2ybps2uwdizx4"
},
Expand Down
4 changes: 2 additions & 2 deletions packages/valory/agents/market_maker/aea-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ protocols:
skills:
- valory/abstract_abci:0.1.0:bafybeiflcfufixmsrhobf56bn5745m2iipcfqyulwk2qegtnagb3kvaaxi
- valory/abstract_round_abci:0.1.0:bafybeiaqcl7h2famylusiffigwem7tevkcsyocdu5xd42jkmgq6kvowzgq
- valory/market_maker_abci:0.1.0:bafybeihl5s3edflvboifkg44kipx54mk7oxpzeag7vzpgd4cpwjgcthrou
- valory/market_maker_abci:0.1.0:bafybeidfmvqcnzcd6zy6r56xek4rqjremlcfc37x6is6qggp4mdsblmpyq
- valory/registration_abci:0.1.0:bafybeic2ynseiak7jpta7jfwuqwyp453b4p7lolr4wihxmpn633uekv5am
- valory/market_creation_manager_abci:0.1.0:bafybeia6sk3zu5cwlxryqnl6jp73bplri32oyhodofzj4gyxu56l26ueuq
- valory/market_creation_manager_abci:0.1.0:bafybeie67exdnu5phmap5q7xfwgjhfitgyld7bgwvzr2z2nhe7apwwqlaa
- valory/reset_pause_abci:0.1.0:bafybeidzajbe3erygeh2xbd6lrjv7nsptznjuzrt24ykgvhgotdeyhfnba
- valory/termination_abci:0.1.0:bafybeie4zvjfxvdu7qrulmur3chpjz3kpj5m4bjsxvpk4gvj5zbyyayfaa
- valory/transaction_settlement_abci:0.1.0:bafybeiaefgqbs7zsn5xe5kdwrujj7ivygkn3ujpw6crnvi3knvxw75qmja
Expand Down
2 changes: 1 addition & 1 deletion packages/valory/services/market_maker/service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ license: Apache-2.0
fingerprint:
README.md: bafybeibwz3af6326msp4h3kqehijvmyhaytvyfbo3o2npc2w4b6zrg6pfq
fingerprint_ignore_patterns: []
agent: valory/market_maker:0.1.0:bafybeiftycxdzvw62ouvlohwsjl4mldtnihn4lsztdazra4ylrmydc6zoe
agent: valory/market_maker:0.1.0:bafybeialdamcroevqq7d77jiuxg7ga7sq6uzc23uqauiaa3hjskzga2hfu
number_of_agents: 1
deployment:
agent:
Expand Down
149 changes: 95 additions & 54 deletions packages/valory/skills/market_creation_manager_abci/behaviours.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import json
import random
from abc import ABC
from collections import defaultdict
from datetime import datetime, timedelta, timezone
from string import Template
from typing import (
Expand Down Expand Up @@ -172,8 +173,12 @@
FPMM_QUERY = Template(
"""{
fixedProductMarketMakers(
where: {creator: "$creator"}
first: 100
where: {
creator: "$creator"
openingTimestamp_gte:"$openingTimestamp_gte"
openingTimestamp_lte:"$openingTimestamp_lte"
}
first: 1000
orderBy: creationTimestamp
orderDirection: desc
) {
Expand Down Expand Up @@ -448,69 +453,84 @@ def async_act(self) -> Generator:

with self.context.benchmark_tool.measure(self.behaviour_id).local():
sender = self.context.agent_address
latest_open_markets = yield from self._collect_latest_open_markets()
current_timestamp = self.last_synced_timestamp
self.context.logger.info(f"current_timestamp={current_timestamp}")

openingTimestamp_gte = current_timestamp + _ONE_DAY
self.context.logger.info(f"openingTimestamp_gte={openingTimestamp_gte}")

openingTimestamp_lte = current_timestamp + (
self.params.approve_market_event_days_offset * _ONE_DAY
)
self.context.logger.info(f"openingTimestamp_lte={openingTimestamp_lte}")

# Compute required openingTimestamp (between now and now + approve_market_event_days_offset)
required_opening_ts = []
current_day_start_timestamp = (
openingTimestamp_gte - (openingTimestamp_gte % _ONE_DAY) + _ONE_DAY
)
while current_day_start_timestamp <= openingTimestamp_lte:
required_opening_ts.append(current_day_start_timestamp)
current_day_start_timestamp += _ONE_DAY

self.context.logger.info(f"required_opening_ts={required_opening_ts}")

# Get existing (open) markets count per openingTimestamp (between now and now + approve_market_event_days_offset)
latest_open_markets = yield from self._collect_latest_open_markets(
openingTimestamp_gte, openingTimestamp_lte
)
existing_market_count: Dict[int, int] = defaultdict(int)

for market in latest_open_markets["fixedProductMarketMakers"]:
ts = int(market.get("openingTimestamp"))
existing_market_count[ts] += 1

self.context.logger.info(f"existing_market_count={existing_market_count}")

# Determine number of markets required to be approved per openingTimestamp (between now and now + approve_market_event_days_offset)
required_markets_to_approve: Dict[int, int] = defaultdict(int)
N = self.params.markets_to_approve_per_day

for ts in required_opening_ts:
required_markets_to_approve[ts] = max(
0, N - existing_market_count.get(ts, 0)
)

num_markets_to_approve = sum(required_markets_to_approve.values())

self.context.logger.info(
f"Collected latest open markets: {latest_open_markets}"
f"markets_to_approve={required_markets_to_approve}"
)
self.context.logger.info(f"num_markets_to_approve={num_markets_to_approve}")

current_timestamp = self.last_synced_timestamp
# Determine largest creation timestamp in markets with openingTimestamp between now and now + approve_market_event_days_offset
creation_timestamps = [
int(entry["creationTimestamp"])
for entry in latest_open_markets.get("fixedProductMarketMakers", {})
]
largest_creation_timestamp = max(creation_timestamps)

latest_approve_market_timestamp = (
self.synchronized_data.approved_markets_timestamp
)

# Determine num_markets_to_approve so that each day there are N closing markets.
opening_timestamps = [
int(entry["openingTimestamp"])
for entry in latest_open_markets.get("fixedProductMarketMakers", {})
]
sorted_opening_timestamps = sorted(opening_timestamps, reverse=True)
# TODO Make params
N = self.params.markets_to_approve_per_day
latest_opening_timestamps = sorted_opening_timestamps[:N]
approve_market_event_days_offset = (
self.params.approve_market_event_days_offset
)
start_timestamp = (
current_timestamp + approve_market_event_days_offset * _ONE_DAY
)
end_timestamp = (
current_timestamp + (approve_market_event_days_offset + 1) * _ONE_DAY
)
num_markets_to_approve = sum(
1
for timestamp in latest_opening_timestamps
if timestamp <= start_timestamp
self.context.logger.info(
f"largest_creation_timestamp={largest_creation_timestamp}"
)

# Collect misc data related to market approval
min_approve_markets_epoch_seconds = (
self.params.min_approve_markets_epoch_seconds
)
self.context.logger.info(
f"min_approve_markets_epoch_seconds={min_approve_markets_epoch_seconds}"
)
approved_markets_count = self.synchronized_data.approved_markets_count

self.context.logger.info(f"approved_markets_count={approved_markets_count}")
self.context.logger.info(f"current_timestamp={current_timestamp}")
self.context.logger.info(f"start_timestamp={start_timestamp}")
self.context.logger.info(f"end_timestamp={end_timestamp}")
self.context.logger.info(
f"largest_creation_timestamp={largest_creation_timestamp}"

latest_approve_market_timestamp = (
self.synchronized_data.approved_markets_timestamp
)
self.context.logger.info(
f"latest_approve_market_execution={latest_approve_market_timestamp}"
)
self.context.logger.info(
f"min_approve_markets_epoch_seconds={min_approve_markets_epoch_seconds}"
)
self.context.logger.info(
f"latest_opening_timestamps={latest_opening_timestamps}"
)
self.context.logger.info(f"num_markets_to_approve={num_markets_to_approve}")

# Main logic of the behaviour
if (
self.params.max_approved_markets >= 0
and approved_markets_count >= self.params.max_approved_markets
Expand All @@ -536,27 +556,44 @@ def async_act(self) -> Generator:
content = CollectProposedMarketsRound.SKIP_MARKET_APPROVAL_PAYLOAD
else:
self.context.logger.info("Timeout to approve markets reached.")
approve_market_event_days_offset = (
self.params.approve_market_event_days_offset

min_timestamp_to_approve = min(
(
ts
for ts, value in required_markets_to_approve.items()
if value > 0
),
default=0,
)

# On the market approval server, resolution_time is one day less than openingTimestamp
proposed_markets = yield from self._collect_latest_proposed_markets(
start_timestamp,
end_timestamp,
min_timestamp_to_approve - _ONE_DAY,
min_timestamp_to_approve,
)

proposed_markets_timestamps: Dict[int, int] = defaultdict(int)

for market_data in proposed_markets["proposed_markets"].values():
proposed_markets_timestamps[market_data["resolution_time"]] += 1

self.context.logger.info(
f"Collected proposed markets: {proposed_markets}"
f"proposed_markets_timestamps={proposed_markets_timestamps}"
)
content_data = {}
content_data.update(latest_open_markets)
content_data.update(proposed_markets)
content_data["num_markets_to_approve"] = num_markets_to_approve
content_data["num_markets_to_approve"] = required_markets_to_approve[
min_timestamp_to_approve
]
content_data["timestamp"] = current_timestamp
content = json.dumps(content_data, sort_keys=True)

payload = CollectProposedMarketsPayload(
sender=sender,
content=content,
)

with self.context.benchmark_tool.measure(self.behaviour_id).consensus():
yield from self.send_a2a_transaction(payload)
yield from self.wait_until_round_end()
Expand Down Expand Up @@ -600,7 +637,7 @@ def _collect_latest_proposed_markets(
"proposed_markets": {
market_id: market_info
for market_id, market_info in response_data["proposed_markets"].items()
if from_timestamp <= market_info["resolution_time"] <= to_timestamp
if from_timestamp <= market_info["resolution_time"] < to_timestamp
}
}

Expand All @@ -611,12 +648,16 @@ def _collect_latest_proposed_markets(
return filtered_markets_data

def _collect_latest_open_markets(
self,
self, openingTimestamp_gte: int, openingTimestamp_lte: int
) -> Generator[None, None, Dict[str, Any]]:
"""Collect FPMM from subgraph."""
creator = self.params.approve_market_creator
response = yield from self.get_subgraph_result(
query=FPMM_QUERY.substitute(creator=creator)
query=FPMM_QUERY.substitute(
creator=creator,
openingTimestamp_gte=openingTimestamp_gte,
openingTimestamp_lte=openingTimestamp_lte,
)
)

# TODO Handle retries
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ aea_version: '>=1.0.0, <2.0.0'
fingerprint:
.gitignore: bafybeihdfdezgtr3s2lzq5y3oaitfrdy4u4pehionju2bdez35wcjgqx6y
__init__.py: bafybeibkyjt4covc4yhd22aw7kav45zozk3exdv344emt3lilln64soaxm
behaviours.py: bafybeieiutqdsgzxlpkwlbkavwf2o6am4cayplmliedllanrwdzkskupvu
behaviours.py: bafybeiaerlo26yxcg55cbverp5lxirowzzr3glqjeobukpvp76tmwmjjyq
dialogues.py: bafybeicmaufkl7vdomnfciv7lw4536ssld7x4uemdapuhsyvfpd4ncibza
fsm_specification.yaml: bafybeiglegr5e55k3kra4movl5klfoqc6c2lm4cbh3fzicilwq6lhmnmxa
handlers.py: bafybeietxjfli2i57kb7heoy772rcq2znusl36gg7jjj5g3pddw7egny3q
Expand Down
2 changes: 1 addition & 1 deletion packages/valory/skills/market_maker_abci/skill.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ skills:
- valory/abstract_round_abci:0.1.0:bafybeiaqcl7h2famylusiffigwem7tevkcsyocdu5xd42jkmgq6kvowzgq
- valory/registration_abci:0.1.0:bafybeic2ynseiak7jpta7jfwuqwyp453b4p7lolr4wihxmpn633uekv5am
- valory/reset_pause_abci:0.1.0:bafybeidzajbe3erygeh2xbd6lrjv7nsptznjuzrt24ykgvhgotdeyhfnba
- valory/market_creation_manager_abci:0.1.0:bafybeia6sk3zu5cwlxryqnl6jp73bplri32oyhodofzj4gyxu56l26ueuq
- valory/market_creation_manager_abci:0.1.0:bafybeie67exdnu5phmap5q7xfwgjhfitgyld7bgwvzr2z2nhe7apwwqlaa
- valory/termination_abci:0.1.0:bafybeie4zvjfxvdu7qrulmur3chpjz3kpj5m4bjsxvpk4gvj5zbyyayfaa
- valory/transaction_settlement_abci:0.1.0:bafybeiaefgqbs7zsn5xe5kdwrujj7ivygkn3ujpw6crnvi3knvxw75qmja
behaviours:
Expand Down

0 comments on commit 0dbae99

Please sign in to comment.