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

feat/add-kelly-strategy #119

Merged
merged 84 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
b72df42
WIP: Add logging messages
jhehemann Oct 4, 2023
e4dcd8d
chore: Update packages
jhehemann Oct 4, 2023
dc6d71c
chore: Update packages
jhehemann Oct 4, 2023
1a9acf2
feat: Add mech_price to potential_net_profit calculation
jhehemann Oct 4, 2023
e820137
refactor: Make trading strategy an environment variable
jhehemann Oct 5, 2023
54d93e2
WIP: Add odds and win probability as variables
jhehemann Oct 7, 2023
1ee8977
feat: Add kelly bet amount calculation
jhehemann Oct 10, 2023
6bb29a9
chore: update packages
jhehemann Oct 10, 2023
8ef44c6
chore: Update hashes and packages
jhehemann Oct 10, 2023
4c77480
feat: Add kelly bet amount calculation function
jhehemann Oct 11, 2023
198cdc5
Merge branch 'main' of https://github.com/valory-xyz/trader into kell…
jhehemann Oct 14, 2023
93b03cb
chore: update packages
jhehemann Oct 17, 2023
88b3a65
chore: Update packages
jhehemann Oct 17, 2023
133a6d6
refactor: Reset mech tools
jhehemann Oct 18, 2023
5867590
refactor: Outsourced Kelly calc
jhehemann Oct 18, 2023
935242d
chore: Update packages
jhehemann Oct 18, 2023
5e0d810
fix: Manually resolve dependencies
jhehemann Oct 19, 2023
4ad2b14
fix: Add dev dependencies
jhehemann Oct 19, 2023
81c58fa
fix: Remove dev dependencies
jhehemann Oct 19, 2023
c7ad754
WIP: Implement betting strategy 'kelly criterion'
jhehemann Oct 19, 2023
f804ac9
fix: Resolved dependency mismatches
jhehemann Oct 19, 2023
a1510ee
fix: Resolved package incompatibilities manually
jhehemann Oct 19, 2023
603c50e
fix: Resolved package incompatibilities manually
jhehemann Oct 19, 2023
38a0f77
fix: Resolved package incompatibilities manually
jhehemann Oct 19, 2023
c7845cc
chore: Update packages
jhehemann Oct 19, 2023
a54e710
WIP: Implement betting strategy 'kelly criterion'
jhehemann Oct 19, 2023
b390eac
WIP: Implement betting strategy 'kelly criterion'
jhehemann Oct 19, 2023
e661e59
WIP: Implement betting strategy 'kelly criterion'
jhehemann Oct 20, 2023
3ef8dbb
WIP: Implement betting strategy 'kelly criterion'
jhehemann Oct 20, 2023
16f5aae
feat: Add confidence to kelly calculation
jhehemann Oct 20, 2023
e00dfb6
feat: Add kelly fraction parameter
jhehemann Oct 20, 2023
0d9f9e3
fix: Changed variable template
jhehemann Oct 20, 2023
42a630e
fix: Adjust bet kelly fraction datatype
jhehemann Oct 20, 2023
7cf7bba
fix: Add missing bet_kelly_fraction key in skill.yaml
jhehemann Oct 20, 2023
856c107
feat: Add max bet amount calculation as fallback for kelly bet amount
jhehemann Oct 20, 2023
94ec9d9
chore: Adjusted log variable
jhehemann Oct 20, 2023
1b35de2
feat: Restrict bet sampling to the next 48h
jhehemann Oct 20, 2023
c55f0bf
chore: Add log for short term bet filter
jhehemann Oct 20, 2023
2309b1c
chore: Convert filter to list
jhehemann Oct 20, 2023
aba93a3
fix: changed datatype of short_term_bets
jhehemann Oct 20, 2023
9f42cd9
fix: Handled negative value kelly bet
jhehemann Oct 20, 2023
0104cbd
refactor: Cap max buy amount to a fraction of available shares
jhehemann Oct 21, 2023
57d27e7
refactor: Add bet_amount to synchonized data
jhehemann Oct 21, 2023
69fda09
fix: Use net bet amount for calculating shares
jhehemann Oct 21, 2023
173f4f5
fix: Initialize bet amount with default value 0
jhehemann Oct 21, 2023
d95d4f1
feat: Activated Kelly calc
jhehemann Oct 21, 2023
fdb3306
chore: Update packages
jhehemann Oct 21, 2023
4112aa0
refactor: Add log for payload values
jhehemann Oct 21, 2023
eff5d12
fix: Adjusted log string
jhehemann Oct 21, 2023
8373687
refactor: Add threshold for minimum bankroll after kelly bet
jhehemann Oct 22, 2023
031472e
refactor: Add log for adjusted bankroll and make floor bankroll a var…
jhehemann Oct 22, 2023
efff0c7
feat: Activate kelly bet strategy
jhehemann Oct 22, 2023
4f69d83
refactor: Add loging for decision receive payload and sync data
jhehemann Oct 22, 2023
1195209
fix: Set bet amount initially to None; Remove odds
jhehemann Oct 22, 2023
d063fbd
chore: Update logging
jhehemann Oct 22, 2023
c863d7a
fix: Add non zero check for sampled bets; Adjusted logging
jhehemann Oct 22, 2023
9f604b9
Merge branch 'kelly-calc-fix' into kelly-calc
jhehemann Oct 25, 2023
14d4f39
chore: Update packages
jhehemann Oct 25, 2023
b7ace28
chore: Update package hashes manually
jhehemann Oct 25, 2023
1bc74a5
Merge branch 'main' of https://github.com/valory-xyz/trader into develop
jhehemann Oct 25, 2023
614c39f
chore: Update dependency versions manually
jhehemann Oct 25, 2023
6e1f960
Doc: Add kelly strategy explanation
jhehemann Oct 26, 2023
1bb332b
Merge branch 'main' of https://github.com/valory-xyz/trader into develop
jhehemann Oct 26, 2023
e5208f4
chore: Update packages
jhehemann Oct 26, 2023
84bfe30
doc: Add explanation for kelly calculation
jhehemann Oct 28, 2023
3e87ed7
feat: Add closing timespan for selecting bets as parameter variable
jhehemann Oct 28, 2023
0cf81d3
fix: Remove kelly bet fraction check; remove bet adjustment when high…
jhehemann Oct 29, 2023
9d830b2
fix: Add params check
jhehemann Oct 29, 2023
c4c6b84
refactor: Reactivate bet threshold based on market liquidity for test…
jhehemann Oct 29, 2023
58e413f
refactor: Remove bet threshold based on liquidity measure
jhehemann Oct 29, 2023
a9f58c8
fix: bets filtering for `kelly_criterion`
Adamantios Nov 1, 2023
8323302
fix: add missing overrides
Adamantios Nov 1, 2023
71a9ee9
refactor: remove unused `win_probability`
Adamantios Nov 1, 2023
adc3c7c
refactor: guard clauses
Adamantios Nov 1, 2023
148a232
fix: kelly return values
Adamantios Nov 1, 2023
94bcf94
refactor: remove unused `bankroll`
Adamantios Nov 1, 2023
3d832b3
refactor: do not return `None`
Adamantios Nov 1, 2023
8d92f98
style: remove unnecessary code
Adamantios Nov 1, 2023
4b1936a
fix: potential net profit calculation and unnecessary code
Adamantios Nov 1, 2023
53ceb42
fix: `_get_bet_sample_info`
Adamantios Nov 1, 2023
2116ee2
chore: format code
Adamantios Nov 1, 2023
8ec6054
Merge branch 'main' into feat/add-kelly-strategy
Adamantios Nov 1, 2023
f677722
fix: add missing contract
Adamantios Nov 1, 2023
f60751f
chore: run generators
Adamantios Nov 1, 2023
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,5 @@ trader/
!/packages/valory/agents/trader/
!/packages/valory/services/trader/
/trader_service/

