mm

package
v0.0.0-...-5cc1e8b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 4, 2024 License: BlueOak-1.0.0 Imports: 28 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ArbMarketMakerConfig

type ArbMarketMakerConfig struct {
	BuyPlacements      []*ArbMarketMakingPlacement `json:"buyPlacements"`
	SellPlacements     []*ArbMarketMakingPlacement `json:"sellPlacements"`
	Profit             float64                     `json:"profit"`
	DriftTolerance     float64                     `json:"driftTolerance"`
	NumEpochsLeaveOpen uint64                      `json:"orderPersistence"`
}

ArbMarketMakerConfig is the configuration for a market maker that places orders on both sides of the DEX order book, at rates where there are profitable counter trades on a CEX order book. Whenever a DEX order is filled, the opposite trade will immediately be made on the CEX.

Each placement in BuyPlacements and SellPlacements represents an order that will be made on the DEX order book. The first placement will be placed at a rate closest to the CEX mid-gap, and each subsequent one will get farther.

The bot calculates the extrema rate on the CEX order book where it can buy or sell the quantity of lots specified in the placement multiplied by the multiplier amount. This will be the rate of the expected counter trade. The bot will then place an order on the DEX order book where if both trades are filled, the bot will earn the profit specified in the configuration.

The multiplier is important because it ensures that even if some of the trades closest to the mid-gap on the CEX order book are filled before the bot's orders on the DEX are matched, the bot will still be able to earn the expected profit.

Consider the following example:

Market:
	DCR/BTC, lot size = 10 DCR.

Sell Placements:
	1. { Lots: 1, Multiplier: 1.5 }
	2. { Lots 1, Multiplier: 1.0 }

 Profit:
   0.01 (1%)

CEX Asks:
	1. 10 DCR @ .005 BTC/DCR
	2. 10 DCR @ .006 BTC/DCR
	3. 10 DCR @ .007 BTC/DCR

For the first placement, the bot will find the rate at which it can buy 15 DCR (1 lot * 1.5 multiplier). This rate is .006 BTC/DCR. Therefore, it will place place a sell order at .00606 BTC/DCR (.006 BTC/DCR * 1.01).

For the second placement, the bot will go deeper into the CEX order book and find the rate at which it can buy 25 DCR. This is the previous 15 DCR used for the first placement plus the Quantity * Multiplier of the second placement. This rate is .007 BTC/DCR. Therefore it will place a sell order at .00707 BTC/DCR (.007 BTC/DCR * 1.01).

type ArbMarketMakingPlacement

type ArbMarketMakingPlacement struct {
	Lots       uint64  `json:"lots"`
	Multiplier float64 `json:"multiplier"`
}

ArbMarketMakingPlacement is the configuration for an order placement on the DEX order book based on the existing orders on a CEX order book.

type AutoRebalanceConfig

type AutoRebalanceConfig struct {
	MinBaseAmt       uint64 `json:"minBaseAmt"`
	MinBaseTransfer  uint64 `json:"minBaseTransfer"`
	MinQuoteAmt      uint64 `json:"minQuoteAmt"`
	MinQuoteTransfer uint64 `json:"minQuoteTransfer"`
}

AutoRebalanceConfig determines how the bot will automatically rebalance its assets between the CEX and DEX. If the base or quote asset dips below the minimum amount, a transfer will take place, but only if both balances can be brought above the minimum amount and the transfer amount would be above the minimum transfer amount.

type BalanceState

type BalanceState struct {
	FiatRates     map[uint32]float64     `json:"fiatRates"`
	Balances      map[uint32]*BotBalance `json:"balances"`
	InventoryMods map[uint32]int64       `json:"invMods"`
}

BalanceState contains the fiat rates and bot balances at the latest point of a run.

type BasicMarketMakingConfig

