Example #1
0
/* FIXME */
void sall_command(client c) {
	dstr res = get_indices();
	dstr *fields = NULL;
	int nfield = 0, i;

	RTRIM(res);
	fields = dstr_split_len(res, dstr_length(res), ",", 1, &nfield);
	for (i = 1; i < nfield; ++i) {
		dstr pkey = dstr_new(fields[i]);
		dstr skey = dstr_new(pkey);
		dlist_t dlist;
		struct kvd *kvd;

		table_rwlock_wrlock(subscribers);
		if ((dlist = table_get_value(subscribers, pkey)) == NULL) {
			if (NEW(kvd)) {
				kvd->key = skey;
				kvd->u.dlist = dlist_new(NULL, NULL);
				dlist_insert_tail(kvd->u.dlist, c);
				dlist = dlist_new(cmpkvd, kdfree);
				dlist_insert_sort(dlist, kvd);
				table_insert(subscribers, pkey, dlist);
			} else {
				add_reply_error(c, "error allocating memory for kvd\r\n");
				dstr_free(skey);
				dstr_free(pkey);
			}
		} else {
			if (NEW(kvd)) {
				dlist_node_t node;

				kvd->key     = skey;
				kvd->u.dlist = dlist_new(NULL, NULL);
				if ((node = dlist_find(dlist, kvd)) == NULL) {
					dlist_insert_tail(kvd->u.dlist, c);
					dlist_insert_sort(dlist, kvd);
				} else {
					kdfree(kvd);
					kvd = (struct kvd *)dlist_node_value(node);
					if (dlist_find(kvd->u.dlist, c) == NULL)
						dlist_insert_tail(kvd->u.dlist, c);
				}
			} else {
				add_reply_error(c, "error allocating memory for kvd\r\n");
				dstr_free(skey);
			}
			dstr_free(pkey);
		}
		table_rwlock_unlock(subscribers);
	}
	dstr_free(res);
//--------------------------------------------------------------------------------------------------------------------
//	FIXME
//--------------------------------------------------------------------------------------------------------------------
}
Example #2
0
/* FIXME */
void u_command(client c) {
	dstr pkey, skey;
	dlist_t dlist;

	if (dstr_length(c->argv[0]) == 1) {
		add_reply_error(c, "index can't be empty\r\n");
		return;
	}
	pkey = dstr_new(c->argv[0] + 1);
	skey = dstr_new(pkey);
	if (c->argc > 1) {
		int i;

		for (i = 1; i < c->argc; ++i) {
			skey = dstr_cat(skey, ",");
			skey = dstr_cat(skey, c->argv[i]);
		}
	}
	table_rwlock_wrlock(subscribers);
	if ((dlist = table_get_value(subscribers, pkey))) {
		struct kvd *kvd;

		if (NEW(kvd)) {
			dlist_node_t node, node2;

			kvd->key = skey;
			if ((node = dlist_find(dlist, kvd))) {
				FREE(kvd);
				kvd = (struct kvd *)dlist_node_value(node);
				if ((node2 = dlist_find(kvd->u.dlist, c)))
					dlist_remove(kvd->u.dlist, node2);
				if (dlist_length(kvd->u.dlist) == 0) {
					dlist_remove(dlist, node);
					kdfree(kvd);
				}
				if (dlist_length(dlist) == 0) {
					table_remove(subscribers, pkey);
					dlist_free(&dlist);
				}
			} else
				FREE(kvd);
		} else
			add_reply_error(c, "error allocating memory for kvd");
	}
	table_rwlock_unlock(subscribers);
	dstr_free(skey);
	dstr_free(pkey);
	add_reply_string(c, "\r\n", 2);
}
Example #3
0
/* FIXME */
void uall_command(client c) {
	dstr res = get_indices();
	dstr *fields = NULL;
	int nfield = 0, i;

	RTRIM(res);
	fields = dstr_split_len(res, dstr_length(res), ",", 1, &nfield);
	for (i = 1; i < nfield; ++i) {
		dstr pkey = dstr_new(fields[i]);
		dstr skey = dstr_new(pkey);
		dlist_t dlist;

		table_rwlock_wrlock(subscribers);
		if ((dlist = table_get_value(subscribers, pkey))) {
			struct kvd *kvd;

			if (NEW(kvd)) {
				dlist_node_t node, node2;

				kvd->key = skey;
				if ((node = dlist_find(dlist, kvd))) {
					FREE(kvd);
					kvd = (struct kvd *)dlist_node_value(node);
					if ((node2 = dlist_find(kvd->u.dlist, c)))
						dlist_remove(kvd->u.dlist, node2);
					if (dlist_length(kvd->u.dlist) == 0) {
						dlist_remove(dlist, node);
						kdfree(kvd);
					}
					if (dlist_length(dlist) == 0) {
						table_remove(subscribers, pkey);
						dlist_free(&dlist);
					}
				} else
					FREE(kvd);
			} else
				add_reply_error(c, "error allocating memory for kvd");
		}
		table_rwlock_unlock(subscribers);
		dstr_free(skey);
		dstr_free(pkey);
	}
	add_reply_string(c, "\r\n", 2);
	dstr_free(res);
}
Example #4
0
static int impvbaw_exec(void *data, void *data2) {
	RAII_VAR(struct msg *, msg, (struct msg *)data, msg_decr);
	Quote *quote = (Quote *)msg->data;
	struct msgs *out = (struct msgs *)data2;
	dstr contract;
	float last;
	char *p;
	table_node_t node;

	contract = dstr_new(quote->thyquote.m_cHYDM);
	if (!strcmp(contract, "") || (fabs(quote->thyquote.m_dZXJ) <= 0.000001 &&
		fabs(quote->thyquote.m_dMRJG1) <= 0.000001 &&
		fabs(quote->thyquote.m_dMCJG1) <= 0.000001)) {
		xcb_log(XCB_LOG_WARNING, "Invalid quote: '%d,%d,%s,%.2f,%.2f,%.2f'",
			quote->thyquote.m_nTime,
			quote->m_nMSec,
			contract,
			quote->thyquote.m_dZXJ,
			quote->thyquote.m_dMRJG1,
			quote->thyquote.m_dMCJG1);
		goto end;
	}
	/* FIXME */
	if (!strncasecmp(contract, "IO", 2) || !strncasecmp(contract, "HO", 2) ||
		!strncasecmp(contract, "00", 2) || !strncasecmp(contract, "60", 2))
		goto end;
	last = quote->thyquote.m_dZXJ;
	if ((p = strrchr(contract, 'C')) == NULL)
		p = strrchr(contract, 'P');
	/* FIXME: option quote */
	if (p && p != contract && p != contract + dstr_length(contract) - 1 &&
		((*(p - 1) == '-' && *(p + 1) == '-') || (isdigit(*(p - 1)) && isdigit(*(p + 1))))) {
		dstr spotname, type, strike;
		float spot;
		struct prices *prices;
		double expiry, vol, vol2, vol3;
		struct tm lt;
		char *res;

		spotname = *(p - 1) == '-' ? dstr_new_len(contract, p - contract - 1) :
			dstr_new_len(contract, p - contract);
		type     = dstr_new_len(p, 1);
		strike   = *(p + 1) == '-' ? dstr_new_len(p + 2, contract + dstr_length(contract) - p - 2) :
			dstr_new_len(p + 1, contract + dstr_length(contract) - p - 1);
		table_rwlock_rdlock(spots);
		if ((node = table_find(spots, spotname)) == NULL) {
			table_rwlock_unlock(spots);
			dstr_free(strike);
			dstr_free(type);
			dstr_free(spotname);
			goto end;
		}
		spot = table_node_float(node);
		table_rwlock_unlock(spots);
		if (fabs(spot) <= 0.000001) {
			xcb_log(XCB_LOG_WARNING, "The price of spot '%s' be zero", spotname);
			dstr_free(strike);
			dstr_free(type);
			dstr_free(spotname);
			goto end;
		}
		table_lock(optns);
		if ((node = table_find(optns, contract)) == NULL) {
			if (NEW(prices)) {
				prices->prelast = last;
				prices->prebid1 = quote->thyquote.m_dMRJG1;
				prices->preask1 = quote->thyquote.m_dMCJG1;
				prices->prespot = spot;
				table_insert(optns, dstr_new(contract), prices);
			} else
				xcb_log(XCB_LOG_WARNING, "Error allocating memory for prices");
		} else {
			prices = (struct prices *)table_node_value(node);

			if (fabs(prices->prelast - last) <= 0.000001 &&
				fabs(prices->prebid1 - quote->thyquote.m_dMRJG1) <= 0.000001 &&
				fabs(prices->preask1 - quote->thyquote.m_dMCJG1) <= 0.000001 &&
				fabs(prices->prespot - spot) <= 0.000001) {
				table_unlock(optns);
				dstr_free(strike);
				dstr_free(type);
				dstr_free(spotname);
				goto end;
			} else {
				prices->prelast = last;
				prices->prebid1 = quote->thyquote.m_dMRJG1;
				prices->preask1 = quote->thyquote.m_dMCJG1;
				prices->prespot = spot;
			}
		}
		table_unlock(optns);
		if ((node = table_find(expiries, contract)))
			expiry = table_node_double(node);
		else {
			char *month;
			struct timeval tv;
			int diff;

			xcb_log(XCB_LOG_WARNING, "No exact expiry date for '%s'", contract);
			month = spotname + dstr_length(spotname) - 2;
			gettimeofday(&tv, NULL);
			if ((diff = atoi(month) - localtime_r(&tv.tv_sec, &lt)->tm_mon - 1) < 0)
				diff += 12;
			if (diff == 0)
				diff = 1;
			expiry = diff / 12.0;
		}
		/* FIXME: last price */
		if (fabs(last) <= 0.000001)
			vol = NAN;
		else
			vol = impv_baw(spot, atof(strike), r, r, expiry, last,
				!strcasecmp(type, "C") ? AMER_CALL : AMER_PUT);
		/* FIXME: bid price 1 */
		if (fabs(quote->thyquote.m_dMRJG1) <= 0.000001)
			vol2 = NAN;
		else if (fabs(quote->thyquote.m_dMRJG1 - last) <= 0.000001)
			vol2 = vol;
		else
			vol2 = impv_baw(spot, atof(strike), r, r, expiry, quote->thyquote.m_dMRJG1,
				!strcasecmp(type, "C") ? AMER_CALL : AMER_PUT);
		/* FIXME: ask price 1 */
		if (fabs(quote->thyquote.m_dMCJG1) <= 0.000001)
			vol3 = NAN;
		else if (fabs(quote->thyquote.m_dMCJG1 - last) <= 0.000001)
			vol3 = vol;
		else
			vol3 = impv_baw(spot, atof(strike), r, r, expiry, quote->thyquote.m_dMCJG1,
				!strcasecmp(type, "C") ? AMER_CALL : AMER_PUT);
		if ((res = ALLOC(512))) {
			time_t t = (time_t)quote->thyquote.m_nTime;
			char datestr[64];

			strftime(datestr, sizeof datestr, "%F %T", localtime_r(&t, &lt));
			snprintf(res, 512, "IMPVBAW,%s.%03d,%s|%.2f,%f,%.2f,%f,%.2f,%f,%.2f",
				datestr,
				quote->m_nMSec,
				contract,
				last,
				vol,
				quote->thyquote.m_dMRJG1,
				vol2,
				quote->thyquote.m_dMCJG1,
				vol3,
				spot);
			out2rmp(res);
			snprintf(res, 512, "IMPVBAW,%d,%d,%s,%.2f,%f,%.2f,%f,%.2f,%f,%.2f,%s,%s,%s,%f,%f,%d,0,0",
				quote->thyquote.m_nTime,
				quote->m_nMSec,
				contract,
				last,
				vol,
				quote->thyquote.m_dMRJG1,
				vol2,
				quote->thyquote.m_dMCJG1,
				vol3,
				spot,
				spotname,
				type,
				strike,
				r,
				expiry,
				quote->thyquote.m_nCJSL);
			if (out2msgs(res, out) == -1)
				FREE(res);
		} else
			xcb_log(XCB_LOG_WARNING, "Error allocating memory for result");
		dstr_free(strike);
		dstr_free(type);
		dstr_free(spotname);
	/* future quote */
	} else {
		table_rwlock_wrlock(spots);
		if ((node = table_find(spots, contract)) == NULL) {
			if ((node = table_insert_raw(spots, contract)))
				table_set_float(node, last);
		} else {
			table_set_float(node, last);
			dstr_free(contract);
		}
		table_rwlock_unlock(spots);
		return 0;
	}

end:
	dstr_free(contract);
	return 0;
}
Example #5
0
/* FIXME */
void s_command(client c) {
	dstr pkey, skey;
	int i;
	dlist_t dlist;
	struct kvd *kvd;

	if (dstr_length(c->argv[0]) == 1) {
		add_reply_error(c, "index can't be empty\r\n");
		return;
	}
	pkey = dstr_new(c->argv[0] + 1);
	skey = dstr_new(pkey);
	if (c->argc > 1)
		for (i = 1; i < c->argc; ++i) {
			skey = dstr_cat(skey, ",");
			skey = dstr_cat(skey, c->argv[i]);
		}
	table_lock(cache);
	if ((dlist = table_get_value(cache, pkey))) {
		dlist_iter_t iter = dlist_iter_new(dlist, DLIST_START_HEAD);
		dlist_node_t node;

		/* FIXME: still has room to improve */
		while ((node = dlist_next(iter))) {
			kvd = (struct kvd *)dlist_node_value(node);
			if (dstr_length(kvd->key) >= dstr_length(skey) &&
				!memcmp(kvd->key, skey, dstr_length(skey))) {
				dstr *fields = NULL;
				int nfield = 0;
				dstr res, contracts = NULL;

				fields = dstr_split_len(kvd->key, dstr_length(kvd->key), ",", 1, &nfield);
				res = dstr_new(fields[0]);
				if (nfield > 1) {
					contracts = dstr_new(fields[1]);
					for (i = 2; i < nfield; ++i) {
						contracts = dstr_cat(contracts, ",");
						contracts = dstr_cat(contracts, fields[i]);
					}
				}
				dstr_free_tokens(fields, nfield);
				fields = NULL, nfield = 0;
				fields = dstr_split_len(kvd->u.value, dstr_length(kvd->u.value),
					",", 1, &nfield);
				res = dstr_cat(res, ",");
				res = dstr_cat(res, fields[0]);
				if (contracts) {
					res = dstr_cat(res, ",");
					res = dstr_cat(res, contracts);
				}
				for (i = 1; i < nfield; ++i) {
					res = dstr_cat(res, ",");
					res = dstr_cat(res, fields[i]);
				}
				res = dstr_cat(res, "\r\n");
				pthread_spin_lock(&c->lock);
				if (!(c->flags & CLIENT_CLOSE_ASAP)) {
					if (net_try_write(c->fd, res, dstr_length(res),
						10, NET_NONBLOCK) == -1) {
						xcb_log(XCB_LOG_WARNING, "Writing to client '%p': %s",
							c, strerror(errno));
						if (++c->eagcount >= 3) {
							client_free_async(c);
							pthread_spin_unlock(&c->lock);
							dstr_free(contracts);
							dstr_free(res);
							dstr_free_tokens(fields, nfield);
							table_unlock(cache);
							dstr_free(skey);
							dstr_free(pkey);
							return;
						}
					} else if (c->eagcount)
						c->eagcount = 0;
				}
				pthread_spin_unlock(&c->lock);
				dstr_free(contracts);
				dstr_free(res);
				dstr_free_tokens(fields, nfield);
			}
		}
		dlist_iter_free(&iter);
	}
	table_unlock(cache);
	table_rwlock_wrlock(subscribers);
	if ((dlist = table_get_value(subscribers, pkey)) == NULL) {
		if (NEW(kvd)) {
			kvd->key     = skey;
			kvd->u.dlist = dlist_new(NULL, NULL);
			dlist_insert_tail(kvd->u.dlist, c);
			dlist = dlist_new(cmpkvd, kdfree);
			dlist_insert_sort(dlist, kvd);
			table_insert(subscribers, pkey, dlist);
		} else {
			add_reply_error(c, "error allocating memory for kvd\r\n");
			dstr_free(skey);
			dstr_free(pkey);
		}
	} else {
		if (NEW(kvd)) {
			dlist_node_t node;

			kvd->key     = skey;
			kvd->u.dlist = dlist_new(NULL, NULL);
			if ((node = dlist_find(dlist, kvd)) == NULL) {
				dlist_insert_tail(kvd->u.dlist, c);
				dlist_insert_sort(dlist, kvd);
			} else {
				kdfree(kvd);
				kvd = (struct kvd *)dlist_node_value(node);
				if (dlist_find(kvd->u.dlist, c) == NULL)
					dlist_insert_tail(kvd->u.dlist, c);
			}
		} else {
			add_reply_error(c, "error allocating memory for kvd\r\n");
			dstr_free(skey);
		}
		dstr_free(pkey);
	}
	table_rwlock_unlock(subscribers);
}