def settle(self, market_metadata: MarketMetadata, market: Market) -> typing.List[str]: base_token_account = TokenAccount.fetch_or_create_largest_for_owner_and_token( self.context, self.wallet.account, market_metadata.base.token) quote_token_account = TokenAccount.fetch_or_create_largest_for_owner_and_token( self.context, self.wallet.account, market_metadata.quote.token) open_orders = OpenOrders.load_for_market_and_owner( self.context, market_metadata.address, self.wallet.account.public_key(), self.context.dex_program_id, market_metadata.base.token.decimals, market_metadata.quote.token.decimals) transaction_ids = [] for open_order_account in open_orders: if (open_order_account.base_token_free > 0) or (open_order_account.quote_token_free > 0): self.reporter( f"Need to settle open orders: {open_order_account}\nBase account: {base_token_account.address}\nQuote account: {quote_token_account.address}" ) response = market.settle_funds(self.wallet.account, open_order_account.to_pyserum(), base_token_account.address, quote_token_account.address) transaction_id = self.context.unwrap_transaction_id_or_raise_exception( response) self.reporter(f"Settlement transaction ID: {transaction_id}") transaction_ids += [transaction_id] return transaction_ids
def test_settle_fund( bootstrapped_market: Market, stubbed_payer: Account, stubbed_quote_wallet: Account, stubbed_base_wallet: Account, ): open_order_accounts = bootstrapped_market.find_open_orders_accounts_for_owner( stubbed_payer.public_key()) for open_order_account in open_order_accounts: assert "error" not in bootstrapped_market.settle_funds( stubbed_payer, open_order_account, stubbed_base_wallet.public_key(), stubbed_quote_wallet.public_key(), opts=TxOpts(skip_confirmation=False), )
def __init__(self, upper: float, lower: float, amount: float, grid: int, pair: str, base: str, quote: str, owner: str, private: str): """ :params upper: price up :params lower: price down :params amount: amount of the order :params grid: amount of grid :params pair: dexlab trading pair address :params base: youur base coin address for trading :params quote: your quote coin address for trading :params owner: your solana wallet address :params private: your private key for pay the transaction gas """ self.upper = upper self.lower = lower self.amount = amount self.grid = grid self.pair = pair self.base = base self.quote = quote self.owner = owner self.key = base58.b58decode(private) self.payer = Account(self.key[:32]) self.client = Client('', '') self.cc = conn('https://api.mainnet-beta.solana.com/') self.market = Market.load( self.cc, PublicKey(self.pair), program_id=PublicKey( '9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin')) try: self.open_acc = self.market.find_open_orders_accounts_for_owner( self.payer.public_key())[0].address except: self.open_acc = '' self.base_decimal = self.market.state.base_spl_token_decimals() self.quote_decimal = self.market.state.quote_spl_token_decimals() print(f'Initialize...\n\n' f'----parameters----\n\n' f'upper: {self.upper}\n' f'lower: {self.lower}\n' f'amount: {self.amount}\n' f'grid: {self.grid}\n' f'base decimal: {self.base_decimal}\n' f'quote decimal: {self.quote_decimal}\n' f'pair: {self.pair}\n' f'base: {self.base}\n' f'quote: {self.quote}\n' f'owner: {self.owner}\n' f'open orders account: {self.open_acc}\n' f'key: {self.key[:32]}\n\n' f'----start----\n')
def _wait_for_order_fill(self, market: Market, client_id: int, max_wait_in_seconds: int = 60): self.logger.info( f"Waiting up to {max_wait_in_seconds} seconds for {client_id}.") return rx.interval(1.0).pipe( ops.flat_map(lambda _: market.load_event_queue()), ops.skip_while(lambda item: item.client_order_id != client_id), ops.skip_while(lambda item: not item.event_flags.fill), ops.first(), ops.map(lambda _: True), ops.timeout(max_wait_in_seconds, rx.return_value(False))).run()
def stubbed_market() -> Market: conn = Client("http://stubbed_endpoint:123/") market_state = State( Container( dict( account_flags=AccountFlags( initialized=True, market=True, bids=False, ), quote_dust_threshold=100, base_lot_size=100, quote_lot_size=10, )), program_id=DEFAULT_DEX_PROGRAM_ID, base_mint_decimals=6, quote_mint_decimals=6, ) return Market(conn, market_state)
def test_match_order(bootstrapped_market: Market, stubbed_payer: Account): bootstrapped_market.match_orders(stubbed_payer, 2, TxOpts(skip_confirmation=False)) request_queue = bootstrapped_market.load_request_queue() # 0 request after matching. assert len(request_queue) == 0 event_queue = bootstrapped_market.load_event_queue() # 5 event after the order is matched, including 2 fill events. assert len(event_queue) == 5 # There should be no bid order. bids = bootstrapped_market.load_bids() assert sum(1 for _ in bids) == 0 # There should be no ask order. asks = bootstrapped_market.load_asks() assert sum(1 for _ in asks) == 0
cc = conn("https://api.mainnet-beta.solana.com/") quote_token = Token( cc, pubkey=PublicKey(quote_ccy_mint[quote_ccy]), # mint address of token program_id=TOKEN_PROGRAM_ID, payer=payer, ) quote_wallet = quote_token.create_account( payer.public_key(), skip_confirmation=False) # Make sure you send tokens to this address print("quote wallet: ", str(quote_wallet)) market_address = PublicKey(pair_mkt[pair]) market = Market.load(cc, market_address) tx_sig = market.place_order( payer=quote_wallet, #PublicKey(pubkey), # My public key owner=payer, side=side, order_type=OrderType.LIMIT, limit_price=100, max_quantity=0.1, opts=TxOpts(skip_preflight=False)) print(tx_sig) summary = { "mkt_add": pair_mkt[pair], "token_mint": quote_ccy_mint[quote_ccy], "public_key": str(payer.public_key()),
def test_market_load_requests(bootstrapped_market: Market): request_queue = bootstrapped_market.load_request_queue() # 2 requests in the request queue in the beginning with one bid and one ask assert len(request_queue) == 2
def test_market_load_events(bootstrapped_market: Market): event_queue = bootstrapped_market.load_event_queue() assert len(event_queue) == 0
def test_market_load_asks(bootstrapped_market: Market): # TODO: test for non-zero order case. asks = bootstrapped_market.load_asks() assert sum(1 for _ in asks) == 0
def test_market_load_bid(bootstrapped_market: Market): # TODO: test for non-zero order case. bids = bootstrapped_market.load_bids() assert sum(1 for _ in bids) == 0
def bootstrapped_market(http_client: Client, stubbed_market_pk: PublicKey, stubbed_dex_program_pk: PublicKey) -> Market: return Market.load(http_client, stubbed_market_pk, stubbed_dex_program_pk)
def test_order_placement_cancellation_cycle( bootstrapped_market: Market, stubbed_payer: Account, stubbed_quote_wallet: Account, stubbed_base_wallet: Account, ): initial_request_len = len(bootstrapped_market.load_request_queue()) bootstrapped_market.place_order( payer=stubbed_quote_wallet.public_key(), owner=stubbed_payer, side=Side.Buy, order_type=OrderType.Limit, limit_price=1000, max_quantity=3000, opts=TxOpts(skip_confirmation=False), ) request_queue = bootstrapped_market.load_request_queue() # 0 request after matching. assert len(request_queue) == initial_request_len + 1 # There should be no bid order. bids = bootstrapped_market.load_bids() assert sum(1 for _ in bids) == 0 # There should be no ask order. asks = bootstrapped_market.load_asks() assert sum(1 for _ in asks) == 0 bootstrapped_market.place_order( payer=stubbed_base_wallet.public_key(), owner=stubbed_payer, side=Side.Sell, order_type=OrderType.Limit, limit_price=1500, max_quantity=3000, opts=TxOpts(skip_confirmation=False), ) # The two order shouldn't get executed since there is a price difference of 1 bootstrapped_market.match_orders( stubbed_payer, 2, opts=TxOpts(skip_confirmation=False), ) # There should be 1 bid order that we sent earlier. bids = bootstrapped_market.load_bids() assert sum(1 for _ in bids) == 1 # There should be 1 ask order that we sent earlier. asks = bootstrapped_market.load_asks() assert sum(1 for _ in asks) == 1 for bid in bids: bootstrapped_market.cancel_order(stubbed_payer, bid, opts=TxOpts(skip_confirmation=False)) bootstrapped_market.match_orders(stubbed_payer, 1, opts=TxOpts(skip_confirmation=False)) # All bid order should have been cancelled. bids = bootstrapped_market.load_bids() assert sum(1 for _ in bids) == 0 for ask in asks: bootstrapped_market.cancel_order(stubbed_payer, ask, opts=TxOpts(skip_confirmation=False)) bootstrapped_market.match_orders(stubbed_payer, 1, opts=TxOpts(skip_confirmation=False)) # All ask order should have been cancelled. asks = bootstrapped_market.load_asks() assert sum(1 for _ in asks) == 0