Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new round and behavior with API integration #5

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions packages/packages.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"dev": {
"contract/valory/erc20/0.1.0": "bafybeibyhuxozkkvsymqz45vxixr3w3bs4vsvxg2nsx5jlyi3f3hhn7ezi",
"skill/valory/learning_abci/0.1.0": "bafybeih5m372dqrdfy7w6iah4m5qfgf3j5t7ihsgorzyzhax5srm32wmim",
"skill/valory/learning_chained_abci/0.1.0": "bafybeihu6uvvdnfntgluhrbxqus5malsit36xqsyxv46wjqsmuodadarpm",
"agent/valory/learning_agent/0.1.0": "bafybeiatizepnj42umexk3p5rnop67cdshbgrflvnysaagm3t4xqo74kem",
"service/valory/learning_service/0.1.0": "bafybeig34lg3wztyj7ecsbyb6qj7ryf34gnpr2cuoz3akjvgdsh3pejboq"
"skill/valory/learning_abci/0.1.0": "bafybeibpzxfcsuomucmqbetupbmfpwbaddnepntfpt2xn2kzpn2is4wyby",
"skill/valory/learning_chained_abci/0.1.0": "bafybeidqmzqdh3hpf4mlkjznbhqyl6pakqjp7zssgycakmytbxb3iaxuty",
"agent/valory/learning_agent/0.1.0": "bafybeibsqxkkjgkqrpvtgzqec6cvrk5azawpcydy37evipfvwwb2hlk65a",
"service/valory/learning_service/0.1.0": "bafybeieqgkhlmzq5c3ev4hrasvs3zb3qagqwlu3p57vbncuezk3ex4vyge"
},
"third_party": {
"protocol/open_aea/signing/1.0.0": "bafybeihv62fim3wl2bayavfcg3u5e5cxu3b7brtu4cn5xoxd6lqwachasi",
Expand Down
17 changes: 15 additions & 2 deletions packages/valory/agents/learning_agent/aea-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ protocols:
skills:
- valory/abstract_abci:0.1.0:bafybeidz54kvxhbdmpruzguuzzq7bjg4pekjb5amqobkxoy4oqknnobopu
- valory/abstract_round_abci:0.1.0:bafybeiajjzuh6vf23crp55humonknirvv2f4s3dmdlfzch6tc5ow52pcgm
- valory/learning_abci:0.1.0:bafybeih5m372dqrdfy7w6iah4m5qfgf3j5t7ihsgorzyzhax5srm32wmim
- valory/learning_chained_abci:0.1.0:bafybeihu6uvvdnfntgluhrbxqus5malsit36xqsyxv46wjqsmuodadarpm
- valory/learning_abci:0.1.0:bafybeibpzxfcsuomucmqbetupbmfpwbaddnepntfpt2xn2kzpn2is4wyby
- valory/learning_chained_abci:0.1.0:bafybeidqmzqdh3hpf4mlkjznbhqyl6pakqjp7zssgycakmytbxb3iaxuty
- valory/registration_abci:0.1.0:bafybeiffipsowrqrkhjoexem7ern5ob4fabgif7wa6gtlszcoaop2e3oey
- valory/reset_pause_abci:0.1.0:bafybeif4lgvbzsmzljesxbphycdv52ka7qnihyjrjpfaseclxadcmm6yiq
- valory/termination_abci:0.1.0:bafybeiekkpo5qef5zaeagm3si6v45qxcojvtjqe4a5ceccvk4q7k3xi3bi
Expand Down Expand Up @@ -219,3 +219,16 @@ models:
response_type: dict
retries: 5
url: https://api.coingecko.com/api/v3/simple/price
coingecko_pricehistorydata_specs:
args:
api_id: coingecko
headers:
Accept: application/json
method: GET
parameters:
vs_currency: usd
days: 1
response_key: prices
response_type: list
retries: 5
url: https://api.coingecko.com/api/v3/coins/autonolas/market_chart
54 changes: 53 additions & 1 deletion packages/valory/services/learning_service/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: bafybeid42pdrf6qrohedylj4ijrss236ai6geqgf3he44huowiuf7pl464
fingerprint_ignore_patterns: []
agent: valory/learning_agent:0.1.0:bafybeiatizepnj42umexk3p5rnop67cdshbgrflvnysaagm3t4xqo74kem
agent: valory/learning_agent:0.1.0:bafybeibsqxkkjgkqrpvtgzqec6cvrk5azawpcydy37evipfvwwb2hlk65a
number_of_agents: 4
deployment:
agent:
Expand Down Expand Up @@ -108,6 +108,19 @@ extra:
response_type: dict
retries: 5
url: https://api.coingecko.com/api/v3/simple/price
coingecko_pricehistorydata_specs:
args:
api_id: coingecko
headers:
Accept: application/json
method: GET
parameters:
vs_currency: usd
days: 1
response_key: prices
response_type: list
retries: 5
url: https://api.coingecko.com/api/v3/coins/autonolas/market_chart
1:
models:
benchmark_tool:
Expand Down Expand Up @@ -169,6 +182,19 @@ extra:
response_type: dict
retries: 5
url: https://api.coingecko.com/api/v3/simple/price
coingecko_pricehistorydata_specs:
args:
api_id: coingecko
headers:
Accept: application/json
method: GET
parameters:
vs_currency: usd
days: 1
response_key: prices
response_type: list
retries: 5
url: https://api.coingecko.com/api/v3/coins/autonolas/market_chart
2:
models:
benchmark_tool:
Expand Down Expand Up @@ -230,6 +256,19 @@ extra:
response_type: dict
retries: 5
url: https://api.coingecko.com/api/v3/simple/price
coingecko_pricehistorydata_specs:
args:
api_id: coingecko
headers:
Accept: application/json
method: GET
parameters:
vs_currency: usd
days: 1
response_key: prices
response_type: list
retries: 5
url: https://api.coingecko.com/api/v3/coins/autonolas/market_chart
3:
models:
benchmark_tool:
Expand Down Expand Up @@ -291,6 +330,19 @@ extra:
response_type: dict
retries: 5
url: https://api.coingecko.com/api/v3/simple/price
coingecko_pricehistorydata_specs:
args:
api_id: coingecko
headers:
Accept: application/json
method: GET
parameters:
vs_currency: usd
days: 1
response_key: prices
response_type: list
retries: 5
url: https://api.coingecko.com/api/v3/coins/autonolas/market_chart
---
public_id: valory/ledger:0.19.0
type: connection
Expand Down
86 changes: 85 additions & 1 deletion packages/valory/skills/learning_abci/behaviours.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,18 @@
CoingeckoSpecs,
Params,
SharedState,
Coingeckopricehistorydataspecs,
)
from packages.valory.skills.learning_abci.payloads import (
DataPullPayload,
DecisionMakingPayload,
EvaluationPayload,
TxPreparationPayload,
)
from packages.valory.skills.learning_abci.rounds import (
DataPullRound,
DecisionMakingRound,
EvaluationRound,
Event,
LearningAbciApp,
SynchronizedData,
Expand Down Expand Up @@ -99,6 +102,11 @@ def local_state(self) -> SharedState:
def coingecko_specs(self) -> CoingeckoSpecs:
"""Get the Coingecko api specs."""
return self.context.coingecko_specs

@property
def coingecko_pricehistorydata_specs(self) -> Coingeckopricehistorydataspecs:
"""Get the Coingecko api specs."""
return self.context.coingecko_pricehistorydata_specs

@property
def metadata_filepath(self) -> str:
Expand Down Expand Up @@ -278,7 +286,6 @@ def get_native_balance(self) -> Generator[None, None, Optional[float]]:

return balance


class DecisionMakingBehaviour(
LearningBaseBehaviour
): # pylint: disable=too-many-ancestors
Expand Down Expand Up @@ -384,6 +391,81 @@ def get_price_from_ipfs(self) -> Generator[None, None, Optional[dict]]:
self.context.logger.error(f"Got price from IPFS: {price}")
return price

class EvaluationBehaviour(DataPullBehaviour,LearningBaseBehaviour):
"""Behaviour to handle the evaluation of current vs historical prices."""

matching_round: Type[AbstractRound] = EvaluationRound

def async_act(self) -> Generator:
"""Perform the evaluation logic."""
try:
with self.context.benchmark_tool.measure(self.behaviour_id).local():
self.context.logger.debug("Starting EvaluationBehaviour logic")

current_price = yield from self.get_token_price_specs()
self.context.logger.info(f"Current price fetched: {current_price}")

historical_data = yield from self.get_historical_price_data()
self.context.logger.info(f"Historical data fetched: {historical_data}")

if not historical_data:
self.context.logger.error("No historical data available.")
return self.synchronized_data, Event.ERROR

average_historical_price = sum(historical_data) / len(historical_data)
self.context.logger.info(f"Average historical price computed: {average_historical_price}")

comparison_result = self.compare_prices(current_price, average_historical_price)
self.context.logger.info(f"Price comparison result: {comparison_result}")

payload = EvaluationPayload(
sender=self.context.agent_address,
comparison_data=comparison_result,
)
self.context.logger.info("EvaluationPayload prepared and being sent.")

with self.context.benchmark_tool.measure(self.behaviour_id).consensus():
yield from self.send_a2a_transaction(payload)
yield from self.wait_until_round_end()
self.context.logger.info("EvaluationBehaviour completed.")

self.set_done()

except Exception as e:
self.context.logger.error(f"Error in EvaluationBehaviour: {str(e)}")
raise

def compare_prices(self, current, historical_average) -> str:
"""Log comparison of current price to historical average."""
if current > historical_average:
self.context.logger.info("Current price is higher than the average of last day.")
elif current < historical_average:
self.context.logger.info("Current price is lower than the average of last day.")
else:
self.context.logger.info("Current price is the same as the average of last day.")
return current > historical_average

def get_historical_price_data(self) -> Generator[None, None, list[float]]:
"""Fetch historical price data from the Coingecko API."""
try:
self.context.logger.debug("Fetching historical price data.")
specs = self.coingecko_pricehistorydata_specs.get_spec()
response = yield from self.get_http_response(**specs)
if response.status_code != HTTP_OK:
self.context.logger.error(f"Failed to fetch historical data: {response.body}")
return []

historical_data = self.coingecko_pricehistorydata_specs.process_response(response)
if historical_data is None:
self.context.logger.error("No historical data returned from processing.")
return []

prices = [price[1] for price in historical_data]
self.context.logger.info(f"Historical prices fetched: {prices}")
return prices # Assuming prices is a list of floats
except Exception as e:
self.context.logger.error(f"Exception in fetching historical data: {str(e)}")
return []

class TxPreparationBehaviour(
LearningBaseBehaviour
Expand All @@ -410,6 +492,7 @@ def async_act(self) -> Generator:
yield from self.wait_until_round_end()

self.set_done()


def get_tx_hash(self) -> Generator[None, None, Optional[str]]:
"""Get the transaction hash"""
Expand Down Expand Up @@ -659,5 +742,6 @@ class LearningRoundBehaviour(AbstractRoundBehaviour):
behaviours: Set[Type[BaseBehaviour]] = [ # type: ignore
DataPullBehaviour,
DecisionMakingBehaviour,
EvaluationBehaviour,
TxPreparationBehaviour,
]
9 changes: 7 additions & 2 deletions packages/valory/skills/learning_abci/fsm_specification.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ start_states:
states:
- DataPullRound
- DecisionMakingRound
- EvaluationRound
- FinishedDecisionMakingRound
- FinishedTxPreparationRound
- TxPreparationRound
Expand All @@ -25,7 +26,11 @@ transition_func:
(DecisionMakingRound, ERROR): FinishedDecisionMakingRound
(DecisionMakingRound, NO_MAJORITY): DecisionMakingRound
(DecisionMakingRound, ROUND_TIMEOUT): DecisionMakingRound
(DecisionMakingRound, TRANSACT): TxPreparationRound
(DecisionMakingRound, TRANSACT): EvaluationRound
(EvaluationRound, DONE): TxPreparationRound
(EvaluationRound, ERROR): FinishedDecisionMakingRound
(EvaluationRound, NO_MAJORITY): EvaluationRound
(EvaluationRound, ROUND_TIMEOUT): EvaluationRound
(TxPreparationRound, DONE): FinishedTxPreparationRound
(TxPreparationRound, NO_MAJORITY): TxPreparationRound
(TxPreparationRound, ROUND_TIMEOUT): TxPreparationRound
(TxPreparationRound, ROUND_TIMEOUT): TxPreparationRound
2 changes: 1 addition & 1 deletion packages/valory/skills/learning_abci/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@
LedgerApiHandler = BaseLedgerApiHandler
ContractApiHandler = BaseContractApiHandler
TendermintHandler = BaseTendermintHandler
IpfsHandler = BaseIpfsHandler
IpfsHandler = BaseIpfsHandler
3 changes: 3 additions & 0 deletions packages/valory/skills/learning_abci/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,6 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:

class CoingeckoSpecs(ApiSpecs):
"""A model that wraps ApiSpecs for Coingecko API."""

class Coingeckopricehistorydataspecs(ApiSpecs):
"""A model that wraps ApiSpecs for Coingecko API."""
10 changes: 8 additions & 2 deletions packages/valory/skills/learning_abci/payloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

"""This module contains the transaction payloads of the LearningAbciApp."""

from dataclasses import dataclass
from dataclasses import dataclass,field
from typing import Optional

from packages.valory.skills.abstract_round_abci.base import BaseTxPayload
Expand All @@ -42,9 +42,15 @@ class DecisionMakingPayload(BaseTxPayload):
event: str


@dataclass(frozen=True)
class EvaluationPayload(BaseTxPayload):
"""Represent a transaction payload for the EvaluationRound."""

comparison_data: bool = field(default=False)

@dataclass(frozen=True)
class TxPreparationPayload(BaseTxPayload):
"""Represent a transaction payload for the TxPreparationRound."""

tx_submitter: Optional[str] = None
tx_hash: Optional[str] = None
tx_hash: Optional[str] = None
Loading