type BasicMarketMakingConfig struct {
	// GapStrategy selects an algorithm for calculating the distance from
	// the basis price to place orders.
	GapStrategy GapStrategy `json:"gapStrategy"`

	// SellPlacements is a list of order placements for sell orders.
	// The orders are prioritized from the first in this list to the
	// last.
	SellPlacements []*OrderPlacement `json:"sellPlacements"`

	// BuyPlacements is a list of order placements for buy orders.
	// The orders are prioritized from the first in this list to the
	// last.
	BuyPlacements []*OrderPlacement `json:"buyPlacements"`

	// DriftTolerance is how far away from an ideal price orders can drift
	// before they are replaced (units: ratio of price). Default: 0.1%.
	// 0 <= x <= 0.01.
	DriftTolerance float64 `json:"driftTolerance"`

	// OracleWeighting affects how the target price is derived based on external
	// market data. OracleWeighting, r, determines the target price with the
	// formula:
	//   target_price = dex_mid_gap_price * (1 - r) + oracle_price * r
	// OracleWeighting is limited to 0 <= x <= 1.0.
	// Fetching of price data is disabled if OracleWeighting = 0.
	OracleWeighting *float64 `json:"oracleWeighting"`

	// OracleBias applies a bias in the positive (higher price) or negative
	// (lower price) direction. -0.05 <= x <= 0.05.
	OracleBias float64 `json:"oracleBias"`

	// EmptyMarketRate can be set if there is no market data available, and is
	// ignored if there is market data available.
	EmptyMarketRate float64 `json:"emptyMarketRate"`
}

BasicMarketMakingConfig is the configuration for a simple market maker that places orders on both sides of the order book.

func (*BasicMarketMakingConfig) Validate

func (c *BasicMarketMakingConfig) Validate() error

type BotBalance

type BotBalance struct {
	Available uint64 `json:"available"`
	Locked    uint64 `json:"locked"`
	Pending   uint64 `json:"pending"`
	Reserved  uint64 `json:"reserved"`
}

BotBalance keeps track of the amount of funds available for a bot's use, locked to fund orders, and pending.

type BotBalanceAllocation

type BotBalanceAllocation struct {
	DEX map[uint32]uint64 `json:"dex"`
	CEX map[uint32]uint64 `json:"cex"`
}

BotBalanceAllocation is the initial allocation of funds for a bot.

type BotBalances

type BotBalances struct {
	DEX *BotBalance `json:"dex"`
	CEX *BotBalance `json:"cex"`
}

type BotCEXCfg

type BotCEXCfg struct {
	Name          string               `json:"name"`
	AutoRebalance *AutoRebalanceConfig `json:"autoRebalance"`
}

BotCEXCfg specifies the CEX that a bot uses, the initial balances that should be allocated to the bot on that CEX, and the configuration for automatically rebalancing between the CEX and DEX.

type BotConfig

type BotConfig struct {
	Host    string `json:"host"`
	BaseID  uint32 `json:"baseID"`
	QuoteID uint32 `json:"quoteID"`

	BaseWalletOptions  map[string]string `json:"baseWalletOptions"`
	QuoteWalletOptions map[string]string `json:"quoteWalletOptions"`

	// Only applicable for arb bots.
	CEXCfg *BotCEXCfg `json:"cexCfg"`

	// Alloc will be the initial balance allocation used when the bot is
	// started.
	Alloc *BotBalanceAllocation `json:"alloc"`

	// Only one of the following configs should be set
	BasicMMConfig        *BasicMarketMakingConfig `json:"basicMarketMakingConfig,omitempty"`
	SimpleArbConfig      *SimpleArbConfig         `json:"simpleArbConfig,omitempty"`
	ArbMarketMakerConfig *ArbMarketMakerConfig    `json:"arbMarketMakingConfig,omitempty"`
}

BotConfig is the configuration for a market making bot. The balance fields are the initial amounts that will be reserved to use for this bot. As the bot trades, the amounts reserved for it will be updated.

type BotInventoryDiffs

