func main() {

	info := gofighter.TradingInfo{
		Account:      ACCOUNT,
		Venue:        VENUE,
		Symbol:       SYMBOL,
		ApiKey:       KEY,
		BaseURL:      BASE_URL,
		WebSocketURL: WS_URL,
	}

	// The market and position will be watched by 2 goroutines. In order to get info
	// back from them, we create 2 channels that we can use to request the current
	// state from them. We request the state by sending... a channel, of course.

	market_queries := make(chan chan gofighter.Market)
	go gofighter.MarketWatch(info, market_queries)

	position_queries := make(chan chan gofighter.Position)
	go gofighter.PositionWatch(info, position_queries)

	for {
		market := gofighter.GetMarket(market_queries) // Behind the scenes, this sends a channel
		// and gets the response through it.

		// The .Last member of the quote gets set to -1 if not present in the JSON from the server,
		// which usually means there is no activity yet...

		if market.Quote.Last == -1 {
			fmt.Printf("Waiting for market action to start...\n")
			time.Sleep(1 * time.Second)
			continue
		}

		pos := gofighter.GetPosition(position_queries) // This works like .GetMarket() above, but for position

		pos.Print(market.Quote.Last) // The argument here is the price to use when calculating NAV

		var order gofighter.ShortOrder
		order.OrderType = "limit"
		order.Qty = 50 + rand.Intn(50)

		// Buy if short. Sell if long. If neither, flip a coin...

		if pos.Shares > 0 || (pos.Shares == 0 && rand.Intn(2) == 0) {
			order.Direction = "sell"
			order.Price = market.Quote.Last + 50
		} else {
			order.Direction = "buy"
			order.Price = market.Quote.Last - 50
		}
		if order.Price < 0 {
			order.Price = 0
		}

		go order_and_cancel(info, order)

		time.Sleep(500 * time.Millisecond)
	}
}
func main() {

	info := gofighter.TradingInfo{
		Account:      ACCOUNT,
		Venue:        VENUE,
		Symbol:       SYMBOL,
		ApiKey:       KEY,
		BaseURL:      BASE_URL,
		WebSocketURL: WS_URL,
	}

	go quote_updater(info)

	pos := gofighter.Position{}

	move_chan := make(chan gofighter.Movement)

	for {
		Quote_MUTEX.Lock()
		localquote := UnsafeQuote
		Quote_MUTEX.Unlock()

		if localquote.Last == -1 {
			fmt.Printf("Waiting for market action to start...\n")
			time.Sleep(1 * time.Second)
			continue
		}

		lastprice := localquote.Last

	update_position:
		for {
			select {
			case move := <-move_chan:
				pos.UpdateFromMovement(move)
			default:
				break update_position
			}
		}

		pos.Print(lastprice)

		var order gofighter.ShortOrder
		order.OrderType = "limit"
		order.Qty = 50 + rand.Intn(50)
		if pos.Shares > 0 || (pos.Shares == 0 && rand.Intn(2) == 0) {
			order.Direction = "sell"
			order.Price = lastprice + 50
		} else {
			order.Direction = "buy"
			order.Price = lastprice - 50
		}
		if order.Price < 0 {
			order.Price = 0
		}

		go order_cancel_report(info, order, move_chan)

		time.Sleep(500 * time.Millisecond)
	}
}