Example #1
0
func CreateMarket(basisCoin, coin string) *Market {
	marketName := coin + "/" + basisCoin
	numMemPool := (MIN_MEMPOOL + MAX_MEMPOOL) / 2

	// First, get the maximum executed (completed) order number.
	// Any pending orders greater than this need to get re-executed.
	// NOTE: this is only an estimate. It's possible that a later order
	// was successfully processed as a new limit order,
	// but it doesn't hurt to re-process them since they have no further side effects.
	lastOrderId := LastCompletedOrderId(basisCoin, coin)

	// Load limit orders.
	bidsSlice, hasMoreBids := LoadLimitBids(basisCoin, coin, numMemPool+1, math.MaxInt64, 0, lastOrderId)
	asksSlice, hasMoreAsks := LoadLimitAsks(basisCoin, coin, numMemPool+1, 0, 0, lastOrderId)
	bids, asks := llrb.New(), llrb.New()
	for _, bid := range bidsSlice {
		bids.InsertNoReplace(llrb.Item(bid))
	}
	for _, ask := range asksSlice {
		asks.InsertNoReplace(llrb.Item(ask))
	}
	market := &Market{
		Coin:        coin,
		BasisCoin:   basisCoin,
		Bids:        bids,
		Asks:        asks,
		HasMoreBids: hasMoreBids,
		HasMoreAsks: hasMoreAsks,
		PriceLogger: &PriceLogger{Market: marketName},
	}
	// TODO: graceful continuing after server restart.
	// currently the PriceLogger is at the BasisInterval scale.
	market.PriceLogger.Initialize()

	// Process pending orders from last app shutdown.
	pendingOrders := LoadPendingOrdersSince(basisCoin, coin, lastOrderId+1)
	if len(pendingOrders) > 0 {
		Info("[%v/%v] Processing %v orders from last shutdown...", coin, basisCoin, len(pendingOrders))
		for _, order := range pendingOrders {
			market.ProcessOrder(order)
		}
		Info("[%v/%v] Done processing.", coin, basisCoin)
	}

	return market
}
Example #2
0
// Loads more bids or orders, updating .Asks/.HasMoreAsks or .Bids/.HasMoreBids.
// lastOrderId: We need this for the 'maxId' parameter of loadLimitBids/loadLimitAsks.
//              It must be the same as the result of LastCompletedOrderId()
func (market *Market) LoadMore(orderType string, lastOrderId int64) {
	if orderType == ORDER_TYPE_BID {
		// Maybe we need to load more asks.
		if market.HasMoreAsks && market.Asks.Len() < MIN_MEMPOOL {
			if market.Asks.Len() == 0 {
				panic("market.HasMoreAsks but no asks in mempool?")
			}
			moreAsks, hasMoreAsks := LoadLimitAsks(
				market.BasisCoin,
				market.Coin,
				(MAX_MEMPOOL-MIN_MEMPOOL)/2,
				market.Asks.Max().(*Order).Price,
				market.Asks.Max().(*Order).Id,
				lastOrderId,
			)
			for _, ask := range moreAsks {
				market.Asks.InsertNoReplace(llrb.Item(ask))
			}
			market.HasMoreAsks = hasMoreAsks
		}
	} else {
		// Maybe we need to load more bids.
		if market.HasMoreBids && market.Bids.Len() < MIN_MEMPOOL {
			if market.Bids.Len() == 0 {
				panic("market.HasMoreBids but no bids in mempool?")
			}
			moreBids, hasMoreBids := LoadLimitBids(
				market.BasisCoin,
				market.Coin,
				(MAX_MEMPOOL-MIN_MEMPOOL)/2,
				market.Bids.Max().(*Order).Price,
				market.Bids.Max().(*Order).Id,
				lastOrderId,
			)
			for _, bid := range moreBids {
				market.Bids.InsertNoReplace(llrb.Item(bid))
			}
			market.HasMoreBids = hasMoreBids
		}
	}
}