type BotInventoryDiffs struct {
	DEX map[uint32]int64 `json:"dex"`
	CEX map[uint32]int64 `json:"cex"`
}

BotInventoryDiffs is the amount of funds to add or remove from a bot's allocation.

type BotStatus

type BotStatus struct {
	Config  *BotConfig `json:"config"`
	Running bool       `json:"running"`
	// RunStats being non-nil means the bot is running.
	RunStats *RunStats `json:"runStats"`
	// Balances is the current state of balance allocation.
	Balances map[uint32]*BotBalances `json:"balances"`
}

BotStatus is state information about a configured bot.

type CEXConfig

type CEXConfig struct {
	// Name is the name of the cex.
	Name string `json:"name"`
	// APIKey is the API key for the CEX.
	APIKey string `json:"apiKey"`
	// APISecret is the API secret for the CEX.
	APISecret string `json:"apiSecret"`
}

CEXConfig is a configuration for connecting to a CEX API.

type CEXOrderEvent

type CEXOrderEvent struct {
	ID          string `json:"id"`
	Rate        uint64 `json:"rate"`
	Qty         uint64 `json:"qty"`
	Sell        bool   `json:"sell"`
	BaseFilled  uint64 `json:"baseFilled"`
	QuoteFilled uint64 `json:"quoteFilled"`
}

CEXOrderEvent represents a a cex order that a bot placed.

type CEXStatus

type CEXStatus struct {
	Config          *CEXConfig      `json:"config"`
	Connected       bool            `json:"connected"`
	ConnectionError string          `json:"connectErr"`
	Markets         []*libxc.Market `json:"markets"`
}

CEXStatus is state information about a cex.

type CfgUpdate

type CfgUpdate struct {
	Timestamp int64      `json:"timestamp"`
	Cfg       *BotConfig `json:"cfg"`
}

CfgUpdate contains a BotConfig and the timestamp the bot started to use this configuration.

type DEXOrderEvent

type DEXOrderEvent struct {
	ID           string                     `json:"id"`
	Rate         uint64                     `json:"rate"`
	Qty          uint64                     `json:"qty"`
	Sell         bool                       `json:"sell"`
	Transactions []*asset.WalletTransaction `json:"transactions"`
}

DEXOrderEvent represents a a dex order that a bot placed.

type DepositEvent

type DepositEvent struct {
	Transaction *asset.WalletTransaction `json:"transaction"`
	AssetID     uint32                   `json:"assetID"`
	CEXCredit   uint64                   `json:"cexCredit"`
}

DepositEvent represents a deposit that a bot made.

type FeeGapStats

type FeeGapStats struct {
	BasisPrice    uint64 `json:"basisPrice"`
	RemoteGap     uint64 `json:"remoteGap"`
	FeeGap        uint64 `json:"feeGap"`
	RoundTripFees uint64 `json:"roundTripFees"` // base units
}

FeeGapStats is info about market and fee state. The intepretation of the various statistics may vary slightly with bot type.

type GapStrategy

type GapStrategy string

GapStrategy is a specifier for an algorithm to choose the maker bot's target spread.

const (
	// GapStrategyMultiplier calculates the spread by multiplying the
	// break-even gap by the specified multiplier, 1 <= r <= 100.
	GapStrategyMultiplier GapStrategy = "multiplier"
	// GapStrategyAbsolute sets the spread to the rate difference.
	GapStrategyAbsolute GapStrategy = "absolute"
	// GapStrategyAbsolutePlus sets the spread to the rate difference plus the
	// break-even gap.
	GapStrategyAbsolutePlus GapStrategy = "absolute-plus"
	// GapStrategyPercent sets the spread as a ratio of the mid-gap rate.
	// 0 <= r <= 0.1
	GapStrategyPercent GapStrategy = "percent"
	// GapStrategyPercentPlus sets the spread as a ratio of the mid-gap rate
	// plus the break-even gap.
	GapStrategyPercentPlus GapStrategy = "percent-plus"
)

