Python SDK

Python SDK: https://pypi.org/project/gfx-perp-sdk/ This SDK contains 3 classes to interact with the GooseFX on-chain perpetual futures.

  • Perp

  • Product

  • Trader

Perp

The Perp class is required to initialize the connection and wallet that is going to be used for subsequent interaction.

Constructor

perp = Perp(connection, network_type, wallet, mpg=None, mpgBytes=None)
ParametersDescription

connection (Client)

An instance of the Client class from solana.rpc.api to communicate with the Solana blockchain.

network_type (NETWORK_TYPE)

An enum value indicating the network type (either NETWORK_TYPE.mainnet or NETWORK_TYPE.devnet).

wallet (Keypair)

An instance of the Keypair class representing the user's wallet.

mpg (MarketProductGroup, optional)

Optional. An instance of the MarketProductGroup class for initializing the market product group directly.

mpgBytes (bytes, optional)

Optional. Raw bytes data for the market product group.

Methods

init()

Initializes the Perp instance by setting up the market product group and related data.

perp.init()

Returns: None (Can raise exceptions for error handling)

place_order(product, order_type, trade_side, size, price)

Places an order in the perpetual market.

perp.place_order(product, order_type, trade_side, size, price)
ParametersDescription

product (Product)

The product instance for which the order is being placed.

order_type (OrderType)

The type of order (e.g., OrderType.limit, OrderType.market).

trade_side (TradeSide)

The side of the trade (TradeSide.buy or TradeSide.sell).

size (int)

The size of the order.

price (float)

The price at which the order is to be executed.

Returns: None (Implementation-dependent, can return order details or raise exceptions)

PropertiesDescription

marketProductGroup

A MarketProductGroup instance containing market product group details.

mpgBytes

Raw bytes data representing the market product group.

connection

The Client instance for Solana network communication.

wallet

The Keypair instance representing the user's wallet.

networkType

The network type (NETWORK_TYPE.mainnet or NETWORK_TYPE.devnet).

ADDRESSES

A ConstantIDs instance containing various constant IDs for the perpetual market.

Initializing the Perp class should be the first step irrespective of the type of operation in the following manner:

perp = Perp(rpc_client, 'devnet', wallet)
perp.init()

Product

An instance of the product class signifies one of the perp product we offer to trade.

Constructor

product = Product(name, PRODUCT_ID, ORDERBOOK_ID, BIDS, ASKS, EVENT_QUEUE, tick_size, decimals)
ParametersDescription

name (str)

A string representing the name of the product.

PRODUCT_ID (PublicKey)

An instance of the PublicKey class representing the unique identifier for the product.

ORDERBOOK_ID (PublicKey)

An instance of the PublicKey class representing the order book identifier for the product.

BIDS (PublicKey)

An instance of the PublicKey class representing the bids in the order book.

ASKS (PublicKey)

An instance of the PublicKey class representing the asks in the order book.

EVENT_QUEUE (PublicKey)

An instance of the PublicKey class representing the event queue for the product.

tick_size (int)

An integer specifying the minimum price movement of the product.

decimals (int)

An integer indicating the decimal precision of the product prices.

Methods

The Product class primarily serves as a data structure and does not contain specific methods for operations.

PropertiesDescription

name

The name of the product.

PRODUCT_ID

The unique identifier for the product.

ORDERBOOK_ID

The identifier for the product's order book.

BIDS

The PublicKey for bids in the order book.

ASKS

The PublicKey for asks in the order book.

EVENT_QUEUE

The PublicKey for the product's event queue.

tick_size

The minimum price movement for the product.

decimals

The decimal precision for the product's prices.

Initialization of the product class can be done in one of two ways:

  1. By index:

perp = Perp(rpc_client, 'devnet', wallet)
perp.init()
product = Product(perp)
product.initByIndex(0)
  1. By name:

perp = Perp(rpc_client, 'devnet', wallet)
perp.init()
product = Product(perp)
product.initByName('SOL-PERP')

This product instance will be useful for the following functions:

  • GET L2 Orderbook: Get the latest layer 2 orderbook

orderbook = product.get_orderbook_L2()
  • GET L3 Orderbook: Get the latest layer 3 orderbook. (Orders mapped to users)

orderbook = product.get_orderbook_L3()

Trader

The Trader class is required to get instructions to send transactions to the program. Each wallet must have a unique trader account initialized to be able to place orders and deposit funds. This account needs to be created once using the create_trader_account_ixs instruction. After it has been created once, for all subsequent interactions by the wallet, the Trader class needs to be initialized using the init function.

Constructor

trader = Trader(connection, network_type, wallet, product, order_type, trade_side, size, price)
ParametersDescription

connection (Client)

An instance of the Client class from solana.rpc.api, used to communicate with the Solana blockchain.

network_type (NETWORK_TYPE)

An enum value representing the network type (either NETWORK_TYPE.mainnet or NETWORK_TYPE.devnet).

wallet (Keypair)

An instance of the Keypair class from solders.keypair, representing the user's wallet.

product (Product)

An instance of the Product class, representing the trading product.

order_type (OrderType)

An enum value representing the type of order (e.g., OrderType.limit, OrderType.market).

trade_side (TradeSide)

An enum value representing the side of the trade (TradeSide.buy or TradeSide.sell).

size (int)

An integer specifying the size of the order.

price (float)

A float specifying the price at which the order is to be executed.

Methods

place_order()

Places an order in the market.

trader.place_order()

Returns: Varies depending on implementation, typically order details or confirmation.

cancel_order(order_id)

trader.cancel_order(order_id)
ParametersDescription

order_id (str)

The ID of the order to be cancelled.

Returns: Varies depending on implementation, typically cancellation confirmation.

update_order(order_id, new_size, new_price)

Updates an existing order.

trader.update_order(order_id, new_size, new_price)
ParametersDescription

order_id (str)

The ID of the order to be updated.

new_size (int)

The new size of the order.

new_price (float)

The new price of the order.

Returns: aries depending on implementation, typically update confirmation.

PropertiesDescription

wallet

The user's Keypair wallet instance.

connection

The Client instance for communication with the Solana network.

networkType (Keypair)

The network type (NETWORK_TYPE.mainnet or NETWORK_TYPE.devnet).

product

The Product instance for the trading operations.

orderType

The type of order to be placed.

tradeSide

The side of the trade (buy or sell).

size

The size of the trade order.

price

The price at which the trade order will be executed.

  • To create a new Trader account on-chain:

  perp = Perp(rpc_client, 'devnet', wallet)
  perp.init()
  trader = Trader(perp)
  [ixs, signers] = trader.create_trader_account_ixs()

where ixs is an array of required instructions and signers is an array of required wallet pairs for signature. The wallet must also sign the transaction along with the wallet pairs in the signers array

  • Once the account is created successfully, the Trader instance must be initialized in the following way:

  perp = Perp(rpc_client, 'devnet', wallet)
  perp.init()
  trader = Trader(perp)
  trader.init()

Fractional Datatype

The Fractional data type uses a simple formula to represent a fractional number based on its mantissa (m) and exponent (exp): number = mantissa / (10 ^ exponent)

Trader Instructions

Deposit Funds

To start placing new orders, traders need to deposit some collateral. This instruction will transfer the required USDC from the wallet to the trader account which will be used as collateral to place new orders.

The only parameter to this function is the amount of USDC to be deposited.

  perp = Perp(rpc_client, 'devnet', wallet)
  perp.init()
  trader = Trader(perp) 
  trader.init()
  [ix, signers] = trader.deposit_funds_ix(Fractional.to_decimal(100))

Withdraw Funds

Similar to deposit funds, this function takes the amount of USDC to be withdrawn as the only parameter. This instruction will transfer funds from the trader account to the wallet address.

  perp = Perp(rpc_client, 'devnet', wallet)
  perp.init()
  trader = Trader(perp) 
  trader.init()
  [ix, signers] = await trader.withdraw_funds_ix(Fractional.to_decimal(100))

NOTE: The above two instructions do not need a product instance as a parameter since the market is cross-collateralized and the amount of USDC deposited can be used across products. The following two instructions to place a new order and cancel an order are specific to products and hence need a product instance as one of the parameters.

Trader's open orders for a product

To get all open orders for a Trader for a product:

  perp = Perp(rpc_client, 'devnet', wallet)
  perp.init()
  product = Product(perp)
  product.initByIndex(0)
  trader = Trader(perp) 
  trader.init()
  orderbookData = trader.getOpenOrders(product)

New Order

The New order instruction needs the following as parameters

  • Quantity (Fractional) Please note: 1 unit of the product is denoted by 1 * 100000 units. So to buy 1 unit, the parameter to pass as quantity should be

  Fractional.to_decimal(100000)
  • Price (Fractional)

  • Order side ('buy' or 'sell')

  • Order Type ('limit', 'market', 'immediateOrCancel', 'postOnly')

  • Product instance

  perp = Perp(rpc_client, 'devnet',wallet)
  perp.init()
  product = Product(perp)
  product.initByIndex(0)
  trader = Trader(perp) 
  trader.init()
  [ix, signers] = trader.new_order_ix(product, Fractional.to_decimal(50000), Fractional.to_decimal(35), 'ask', 'limit')

Cancel Order

The cancel order instruction needs the orderId in string format to cancel the order. Use getOpenOrders() to get open orders and its id's to pass as a parameter to cancel the order

  perp = Perp(rpc_client, 'devnet',wallet)
  perp.init()
  product = Product(perp)
  product.initByIndex(0)
  trader = Trader(perp) 
  trader.init()
  [ix, signers] = trader.cancel_order_ix(product, 269375752548498747818049433352371) # Get this order id from t.get_open_orders()

Get All Trader Risk Group Accounts

get_all_trg_accounts() will fetch all the trader accounts in your wallet

Withdraw Funds for Trader Risk Group

withdraw_funds_ix_for_trg() will withdraw funds from specific trg(trader) account

Close Trader Risk Group

close_trader_risk_group_ix_for_trg() will close a specific trg(trader) account (ideally it can be done after withdrawing funds)

Get Cash Balance

get_cash_balance() will fetch available balances of the main trader account.

Get Cash Balance for Trader Risk Group

get_cash_balance_for_trg() will fetch available balance of specific trader account

Get Deposited Amount

get_deposited_amount() will fetch available deposited amounts

Get Withdrawn Amount

get_withdrawn_amount() will fetch available withdrawn amounts

Get Trader Positions by Product Index

get_trader_positions_by_product_index() will get all trader positions by product index

Get Trader Positions by Product Name

get_trader_positions_by_product_name() will get all trader positions by product name

Get Trader Positions by Trader Risk Group

get_trader_positions_for_trg() will get all trader positions for the Trader Risk Group

Checkout https://github.com/GooseFX1/gfx-perps-python-sdk/blob/dev/test_perp.py for examples on the above functionalities! Happy trading!

Last updated