kelly_strategy_explanation.md
10 changes: 5 additions & 5 deletions packages/packages.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"dev": {
"skill/valory/market_manager_abci/0.1.0": "bafybeidropskas24c4lcekzdbwoflhnzaglmeqxvpyuoa7cf7q2rf2yex4",
"skill/valory/decision_maker_abci/0.1.0": "bafybeid6ysjyi67q62yvf5g2v5jqlqbf25uylqiklwoeax7fnulfrrj65u",
"skill/valory/trader_abci/0.1.0": "bafybeiextdo2zomsnmpmo3dxtm7s4tjku6g46c2znpbtaqjauipksaxg6y",
"skill/valory/decision_maker_abci/0.1.0": "bafybeie4k3s546hx4p5g3dtn75hlrysyh3ieslszexctwal4odmarx34fm",
"skill/valory/trader_abci/0.1.0": "bafybeigpzcq345ed5acmehnp7uj4nwv22xtl35mbp4x2howw7sps3iwi2e",
"contract/valory/market_maker/0.1.0": "bafybeif4mm2s3gxtvp227yypkcnna5ftec7vajcftvtbdmqddh7nprah5m",
"agent/valory/trader/0.1.0": "bafybeib5qyuv6m6hud6ibym3rzuastkdvnfe2ijy2ruscocdigu24u7iv4",
"service/valory/trader/0.1.0": "bafybeic4g5lxp2ia2xbj45dmsfrinfgziwixj2l2kumzpk2ujuus66qlpy",
"agent/valory/trader/0.1.0": "bafybeicda6weararan4qyidf7dd4vxwesektyrjmu6mhvraew6q2mrezhu",
"service/valory/trader/0.1.0": "bafybeigwj6jajdge5qcjz6mimoylkv6zhbso45w4t6zo2m7olwkbb5puyq",
"contract/valory/erc20/0.1.0": "bafybeieqj7dea4tcv6z2yqkgtmhd23vbiycsr5trhwxdvlbwulpl6vhmam",
"skill/valory/tx_settlement_multiplexer_abci/0.1.0": "bafybeidqyfnc4nvqraem4fpnkejqd77iwfcixg6fh3hc5ulhvstwcbdhbm",
"skill/valory/tx_settlement_multiplexer_abci/0.1.0": "bafybeiet3hqejz7rtutuzmvyl7wqwqqi2buqagryawav4yeuem45ohpr2e",
"contract/valory/mech/0.1.0": "bafybeihvc6btuk3nvernzcx4qpezvuhiw2wwnagqj5nkeljvszghv7mq64",
"contract/valory/realitio/0.1.0": "bafybeid6kh4tiqswpeufkr7eowmq7seoyhkssnedgzw6pe4h7wswui6dlm",
"contract/valory/realitio_proxy/0.1.0": "bafybeidx37xzjjmapwacedgzhum6grfzhp5vhouz4zu3pvpgdy5pgb2fr4",
Expand Down
10 changes: 7 additions & 3 deletions packages/valory/agents/trader/aea-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ contracts:
- valory/realitio:0.1.0:bafybeid6kh4tiqswpeufkr7eowmq7seoyhkssnedgzw6pe4h7wswui6dlm
- valory/realitio_proxy:0.1.0:bafybeidx37xzjjmapwacedgzhum6grfzhp5vhouz4zu3pvpgdy5pgb2fr4
- valory/agent_registry:0.1.0:bafybeifwdtwxdc2jdlhzdyxctqdmoz6zroxf5o4nhuok5l4luvnofqavty
- valory/service_staking_token:0.1.0:bafybeibifxmoeaiptovouispl5jdgm4lduzcfgsx723zlw45cfpllecuwy
protocols:
- open_aea/signing:1.0.0:bafybeie7xyems76v5b4wc2lmaidcujizpxfzjnnwdeokmhje53g7ym25ii
- valory/abci:0.1.0:bafybeihmzlmmb4pdo3zkhg6ehuyaa4lhw7bfpclln2o2z7v3o6fcep26iu
Expand All @@ -42,10 +43,10 @@ skills:
- valory/reset_pause_abci:0.1.0:bafybeicpxn2khtaesuf4cq6ypwdmdmonlqroj2q2i6cxvpizc2y4cw66pe
- valory/termination_abci:0.1.0:bafybeieqm46zuccaagnko3qlw6p3nvoohdrfgvpmw467r5lyil2dqrzjsy
- valory/transaction_settlement_abci:0.1.0:bafybeia6cdxdlqrcwk2maw25fo7dafzd2p3rs7syropvufophk2pitzbwy
- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeidqyfnc4nvqraem4fpnkejqd77iwfcixg6fh3hc5ulhvstwcbdhbm
- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeiet3hqejz7rtutuzmvyl7wqwqqi2buqagryawav4yeuem45ohpr2e
- valory/market_manager_abci:0.1.0:bafybeidropskas24c4lcekzdbwoflhnzaglmeqxvpyuoa7cf7q2rf2yex4
- valory/decision_maker_abci:0.1.0:bafybeid6ysjyi67q62yvf5g2v5jqlqbf25uylqiklwoeax7fnulfrrj65u
- valory/trader_abci:0.1.0:bafybeiextdo2zomsnmpmo3dxtm7s4tjku6g46c2znpbtaqjauipksaxg6y
- valory/decision_maker_abci:0.1.0:bafybeie4k3s546hx4p5g3dtn75hlrysyh3ieslszexctwal4odmarx34fm
- valory/trader_abci:0.1.0:bafybeigpzcq345ed5acmehnp7uj4nwv22xtl35mbp4x2howw7sps3iwi2e
default_ledger: ethereum
required_ledgers:
- ethereum
Expand Down Expand Up @@ -163,6 +164,9 @@ models:
average_block_time: ${int:5}
abt_error_mult: ${int:5}
mech_agent_address: ${str:0xff82123dfb52ab75c417195c5fdb87630145ae81}
sample_bets_closing_days: ${int:10}
trading_strategy: ${str:bet_amount_per_conf_threshold}
bet_kelly_fraction: ${float:1.0}
bet_amount_per_threshold:
0.0: ${int:0}
0.1: ${int:0}
Expand Down
14 changes: 13 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:bafybeib5qyuv6m6hud6ibym3rzuastkdvnfe2ijy2ruscocdigu24u7iv4
agent: valory/trader:0.1.0:bafybeicda6weararan4qyidf7dd4vxwesektyrjmu6mhvraew6q2mrezhu
number_of_agents: 4
deployment: {}
---
Expand Down Expand Up @@ -78,6 +78,9 @@ type: skill
average_block_time: ${ABT:int:5}
abt_error_mult: ${ABT_ERROR_MULT:int:5}
mech_agent_address: ${MECH_AGENT_ADDRESS:str:0xff82123dfb52ab75c417195c5fdb87630145ae81}
sample_bets_closing_days: ${SAMPLE_BETS_CLOSING_DAYS:int:10}
trading_strategy: ${TRADING_STRATEGY:str:bet_amount_per_conf_threshold}
bet_kelly_fraction: ${BET_KELLY_FRACTION:float:1.0}
bet_amount_per_threshold: &id004
0.0: ${BET_AMOUNT_PER_THRESHOLD_000:int:0}
0.1: ${BET_AMOUNT_PER_THRESHOLD_010:int:0}
Expand Down Expand Up @@ -159,6 +162,9 @@ type: skill
average_block_time: ${ABT:int:5}
abt_error_mult: ${ABT_ERROR_MULT:int:5}
mech_agent_address: ${MECH_AGENT_ADDRESS:str:0xff82123dfb52ab75c417195c5fdb87630145ae81}
sample_bets_closing_days: ${SAMPLE_BETS_CLOSING_DAYS:int:10}
trading_strategy: ${TRADING_STRATEGY:str:bet_amount_per_conf_threshold}
bet_kelly_fraction: ${BET_KELLY_FRACTION:float:1.0}
bet_amount_per_threshold: *id004
bet_threshold: ${BET_THRESHOLD:int:100000000000000000}
blacklisting_duration: ${BLACKLISTING_DURATION:int:3600}
Expand Down Expand Up @@ -227,6 +233,9 @@ type: skill
average_block_time: ${ABT:int:5}
abt_error_mult: ${ABT_ERROR_MULT:int:5}
mech_agent_address: ${MECH_AGENT_ADDRESS:str:0xff82123dfb52ab75c417195c5fdb87630145ae81}
sample_bets_closing_days: ${SAMPLE_BETS_CLOSING_DAYS:int:10}
trading_strategy: ${TRADING_STRATEGY:str:bet_amount_per_conf_threshold}
bet_kelly_fraction: ${BET_KELLY_FRACTION:float:1.0}
bet_amount_per_threshold: *id004
bet_threshold: ${BET_THRESHOLD:int:100000000000000000}
blacklisting_duration: ${BLACKLISTING_DURATION:int:3600}
Expand Down Expand Up @@ -295,6 +304,9 @@ type: skill
average_block_time: ${ABT:int:5}
abt_error_mult: ${ABT_ERROR_MULT:int:5}
mech_agent_address: ${MECH_AGENT_ADDRESS:str:0xff82123dfb52ab75c417195c5fdb87630145ae81}
sample_bets_closing_days: ${SAMPLE_BETS_CLOSING_DAYS:int:10}
trading_strategy: ${TRADING_STRATEGY:str:bet_amount_per_conf_threshold}
bet_kelly_fraction: ${BET_KELLY_FRACTION:float:1.0}
bet_amount_per_threshold: *id004
bet_threshold: ${BET_THRESHOLD:int:100000000000000000}
blacklisting_duration: ${BLACKLISTING_DURATION:int:3600}
Expand Down
142 changes: 142 additions & 0 deletions packages/valory/skills/decision_maker_abci/behaviours/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ def synchronized_data(self) -> SynchronizedData:
"""Return the synchronized data."""
return SynchronizedData(super().synchronized_data.db)

@property
def synced_timestamp(self) -> int:
"""Return the synchronized timestamp across the agents."""
return int(self.round_sequence.last_round_transition_timestamp.timestamp())

@property
def safe_tx_hash(self) -> str:
"""Get the safe_tx_hash."""
Expand Down Expand Up @@ -210,6 +215,143 @@ def check_balance(self) -> WaitableConditionType:
self.context.logger.info(f"The safe has {native} xDAI and {collateral}.")
return True

def _calculate_kelly_bet_amount(
self, x: int, y: int, p: float, c: float, b: int, f: float
) -> int:
"""Calculate the Kelly bet amount."""
if b == 0 or x**2 * f == y**2 * f:
self.context.logger.error(
"Could not calculate Kelly bet amount. "
"Either bankroll is 0 or pool token amount is distributed as x^2*f - y^2*f = 0:\n"
f"Bankroll: {b}\n"
f"Pool token amounts: {x}, {y}"
f"Fee, fee fraction f: {1-f}, {f}"
)
return 0
kelly_bet_amount = (
-4 * x**2 * y
+ b * y**2 * p * c * f
+ 2 * b * x * y * p * c * f
+ b * x**2 * p * c * f
- 2 * b * y**2 * f
- 2 * b * x * y * f
+ (
(
4 * x**2 * y
- b * y**2 * p * c * f
- 2 * b * x * y * p * c * f
- b * x**2 * p * c * f
+ 2 * b * y**2 * f
+ 2 * b * x * y * f
)
** 2
- (
4
* (x**2 * f - y**2 * f)
* (
-4 * b * x * y**2 * p * c
- 4 * b * x**2 * y * p * c
+ 4 * b * x * y**2
)
)
)
** (1 / 2)
) / (2 * (x**2 * f - y**2 * f))
return int(kelly_bet_amount)

def get_max_bet_amount(self, a: int, x: int, y: int, f: float) -> int:
"""Get max bet amount based on available shares."""
if x**2 * f**2 + 2 * x * y * f**2 + y**2 * f**2 == 0:
self.context.logger.error(
"Could not recalculate. "
"Either bankroll is 0 or pool token amount is distributed such as "
"x**2*f**2 + 2*x*y*f**2 + y**2*f**2 == 0:\n"
f"Available tokens: {a}\n"
f"Pool token amounts: {x}, {y}\n"
f"Fee, fee fraction f: {1-f}, {f}"
)
return 0
else:
pre_root = -2 * x**2 + a * x - 2 * x * y
sqrt = (
4 * x**4
+ 8 * x**3 * y
+ a**2 * x**2
+ 4 * x**2 * y**2
+ 2 * a**2 * x * y
+ a**2 * y**2
)
numerator = y * (pre_root + sqrt**0.5 + a * y)
denominator = f * (x**2 + 2 * x * y + y**2)
new_bet_amount = numerator / denominator
return int(new_bet_amount)

def get_bet_amount(
self,
strategy: str,
win_probability: float,
confidence: float,
selected_type_tokens_in_pool: int,
other_tokens_in_pool: int,
bet_fee: int,
) -> int:
"""Get the bet amount given a specified trading strategy."""

if strategy == "bet_amount_per_conf_threshold":
self.context.logger.info(
"Used trading strategy: Bet amount per confidence threshold"
)
threshold = round(confidence, 1)
bet_amount = self.params.bet_amount_per_threshold[threshold]
return bet_amount

if strategy != "kelly_criterion":
raise ValueError(f"Invalid trading strategy: {strategy}")

self.context.logger.info("Used trading strategy: Kelly Criterion")
# bankroll: the max amount of DAI available to trade
bankroll = self.token_balance + self.wallet_balance
# keep `floor_balance` xDAI in the bankroll
floor_balance = 500000000000000000
bankroll_adj = bankroll - floor_balance
self.context.logger.info(f"Adjusted bankroll: {bankroll_adj} DAI")
if bankroll_adj <= 0:
self.context.logger.info(
f"Bankroll ({bankroll_adj}) is less than the floor balance ({floor_balance}). "
"Set bet amount to 0."
"Top up safe with DAI or wait for redeeming."
)
return 0

fee_fraction = 1 - self.wei_to_native(bet_fee)
self.context.logger.info(f"Fee fraction: {fee_fraction}")
kelly_bet_amount = self._calculate_kelly_bet_amount(
selected_type_tokens_in_pool,
other_tokens_in_pool,
win_probability,
confidence,
bankroll_adj,
fee_fraction,
)
if kelly_bet_amount < 0:
self.context.logger.info(
f"Invalid value for kelly bet amount: {kelly_bet_amount}\n"
"Set bet amount to 0."
)
return 0

self.context.logger.info(
f"Kelly bet amount: {self.wei_to_native(kelly_bet_amount)} xDAI"
)
self.context.logger.info(
f"Bet kelly fraction: {self.params.bet_kelly_fraction}"
)
adj_kelly_bet_amount = int(kelly_bet_amount * self.params.bet_kelly_fraction)
self.context.logger.info(
f"Adjusted Kelly bet amount: {self.wei_to_native(adj_kelly_bet_amount)} xDAI"
)
return adj_kelly_bet_amount

def default_error(
self, contract_id: str, contract_callable: str, response_msg: ContractApiMessage
) -> None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def market_maker_contract_address(self) -> str:
@property
def investment_amount(self) -> int:
"""Get the investment amount of the bet."""
return self.params.get_bet_amount(self.synchronized_data.confidence)
return self.synchronized_data.bet_amount

@property
def w_xdai_deficit(self) -> int:
Expand Down
Loading