type LotFeeRange

type LotFeeRange struct {
	Max       *LotFees `json:"max"`
	Estimated *LotFees `json:"estimated"`
}

LotFeeRange combine the estimated and maximum LotFees.

type LotFees

type LotFees struct {
	Swap   uint64 `json:"swap"`
	Redeem uint64 `json:"redeem"`
	Refund uint64 `json:"refund"`
}

LotFees are the fees for trading one lot.

type MarketMaker

type MarketMaker struct {
	// contains filtered or unexported fields
}

MarketMaker handles the market making process. It supports running different strategies on different markets.

func NewMarketMaker

func NewMarketMaker(c clientCore, eventLogDBPath, cfgPath string, log dex.Logger) (*MarketMaker, error)

NewMarketMaker creates a new MarketMaker.

func (*MarketMaker) ArchivedRuns

func (m *MarketMaker) ArchivedRuns() ([]*MarketMakingRun, error)

ArchivedRuns returns all archived market making runs.

func (*MarketMaker) AvailableBalances

func (m *MarketMaker) AvailableBalances(mkt *MarketWithHost, alternateConfigPath *string) (dexBalances, cexBalances map[uint32]uint64, _ error)

AvailableBalances returns the available balances of assets relevant to market making on the specified market on the DEX (including fee assets), and optionally a CEX depending on the configured strategy.

func (*MarketMaker) CEXBalance

func (m *MarketMaker) CEXBalance(cexName string, assetID uint32) (*libxc.ExchangeBalance, error)

func (*MarketMaker) CEXBook

func (m *MarketMaker) CEXBook(host string, baseID, quoteID uint32) (buys, sells []*core.MiniOrder, _ error)

CEXBook generates a snapshot of the specified CEX order book.

func (*MarketMaker) Connect

func (m *MarketMaker) Connect(ctx context.Context) (*sync.WaitGroup, error)

func (*MarketMaker) MarketReport

func (m *MarketMaker) MarketReport(host string, baseID, quoteID uint32) (*MarketReport, error)

MarketReport returns information about the oracle rates on a market pair and the fiat rates of the base and quote assets.

func (*MarketMaker) RemoveBotConfig

func (m *MarketMaker) RemoveBotConfig(host string, baseID, quoteID uint32) error

RemoveConfig removes a bot config from the market making config.

func (*MarketMaker) RunLogs

func (m *MarketMaker) RunLogs(startTime int64, mkt *MarketWithHost, n uint64, refID *uint64) ([]*MarketMakingEvent, error)

RunLogs returns the event logs of a market making run. At most n events are returned, if n == 0 then all events are returned. If refID is not nil, then the events including and after refID are returned.

func (*MarketMaker) RunOverview

func (m *MarketMaker) RunOverview(startTime int64, mkt *MarketWithHost) (*MarketMakingRunOverview, error)

RunOverview returns the overview of a market making run.

func (*MarketMaker) RunningBotsStatus

func (m *MarketMaker) RunningBotsStatus() *Status

RunningBotsStatus returns the status of all currently running bots. This should be used by the CLI which may have passed in an alternate config file when starting bots.

func (*MarketMaker) StartAllBots

func (m *MarketMaker) StartAllBots(alternateConfigPath *string, appPW []byte) (err error)

StartAllBots starts all of the bots in configuration.

func (*MarketMaker) StartBot

func (m *MarketMaker) StartBot(mkt *MarketWithHost, alternateConfigPath *string, appPW []byte) (err error)

StartBot starts a market making bot.

func (*MarketMaker) Status

func (m *MarketMaker) Status() *Status

Status generates a Status for the MarketMaker. This returns the status of all bots specified in the default config file.

func (*MarketMaker) StopAllBots

func (m *MarketMaker) StopAllBots() error

StopAllBots stops all running bots.

