Skip to content

Commit

Permalink
Merge pull request #72 from valory-xyz/refactor/strategy
Browse files Browse the repository at this point in the history
Make the strategy more sensible
  • Loading branch information
Adamantios authored Sep 7, 2023
2 parents 6d74435 + 7d24415 commit 618ac27
Show file tree
Hide file tree
Showing 26 changed files with 219 additions and 84 deletions.
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ These are the description of the variables used by the Trader service:
- `OMEN_CREATORS`: addresses of the market creator(s) that the service will track
for placing bets on Omen. The address `0x89c5cc945dd550BcFfb72Fe42BfF002429F46Fec` corresponds to the Market creator agent for the Hackathon.
- `BET_AMOUNT_PER_THRESHOLD_X`: amount (wei) to bet when the prediction returned by the AI Mech surpasses a threshold of `X`% confidence for a given prediction market. In the values provided above the amounts vary between 0.03 xDAI (60% confidence) and 0.1 xDAI (100% confidence).
- `BET_THRESHOLD`: threshold (wei) for placing a bet. A bet will only be placed if `expected_return - bet_fees >= BET_THRESHOLD`. [See below](#some-notes-on-the-service).
- `BET_THRESHOLD`: threshold (wei) for placing a bet. A bet will only be placed if `potential_net_profit - BET_THRESHOLD >= 0`. [See below](#some-notes-on-the-service).
- `PROMPT_TEMPLATE`: prompt to be used with the prediction AI Mech. Please keep it as a single line including the placeholders `@{question}`, `@{yes}` and `@{no}`.


Expand Down Expand Up @@ -153,8 +153,15 @@ Once you have configured (exported) the environment variables, you are in positi
Please take into consideration the following:

- If the service does not have enough funds for placing a bet, you will see an `Event.INSUFICIENT_FUNDS` in the service logs.
- If the service determines that a bet is not profitable (i.e., `expected_return - bet_fees < BET_THRESHOLD`), you will see an `Event.UNPROFITABLE` in the service logs, and the service will transition into the blacklisting round. This round blacklists a bet for a predetermined amount of time. This can be adjusted by using the `BLACKLISTING_DURATION` environment variable.
- For simplicity, the current implementation considers `expected_return = bet_amount`, although this calculation might be refined.
- If the service determines that a bet is not profitable
(i.e., `potential_net_profit - BET_THRESHOLD < 0`), you will see an `Event.UNPROFITABLE` in the service logs,
and the service will transition into the blacklisting round.
This round blacklists a bet for a predetermined amount of time.
This can be adjusted by using the `BLACKLISTING_DURATION` environment variable.
- For simplicity,
the current implementation considers `potential_net_profit = num_shares - net_bet_amount - mech_price - BET_THRESHOLD`,
although this calculation might be refined.
The `net_bet_amount` is the bet amount minus the FPMM's fees.
- When assigning `BET_THRESHOLD` take into consideration that fees (at the time of writing this guide) are in the range of 0.02 xDAI. See, for example, [here](https://api.thegraph.com/subgraphs/name/protofire/omen-xdai/graphql?query=%7B%0A++fixedProductMarketMakers%28%0A++++where%3A+%7B%0A++++++creator_in%3A+%5B%220x89c5cc945dd550BcFfb72Fe42BfF002429F46Fec%22%5D%2C%0A++++++outcomeSlotCount%3A+2%2C%0A++++++isPendingArbitration%3A+false%0A++++%7D%2C%0A++++orderBy%3A+creationTimestamp%0A++++orderDirection%3A+desc%0A++%29%7B%0A++++fee%0A++%7D%0A%7D). We urge you to keep an eye on these fees, as they might vary.
## For advanced users
Expand Down
16 changes: 8 additions & 8 deletions packages/packages.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
{
"dev": {
"skill/valory/market_manager_abci/0.1.0": "bafybeibwcm2wqoucpbep6pav4fb5mofhjahxiqszul4wcv4xr52dei6pe4",
"skill/valory/decision_maker_abci/0.1.0": "bafybeiejy2zxj5wzriay2vwecgvxxprwvs6rt32627jtjfn7gtsy46eimy",
"skill/valory/trader_abci/0.1.0": "bafybeiexo6pdhhdipnceixtls47jonhflcqsxnbv2c333zmgfxmoygfwgu",
"skill/valory/market_manager_abci/0.1.0": "bafybeih6tmi4blhdqkjgtvqkwbtbky5kzhl57h6ze4rtr3r2rh43pkhvyi",
"skill/valory/decision_maker_abci/0.1.0": "bafybeibadjiuw4icm64rm5mrooht6he2xw6ery6yxu5qnwhqkpwlfhen2m",
"skill/valory/trader_abci/0.1.0": "bafybeif7zbal6iqiui3dwqfswnev6tcjsszixhrpv3m6kufgxfvh7veadi",
"contract/valory/market_maker/0.1.0": "bafybeiftimqgvrbval2lxp7au6y72amioo4gtcdth2dflrbwa47i6opyb4",
"agent/valory/trader/0.1.0": "bafybeidclpkg6uwii2d5gk74b4l6pv3vfgrg5tt3njumhk2ab3uidcogky",
"service/valory/trader/0.1.0": "bafybeidug5h7tac43yp5t6mfyl3qdmfwzh63otz63l547iiguosyyygmnq",
"agent/valory/trader/0.1.0": "bafybeietnokftb3klhladvtrrrwhizq7nj64s4tqxbw3xwylxpgulr4g5u",
"service/valory/trader/0.1.0": "bafybeiczvwvd7s2q7yc5lh4qxzolpga4f2xstme4rzq6sot7oefnz7dqim",
"contract/valory/erc20/0.1.0": "bafybeifjwr6rwklgg2uk2zkfysn55qqy7dfi4jx7sek6lzdup37fynhpxe",
"skill/valory/tx_settlement_multiplexer_abci/0.1.0": "bafybeiffvwkifzq4eiqr4syfbbsfjcrsea5wj55ttismoxozt6trithu7u",
"skill/valory/tx_settlement_multiplexer_abci/0.1.0": "bafybeiez2gopga42empgxlgprmw34joobw3rx2h5ybnk2u35vdmpkjtjfq",
"contract/valory/mech/0.1.0": "bafybeie753wdqks6k4x5fqlpo7tgll2avutjcaodpwlptqvzefsi5xbvai",
"contract/valory/realitio/0.1.0": "bafybeid5cdncqui3egi57eh6ptz2yqxsjpnmwzdc2siewuown3gktdwm6m",
"contract/valory/realitio/0.1.0": "bafybeigb722aznqhc5lsbt3dn4bpyaqe5hnl5onmnestqmzliwtvl3eaom",
"contract/valory/realitio_proxy/0.1.0": "bafybeibvndq6756qck7forgeavhdbn6ykgqs2ufyg7n5g6qdfpveatxuwy",
"contract/valory/conditional_tokens/0.1.0": "bafybeiftqtsn6yygfhubzcsc2jluhhx5pt2udzvh4cjr26a4qxmp4bjqba"
"contract/valory/conditional_tokens/0.1.0": "bafybeiaqcyzbuhv4ey2h7hn2dq5zibf3pmkotx2t7fihdawf5h4u4uu65e"
},
"third_party": {
"protocol/open_aea/signing/1.0.0": "bafybeifuxs7gdg2okbn7uofymenjlmnih2wxwkym44lsgwmklgwuckxm2m",
Expand Down
13 changes: 7 additions & 6 deletions packages/valory/agents/trader/aea-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ contracts:
- valory/erc20:0.1.0:bafybeifjwr6rwklgg2uk2zkfysn55qqy7dfi4jx7sek6lzdup37fynhpxe
- valory/multisend:0.1.0:bafybeie7m7pjbnw7cccpbvmbgkut24dtlt4cgvug3tbac7gej37xvwbv3a
- valory/mech:0.1.0:bafybeie753wdqks6k4x5fqlpo7tgll2avutjcaodpwlptqvzefsi5xbvai
- valory/conditional_tokens:0.1.0:bafybeiftqtsn6yygfhubzcsc2jluhhx5pt2udzvh4cjr26a4qxmp4bjqba
- valory/realitio:0.1.0:bafybeid5cdncqui3egi57eh6ptz2yqxsjpnmwzdc2siewuown3gktdwm6m
- valory/conditional_tokens:0.1.0:bafybeiaqcyzbuhv4ey2h7hn2dq5zibf3pmkotx2t7fihdawf5h4u4uu65e
- valory/realitio:0.1.0:bafybeigb722aznqhc5lsbt3dn4bpyaqe5hnl5onmnestqmzliwtvl3eaom
- valory/realitio_proxy:0.1.0:bafybeibvndq6756qck7forgeavhdbn6ykgqs2ufyg7n5g6qdfpveatxuwy
protocols:
- open_aea/signing:1.0.0:bafybeifuxs7gdg2okbn7uofymenjlmnih2wxwkym44lsgwmklgwuckxm2m
Expand All @@ -41,10 +41,10 @@ skills:
- valory/reset_pause_abci:0.1.0:bafybeifoihgilpfr76hc5skzspm6qehkwivx7ld2cy3veipcsi4gr2c7na
- valory/termination_abci:0.1.0:bafybeigcsls72uosoui2y5ppmnvsljjhnxakkeh3fdohklcg66aqq4g7xu
- valory/transaction_settlement_abci:0.1.0:bafybeiglsnh2hvfau5gab7requh34k4sbqwbjvrhhqjpes4hakcwq46cpi
- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeiffvwkifzq4eiqr4syfbbsfjcrsea5wj55ttismoxozt6trithu7u
- valory/market_manager_abci:0.1.0:bafybeibwcm2wqoucpbep6pav4fb5mofhjahxiqszul4wcv4xr52dei6pe4
- valory/decision_maker_abci:0.1.0:bafybeiejy2zxj5wzriay2vwecgvxxprwvs6rt32627jtjfn7gtsy46eimy
- valory/trader_abci:0.1.0:bafybeiexo6pdhhdipnceixtls47jonhflcqsxnbv2c333zmgfxmoygfwgu
- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeiez2gopga42empgxlgprmw34joobw3rx2h5ybnk2u35vdmpkjtjfq
- valory/market_manager_abci:0.1.0:bafybeih6tmi4blhdqkjgtvqkwbtbky5kzhl57h6ze4rtr3r2rh43pkhvyi
- valory/decision_maker_abci:0.1.0:bafybeibadjiuw4icm64rm5mrooht6he2xw6ery6yxu5qnwhqkpwlfhen2m
- valory/trader_abci:0.1.0:bafybeif7zbal6iqiui3dwqfswnev6tcjsszixhrpv3m6kufgxfvh7veadi
default_ledger: ethereum
required_ledgers:
- ethereum
Expand Down Expand Up @@ -185,6 +185,7 @@ models:
realitio_proxy_address: ${str:0xAB16D643bA051C11962DA645f74632d3130c81E2}
realitio_address: ${str:0x79e32aE03fb27B07C89c0c568F80287C01ca2E57}
redeeming_batch_size: ${int:5}
slippage: ${float:0.01}
---
public_id: valory/p2p_libp2p_client:0.1.0
type: connection
Expand Down
17 changes: 7 additions & 10 deletions packages/valory/contracts/conditional_tokens/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@

from typing import List, Dict

import requests
from requests.exceptions import ReadTimeout as RequestsReadTimeoutError
from urllib3.exceptions import ReadTimeoutError as Urllib3ReadTimeoutError
from aea.common import JSONLike
from aea.configurations.base import PublicId
from aea.contracts.base import Contract
Expand All @@ -34,10 +35,6 @@
DEFAULT_TO_BLOCK = "latest"


class RPCTimedOutError(Exception):
"""Exception to raise when the RPC times out."""


class ConditionalTokensContract(Contract):
"""The ConditionalTokens smart contract."""

Expand Down Expand Up @@ -86,16 +83,16 @@ def check_redeemed(

try:
redeemed = list(payout_filter.deploy(ledger_api.api).get_all_entries())
except requests.exceptions.ReadTimeout as exc:
except (Urllib3ReadTimeoutError, RequestsReadTimeoutError):
msg = (
"The RPC timed out! This usually happens if the filtering is too wide. "
f"The service tried to filter from block {earliest_block} to latest, "
f"as the earliest market creation transaction took place at block {earliest_block}."
f"as the earliest market creation transaction took place at block {earliest_block}. "
f"Did the creation happen too long in the past?\n"
"Please consider manually redeeming for the market with condition id "
f"{earliest_condition_id!r} if this issue persists."
f"The market with condition id {earliest_condition_id!r} "
f"is the oldest one and the block filtering was set based on it."
)
raise RPCTimedOutError(msg) from exc
return dict(error=msg)

payouts = {}
for redeeming in redeemed:
Expand Down
4 changes: 3 additions & 1 deletion packages/valory/contracts/conditional_tokens/contract.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ aea_version: '>=1.0.0, <2.0.0'
fingerprint:
__init__.py: bafybeidhdxio3oq5gqdnxmngumvt3fcd6zyiyrpk5f2k4dwhflbg4e5iky
build/ConditionalTokens.json: bafybeia2ahis7zx2yhhf23kpkcxu56hto6fwg6ptjg5ld46lp4dgz7cz3e
contract.py: bafybeic2j4bpss23dgsavdxnng5ulas4hchmwn4djs4ock4i7dawab3hxu
contract.py: bafybeiamr2y22rcwlf2h75uryweqx4qjztjrmhzb2flivkcfqvifedvdpi
fingerprint_ignore_patterns: []
class_name: ConditionalTokensContract
contract_interface_paths:
Expand All @@ -19,4 +19,6 @@ dependencies:
version: ==6.0.1
requests:
version: ==2.28.2
urllib3:
version: ==1.26.16
contracts: []
22 changes: 11 additions & 11 deletions packages/valory/contracts/realitio/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@

"""This module contains the Realitio_v2_1 contract definition."""

from typing import List, Tuple
from typing import List, Tuple, Union

import requests
from requests.exceptions import ReadTimeout as RequestsReadTimeoutError
from urllib3.exceptions import ReadTimeoutError as Urllib3ReadTimeoutError
from aea.common import JSONLike
from aea.configurations.base import PublicId
from aea.contracts.base import Contract
Expand All @@ -34,10 +35,6 @@
ZERO_BYTES = bytes.fromhex(ZERO_HEX)


class RPCTimedOutError(Exception):
"""Exception to raise when the RPC times out."""


class RealitioContract(Contract):
"""The Realitio_v2_1 smart contract."""

Expand All @@ -62,7 +59,7 @@ def _get_claim_params(
contract_address: str,
from_block: BlockIdentifier,
question_id: bytes,
) -> Tuple[bytes, List[bytes], List[ChecksumAddress], List[int], List[bytes]]:
) -> Union[str, Tuple[bytes, List[bytes], List[ChecksumAddress], List[int], List[bytes]]]:
"""Filters the `LogNewAnswer` event by question id to calculate the history hashes."""
contract_instance = cls.get_instance(ledger_api, contract_address)

Expand All @@ -73,21 +70,21 @@ def _get_claim_params(

try:
answered = list(answer_filter.deploy(ledger_api.api).get_all_entries())
except requests.exceptions.ReadTimeout as exc:
except (Urllib3ReadTimeoutError, RequestsReadTimeoutError):
msg = (
"The RPC timed out! This usually happens if the filtering is too wide. "
f"The service tried to filter from block {from_block} to latest, "
"as the market was created at this time. Did the market get created too long in the past?\n"
"Please consider manually redeeming for the market with question id "
f"{question_id!r} if this issue persists."
)
raise RPCTimedOutError(msg) from exc
return msg
else:
n_answered = len(answered)

if n_answered == 0:
msg = f"No answers have been given for question with id {question_id}!"
raise ValueError(msg)
msg = f"No answers have been given for question with id {question_id.hex()}!"
return msg

history_hashes = []
addresses = []
Expand Down Expand Up @@ -123,6 +120,9 @@ def build_claim_winnings(
claim_params = cls._get_claim_params(
ledger_api, contract_address, from_block, question_id
)
if isinstance(claim_params, str):
return dict(error=claim_params)

data = contract.encodeABI(
fn_name="claimWinnings",
args=claim_params,
Expand Down
4 changes: 3 additions & 1 deletion packages/valory/contracts/realitio/contract.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ aea_version: '>=1.0.0, <2.0.0'
fingerprint:
__init__.py: bafybeictahkgfmlqv5kksvj6klmxtmjdpeq4sp3x7dp2yr5x4kmzbcihse
build/Realitio.json: bafybeiagi7zoeoy5s7duhg4oeuekj2s6z5mad2z6g2pn3n5elsvze25qiu
contract.py: bafybeiack5tz6vyesyvpq6wqhkkrdfevjedopdvjgyv5erhatknw2fazz4
contract.py: bafybeibygb64t4bhajvoyf54o6tkvwedsczhwltkqwwxmix2w6ar2wcvyy
fingerprint_ignore_patterns: []
class_name: RealitioContract
contract_interface_paths:
Expand All @@ -20,4 +20,6 @@ dependencies:
version: ==6.0.1
requests:
version: ==2.28.2
urllib3:
version: ==1.26.16
contracts: []
6 changes: 5 additions & 1 deletion packages/valory/services/trader/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: bafybeigtuothskwyvrhfosps2bu6suauycolj67dpuxqvnicdrdu7yhtvq
fingerprint_ignore_patterns: []
agent: valory/trader:0.1.0:bafybeidclpkg6uwii2d5gk74b4l6pv3vfgrg5tt3njumhk2ab3uidcogky
agent: valory/trader:0.1.0:bafybeietnokftb3klhladvtrrrwhizq7nj64s4tqxbw3xwylxpgulr4g5u
number_of_agents: 4
deployment: {}
---
Expand Down Expand Up @@ -102,6 +102,7 @@ type: skill
realitio_proxy_address: ${REALITIO_PROXY_ADDRESS:str:0xAB16D643bA051C11962DA645f74632d3130c81E2}
realitio_address: ${REALITIO_ADDRESS:str:0x79e32aE03fb27B07C89c0c568F80287C01ca2E57}
redeeming_batch_size: ${REDEEMING_BATCH_SIZE:int:5}
slippage: ${SLIPPAGE:float:0.01}
benchmark_tool: &id005
args:
log_dir: ${LOG_DIR:str:/benchmarks}
Expand Down Expand Up @@ -164,6 +165,7 @@ type: skill
realitio_proxy_address: ${REALITIO_PROXY_ADDRESS:str:0xAB16D643bA051C11962DA645f74632d3130c81E2}
realitio_address: ${REALITIO_ADDRESS:str:0x79e32aE03fb27B07C89c0c568F80287C01ca2E57}
redeeming_batch_size: ${REDEEMING_BATCH_SIZE:int:5}
slippage: ${SLIPPAGE:float:0.01}
benchmark_tool: *id005
2:
models:
Expand Down Expand Up @@ -224,6 +226,7 @@ type: skill
realitio_proxy_address: ${REALITIO_PROXY_ADDRESS:str:0xAB16D643bA051C11962DA645f74632d3130c81E2}
realitio_address: ${REALITIO_ADDRESS:str:0x79e32aE03fb27B07C89c0c568F80287C01ca2E57}
redeeming_batch_size: ${REDEEMING_BATCH_SIZE:int:5}
slippage: ${SLIPPAGE:float:0.01}
benchmark_tool: *id005
3:
models:
Expand Down Expand Up @@ -284,6 +287,7 @@ type: skill
realitio_proxy_address: ${REALITIO_PROXY_ADDRESS:str:0xAB16D643bA051C11962DA645f74632d3130c81E2}
realitio_address: ${REALITIO_ADDRESS:str:0x79e32aE03fb27B07C89c0c568F80287C01ca2E57}
redeeming_batch_size: ${REDEEMING_BATCH_SIZE:int:5}
slippage: ${SLIPPAGE:float:0.01}
benchmark_tool: *id005
---
public_id: valory/ledger:0.19.0
Expand Down
8 changes: 8 additions & 0 deletions packages/valory/skills/decision_maker_abci/behaviours/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@
SAFE_GAS = 0


def remove_fraction_wei(amount: int, fraction: float) -> int:
"""Removes the given fraction from the given integer amount and returns the value as an integer."""
if 0 <= fraction <= 1:
keep_percentage = 1 - fraction
return int(amount * keep_percentage)
raise ValueError(f"The given fraction {fraction!r} is not in the range [0, 1].")


class DecisionMakerBaseBehaviour(BaseBehaviour, ABC):
"""Represents the base class for the decision-making FSM behaviour."""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from packages.valory.skills.decision_maker_abci.behaviours.base import (
DecisionMakerBaseBehaviour,
WaitableConditionType,
remove_fraction_wei,
)
from packages.valory.skills.decision_maker_abci.models import MultisendBatch
from packages.valory.skills.decision_maker_abci.payloads import MultisigTxPayload
Expand Down Expand Up @@ -199,7 +200,7 @@ def _calc_buy_amount(self) -> WaitableConditionType:
)
return False

self.buy_amount = int(buy_amount)
self.buy_amount = remove_fraction_wei(buy_amount, self.params.slippage)
return True

def _build_buy_tx(self) -> WaitableConditionType:
Expand Down
Loading

0 comments on commit 618ac27

Please sign in to comment.