mango-explorer/bin/simple-marketmaker

83 lines
3.7 KiB
Plaintext
Executable File

#!/usr/bin/env pyston3
import argparse
import logging
import os
import os.path
import sys
import threading
import traceback
from datetime import timedelta
from decimal import Decimal
from threading import Thread
sys.path.insert(0, os.path.abspath(
os.path.join(os.path.dirname(__file__), "..")))
import mango # nopep8
import mango.simplemarketmaking.simplemarketmaker # nopep8
parser = argparse.ArgumentParser(description="Runs a simple market-maker.")
mango.ContextBuilder.add_command_line_parameters(parser)
mango.Wallet.add_command_line_parameters(parser)
parser.add_argument("--market", type=str, required=True, help="market symbol to buy (e.g. ETH/USDC)")
parser.add_argument("--spread-ratio", type=Decimal, required=True,
help="fraction of the mid price to be added and subtracted to calculate buy and sell prices")
parser.add_argument("--position-size-ratio", type=Decimal, required=True,
help="fraction of the token inventory to be bought or sold in each order")
parser.add_argument("--existing-order-tolerance", type=Decimal, default=Decimal("0.001"),
help="fraction of the token inventory to be bought or sold in each order")
parser.add_argument("--pause-duration", type=int, default=10,
help="number of seconds to pause between placing orders and cancelling them")
parser.add_argument("--oracle-provider", type=str, default="serum",
help="name of the oracle service providing the prices")
parser.add_argument("--account-index", type=int, default=0,
help="index of the account to use, if more than one available")
parser.add_argument("--dry-run", action="store_true", default=False,
help="runs as read-only and does not perform any transactions")
args = parser.parse_args()
logging.getLogger().setLevel(args.log_level)
logging.warning(mango.WARNING_DISCLAIMER_TEXT)
try:
context = mango.ContextBuilder.from_command_line_parameters(args)
wallet = mango.Wallet.from_command_line_parameters_or_raise(args)
group = mango.Group.load(context, context.group_id)
account = mango.Account.load_for_owner_by_index(context, wallet.address, group, args.account_index)
market_symbol = args.market.upper()
market = context.market_lookup.find_by_symbol(market_symbol)
if market is None:
raise Exception(f"Could not find spot market {market_symbol}")
market_operations: mango.MarketOperations = mango.create_market_operations(
context, wallet, account, market, args.dry_run)
oracle_provider: mango.OracleProvider = mango.create_oracle_provider(context, args.oracle_provider)
oracle = oracle_provider.oracle_for_market(context, market)
if oracle is None:
raise Exception(f"Could not find oracle for spot market {market_symbol}")
pause_duration = timedelta(seconds=args.pause_duration)
market_maker = mango.simplemarketmaking.simplemarketmaker.SimpleMarketMaker(
context, wallet, market, market_operations, oracle, args.spread_ratio, args.position_size_ratio, args.existing_order_tolerance, pause_duration)
print(f"Starting {market_maker} - use <Enter> to stop.")
thread = Thread(target=market_maker.start)
thread.start()
# Wait - don't exit. Exiting will be handled by signals/interrupts.
waiter = threading.Event()
try:
waiter.wait()
except:
pass
print(f"Stopping {market_maker} on next iteration...")
market_maker.stop()
except Exception as exception:
logging.critical(f"Market maker stopped because of exception: {exception} - {traceback.format_exc()}")
except:
logging.critical(f"Market maker stopped because of uncatchable error: {traceback.format_exc()}")