func (*MarketMaker) StopBot

func (m *MarketMaker) StopBot(mkt *MarketWithHost) error

StopBot stops a running bot.

func (*MarketMaker) UpdateBotConfig

func (m *MarketMaker) UpdateBotConfig(updatedCfg *BotConfig) error

UpdateBotConfig updates the configuration for one of the bots.

func (*MarketMaker) UpdateCEXConfig

func (m *MarketMaker) UpdateCEXConfig(updatedCfg *CEXConfig) error

func (*MarketMaker) UpdateRunningBotCfg

func (m *MarketMaker) UpdateRunningBotCfg(cfg *BotConfig, balanceDiffs *BotInventoryDiffs, saveUpdate bool) error

UpdateRunningBotCfg updates the configuration and balance allocation for a running bot. If saveUpdate is true, the update configuration will be saved to the default config file.

func (*MarketMaker) UpdateRunningBotInventory

func (m *MarketMaker) UpdateRunningBotInventory(mkt *MarketWithHost, balanceDiffs *BotInventoryDiffs) error

UpdateRunningBotInventory updates the inventory of a running bot.

type MarketMakingConfig

type MarketMakingConfig struct {
	BotConfigs []*BotConfig `json:"botConfigs"`
	CexConfigs []*CEXConfig `json:"cexConfigs"`
}

MarketMakingConfig is the overall configuration of the market maker.

func (*MarketMakingConfig) Copy

type MarketMakingEvent

type MarketMakingEvent struct {
	ID         uint64 `json:"id"`
	TimeStamp  int64  `json:"timestamp"`
	BaseDelta  int64  `json:"baseDelta"`
	QuoteDelta int64  `json:"quoteDelta"`
	BaseFees   uint64 `json:"baseFees"`
	QuoteFees  uint64 `json:"quoteFees"`
	Pending    bool   `json:"pending"`

	// Only one of the following will be populated.
	DEXOrderEvent   *DEXOrderEvent    `json:"dexOrderEvent,omitempty"`
	CEXOrderEvent   *CEXOrderEvent    `json:"cexOrderEvent,omitempty"`
	DepositEvent    *DepositEvent     `json:"depositEvent,omitempty"`
	WithdrawalEvent *WithdrawalEvent  `json:"withdrawalEvent,omitempty"`
	UpdateConfig    *BotConfig        `json:"updateConfig,omitempty"`
	UpdateInventory *map[uint32]int64 `json:"updateInventory,omitempty"`
}

MarketMakingEvent represents an action that a market making bot takes.

type MarketMakingRun

type MarketMakingRun struct {
	StartTime int64           `json:"startTime"`
	Market    *MarketWithHost `json:"market"`
}

MarketMakingRun identifies a market making run.

type MarketMakingRunOverview

type MarketMakingRunOverview struct {
	EndTime         *int64            `json:"endTime,omitempty"`
	Cfgs            []*CfgUpdate      `json:"cfgs"`
	InitialBalances map[uint32]uint64 `json:"initialBalances"`
	FinalBalances   map[uint32]uint64 `json:"finalBalances"`
	ProfitLoss      float64           `json:"profitLoss"`
	ProfitRatio     float64           `json:"profitRatio"`
}

MarketMakingRunOverview contains information about a market making run.

type MarketReport

type MarketReport struct {
	Price         float64         `json:"price"`
	Oracles       []*OracleReport `json:"oracles"`
	BaseFiatRate  float64         `json:"baseFiatRate"`
	QuoteFiatRate float64         `json:"quoteFiatRate"`
	BaseFees      *LotFeeRange    `json:"baseFees"`
	QuoteFees     *LotFeeRange    `json:"quoteFees"`
}

MarketReport contains a market's rates on various exchanges and the fiat rates of the base/quote assets.

type MarketWithHost

type MarketWithHost struct {
	Host    string `json:"host"`
	BaseID  uint32 `json:"base"`
	QuoteID uint32 `json:"quote"`
}

