Example #1
0
// Handle communication for a FOK order
func fillOrKill(exg exchange.Interface, action string, amount, price float64, fillChan chan<- float64) {
	var (
		id    int64
		err   error
		order exchange.Order
	)

	// Send order
	id, err = exg.SendOrder(action, "limit", amount, price)
	if isError(err) || id == 0 {
		fillChan <- 0
		return
	}

	// Check status and cancel if necessary
	for {
		order, err = exg.GetOrderStatus(id)
		isError(err)
		if order.Status == "live" {
			_, err = exg.CancelOrder(id)
			isError(err)
		} else if order.Status == "dead" {
			break
		}
		// Continues while order status is empty
	}

	filledAmount := order.FilledAmount

	// Update position
	if action == "buy" {
		if exg.HasCryptoFee() {
			filledAmount = filledAmount * (1 - exg.Fee())
		}
		exg.SetPosition(exg.Position() + filledAmount)
	} else {
		exg.SetPosition(exg.Position() - filledAmount)
	}
	// Print to log
	log.Printf("%s trade: %s %.4f at %.4f\n", exg, action, order.FilledAmount, price)

	fillChan <- filledAmount
}
Example #2
0
// Calculate arb needed for a trade based on existing positions
func calcNeededArb(buyExg, sellExg exchange.Interface) float64 {
	// Middle between min and max
	center := (cfg.Sec.MaxArb + cfg.Sec.MinArb) / 2
	// Half distance from center to min and max
	halfDist := (cfg.Sec.MaxArb - center) / 2
	// If taking currency risk, add required premium
	if buyExg.CurrencyCode() != sellExg.CurrencyCode() {
		center += cfg.Sec.FXPremium
	}
	// Percent of max
	buyExgPct := buyExg.Position() / buyExg.MaxPos()
	sellExgPct := sellExg.Position() / sellExg.MaxPos()

	// Return required arb
	return center + buyExgPct*halfDist - sellExgPct*halfDist
}