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: integrate volume discount program into market-sim #516

Merged
merged 6 commits into from
Oct 2, 2023
Merged
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
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VEGA_SIM_VEGA_TAG=aaa9b4eb0b8fba1e118e19fc90d81b74cd02092d
VEGA_SIM_VEGA_TAG=6b2a26f0d4a6ed3bf928bcebaa0014f5891e728f
VEGA_SIM_CONSOLE_TAG=develop
VEGA_DEFAULT_KEY_NAME='Key 1'
VEGA_SIM_NETWORKS_INTERNAL_TAG=main
Expand Down
2 changes: 1 addition & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pipeline {
disableConcurrentBuilds(abortPrevious: true)
}
parameters {
string( name: 'VEGA_VERSION', defaultValue: 'aaa9b4eb0b8fba1e118e19fc90d81b74cd02092d',
string( name: 'VEGA_VERSION', defaultValue: '6b2a26f0d4a6ed3bf928bcebaa0014f5891e728f',
description: 'Git branch, tag or hash of the vegaprotocol/vega repository')
string( name: 'VEGACAPSULE_VERSION', defaultValue: 'main',
description: 'Git branch, tag or hash of the vegaprotocol/vegacapsule repository')
Expand Down
76 changes: 76 additions & 0 deletions tests/integration/test_trading.py
Original file line number Diff line number Diff line change
Expand Up @@ -1616,3 +1616,79 @@ def test_referral_program(vega_service_with_market: VegaServiceNull):
next_epoch(vega=vega)
referral_program = vega.get_current_referral_program()
assert referral_program is not None


@pytest.mark.integration
def test_volume_discount_program(vega_service_with_market: VegaServiceNull):
vega = vega_service_with_market
market_id = vega.all_markets()[0].id
create_and_faucet_wallet(vega=vega, wallet=PARTY_A, amount=1e9)
vega.wait_for_total_catchup()
create_and_faucet_wallet(vega=vega, wallet=PARTY_B, amount=1e9)
vega.wait_for_total_catchup()
vega.update_volume_discount_program(
proposal_key=MM_WALLET.name,
benefit_tiers=[
{
"minimum_running_notional_taker_volume": 1,
"volume_discount_factor": 0.01,
},
],
window_length=7,
)
next_epoch(vega=vega)
vega.submit_order(
trading_key=PARTY_A.name,
market_id=market_id,
order_type="TYPE_LIMIT",
time_in_force="TIME_IN_FORCE_GTC",
side="SIDE_BUY",
price=0.30,
volume=100,
)
vega.wait_fn(1)
non_discounted_order_id = vega.submit_order(
trading_key=PARTY_B.name,
market_id=market_id,
order_type="TYPE_LIMIT",
time_in_force="TIME_IN_FORCE_GTC",
side="SIDE_SELL",
price=0.30,
volume=100,
wait=True,
)
non_discounted_trades = vega.get_trades(
market_id=market_id, order_id=non_discounted_order_id
)
assert vega.get_current_volume_discount_program() is not None
assert non_discounted_trades[0].seller_fee.maker_fee_volume_discount == 0
assert non_discounted_trades[0].seller_fee.liquidity_fee_volume_discount == 0
assert non_discounted_trades[0].seller_fee.infrastructure_fee_volume_discount == 0
next_epoch(vega=vega)
assert vega.get_volume_discount_stats(key_name=PARTY_B.name) is not None
vega.submit_order(
trading_key=PARTY_A.name,
market_id=market_id,
order_type="TYPE_LIMIT",
time_in_force="TIME_IN_FORCE_GTC",
side="SIDE_SELL",
price=0.30,
volume=10000,
)
vega.wait_fn(1)
discounted_order_id = vega.submit_order(
trading_key=PARTY_B.name,
market_id=market_id,
order_type="TYPE_LIMIT",
time_in_force="TIME_IN_FORCE_GTC",
side="SIDE_BUY",
price=0.30,
volume=10000,
wait=True,
)
discounted_trades = vega.get_trades(
market_id=market_id, order_id=discounted_order_id
)
assert discounted_trades[0].buyer_fee.maker_fee_volume_discount != 0
assert discounted_trades[0].buyer_fee.liquidity_fee_volume_discount != 0
assert discounted_trades[0].buyer_fee.infrastructure_fee_volume_discount != 0
36 changes: 34 additions & 2 deletions tests/vega_sim/api/test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -557,8 +557,28 @@ def test_get_trades(
sell_order="so1",
timestamp=100,
trade_type=vega_protos.vega.Trade.TYPE_DEFAULT,
buyer_fee=Fee(maker_fee=10, infrastructure_fee=1.2, liquidity_fee=1.4),
seller_fee=Fee(maker_fee=20, infrastructure_fee=12.2, liquidity_fee=14.4),
buyer_fee=Fee(
maker_fee=10,
infrastructure_fee=1.2,
liquidity_fee=1.4,
maker_fee_referrer_discount=0,
maker_fee_volume_discount=0,
infrastructure_fee_referrer_discount=0,
infrastructure_fee_volume_discount=0,
liquidity_fee_referrer_discount=0,
liquidity_fee_volume_discount=0,
),
seller_fee=Fee(
maker_fee=20,
infrastructure_fee=12.2,
liquidity_fee=14.4,
maker_fee_referrer_discount=0,
maker_fee_volume_discount=0,
infrastructure_fee_referrer_discount=0,
infrastructure_fee_volume_discount=0,
liquidity_fee_referrer_discount=0,
liquidity_fee_volume_discount=0,
),
buyer_auction_batch=100,
seller_auction_batch=96,
)
Expand Down Expand Up @@ -592,11 +612,23 @@ def ListTrades(self, request, context):
maker_fee="100",
infrastructure_fee="12",
liquidity_fee="14",
maker_fee_referrer_discount="0",
maker_fee_volume_discount="0",
infrastructure_fee_referrer_discount="0",
infrastructure_fee_volume_discount="0",
liquidity_fee_referrer_discount="0",
liquidity_fee_volume_discount="0",
),
seller_fee=vega_protos.vega.Fee(
maker_fee="200",
infrastructure_fee="122",
liquidity_fee="144",
maker_fee_referrer_discount="0",
maker_fee_volume_discount="0",
infrastructure_fee_referrer_discount="0",
infrastructure_fee_volume_discount="0",
liquidity_fee_referrer_discount="0",
liquidity_fee_volume_discount="0",
),
buyer_auction_batch=100,
seller_auction_batch=96,
Expand Down
134 changes: 133 additions & 1 deletion vega_sim/api/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,12 @@ class Fee:
maker_fee: float
infrastructure_fee: float
liquidity_fee: float
maker_fee_volume_discount: float
infrastructure_fee_volume_discount: float
liquidity_fee_volume_discount: float
maker_fee_referrer_discount: float
infrastructure_fee_referrer_discount: float
liquidity_fee_referrer_discount: float


@dataclass(frozen=True)
Expand Down Expand Up @@ -270,6 +276,14 @@ class ReferralSetReferee:
at_epoch: int


@dataclass(frozen=True)
class VolumeDiscountStats:
at_epoch: int
party_id: str
discount_factor: float
running_volume: float


@dataclass(frozen=True)
class BenefitTier:
minimum_running_notional_taker_volume: float
Expand All @@ -295,6 +309,22 @@ class ReferralProgram:
ended_at: int


@dataclass(frozen=True)
class VolumeBenefitTier:
minimum_running_notional_taker_volume: float
volume_discount_factor: float


@dataclass(frozen=True)
class VolumeDiscountProgram:
version: int
id: str
benefit_tiers: List[VolumeBenefitTier]
end_of_program_timestamp: str
window_length: int
ended_at: int


def _ledger_entry_from_proto(
ledger_entry,
asset_decimals: int,
Expand Down Expand Up @@ -354,6 +384,28 @@ def _trade_from_proto(
liquidity_fee=num_from_padded_int(
trade.buyer_fee.liquidity_fee, decimal_spec.asset_decimals
),
maker_fee_volume_discount=num_from_padded_int(
trade.buyer_fee.maker_fee_volume_discount, decimal_spec.asset_decimals
),
infrastructure_fee_volume_discount=num_from_padded_int(
trade.buyer_fee.infrastructure_fee_volume_discount,
decimal_spec.asset_decimals,
),
liquidity_fee_volume_discount=num_from_padded_int(
trade.buyer_fee.liquidity_fee_volume_discount,
decimal_spec.asset_decimals,
),
maker_fee_referrer_discount=num_from_padded_int(
trade.buyer_fee.maker_fee_referrer_discount, decimal_spec.asset_decimals
),
infrastructure_fee_referrer_discount=num_from_padded_int(
trade.buyer_fee.infrastructure_fee_referrer_discount,
decimal_spec.asset_decimals,
),
liquidity_fee_referrer_discount=num_from_padded_int(
trade.buyer_fee.liquidity_fee_referrer_discount,
decimal_spec.asset_decimals,
),
),
seller_fee=Fee(
maker_fee=num_from_padded_int(
Expand All @@ -365,6 +417,29 @@ def _trade_from_proto(
liquidity_fee=num_from_padded_int(
trade.seller_fee.liquidity_fee, decimal_spec.asset_decimals
),
maker_fee_volume_discount=num_from_padded_int(
trade.seller_fee.maker_fee_volume_discount, decimal_spec.asset_decimals
),
infrastructure_fee_volume_discount=num_from_padded_int(
trade.seller_fee.infrastructure_fee_volume_discount,
decimal_spec.asset_decimals,
),
liquidity_fee_volume_discount=num_from_padded_int(
trade.seller_fee.liquidity_fee_volume_discount,
decimal_spec.asset_decimals,
),
maker_fee_referrer_discount=num_from_padded_int(
trade.seller_fee.maker_fee_referrer_discount,
decimal_spec.asset_decimals,
),
infrastructure_fee_referrer_discount=num_from_padded_int(
trade.seller_fee.infrastructure_fee_referrer_discount,
decimal_spec.asset_decimals,
),
liquidity_fee_referrer_discount=num_from_padded_int(
trade.seller_fee.liquidity_fee_referrer_discount,
decimal_spec.asset_decimals,
),
),
buyer_auction_batch=trade.buyer_auction_batch,
seller_auction_batch=trade.seller_auction_batch,
Expand Down Expand Up @@ -769,6 +844,40 @@ def _referral_program_from_proto(referral_program) -> ReferralProgram:
)


def _volume_benefit_tier_from_proto(volume_benefit_tier) -> VolumeBenefitTier:
return VolumeBenefitTier(
minimum_running_notional_taker_volume=float(
volume_benefit_tier.minimum_running_notional_taker_volume
),
volume_discount_factor=float(volume_benefit_tier.volume_discount_factor),
)


def _volume_discount_program_from_proto(
volume_discount_program,
) -> VolumeDiscountProgram:
return VolumeDiscountProgram(
version=int(volume_discount_program.version),
id=str(volume_discount_program.id),
benefit_tiers=[
_volume_benefit_tier_from_proto(volume_benefit_tier)
for volume_benefit_tier in volume_discount_program.benefit_tiers
],
end_of_program_timestamp=int(volume_discount_program.end_of_program_timestamp),
window_length=int(volume_discount_program.window_length),
ended_at=int(volume_discount_program.ended_at),
)


def _volume_discount_stats_from_proto(volume_discount_stats) -> VolumeDiscountStats:
return VolumeDiscountStats(
at_epoch=int(volume_discount_stats.at_epoch),
party_id=str(volume_discount_stats.party_id),
discount_factor=float(volume_discount_stats.discount_factor),
running_volume=float(volume_discount_stats.running_volume),
)


def list_accounts(
data_client: vac.VegaTradingDataClientV2,
pub_key: Optional[str] = None,
Expand Down Expand Up @@ -1809,6 +1918,29 @@ def list_referral_set_referees(
return referral_set_referees


def get_current_referral_program(data_client: vac.trading_data_grpc_v2):
def get_current_referral_program(
data_client: vac.trading_data_grpc_v2,
) -> ReferralProgram:
response = data_raw.get_current_referral_program(data_client=data_client)
return _referral_program_from_proto(referral_program=response)


def get_current_volume_discount_program(
data_client: vac.trading_data_grpc_v2,
) -> VolumeDiscountProgram:
response = data_raw.get_current_volume_discount_program(data_client=data_client)
return _volume_discount_program_from_proto(volume_discount_program=response)


def get_volume_discount_stats(
data_client: vac.trading_data_grpc_v2,
at_epoch: Optional[int] = None,
party_id: Optional[str] = None,
) -> List[VolumeDiscountStats]:
response = data_raw.get_volume_discount_stats(
data_client=data_client, at_epoch=at_epoch, party_id=party_id
)
return [
_volume_discount_stats_from_proto(volume_discount_stats=volume_discount_stats)
for volume_discount_stats in response
]
27 changes: 27 additions & 0 deletions vega_sim/api/data_raw.py
Original file line number Diff line number Diff line change
Expand Up @@ -733,3 +733,30 @@ def get_current_referral_program(data_client: vac.trading_data_grpc_v2):
return data_client.GetCurrentReferralProgram(
data_node_protos_v2.trading_data.GetCurrentReferralProgramRequest()
).current_referral_program


@_retry(3)
def get_current_volume_discount_program(
data_client: vac.trading_data_grpc_v2.TradingDataServiceStub,
):
return data_client.GetCurrentVolumeDiscountProgram(
data_node_protos_v2.trading_data.GetCurrentVolumeDiscountProgramRequest()
).current_volume_discount_program


@_retry(3)
def get_volume_discount_stats(
data_client: vac.trading_data_grpc_v2,
at_epoch: Optional[int] = None,
party_id: Optional[str] = None,
) -> List[data_node_protos_v2.trading_data.ReferralSet]:
base_request = data_node_protos_v2.trading_data.GetVolumeDiscountStatsRequest()
if at_epoch is not None:
setattr(base_request, "at_epoch", at_epoch)
if party_id is not None:
setattr(base_request, "party_id", party_id)
return unroll_v2_pagination(
base_request=base_request,
request_func=lambda x: data_client.GetVolumeDiscountStats(x).stats,
extraction_func=lambda res: [i.node for i in res.edges],
)
Loading
Loading