MarketWithHost represents a market on a specific dex server.

func (MarketWithHost) ID

func (m MarketWithHost) ID() string

func (MarketWithHost) String

func (m MarketWithHost) String() string

type OracleReport

type OracleReport struct {
	Host     string  `json:"host"`
	USDVol   float64 `json:"usdVol"`
	BestBuy  float64 `json:"bestBuy"`
	BestSell float64 `json:"bestSell"`
}

OracleReport is a summary of a market on an exchange.

type OrderPlacement

type OrderPlacement struct {
	// Lots is the max number of lots to place at this distance from the
	// mid-gap rate. If there is not enough balance to place this amount
	// of lots, the max that can be afforded will be placed.
	Lots uint64 `json:"lots"`

	// GapFactor controls the gap width in a way determined by the GapStrategy.
	GapFactor float64 `json:"gapFactor"`
}

OrderPlacement represents the distance from the mid-gap and the amount of lots that should be placed at this distance.

type RunStats

type RunStats struct {
	InitialBalances    map[uint32]uint64      `json:"initialBalances"`
	DEXBalances        map[uint32]*BotBalance `json:"dexBalances"`
	CEXBalances        map[uint32]*BotBalance `json:"cexBalances"`
	ProfitLoss         float64                `json:"profitLoss"`
	ProfitRatio        float64                `json:"profitRatio"`
	StartTime          int64                  `json:"startTime"`
	PendingDeposits    int                    `json:"pendingDeposits"`
	PendingWithdrawals int                    `json:"pendingWithdrawals"`
	CompletedMatches   uint32                 `json:"completedMatches"`
	TradedUSD          float64                `json:"tradedUSD"`
	FeeGap             *FeeGapStats           `json:"feeGap"`
}

RunStats is a snapshot of the bot's balances and performance at a point in time.

type SimpleArbConfig

type SimpleArbConfig struct {
	// ProfitTrigger is the minimum profit before a cross-exchange trade
	// sequence is initiated. Range: 0 < ProfitTrigger << 1. For example, if
	// the ProfitTrigger is 0.01 and a trade sequence would produce a 1% profit
	// or better, a trade sequence will be initiated.
	ProfitTrigger float64 `json:"profitTrigger"`
	// MaxActiveArbs sets a limit on the number of active arbitrage sequences
	// that can be open simultaneously.
	MaxActiveArbs uint32 `json:"maxActiveArbs"`
	// NumEpochsLeaveOpen is the number of epochs an arbitrage sequence will
	// stay open if one or both of the orders were not filled.
	NumEpochsLeaveOpen uint32 `json:"numEpochsLeaveOpen"`
}

SimpleArbConfig is the configuration for an arbitrage bot that only places orders when there is a profitable arbitrage opportunity.

func (*SimpleArbConfig) Validate

func (c *SimpleArbConfig) Validate() error

type Spreader

type Spreader func(ctx context.Context, baseSymbol, quoteSymbol string, log dex.Logger) (sell, buy float64, err error)

Spreader is a function that can generate market spread data for a known exchange.

type Status

type Status struct {
	Bots  []*BotStatus          `json:"bots"`
	CEXes map[string]*CEXStatus `json:"cexes"`
}

Status is state information about the MarketMaker.

type WithdrawalEvent

type WithdrawalEvent struct {
	ID          string                   `json:"id"`
	AssetID     uint32                   `json:"assetID"`
	Transaction *asset.WalletTransaction `json:"transaction"`
	CEXDebit    uint64                   `json:"cexDebit"`
}

WithdrawalEvent represents a withdrawal that a bot made.

Directories

Path Synopsis
This code is available on the terms of the project LICENSE.md file, also available online at https://blueoakcouncil.org/license/1.0.0.
This code is available on the terms of the project LICENSE.md file, also available online at https://blueoakcouncil.org/license/1.0.0.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL