
In our previous article “Wash Trading Strategies in Digital Currency,” we provided a detailed introduction to a strategy framework that accumulates trading volume through same-price buy and sell orders. The primary objective of this strategy is to obtain exchange rebates or tier benefits, rather than generating profits through price spread arbitrage. While wash trading strategies have reference value for learning trading framework architecture, their actual profit-making capability is limited and may face compliance risks. Building upon the previous article, this piece will introduce another market making strategy with greater practical value—Order Book Strategy. Unlike wash trading strategies, the order book strategy is a genuine arbitrage strategy that generates profits by setting price spreads between bid and ask prices, which better aligns with the traditional market maker profit model.
The order book strategy code presented in this article is solely for learning reference framework purposes and does not have any live trading experience. The strategy implementation in this article is intended only for technical learning and research purposes and has not been thoroughly validated in actual market environments. Readers must conduct comprehensive backtesting verification and risk assessment when referencing the content of this article, and should never use it directly for live trading.
The order book strategy is a market-making strategy that leverages the market order book (i.e., market depth) for arbitrage. Under this strategy, market makers dynamically adjust order prices within the bid-ask spread based on market fluctuations, executing order placement and cancellation operations to profit from market liquidity and short-term price volatility.
| Feature | Wash Trading Strategy | Order Book Strategy |
|---|---|---|
| Buy/Sell Prices | Same price | Different prices (with spread) |
| Profit Model | Exchange rebates/incentives | Bid-ask spread |
| Risk Exposure | Low (same-price execution) | High (price volatility risk) |
| Practicality | Limited | Higher |
Improve Market Liquidity: By placing orders in the order book, it increases market depth on both buy and sell sides, attracting more traders to participate. Earn Bid-Ask Spread: By providing liquidity, market makers can earn the bid-ask spread and generate profits. Flexible Response to Market Volatility: The order book strategy can dynamically adjust order prices based on market fluctuations, reducing market risk.
Market Risk: Market price volatility may prevent market makers’ orders from being executed, potentially causing losses. Capital Pressure: Market makers need sufficient capital to maintain order book depth on both sides; insufficient funds may render the strategy ineffective. Complex Order Management: The order book strategy requires regular monitoring of order status and handling of unfilled orders, adding complexity to the strategy.
Consistent with the wash trading strategy, the code implementation in this article presents a market-making strategy based on the order book approach, primarily divided into two classes:
In the initialization method of the MarketMaker class, exchange precision information is first obtained and strategy parameters are initialized, such as volume precision, price precision, etc.
self.precision_info = self.exchange_mid.get_precision() # Get precision information
self.price_precision = self.precision_info['price_precision'] # Price precision
self.amount_precision = self.precision_info['amount_precision'] # Volume precision
The core of the order book strategy is generating the order book dictionary, which contains bid/ask prices and quantities. The code generates the order book dictionary by calculating the mid-price and price offsets.
Order book price movement is achieved by calculating price offsets. The price offset is calculated based on the price range (price_range) and minimum price step (min_price_step).
price_offset = price_range - self.pending_order_count * min_price_step # Calculate price offset
do_trade = price_offset > 0
If the price offset is greater than 0, it indicates that orders can continue to be placed; otherwise, the pending order count is reset.
Based on the price offset, calculate bid and ask prices, and generate the order dictionary.
if do_trade:
buy_price = mid_price - price_offset # Calculate buy price
buy_price = round(buy_price, self.price_precision) # Round buy price
sell_price = mid_price + price_offset # Calculate sell price
sell_price = round(sell_price, self.price_precision) # Round sell price
trade_dict = {
'do_trade': do_trade,
'buy_price': buy_price,
'sell_price': sell_price,
'amount': trade_amount
}
Log('Return order book dictionary:', trade_dict)
return trade_dict
else:
self.pending_order_count = 0 # Reset pending order count
Based on the generated order book dictionary, execute order book trading. The code simultaneously places buy and sell orders by calling the create_order method of the exchange middleware layer.
def make_trade_by_dict(self, trade_dict):
if trade_dict['do_trade']:
buy_id = self.exchange_mid.create_order('buy', trade_dict['buy_price'], trade_dict['amount']) # Place Buy Order
sell_id = self.exchange_mid.create_order('sell', trade_dict['sell_price'], trade_dict['amount']) # Place Sell Order
self.traded_pairs['pan_kou'].append({
'buy_id': buy_id, 'sell_id': sell_id, 'init_time': time.time(), 'amount': trade_dict['amount']
})
Regularly check the status of orders and handle incomplete ones. The logic for processing order status is similar to the arbitrage strategy, but due to price differences, partial fills may result in actual profits or losses.
The price adjustment mechanism in this strategy is relatively simple and has the following limitations:
price_offset = price_range - self.pending_order_count * min_price_step # calculate price offset
Introduce a volatility-based dynamic price adjustment mechanism
Adjust order placement prices based on market depth and liquidity
Incorporate market trend analysis to avoid placing orders against the trend
The order book strategy faces serious inventory risk issues:
One-sided Fill Risk: When only buy or sell orders are filled, it leads to an imbalanced position
Directional Risk: In trending markets, large one-sided positions may accumulate
Capital Occupancy: Excessive inventory occupies a large amount of capital, reducing strategy efficiency
if buy_order_status['Status'] == ORDER_STATE_PENDING:
self.sell_amount += traded_pair['amount'] # Only the sell order is filled, accumulating short positions
elif sell_order_status['Status'] == ORDER_STATE_PENDING:
self.buy_amount += traded_pair['amount'] # Only the buy order is filled, accumulating long positions
Decline in Profitability: One-sided positions may incur losses when prices move unfavorably
Liquidity Pressure: Additional capital is required to hedge inventory risk
Strategy Failure: In extreme cases, the strategy may become inoperable
Inventory Limits: Set maximum position limits to prevent excessive accumulation
Dynamic Hedging: Actively close or hedge positions when inventory exceeds a threshold
Price Skewing: Adjust buy/sell prices based on current inventory to encourage offsetting trades
The order book strategy is a market-making approach based on market depth. It maintains liquidity by dynamically adjusting the price and quantity of buy and sell orders. Compared to wash-trade-based arbitrage strategies, the order book strategy has the following characteristics:
Earns true arbitrage profits from price spreads
Aligns with the traditional market maker profit model
Provides genuine market liquidity
Faces market price fluctuation risks
Requires more sophisticated risk management
Demands higher capital and technical capabilities
Inflexible price adjustment mechanism: linear price movement is hard to adapt to complex market conditions
Significant inventory risk: one-sided fills easily lead to unbalanced positions, especially in trending markets
To address the current limitations of the order book strategy, future improvements can focus on the following areas:
Dynamic Market-Making Strategies:
Adaptive price adjustment based on market volatility
Dynamic order placement adjustment using order book depth
Incorporate machine learning to predict market direction
Inventory Management Strategies:
Real-time inventory monitoring and risk assessment
Dynamic hedging mechanisms and inventory balancing algorithms
Price skewing strategies based on inventory status
Multi-Level Market-Making:
Provide liquidity at multiple price levels simultaneously
Diversify point risk and improve overall stability
Closer to the actual operations of professional market makers
Intelligent Risk Management:
Real-time risk metric monitoring
Automatic stop-loss and risk control mechanisms
Emergency handling for abnormal market conditions
import time, json
class MidClass:
def __init__(self, exchange_instance):
'''
Initialize exchange middleware
Args:
exchange_instance: FMZ exchange structure
'''
self.init_timestamp = time.time() # Record initialization time
self.exchange = exchange_instance # Save exchange object
self.exchange_name = self.exchange.GetName() # Get exchange name
self.trading_pair = self.exchange.GetCurrency() # Get trading pair name (e.g., BTC_USDT)
def get_precision(self):
'''
Get precision information for the trading pair
Returns:
Returns dictionary containing precision information, returns None on failure
'''
symbol_code = self.exchange.GetCurrency()
ticker = self.exchange.GetTicker(symbol_code) # Required for backtesting system
exchange_info = self.exchange.GetMarkets()
data = exchange_info.get(symbol_code)
if not data:
Log("Failed to get market information", GetLastError())
return None
# Get precision information for this trading pair
self.precision_info = {
'tick_size': data['TickSize'], # Price precision
'amount_size': data['AmountSize'], # Quantity precision
'price_precision': data['PricePrecision'], # Price decimal precision
'amount_precision': data['AmountPrecision'], # Quantity decimal precision
'min_qty': data['MinQty'], # Minimum order quantity
'max_qty': data['MaxQty'] # Maximum order quantity
}
return self.precision_info
def get_account(self):
'''
Get account information
Returns:
Returns True if information retrieved successfully, False if failed
'''
self.balance = '---' # Account balance
self.amount = '---' # Account position
self.frozen_balance = '---' # Frozen balance
self.frozen_stocks = '---' # Frozen position
self.init_balance = None
self.init_stocks = None
self.init_equity = None
try:
account_info = self.exchange.GetAccount() # Get account information
self.balance = account_info['Balance'] # Update account balance
self.amount = account_info['Stocks'] # Update position
self.frozen_balance = account_info['FrozenBalance'] # Update frozen balance
self.frozen_stocks = account_info['FrozenStocks'] # Update frozen position
self.equity = self.balance + self.frozen_balance + (self.amount + self.frozen_stocks) * self.last_price
if not self.init_balance or not self.init_stocks or not self.init_equity:
if _G("init_balance") and _G("init_balance") > 0 and _G("init_stocks") and _G("init_stocks") > 0:
self.init_balance = round(_G("init_balance"), 2)
self.init_stocks = round(_G("init_stocks"), 2)
self.init_equity = round(_G("init_equity"), 2)
else:
self.init_balance = round(self.balance + self.frozen_balance, 2)
self.init_stocks = self.amount + self.frozen_stocks
self.init_equity = round(self.init_balance + (self.init_stocks * self.last_price), 2)
_G("init_balance", self.init_balance)
_G("init_stocks", self.init_stocks)
_G("init_equity", self.init_equity)
Log('Get initial equity', self.init_equity)
self.profit = self.equity - self.init_equity
self.profitratio = round((self.equity - self.init_equity)/self.init_equity, 4) * 100
return True
except:
return False # Failed to get account information
def get_ticker(self):
'''
Get market price information (such as best bid, best ask, high, low, etc.)
Returns:
Returns True if information retrieved successfully, False if failed
'''
self.high_price = '---' # High price
self.low_price = '---' # Low price
self.sell_price = '---' # Best ask price
self.buy_price = '---' # Best bid price
self.last_price = '---' # Last trade price
self.volume = '---' # Volume
try:
ticker_info = self.exchange.GetTicker() # Get market price information
self.high_price = ticker_info['High'] # Update high price
self.low_price = ticker_info['Low'] # Update low price
self.sell_price = ticker_info['Sell'] # Update best ask price
self.buy_price = ticker_info['Buy'] # Update best bid price
self.last_price = ticker_info['Last'] # Update last trade price
self.volume = ticker_info['Volume'] # Update volume
return True
except:
return False # Failed to get market price information
def get_depth(self):
'''
Get depth information (order book of buy and sell orders)
Returns:
Returns True if information retrieved successfully, False if failed
'''
self.ask_orders = '---' # Ask order list
self.bid_orders = '---' # Bid order list
try:
depth_info = self.exchange.GetDepth() # Get depth information
self.ask_orders = depth_info['Asks'] # Update ask order list
self.bid_orders = depth_info['Bids'] # Update bid order list
return True
except:
return False # Failed to get depth information
def get_ohlc_data(self, period=PERIOD_M5):
'''
Get K-line information
Args:
period: K-line period, PERIOD_M1 for 1 minute, PERIOD_M5 for 5 minutes, PERIOD_M15 for 15 minutes,
PERIOD_M30 for 30 minutes, PERIOD_H1 for 1 hour, PERIOD_D1 for one day.
'''
self.ohlc_data = self.exchange.GetRecords(period) # Get K-line data
def create_order(self, order_type, price, amount):
'''
Submit an order
Args:
order_type: Order type, 'buy' for buy order, 'sell' for sell order
price: Order price
amount: Order quantity
Returns:
Order ID, can be used to cancel order
'''
if order_type == 'buy':
try:
order_id = self.exchange.Buy(price, amount) # Submit buy order
except:
return False # Buy order submission failed
elif order_type == 'sell':
try:
order_id = self.exchange.Sell(price, amount) # Submit sell order
except:
return False # Sell order submission failed
return order_id # Return order ID
def get_orders(self):
'''
Get list of pending orders
Returns:
List of pending orders
'''
self.open_orders = self.exchange.GetOrders() # Get pending orders
return self.open_orders
def cancel_order(self, order_id):
'''
Cancel an order
Args:
order_id: Order ID to cancel
Returns:
Returns True if order cancellation successful, False if failed
'''
return self.exchange.CancelOrder(order_id) # Cancel order
def refresh_data(self):
'''
Refresh information (account, market price, depth, K-line)
Returns:
Returns 'refresh_data_finish!' if refresh successful, otherwise returns corresponding refresh failure message
'''
if not self.get_ticker(): # Refresh market price information
return 'false_get_ticker'
if not self.get_account(): # Refresh account information
return 'false_get_account'
if not self.get_depth(): # Refresh depth information
return 'false_get_depth'
try:
self.get_ohlc_data() # Refresh K-line information
except:
return 'false_get_K_line_info'
return 'refresh_data_finish!' # Refresh successful
class MarketMaker:
def __init__(self, mid_class):
'''
Initialize market making strategy
Args:
mid_class: Exchange middleware object
'''
self.exchange_mid = mid_class # Exchange middleware object
self.precision_info = self.exchange_mid.get_precision() # Get precision information
self.done_amount = {'pan_kou': 0} # Completed trade volume
# Fix: Correctly assign precision information
self.price_precision = self.precision_info['price_precision'] # Price precision
self.amount_precision = self.precision_info['amount_precision'] # Trade volume precision
self.traded_pairs = {'pan_kou': []} # Placed trading pairs
self.pending_orders = [] # Pending order status
self.pending_order_count = 0 # Order placement count
self.buy_amount = 0
self.sell_amount = 0
self.fee = 0
self.fee_rate = 0.08 / 100
self.chart = {
"__isStock": True,
"tooltip": {"xDateFormat": "%Y-%m-%d %H:%M:%S, %A"},
"title": {"text": "Pending Order Quantity"},
"xAxis": {"type": "datetime"},
"yAxis": {
"title": {"text": "Pending Order Quantity"},
"opposite": False
},
"series": [
{"name": "Pending Buy Volume", "id": "Pending Buy Volume", "data": []},
{"name": "Pending Sell Volume", "id": "Pending Sell Volume", "dashStyle": "shortdash", "data": []}
]
}
def refresh_data(self):
'''
Refresh data (account, market price, depth, K-line)
'''
self.exchange_mid.refresh_data() # Refresh exchange data
self.position_amount = 0 if isinstance(self.exchange_mid.amount, str) else self.exchange_mid.amount # Position amount
self.available_balance = 0 if isinstance(self.exchange_mid.balance, str) else self.exchange_mid.balance # Account balance
self.can_buy_amount = self.available_balance / float(self.exchange_mid.buy_price) # Buyable quantity
self.mid_price = (self.exchange_mid.sell_price + self.exchange_mid.buy_price) / 2 # Mid price
def make_trade_by_dict(self, trade_dict):
'''
Execute trade according to trade dictionary
Args:
trade_dict: Trade dictionary
'''
Log('4Start trading according to dictionary')
self.refresh_data() # Refresh data
if trade_dict['do_trade']:
Log('Current account funds: Coin balance: ', self.position_amount, 'Fund balance: ', self.can_buy_amount)
Log('Check position opening: Coin limit: ', self.position_amount > trade_dict['amount'], 'Fund limit: ', self.can_buy_amount > trade_dict['amount'])
if self.position_amount > trade_dict['amount'] and self.can_buy_amount > trade_dict['amount']:
buy_id = self.exchange_mid.create_order('buy', trade_dict['buy_price'], trade_dict['amount']) # Place buy order
sell_id = self.exchange_mid.create_order('sell', trade_dict['sell_price'], trade_dict['amount']) # Place sell order
self.traded_pairs['pan_kou'].append({
'buy_id': buy_id, 'sell_id': sell_id, 'init_time': time.time(), 'amount': trade_dict['amount']
})
self.last_time = time.time() # Update last trade time
def handle_pending_orders(self):
'''
Handle pending orders
'''
pending_orders = self.exchange_mid.get_orders() # Get pending orders
if len(pending_orders) > 0:
for order in pending_orders:
self.exchange_mid.cancel_order(order['Id']) # Cancel pending orders
def make_pankou_dict(self, price_range, min_price_step, trade_amount):
'''
Generate order book dictionary
Args:
price_range: Price range
min_price_step: Minimum price step
trade_amount: Trade amount per transaction
Returns:
Order book dictionary list
'''
Log('3Create order book dictionary', 'Move order book count', self.pending_order_count)
mid_price = self.mid_price # Mid price
price_offset = price_range - self.pending_order_count * min_price_step # Calculate price offset
do_trade = price_offset > 0
if do_trade:
buy_price = mid_price - price_offset # Calculate buy price
buy_price = round(buy_price, self.price_precision) # Round buy price
sell_price = mid_price + price_offset # Calculate sell price
sell_price = round(sell_price, self.price_precision) # Round sell price
trade_dict = {
'do_trade': do_trade,
'buy_price': buy_price,
'sell_price': sell_price,
'amount': trade_amount
}
Log('Return order book dictionary:', trade_dict)
return trade_dict
else:
Log('Reset move order book count:', self.pending_order_count)
self.pending_order_count = 0 # Reset move order book count
# Fix: Return None or empty dictionary when cannot trade
return None
def check_order_status(self, current_time):
'''
Check order status
Args:
current_time: Current timestamp
'''
Log('1Start order information check')
Log(self.traded_pairs['pan_kou'])
self.buy_pending = 0
self.sell_pending = 0
for traded_pair in self.traded_pairs['pan_kou'].copy():
Log('Check order:', traded_pair['buy_id'], traded_pair['sell_id'])
try:
buy_order_status = self.exchange_mid.exchange.GetOrder(traded_pair['buy_id']) # Get buy order status
sell_order_status = self.exchange_mid.exchange.GetOrder(traded_pair['sell_id']) # Get sell order status
except:
Log(traded_pair, 'Cancel')
self.exchange_mid.cancel_order(traded_pair['buy_id']) # Cancel buy order
self.exchange_mid.cancel_order(traded_pair['sell_id']) # Cancel sell order
self.traded_pairs['pan_kou'].remove(traded_pair) # Remove order
return
Log('Check order:', traded_pair['buy_id'], buy_order_status, traded_pair['sell_id'], sell_order_status, [sell_order_status['Status'], buy_order_status['Status']])
if [sell_order_status['Status'], buy_order_status['Status']] == [0, 0]:
self.buy_pending += 1
self.sell_pending += 1
if current_time % 5 == 0:
Log('Check pending orders, cancel orders (both pending)', buy_order_status['Status'], sell_order_status['Status'], current_time % 5)
self.exchange_mid.cancel_order(traded_pair['buy_id']) # Cancel buy order
self.exchange_mid.cancel_order(traded_pair['sell_id']) # Cancel sell order
self.pending_order_count += 1 # Increment move order book count
self.traded_pairs['pan_kou'].remove(traded_pair) # Remove order
elif {sell_order_status['Status'], buy_order_status['Status']} == {1, 0}:
if buy_order_status['Status'] == ORDER_STATE_PENDING:
self.buy_pending += 1
if sell_order_status['Status'] == ORDER_STATE_PENDING:
self.sell_pending += 1
if current_time % 5 == 0:
Log('Check pending orders, cancel orders (one pending)', buy_order_status['Status'], sell_order_status['Status'])
self.done_amount['pan_kou'] += traded_pair['amount'] # Update trade volume
if buy_order_status['Status'] == ORDER_STATE_PENDING:
self.sell_amount += traded_pair['amount']
self.fee += sell_order_status['Amount'] * self.fee_rate * sell_order_status['Price']
Log('Cancel this buy order, add to pending buy list', traded_pair['buy_id'])
self.exchange_mid.cancel_order(traded_pair['buy_id']) # Cancel buy order
self.pending_orders.append(['buy', buy_order_status['Status']]) # Record pending order
Log('Before clearing:', self.traded_pairs['pan_kou'])
Log('Clear id:', traded_pair)
self.traded_pairs['pan_kou'].remove(traded_pair) # Remove order
Log('After clearing:', self.traded_pairs['pan_kou'])
elif sell_order_status['Status'] == ORDER_STATE_PENDING:
self.buy_amount += traded_pair['amount']
self.fee += buy_order_status['Amount'] * self.fee_rate * buy_order_status['Price']
Log('Cancel this sell order, add to pending sell list', traded_pair['sell_id'])
self.exchange_mid.cancel_order(traded_pair['sell_id']) # Cancel sell order
self.pending_orders.append(['sell', sell_order_status['Status']]) # Record pending order
Log('Before clearing:', self.traded_pairs['pan_kou'])
Log('Clear id:', traded_pair)
self.traded_pairs['pan_kou'].remove(traded_pair) # Remove order
Log('After clearing:', self.traded_pairs['pan_kou'])
elif [sell_order_status['Status'], buy_order_status['Status']] == [1, 1]:
Log('Both orders completed')
Log('Completion status:', buy_order_status['Status'], sell_order_status['Status'], traded_pair['amount'])
self.done_amount['pan_kou'] += 2 * traded_pair['amount'] # Update trade volume
self.buy_amount += traded_pair['amount']
self.sell_amount += traded_pair['amount']
self.fee += buy_order_status['Amount'] * self.fee_rate * buy_order_status['Price']
self.fee += sell_order_status['Amount'] * self.fee_rate * sell_order_status['Price']
self.traded_pairs['pan_kou'].remove(traded_pair) # Remove order
else:
Log('Both orders in unknown status:', buy_order_status, sell_order_status)
Log('Unknown order status:', buy_order_status['Status'], sell_order_status['Status'])
Log('Unknown order information:', traded_pair)
def update_status(self):
self.exchange_mid.refresh_data()
table1 = {
"type": "table",
"title": "Account Information",
"cols": [
"Initial Capital", "Current Capital", "Order Book Buy Quantity", "Order Book Sell Quantity", "Fee Rate", "Total Profit", "Profit Rate"
],
"rows": [
[
self.exchange_mid.init_equity,
self.exchange_mid.equity,
round(self.buy_amount, 4),
round(self.sell_amount, 4),
round(self.fee, 2),
self.exchange_mid.profit,
str(self.exchange_mid.profitratio) + "%"
],
],
}
LogStatus(
f"Initialization time: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(self.exchange_mid.init_timestamp))}\n",
f"`{json.dumps(table1)}`\n",
f"Last execution time: {_D()}\n"
)
LogProfit(round(self.exchange_mid.profit, 3), '&')
def plot_pending(self):
Log('Order book pending quantity:', self.buy_pending, self.sell_pending)
self.obj_chart = Chart(self.chart)
now_time = int(time.time() * 1000)
# Update pending buy volume data
self.obj_chart.add(0, [now_time, self.buy_pending])
# Update pending sell volume data
self.obj_chart.add(1, [now_time, self.sell_pending])
def main():
'''
Main function, run market making strategy
'''
exchange.IO('simulate', True) #OKX spot simulation account
exchange.IO("trade_super_margin")
current_time = 0
target_amount = 1 # Target trade volume
price_range = 5 # Price range
min_price_step = 1 # Minimum price step
trade_amount = 0.01 # Trade amount per transaction
exchange_mid = MidClass(exchange) # Initialize exchange middleware
Log(exchange_mid.refresh_data()) # Refresh data
market_maker = MarketMaker(exchange_mid) # Initialize market making strategy
# Fix: Initialize trade_dict
trade_dict = None
while market_maker.done_amount['pan_kou'] < target_amount: # Loop until target trade volume completed
Log(market_maker.traded_pairs['pan_kou'])
market_maker.check_order_status(current_time) # Check order status
Sleep(1000) # Wait 1 second
market_maker.refresh_data() # Refresh data
if len(market_maker.traded_pairs['pan_kou']) < 1: # Price movement, order book orders cancelled, wait until all orders completed, create new order dictionary
Log('2Order book trading pair quantity less than 1')
trade_dict = market_maker.make_pankou_dict(price_range, min_price_step, trade_amount) # Generate order book dictionary
Log('New trade dictionary', trade_dict)
# Fix: Ensure trade_dict exists and is not None
if trade_dict and trade_dict.get('do_trade', False):
market_maker.make_trade_by_dict(trade_dict) # Execute trade
Log('Order book market making quantity:', market_maker.done_amount['pan_kou']) # Record trade volume
market_maker.plot_pending()
market_maker.update_status()
current_time += 1
Log(market_maker.position_amount, market_maker.can_buy_amount) # Record position amount and buyable quantity
Log('Existing orders:', exchange.GetOrders()) # Record existing orders
def onexit():
Log("Execute cleanup function")
_G("init_balance", None)
_G("init_stocks", None)
_G("init_equity", None)