コード例 #1
0
ファイル: fast_book.c プロジェクト: carrot-garden/libtrading
static int apply_snapshot(struct fast_book_set *set, struct fast_book *dst, struct fast_message *msg)
{
	struct fast_sequence *seq;
	struct fast_field *field;
	struct fast_message *md;
	struct fast_book *book;
	int i;

	field = fast_get_field(msg, "SecurityID");
	if (!field || field_state_empty(field))
		goto fail;

	book = fast_book_find(set, field->uint_value);
	if (!book || book_has_flags(book, FAST_BOOK_ACTIVE))
		goto done;

	if (dst && dst->secid != book->secid)
		goto done;

	field = fast_get_field(msg, "MDEntries");
	if (!field || field_state_empty(field))
		goto fail;

	seq = field->ptr_value;
	if (field_state_empty(&seq->length))
		goto fail;

	field = fast_get_field(msg, "RptSeq");
	if (!field || field_state_empty(field))
		goto fail;

	book->rptseq = field->uint_value;

	book_clear_flags(book, FAST_BOOK_EMPTY);
	book_add_mask(set, book);

	for (i = 1; i <= seq->length.uint_value; i++) {
		md = seq->elements + i;

		if (md_snapshot(book, md))
			goto fail;
	}

	if (!fast_book_is_valid(book)) {
		if (!book_has_flags(book, FAST_BOOK_EMPTY))
			goto fail;
	} else {
		book_add_flags(book, FAST_BOOK_ACTIVE);
	}

done:
	return 0;

fail:
	return -1;
}
コード例 #2
0
ファイル: fast_book.c プロジェクト: carrot-garden/libtrading
static int fast_books_recover(struct fast_book_set *set)
{
	struct fast_book *book;
	struct fast_feed *feed;
	int i;

retry:
	set->inc_gap_mode = false;
	set->inc_msg_num = 0;

	for (i = 0; i < set->inc_feeds_num; i++) {
		feed = set->inc_feeds + i;
		feed->recv_num = 0;
	}

	for (i = 0; i < set->books_num; i++) {
		book = set->books + i;

		book_clear_flags(book, FAST_BOOK_ACTIVE);
	}

	for (i = 0; i < set->books_num; i++) {
		book = set->books + i;

		if (!book_has_flags(book, FAST_BOOK_SUBSCRIBED))
			continue;

		if (fast_books_join(set, book))
			goto retry;
	}

	return 0;
}
コード例 #3
0
ファイル: fast_book.c プロジェクト: carrot-garden/libtrading
static bool fast_book_is_valid(struct fast_book *book)
{
	if (book_has_flags(book, FAST_BOOK_EMPTY))
		return false;

	return order_book_is_valid(&book->ob);
}
コード例 #4
0
ファイル: fast_book.c プロジェクト: carrot-garden/libtrading
static int fast_books_join(struct fast_book_set *set, struct fast_book *book)
{
	struct fast_message *inc_buf = NULL;
	struct fast_message *tmp_buf;
	struct fast_field *field;
	struct fast_message *msg;
	unsigned long size = 32;
	unsigned long pos = 0;
	u64 last_msg_seq_num;
	u64 msg_seq_num = 0;
	unsigned long i;

	if (fast_feed_open(set->snp_feeds))
		goto fail;

	inc_buf = calloc(size, sizeof(struct fast_message));
	if (!inc_buf)
		goto fail;

	book_clear_flags(book, FAST_BOOK_ACTIVE);

	while (!book_has_flags(book, FAST_BOOK_ACTIVE)) {
		if (next_increment(set, &msg))
			goto fail;

		if (!msg)
			continue;

		if (apply_increment(set, NULL, msg))
			goto fail;

		if (pos >= size) {
			size *= 2;

			tmp_buf = realloc(inc_buf, size * sizeof(struct fast_message));
			if (!tmp_buf)
				goto fail;

			inc_buf = tmp_buf;
		}

		if (fast_message_copy(inc_buf + pos, msg)) {
			goto fail;
		} else
			pos++;

		if (!msg_seq_num) {
			field = fast_get_field(msg, "MsgSeqNum");

			if (!field || field_state_empty(field))
				goto fail;

			msg_seq_num = field->uint_value;
		}

		if (next_snapshot(set, &msg))
			goto fail;

		if (!msg)
			continue;

		field = fast_get_field(msg, "LastMsgSeqNumProcessed");
		if (!field || field_state_empty(field))
			goto fail;

		last_msg_seq_num = field->uint_value;

		if (last_msg_seq_num < msg_seq_num)
			continue;

		if (apply_snapshot(set, book, msg))
			goto fail;
	}

	if (!pos)
		goto fail;

	for (i = 0; i < pos; i++) {
		msg = inc_buf + i;

		field = fast_get_field(msg, "MsgSeqNum");
		if (!field || field_state_empty(field))
			goto fail;

		msg_seq_num = field->uint_value;

		if (msg_seq_num <= last_msg_seq_num)
			continue;

		if (apply_increment(set, book, msg))
			goto fail;
	}

	if (fast_feed_close(set->snp_feeds))
		goto fail;

	fast_message_free(inc_buf, pos);

	return 0;

fail:
	fast_feed_close(set->snp_feeds);
	fast_message_free(inc_buf, pos);

	return -1;
}
コード例 #5
0
ファイル: fast_book.c プロジェクト: JerJohn15/libtrading
static int fast_books_join(struct fast_book_set *set, struct fast_book *book)
{
	struct fast_message *inc_msg = NULL;
	struct fast_message *snp_msg = NULL;
	bool snp_received = false;
	struct fast_field *field;
	struct fast_book *sbook;
	struct ob_level *level;
	struct ob_order order;
	u64 last_msg_seq_num;
	u64 msg_num_init = 0;
	u64 msg_num_cur = 0;
	GList *list;

	if (fast_feed_open(set->snp_feeds))
		goto fail;

	book_clear_flags(book, FAST_BOOK_ACTIVE);
	book_add_flags(book, FAST_BOOK_JOIN);

	while (!book_has_flags(book, FAST_BOOK_ACTIVE)) {
		if (next_increment(set, &inc_msg))
			goto fail;

		if (inc_msg) {
			if (apply_increment(set, NULL, inc_msg))
				goto fail;

			field = fast_get_field(inc_msg, "MsgSeqNum");

			if (!field || field_state_empty(field))
				goto fail;

			msg_num_cur = field->uint_value;

			if (!msg_num_init)
				msg_num_init = msg_num_cur;
		}

		if (!snp_received) {
			if (next_snapshot(set, &snp_msg))
				goto fail;
		}

		if (snp_msg) {
			field = fast_get_field(snp_msg, "SecurityID");
			if (field) {
				if (field_state_empty(field))
					goto fail;

				sbook = fast_book_by_id(set, field->uint_value);
				if (!sbook || book->secid != sbook->secid)
					continue;
			} else {
				field = fast_get_field(snp_msg, "Symbol");
				if (!field || field_state_empty(field))
					goto fail;

				sbook = fast_book_by_symbol(set, field->string_value);
				if (!sbook || strcmp(sbook->symbol, book->symbol))
					continue;
			}

			field = fast_get_field(snp_msg, "LastMsgSeqNumProcessed");
			if (!field || field_state_empty(field))
				goto fail;

			last_msg_seq_num = field->uint_value;

			if (!msg_num_init)
				continue;

			if (last_msg_seq_num < msg_num_init)
				continue;

			snp_received = true;

			if (last_msg_seq_num > msg_num_cur)
				continue;

			if (apply_snapshot(set, book, snp_msg))
				goto fail;

			if (book_has_flags(book, FAST_BOOK_EMPTY))
				snp_received = false;
		}
	}

	order.buy = false;
	list = g_list_first(book->ob.glasks);
	while (list) {
		level = g_list_nth_data(list, 0);
		list = g_list_next(list);

		if (!level->size) {
			order.price = level->price;

			if (ob_level_delete(&book->ob, &order))
				goto fail;
		}
	}

	order.buy = true;
	list = g_list_first(book->ob.glbids);
	while (list) {
		level = g_list_nth_data(list, 0);
		list = g_list_next(list);

		if (!level->size) {
			order.price = level->price;

			if (ob_level_delete(&book->ob, &order))
				goto fail;
		}
	}

	book_clear_flags(book, FAST_BOOK_JOIN);

	if (fast_feed_close(set->snp_feeds))
		goto fail;

	return 0;

fail:
	fast_feed_close(set->snp_feeds);

	return -1;
}
コード例 #6
0
ファイル: fast_book.c プロジェクト: JerJohn15/libtrading
static int md_increment(struct fast_book *book, struct fast_message *msg)
{
	struct fast_decimal price;
	struct fast_field *field;
	struct ob_order order;
	char type;
	i64 size;

	field = fast_get_field(msg, "MDEntryType");
	if (!field || field_state_empty(field))
		goto fail;

	type = field->string_value[0];
	if (type == '0') {
		order.buy = true;
	} else if (type == '1') {
		order.buy = false;
	} else if (type == 'J') {
		book_add_flags(book, FAST_BOOK_EMPTY);
		goto exit;
	} else {
		goto fail;
	}

	field = fast_get_field(msg, "MDEntrySize");
	if (!field || field_state_empty(field))
		goto fail;

	switch (field->type) {
	case FAST_TYPE_INT:
		size = field->int_value;
		break;
	case FAST_TYPE_DECIMAL:
		if (decimal_to_int(&field->decimal_value, &size))
			goto fail;
		break;
	case FAST_TYPE_UINT:
	case FAST_TYPE_STRING:
	case FAST_TYPE_VECTOR:
	case FAST_TYPE_SEQUENCE:
	default:
		goto fail;
	}

	field = fast_get_field(msg, "MDEntryPx");
	if (!field || field_state_empty(field))
		goto fail;

	price = field->decimal_value;
	if (price_align(&price, &book->tick))
		goto fail;

	order.seq_num = book->rptseq;
	order.price = price.mnt;
	order.size = size;

	field = fast_get_field(msg, "MDUpdateAction");
	if (!field || field_state_empty(field))
		goto fail;

	if (field->uint_value == 0) {
		if (ob_level_modify(&book->ob, &order))
			goto fail;
	} else if (field->uint_value == 1) {
		if (ob_level_modify(&book->ob, &order))
			goto fail;
	} else if (field->uint_value == 2) {
		if (book_has_flags(book, FAST_BOOK_ACTIVE)) {
			if (ob_level_delete(&book->ob, &order))
				goto fail;
		} else {
			order.size = 0;
			if (ob_level_modify(&book->ob, &order))
				goto fail;
		}
	} else {
		goto fail;
	}

exit:
	return 0;

fail:
	return -1;
}
コード例 #7
0
ファイル: fast_book.c プロジェクト: JerJohn15/libtrading
static int apply_snapshot(struct fast_book_set *set, struct fast_book *dst, struct fast_message *msg)
{
	struct fast_sequence *seq;
	struct fast_field *field;
	struct fast_message *md;
	struct fast_book *book;
	int i;

	field = fast_get_field(msg, "SecurityID");
	if (field) {
		if (field_state_empty(field))
			goto fail;

		book = fast_book_by_id(set, field->uint_value);
		if (!book || book_has_flags(book, FAST_BOOK_ACTIVE))
			goto done;

		if (!book_has_flags(book, FAST_BOOK_JOIN))
			goto done;

		if (dst && dst->secid != book->secid)
			goto done;
	} else {
		field = fast_get_field(msg, "Symbol");
		if (!field || field_state_empty(field))
			goto fail;

		book = fast_book_by_symbol(set, field->string_value);
		if (!book || book_has_flags(book, FAST_BOOK_ACTIVE))
			goto done;

		if (!book_has_flags(book, FAST_BOOK_JOIN))
			goto done;

		if (dst && strncmp(book->symbol, dst->symbol,
						strlen(dst->symbol)))
			goto done;
	}

	field = fast_get_field(msg, "MDEntries");
	if (!field) {
		field = fast_get_field(msg, "GroupMDEntries");
	}

	if (!field || field_state_empty(field))
		goto fail;

	seq = field->ptr_value;
	if (field_state_empty(&seq->length))
		goto fail;

	if (!seq->length.uint_value)
		goto done;

	md = seq->elements;

	field = fast_get_field(md, "TradingSessionID");
	if (field) {
		if (field_state_empty(field))
			goto fail;

		if (strncmp(book->session, field->string_value,
					strlen(book->session)))
			goto done;
	}

	field = fast_get_field(msg, "RptSeq");
	if (!field || field_state_empty(field))
		goto fail;

	book->snpseq = field->uint_value;

	book_clear_flags(book, FAST_BOOK_EMPTY);
	book_add_mask(set, book);

	for (i = 1; i <= seq->length.uint_value; i++) {
		md = seq->elements + i;

		if (md_snapshot(book, md))
			goto fail;
	}

	if (!book_has_flags(book, FAST_BOOK_EMPTY))
		book_add_flags(book, FAST_BOOK_ACTIVE);

done:
	return 0;

fail:
	return -1;
}