{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Streaming Data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This section is about **real-time or streaming data**."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import fxcmpy\n",
"import pandas as pd\n",
"import datetime as dt\n",
"con = fxcmpy.fxcmpy(config_file='fxcm.cfg')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Basic Approach"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Streaming the current market data is straightforward, one just need to **subscribe** to the instrument of interest."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"con.subscribe_market_data('EUR/USD')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A list with the subscribed instruments is returned by the `con.get_subscribed_symbols()` method."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['EUR/USD']"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"con.get_subscribed_symbols()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"One can also check the subscription for a specified instruments."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"con.is_subscribed('EUR/USD')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"After the subscription, `fxcmpy` collects the data in a `pandas` `DataFrame`. The `con.get_prices()` method returns that `DataFrame` object."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Bid | \n",
" Ask | \n",
" High | \n",
" Low | \n",
"
\n",
" \n",
" \n",
" \n",
" 2018-06-06 10:02:42.588 | \n",
" 1.17718 | \n",
" 1.17743 | \n",
" 1.17751 | \n",
" 1.17095 | \n",
"
\n",
" \n",
" 2018-06-06 10:02:45.767 | \n",
" 1.17717 | \n",
" 1.17743 | \n",
" 1.17751 | \n",
" 1.17095 | \n",
"
\n",
" \n",
" 2018-06-06 10:02:47.469 | \n",
" 1.17716 | \n",
" 1.17742 | \n",
" 1.17751 | \n",
" 1.17095 | \n",
"
\n",
" \n",
" 2018-06-06 10:02:47.737 | \n",
" 1.17716 | \n",
" 1.17741 | \n",
" 1.17751 | \n",
" 1.17095 | \n",
"
\n",
" \n",
" 2018-06-06 10:02:53.435 | \n",
" 1.17716 | \n",
" 1.17742 | \n",
" 1.17751 | \n",
" 1.17095 | \n",
"
\n",
" \n",
" 2018-06-06 10:02:54.864 | \n",
" 1.17718 | \n",
" 1.17742 | \n",
" 1.17751 | \n",
" 1.17095 | \n",
"
\n",
" \n",
" 2018-06-06 10:02:56.277 | \n",
" 1.17719 | \n",
" 1.17742 | \n",
" 1.17751 | \n",
" 1.17095 | \n",
"
\n",
" \n",
" 2018-06-06 10:02:57.461 | \n",
" 1.17719 | \n",
" 1.17744 | \n",
" 1.17751 | \n",
" 1.17095 | \n",
"
\n",
" \n",
" 2018-06-06 10:03:20.470 | \n",
" 1.17720 | \n",
" 1.17744 | \n",
" 1.17751 | \n",
" 1.17095 | \n",
"
\n",
" \n",
" 2018-06-06 10:03:21.441 | \n",
" 1.17720 | \n",
" 1.17745 | \n",
" 1.17751 | \n",
" 1.17095 | \n",
"
\n",
" \n",
" 2018-06-06 10:03:23.930 | \n",
" 1.17721 | \n",
" 1.17746 | \n",
" 1.17751 | \n",
" 1.17095 | \n",
"
\n",
" \n",
" 2018-06-06 10:03:27.619 | \n",
" 1.17722 | \n",
" 1.17747 | \n",
" 1.17751 | \n",
" 1.17095 | \n",
"
\n",
" \n",
" 2018-06-06 10:03:32.414 | \n",
" 1.17721 | \n",
" 1.17747 | \n",
" 1.17751 | \n",
" 1.17095 | \n",
"
\n",
" \n",
" 2018-06-06 10:03:34.200 | \n",
" 1.17721 | \n",
" 1.17746 | \n",
" 1.17751 | \n",
" 1.17095 | \n",
"
\n",
" \n",
" 2018-06-06 10:03:35.389 | \n",
" 1.17721 | \n",
" 1.17745 | \n",
" 1.17751 | \n",
" 1.17095 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Bid Ask High Low\n",
"2018-06-06 10:02:42.588 1.17718 1.17743 1.17751 1.17095\n",
"2018-06-06 10:02:45.767 1.17717 1.17743 1.17751 1.17095\n",
"2018-06-06 10:02:47.469 1.17716 1.17742 1.17751 1.17095\n",
"2018-06-06 10:02:47.737 1.17716 1.17741 1.17751 1.17095\n",
"2018-06-06 10:02:53.435 1.17716 1.17742 1.17751 1.17095\n",
"2018-06-06 10:02:54.864 1.17718 1.17742 1.17751 1.17095\n",
"2018-06-06 10:02:56.277 1.17719 1.17742 1.17751 1.17095\n",
"2018-06-06 10:02:57.461 1.17719 1.17744 1.17751 1.17095\n",
"2018-06-06 10:03:20.470 1.17720 1.17744 1.17751 1.17095\n",
"2018-06-06 10:03:21.441 1.17720 1.17745 1.17751 1.17095\n",
"2018-06-06 10:03:23.930 1.17721 1.17746 1.17751 1.17095\n",
"2018-06-06 10:03:27.619 1.17722 1.17747 1.17751 1.17095\n",
"2018-06-06 10:03:32.414 1.17721 1.17747 1.17751 1.17095\n",
"2018-06-06 10:03:34.200 1.17721 1.17746 1.17751 1.17095\n",
"2018-06-06 10:03:35.389 1.17721 1.17745 1.17751 1.17095"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"con.get_prices('EUR/USD')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can also fetch only the last available quotes via `con.get_last_price()`."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Bid 1.17729\n",
"Ask 1.17754\n",
"High 1.17756\n",
"Low 1.17095\n",
"Name: 2018-06-06 10:05:03.066000, dtype: float64"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"con.get_last_price('EUR/USD')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To prevent the resulting `DataFrame` from growing too large, the number of entries can be limited by the class attribute `max_prices`. It is set to 10,000 by default. "
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"10000"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"con.get_max_prices()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can change the value of `max_prices` with `set_prices()`. "
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"con.set_max_prices(1000)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" `None` as value for max_prices means that there is no limit for the number of prices in the `DataFrame`. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To stop the stream and delete (!) the `DataFrame`, use `con.unsubscribe_market_data()`."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"con.unsubscribe_market_data('EUR/USD')"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Bid | \n",
" Ask | \n",
" High | \n",
" Low | \n",
"
\n",
" \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
"Empty DataFrame\n",
"Columns: [Bid, Ask, High, Low]\n",
"Index: []"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"con.get_prices('EUR/USD')"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"## Callback Functions"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"One can add an iterable (e.g. `tuple` or `list` object) with **callback functions** to the subscription, as in the example below.\n",
"\n",
"The function `print_data()` simply prints selected quotes as soon as they are retrieved."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def print_data(data, dataframe):\n",
" print('%3d | %s | %s, %s, %s, %s, %s' \n",
" % (len(dataframe), data['Symbol'], \n",
" pd.to_datetime(int(data['Updated']), unit='ms'), \n",
" data['Rates'][0], data['Rates'][1], data['Rates'][2],\n",
" data['Rates'][3]))"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 1 | EUR/USD | 2018-06-06 10:06:29.800000, 1.17725, 1.17749, 1.17756, 1.17095\n",
" 2 | EUR/USD | 2018-06-06 10:06:34.421000, 1.17725, 1.17748, 1.17756, 1.17095\n"
]
}
],
"source": [
"con.subscribe_market_data('EUR/USD', (print_data,))"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"con.unsubscribe_market_data('EUR/USD')"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"con.close()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}