GithubHelp home page GithubHelp logo

twelvedata / twelvedata-python Goto Github PK

View Code? Open in Web Editor NEW
367.0 15.0 53.0 12.56 MB

Twelve Data Python Client - Financial data API & WebSocket

Home Page: https://twelvedata.com

License: MIT License

Python 100.00%
technical-indicators static-charts ohlc interactive-charts matplotlib twelve-data pandas financial-data financial-analysis twelvedata

twelvedata-python's Introduction

Build Status Open Issues Latest Stable Version License

Twelve Data Python Client for financial API & WebSocket

Official python library for Twelve Data. This package supports all main features of the service:

  • Get stock, forex, cryptocurrency, ETF, and index OHLC time series.
  • Companies' profiles, financials, options, and much more fundamentals data.
  • Get over 100+ technical indicators.
  • Output data as: json, csv, pandas
  • Full support for static and dynamic charts.
  • Real-time WebSocket data stream.

API key is required. If you don't have it yet, get it by signing up here.

Installation

Use the package manager pip to install Twelve Data API library (without optional dependencies):

pip install twelvedata

Or install with pandas support:

pip install twelvedata[pandas]

Or install with pandas, matplotlib, plotly, and websocket support:

pip install twelvedata[pandas,matplotlib,plotly,websocket-client]

Usage

Supported parameters
Parameter Description Type Required
symbol stock ticker (e.g. AAPL, MSFT);
physical currency pair (e.g. EUR/USD, CNY/JPY);
digital currency pair (BTC/USD, XRP/ETH)
string yes
interval time frame: 1min, 5min, 15min, 30min, 45min, 1h, 2h, 4h, 8h, 1day, 1week, 1month string yes
apikey your personal API Key, if you don't have one - get it here string yes
exchange if symbol is traded in multiple exchanges specify the desired one, valid for both stocks and cryptocurrencies string no
mic_code Market Identifier Code (MIC) under ISO 10383 standard, valid for stocks string no
country if symbol is traded in multiple countries specify the desired one, valid for stocks string no
outputsize number of data points to retrieve int no
timezone timezone at which output datetime will be displayed, supports: UTC, Exchange or according to IANA Time Zone Database string no
start_date start date and time of sampling period, accepts yyyy-MM-dd or yyyy-MM-dd hh:mm:ss format string no
end_date end date and time of sampling period, accepts yyyy-MM-dd or yyyy-MM-dd hh:mm:ss format string no
order sorting order of the time series output, supports desc or asc string no
date Could be the exact date, e.g. 2021-10-27, or in human language today or yesterday string no

The basis for all methods is the TDClient object that takes the required apikey parameter.

Time series

  • TDClient.time_series() accepts all common parameters. Time series may be converted to several formats:
    • ts.as_json() - will return JSON array
    • ts.as_csv() - will return CSV with header
    • ts.as_pandas() - will return pandas.DataFrame
    • ts.as_url() - will return list of URLs used
from twelvedata import TDClient

# Initialize client - apikey parameter is requiered
td = TDClient(apikey="YOUR_API_KEY_HERE")

# Construct the necessary time series
ts = td.time_series(
    symbol="AAPL",
    interval="1min",
    outputsize=10,
    timezone="America/New_York",
)

# Returns pandas.DataFrame
ts.as_pandas()

Other core data endpoints:

  • Exchange rate - TDClient.exchange_rate(symbol)
  • Currency conversion - TDClient.currency_conversion(symbol, amount)
  • Quote - TDClient.quote() takes parameters as .time_series()
  • Real-time price - TDClient.price() takes parameters as .time_series()
  • End of day price - TDClient.eod() takes parameters as .time_series()

Fundamentals

All fundamentals are supported across global markets. Refer to API documentation here and find out which countries support which fundamentals by visiting this page.

  • .get_logo(symbol, exchange, country, type)
  • .get_profile(symbol, exchange, country, type)
  • .get_dividends(symbol, exchange, country, type)
  • .get_splits(symbol, exchange, country, type)
  • .get_earnings(symbol, exchange, country, type, period, outputsize, start_date, end_date)
  • .get_earnings_calendar(symbol, exchange, country, period, start_date, end_date)
  • .get_ipo_calendar(symbol, exchange, country, start_date, end_date)
  • .get_statistics(symbol, exchange, country, type)
  • .get_insider_transactions(symbol, exchange, country, type)
  • .get_income_statement(symbol, exchange, country, type, period, start_date, end_date)
  • .get_balance_sheet(symbol, exchange, country, type, period, start_date, end_date)
  • .get_cash_flow(symbol, exchange, country, type, period, start_date, end_date)
  • .get_options_expiration(symbol, exchange, country, type)
  • .get_options_chain(symbol, exchange, country, type, expiration_date, option_id, side)
  • .get_key_executives(symbol, exchange, country, type)
  • .get_institutional_holders(symbol, exchange, country, type)
  • .get_fund_holders(symbol, exchange, country, type)

Only JSON format is supported accessible via .as_json()

from twelvedata import TDClient

td = TDClient(apikey="YOUR_API_KEY_HERE")

# Get all expiration dates
expirations = td.get_options_expiration(
    symbol="AAPL",
).as_json()['dates']

# Extract only put options for the soonest expiration date
put_options = td.get_options_chain(
    symbol="AAPL",
    side="put",
    expiration_date=expirations[0]
).as_json()['puts']

print(put_options)

Technical indicators

This Python library supports all indicators implemented by Twelve Data. Full list of 100+ technical indicators may be found in API documentation.

  • Technical indicators are part of TDClient.time_series() object.
  • It shares the universal format TDClient.time_series().with_{Technical Indicator Name}, e.g. .with_bbands(), .with_percent_b(), .with_macd()
  • Indicator object accepts all parameters according to its specification in API documentation, e.g. .with_bbands() accepts: series_type, time_period, sd, ma_type. If parameter is not provided it will be set to default value.
  • Indicators may be used in arbitrary order and conjugated, e.g. TDClient.time_series().with_aroon().with_adx().with_ema()
  • By default, technical indicator will output with OHLC values. If you do not need OHLC, specify TDClient.time_series().without_ohlc()
from twelvedata import TDClient

td = TDClient(apikey="YOUR_API_KEY_HERE")
ts = td.time_series(
    symbol="ETH/BTC",
    exchange="Huobi",
    interval="5min",
    outputsize=22,
    timezone="America/New_York",
)

# Returns: OHLC, BBANDS(close, 20, 2, EMA), PLUS_DI(9), WMA(20), WMA(40)
ts.with_bbands(ma_type="EMA").with_plus_di().with_wma(time_period=20).with_wma(time_period=40).as_pandas()

# Returns: STOCH(14, 1, 3, SMA, SMA), TSF(close, 9)
ts.without_ohlc().with_stoch().with_tsf().as_json()

Batch requests

With batch requests up to 120 symbols might be returned per single API call. There are two options on how to do this:

# 1. Pass instruments symbols as a string delimited by comma (,)
ts = td.time_series(
    symbol="V, RY, AUD/CAD, BTC/USD:Huobi"
)

# 2. Pass as a list of symbols 
ts = td.time_series(
    symbol=["V", "RY", "AUD/CAD", "BTC/USD:Huobi"]
)

Important. Batch requests are only supported with .as_json() and .as_pandas() formats.

With .as_json() the output will be a dictionary with passed symbols as keys. The value will be a tuple with quotes, just the same as with a single request.

ts = td.time_series(symbol='AAPL,MSFT', interval="1min", outputsize=3)
df = ts.with_macd().with_macd(fast_period=10).with_stoch().as_json()

{
    "AAPL": ({'datetime': '2020-04-23 15:59:00', 'open': '275.23001', 'high': '275.25000', 'low': '274.92999', 'close': '275.01001', 'volume': '393317', 'macd_1': '-0.33538', 'macd_signal_1': '-0.24294', 'macd_hist_1': '-0.09244', 'macd_2': '-0.40894', 'macd_signal_2': '-0.29719', 'macd_hist_2': '-0.11175', 'slow_k': '4.52069', 'slow_d': '7.92871'}, {'datetime': '2020-04-23 15:58:00', 'open': '275.07001', 'high': '275.26999', 'low': '275.00000', 'close': '275.25000', 'volume': '177685', 'macd_1': '-0.31486', 'macd_signal_1': '-0.21983', 'macd_hist_1': '-0.09503', 'macd_2': '-0.38598', 'macd_signal_2': '-0.26925', 'macd_hist_2': '-0.11672', 'slow_k': '14.70578', 'slow_d': '6.82079'}, {'datetime': '2020-04-23 15:57:00', 'open': '275.07001', 'high': '275.16000', 'low': '275.00000', 'close': '275.07751', 'volume': '151169', 'macd_1': '-0.30852', 'macd_signal_1': '-0.19607', 'macd_hist_1': '-0.11245', 'macd_2': '-0.38293', 'macd_signal_2': '-0.24007', 'macd_hist_2': '-0.14286', 'slow_k': '4.55965', 'slow_d': '2.75237'}),
    "MSFT": ({'datetime': '2020-04-23 15:59:00', 'open': '171.59000', 'high': '171.64000', 'low': '171.22000', 'close': '171.42000', 'volume': '477631', 'macd_1': '-0.12756', 'macd_signal_1': '-0.10878', 'macd_hist_1': '-0.01878', 'macd_2': '-0.15109', 'macd_signal_2': '-0.12915', 'macd_hist_2': '-0.02193', 'slow_k': '20.95244', 'slow_d': '26.34919'}, {'datetime': '2020-04-23 15:58:00', 'open': '171.41000', 'high': '171.61000', 'low': '171.33501', 'close': '171.61000', 'volume': '209594', 'macd_1': '-0.12440', 'macd_signal_1': '-0.10408', 'macd_hist_1': '-0.02032', 'macd_2': '-0.14786', 'macd_signal_2': '-0.12367', 'macd_hist_2': '-0.02419', 'slow_k': '39.04785', 'slow_d': '23.80945'}, {'datetime': '2020-04-23 15:57:00', 'open': '171.34500', 'high': '171.48000', 'low': '171.25999', 'close': '171.39999', 'volume': '142450', 'macd_1': '-0.13791', 'macd_signal_1': '-0.09900', 'macd_hist_1': '-0.03891', 'macd_2': '-0.16800', 'macd_signal_2': '-0.11762', 'macd_hist_2': '-0.05037', 'slow_k': '19.04727', 'slow_d': '14.92063'})
}

With .as_pandas() the output will be a 3D DataFrame with MultiIndex for (symbol, datetime).

ts = td.time_series(symbol='AAPL,MSFT', interval="1min", outputsize=3)
df = ts.with_macd().with_macd(fast_period=10).with_stoch().as_pandas()

#                                open       high  ...    slow_k    slow_d
# AAPL 2020-04-23 15:59:00  275.23001  275.25000  ...   4.52069   7.92871
#      2020-04-23 15:58:00  275.07001  275.26999  ...  14.70578   6.82079
#      2020-04-23 15:57:00  275.07001  275.16000  ...   4.55965   2.75237
# MSFT 2020-04-23 15:59:00  171.59000  171.64000  ...  20.95244  26.34919
#      2020-04-23 15:58:00  171.41000  171.61000  ...  39.04785  23.80945
#      2020-04-23 15:57:00  171.34500  171.48000  ...  19.04727  14.92063
# 
# [6 rows x 13 columns]

df.loc['AAPL']

#                           open       high  ...    slow_k   slow_d
# 2020-04-23 15:59:00  275.23001  275.25000  ...   4.52069  7.92871
# 2020-04-23 15:58:00  275.07001  275.26999  ...  14.70578  6.82079
# 2020-04-23 15:57:00  275.07001  275.16000  ...   4.55965  2.75237
# 
# [3 rows x 13 columns]

df.columns

# Index(['open', 'high', 'low', 'close', 'volume', 'macd1', 'macd_signal1',
#        'macd_hist1', 'macd2', 'macd_signal2', 'macd_hist2', 'slow_k',
#        'slow_d'],
#       dtype='object')

Charts

Charts support OHLC, technical indicators and custom bars.

Static

Static charts are based on matplotlib library and require mplfinance package to be installed.

static chart example

  • Use .as_pyplot_figure()
from twelvedata import TDClient

td = TDClient(apikey="YOUR_API_KEY_HERE")
ts = td.time_series(
    symbol="MSFT",
    outputsize=75,
    interval="1day",
)

# 1. Returns OHLCV chart
ts.as_pyplot_figure()

# 2. Returns OHLCV + BBANDS(close, 20, 2, SMA) + %B(close, 20, 2 SMA) + STOCH(14, 3, 3, SMA, SMA)
ts.with_bbands().with_percent_b().with_stoch(slow_k_period=3).as_pyplot_figure()

Interactive

Interactive charts are built on top of plotly library.

interactive chart example

  • Use .as_plotly_figure().show()
from twelvedata import TDClient

td = TDClient(apikey="YOUR_API_KEY_HERE")
ts = td.time_series(
    symbol="DNR",
    outputsize=50,
    interval="1week",
)

# 1. Returns OHLCV chart
ts.as_plotly_figure()

# 2. Returns OHLCV + EMA(close, 7) + MAMA(close, 0.5, 0.05) + MOM(close, 9) + MACD(close, 12, 26, 9)
ts.with_ema(time_period=7).with_mama().with_mom().with_macd().as_plotly_figure().show()

WebSocket

With the WebSocket, a duplex communication channel with the server is established.

Make sure to have websocket_client package installed.

websocket example

Features

  • Real-time low latency stream of financial quotes.
  • You might subscribe to stocks, forex, and crypto.

Example

import time
from twelvedata import TDClient


messages_history = []


def on_event(e):
    # do whatever is needed with data
    print(e)
    messages_history.append(e)


td = TDClient(apikey="YOUR_API_KEY_HERE")
ws = td.websocket(symbols="BTC/USD", on_event=on_event)
ws.subscribe(['ETH/BTC', 'AAPL'])
ws.connect()
while True:
    print('messages received: ', len(messages_history))
    ws.heartbeat()
    time.sleep(10)

Parameters accepted by the .websocket() object:

  • symbols list of symbols to subscribe
  • on_event function that invokes when event from server is received
  • logger instance of logger, otherwise set to default
  • max_queue_size maximum size of queue, default 12000
  • log_level accepts debug or info, otherwise not set

Applicable methods on .websocket() object:

  • ws.subscribe([list of symbols]): get data from the symbols passed
  • ws.unsubscribe([list of symbols]): stop receiving data from the symbols passed
  • ws.reset(): unsubscribe from all symbols
  • ws.connect(): establish connection with WebSocket server
  • ws.disconnect(): close connection with WebSocket server
  • ws.heartbeat(): send heartbeat to server

Important. Do not forget that WebSockets are only available for Twelve Data users on the Pro plan and above. Checkout the trial here.

Advanced

Custom endpoint

This method is used to request unrepresented endpoints on this package, but which are available at Twelve Data.

endpoint = td.custom_endpoint(
    name="quote",
    symbol="AAPL",
)
endpoint.as_json()

The only required parameter is name which should be identical to the endpoint used at Twelve Data. All others can be custom and will vary according to the method.

Debugging

When the method doesn't return the desired data or throws an error, it might be helpful to understand and analyze the API query behind it. Add .as_url() to any method or chain of methods, and it will return the list of used URLs.

ts = td.time_series(
    symbol="AAPL",
    interval="1min",
    outputsize=10,
    timezone="America/New_York",
).with_bbands().with_ema()

ts.as_url()
# ['https://api.twelvedata.com/time_series?symbol=AAPL&interval=1min&outputsize=10&dp=5&timezone=America/New_York&order=desc&prepost=false&format=JSON&apikey=demo', 
# 'https://api.twelvedata.com/bbands?symbol=AAPL&interval=1min&series_type=close&time_period=20&sd=2&ma_type=SMA&outputsize=10&dp=5&timezone=America/New_York&order=desc&prepost=false&format=JSON&apikey=demo', 
# 'https://api.twelvedata.com/ema?symbol=AAPL&interval=1min&series_type=close&time_period=9&outputsize=10&dp=5&timezone=America/New_York&order=desc&prepost=false&format=JSON&apikey=demo']

API usage

This method gives an overview of the current API credits consumption.

api = td.api_usage()

Support

Visit our official website contact page or support center.

Announcements

Follow us for announcements and updates about this library.

Roadmap

  • Fundamentals
  • WebSocket
  • Batch requests
  • Custom plots coloring
  • Interactive charts (plotly)
  • Static charts (matplotlib)
  • Pandas support

Contributing

  1. Clone repo and create a new branch: $ git checkout https://github.com/twelvedata/twelvedata -b name_for_new_branch.
  2. Make changes and test.
  3. Submit Pull Request with comprehensive description of changes.

License

This package is open-sourced software licensed under the MIT license.

twelvedata-python's People

Contributors

dependabot-preview[bot] avatar dependabot[bot] avatar ericvogl-carta avatar gtors avatar midassss avatar sgacode avatar simondamberg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

twelvedata-python's Issues

[Feature Request] Add Support for Exchange in Websocket.py file subscribe function.

Is your feature request related to a problem? Please describe.

  • On subscribing to a price for a specific symbol, BSE exchange price is coming by default instead of NSE.

Describe the solution you'd like

  • While calling the subscribe function we should be able to pass the exchange to which we want to subscribe.

Describe alternatives you've considered

  • For a quick solution, we will be forking the library and adding exchange to use it in our project. But Adding the feature in the library itself will be great.

Add type= as a possible parameter to time_series [Feature Request]

Is your feature request related to a problem? Please describe.
I use the get_indices_list() function to download all the indices with their symbols. Similarly, I use the get_stocks_list() to get a list of all the equity instruments and their symbols. To download the data to populate my chart for an instrument I use time_series(symbol=symbol, exchange=exchange). To call this function for equities I can get the relevant exchange from the get_stocks_list() table. However, for indices the get_indices_list() does not return an exchange for each index symbol. So for indices I then have to bypass my time_series(symbol=symbol, exchange=exchange) call and use:
url = 'https://api.twelvedata.com/time_series'
params = {'symbol': ticker, 'type': 'Index', 'interval': '1day', 'outputsize': 150, 'apikey': key}
IndexDataRequest = requests.get(url, params=params)

And then I have to get all the values in the json into a pandas Dataframe that I can use.
DailyData = pd.DataFrame(IndexDataRequest.json()['values'])
DailyData.set_index(keys=['datetime'], inplace=True)
DailyData.index = pd.to_datetime(DailyData.index)
DailyData = DailyData.astype(dtype='float')

Describe the solution you'd like
My first prize would be if I could get the index symbol's exchange code when I request get_indices_list() because then I can just call the same function for both equities and indices - [time_series(symbol=symbol, exchange=exchange)]
As a second prize time_series(symbol=symbol, type='Index') can also make life easier.

Describe alternatives you've considered
As outlined above (using requests.get)

I can define my own function using request.get in the interim. I just think why not implement it in the Python wrapper if it is already available as an html call

Additional context

UserWarning: The argument 'infer_datetime_ format' is deprecated and will be removed in a future version. [pandas]

Hi, I seem to be getting a warning from pandas (latest version 2.0.1) when I make any request through your python API:

ts = td_client.time_series(
symbol=symbol,
interval=interval,
outputsize=outputsize,
)
timeseries_df = ts.as_pandas()

I think it probably comes from the function:
timeseries_df = ts.as_pandas()

The warning message is as follows:
C:...\site-packages\twelvedata\mixins.py:66: UserWarning: The argument 'infer_datetime_
format' is deprecated and will be removed in a future version. A strict version of it is now the default, see https://pandas.pydata.org/pdeps/0004-consistent-to-datetime-parsing.html. You can safely remove this argument.
df.index = pd.to_datetime(df.index, infer_datetime_format=True)

Even though the error is benign, the problem is that the error message renders all logs unreadable when making numerous requests.

[Bug]

file: twelvedata/websockets.py

when calling TDWebSocket.update_subscription_symbols,

if there are any symbols to be removed (line 157,158),

TDWebSocket.subscribe_event is called instead of TDWebSocket.unsubscribe_event (line 160)

[Question]websocket.TDWebSocket.keep_alive() high cpu usage

websocket.TDWebSocket.keep_alive() is simply an infinite loop, which I've assumed is to keep the main thread alive and results in high cpu usage. Does having a time.sleep() in here affect the performance of the websocket connection? I personally wouldn't think so, but I'm testing while the market is closed.

@staticmethod def keep_alive(): while True: pass

Thanks

[Bug] Duplicate dates in time_series

Describe the bug
A clear and concise description of what the bug is.

When fetching time_series data, a large majority of assets in the NASDAQ 100 and OMX Stockholm GI has duplicate values for a lot of dates, sometimes with different values. I have not tried any other exchanges.

This seems to not only be a bug with the python library, since the web requests return the same results. However, I have not been able to receive a response from the support team, so I thought I would try here as well.

To Reproduce
Some example queries

https://api.twelvedata.com/time_series?apikey=INSERTAPIKEY&interval=1day&start_date=2020-01-01 00:00:00&end_date=2020-02-01 00:00:00&symbol=AMD

https://api.twelvedata.com/time_series?apikey=INSERTAPIKEY&interval=1day&start_date=2020-01-01 00:00:00&end_date=2020-02-01 00:00:00&symbol=META

https://api.twelvedata.com/time_series?apikey=INSERTAPIKEY&interval=1day&start_date=2020-01-01 00:00:00&end_date=2020-02-01 00:00:00&symbol=ASML

Expected behavior
A time series with an interval of 1 day between each consecutive datapoint.

[Bug] Getting AttributeError while trying to import TDClient

Describe the bug
Getting an error AttributeError: module 'twelvedata.endpoints' has no attribute 'KSTEndpointLINEARREGANGLEEndpoint' while trying to import TDClient in the latest version (0.1.7)

To Reproduce
Steps to reproduce the behavior:
run in python the following code:
from twelvedata import TDClient

Expected behavior
Import TDClient

Screenshots
image

Desktop (please complete the following information):

  • OS: Linux Mint 20
  • Browser Firefox
  • Version 77.0.1

Additional context
The problem is in the endpoints.py file where there is a , missing after the attribute KTSEndpoint, also if I put it manually, I get another error of AttributeError: module 'twelvedata.endpoints' has no attribute 'WVAPEndpoint' so there's some problem with the attribute WVAPEndpoint as well

[Bug] Websocket price update events don't include mic_code

Describe the bug

Websocket price events look like this:

{"event":"price","symbol":"NSEI","currency":"INR","exchange":"NSE","type":"Index","timestamp":1675751257,"price":17739.7}

Please note that mic_code is not included. So, you can subscribe based on mic_code, and confirm that the subscription was successful based on mic_code, but you can't handle new trades/prices using mic_code.

To Reproduce

Subscribe to any instrument and observe the subsequent price events.

Expected behavior

Price update events should include mic_code...otherwise, there really is no point in using mic_code to initiate and confirm the subscription. This is important for resolving potential ambiguities with certainty since exchange names are not unique.

Additional context

Also see #61

[Bug] Technical Indicator Plotly

Hello,

I ran the 'static' (chart) example code from git without error using python 3.5.

The chart appeared in my browser.

However, the Technical Indicators are not appearing on the chart. (Compared to the image of the char on the git and pypi pages)

It seems that either there is a bug or,

Do I need to write additional code (presumably using plotly modules) in order to configure the chart to properly display the technical indicators?

I'm on Ubuntu 16.04. Using Pycharm.

I had to use ts.show_plotly() to display the chart, otherwise the chart doesn't show.

I also tried on Python3.6 and 3.7 and neither seemed to make a difference.

Thanks for your help.

Matt

websocket_client and mplfinance should be added to requirements

It's not clear that this is the library used for websockets (i.e. error thrown after import websocket). This should be mentioned in docs, setup.py or a requirements.txt file to avoid future confusion.

Otherwise very useful, thanks!

Edit: This is also the case for mplfinance.

[Bug] Weekend data (inconsistently) appearing in time_series data.

Describe the bug
When requesting time_series data, saturday/sunday candles randomly appear. (I'm assuming this is a bug server side and not python side. But not sure how to raise that).

1day: saturday candle (2022-03-05)

{'datetime': '2022-03-07', 'open': '1.32290', 'high': '1.32410', 'low': '1.31025', 'close': '1.31245'}
{'datetime': '2022-03-05', 'open': '1.32385', 'high': '1.32495', 'low': '1.32175', 'close': '1.32275'}
{'datetime': '2022-03-04', 'open': '1.33515', 'high': '1.33575', 'low': '1.32025', 'close': '1.32375'}

8hour: sunday candles appear (no saturday candle though) (2022-03-06)

{'datetime': '2022-03-06 22:00:00', 'open': '1.31995', 'high': '1.32290', 'low': '1.31415', 'close': '1.31540'}
{'datetime': '2022-03-06 14:00:00', 'open': '1.32290', 'high': '1.32410', 'low': '1.31860', 'close': '1.31990'}
{'datetime': '2022-03-04 14:00:00', 'open': '1.32385', 'high': '1.32495', 'low': '1.32175', 'close': '1.32275'}
{'datetime': '2022-03-04 06:00:00', 'open': '1.33120', 'high': '1.33170', 'low': '1.32025', 'close': '1.32375'}

To Reproduce
Steps to reproduce the behavior:

    c = TDClient(apikey=XXXX)

    td = c.time_series(
        symbol="GBP/USD",
        interval="1day",
        outputsize=10,
        timezone="UTC",
    )

Expected behavior
Data for times when the market is closed doesn't appear, or at least appears consistently.

Return type specified is not getting returned.

When I use any of the .as_...() methods, I get this back <twelvedata.time_series.TimeSeries at 0x7f7ef4e491d0> I was able to use the methods successfully once and now I am not having any luck. I checked the api_usage() and appear to be within my limits... any insight on to what is going on here?

[Bug] "values" KeyError generated in multi-index conversion

Describe the bug
An uncaught KeyError exception is generated at line 165 of twelvedata/utils.py.
The exception is about the key values missing in the dictionary data accessed at that line. The error happens when the module tries to convert the result of the call to the Twelvedata API to a pandas multi-index.

The strangest thing is that I don't experience problems until I add specific tickers to the request (See section below)

To Reproduce
Steps to reproduce the behavior:

This code causes the error:

SAMPLES = 1440
SYMBOLS = [
    "BTC/USD",
    "ETH/USD",
    "ADA/USD",
    "DOGE/USD",
    "BCH/USD"
]
EXCHANGE = "Binance"

td = TDClient(apikey=API_KEY)
ts = td.time_series(
    symbol=SYMBOLS,
    outputsize=SAMPLES,
    interval="1min",
    timezone="America/New_York",
    exchange=EXCHANGE
)
ts.as_pandas()

KeyError Traceback (most recent call last)
in
17 exchange=EXCHANGE
18 )
---> 19 ts.as_pandas()

~/.local/lib/python3.7/site-packages/twelvedata/time_series.py in as_pandas(self, **kwargs)
107
108 if self.price_endpoint_enabled:
--> 109 df = self.price_endpoint.as_pandas()
110 else:
111 df = None

~/.local/lib/python3.7/site-packages/twelvedata/mixins.py in as_pandas(self, **kwargs)
42 data = self.as_json()
43 if hasattr(self, 'is_batch') and self.is_batch:
---> 44 df = convert_collection_to_pandas_multi_index(data)
45 else:
46 df = convert_collection_to_pandas(data, **kwargs)

~/.local/lib/python3.7/site-packages/twelvedata/utils.py in convert_collection_to_pandas_multi_index(val)
163 arr = []
164 for symbol, data in val.items():
--> 165 for quote in data['values']:
166 arr.append(tuple(quote.values())[1:])
167

KeyError: 'values'

While if I remove the BCH/USD ticker, it runs smoothly:

SAMPLES = 1440
SYMBOLS = [
    "BTC/USD",
    "ETH/USD",
    "ADA/USD",
    "DOGE/USD"
]
EXCHANGE = "Binance"

td = TDClient(apikey=API_KEY)
ts = td.time_series(
    symbol=SYMBOLS,
    outputsize=SAMPLES,
    interval="1min",
    timezone="America/New_York",
    exchange=EXCHANGE
)
ts.as_pandas()

Desktop (please complete the following information):

  • OS: Ubuntu 18.04 LTS
  • Version 18.04 LTS

td.get_earnings_calendar() Response Problems

Hello,

I'm running the following command and receiving unexpected results.

In the date column the following extra characters appear:

%!(EXTRA string=)2023-01-16

Another example:

%!(EXTRA float64=5.71)2022-01-13

And this appears on the last row of the data:

%!(EXTRA string=),,,,,,,,,,

Please assist.

Thanks,

Matt

Not enough historical datapoints for MA200 for symbols that have been listed for several years

Hi, this issue is not limited to your python library. It's more generally an issue with your API.

I'm requesting MA200 for instruments listed in omxh, and several instruments that have been listed in omxh for several years return error that states there is lack of historical datapoints for MA200.

For example, enento:omxh

Works
https://api.twelvedata.com/ma?symbol=enento:omxh&interval=1day&timezone=EET&outputsize=102&time_period=102&apikey=

Doesn't work
https://api.twelvedata.com/ma?symbol=enento:omxh&interval=1day&timezone=EET&outputsize=200&time_period=200&apikey=

But I wonder why that is, as enento:omxh should have well over 200 days of datapoints, as it has been listed in omxh since 2015.

I checked the earliest timestamp for enento:omxh using

https://api.twelvedata.com/earliest_timestamp?symbol=enento:omxh&interval=1day&timezone=EET&apikey=

And it returns 2020-09-28, which explains why your system doesn't have enough datapoints for ma200 for enento. But then I should be able to do MA request with time_period of 149, right? But the max time period that works is 102.

EDIT: Ah, the time_period of 102 is the max time_period when I take the days omxh is closed (weekends) into consideration. However, is it expected behavior to have only 102 datapoints of instrument that has been listed since 2015?

[Bug] Batch request error: KeyError: 'values'

Requesting 16 stocks traded on the US exchanges returns the error: KeyError: 'values'

Requested stocks: symbols= [ 'PBFX', 'CATS', 'LIVX', 'CYRX', 'LOMA', 'CTMX', 'FVRR','REVG', 'ARYA', 'THBR', 'ECOM', 'ELMD', 'BLCM', 'GMBL', 'ACTT', 'LORL']

Expected behavior
Price data

Screenshots
TW

[Bug] Websockets does't work

There is an issue with the WebSockets package that this application uses which in turn breaks the functionality. I've attached the screenshot of the error.

image

Dependabot can't resolve your Python dependency files

Dependabot can't resolve your Python dependency files.

As a result, Dependabot couldn't update your dependencies.

The error Dependabot encountered was:

ERROR: ERROR: Could not find a version that matches mplfinance>=0.12
Skipped pre-versions: 0.11.1a0, 0.11.1a0, 0.11.1a1, 0.11.1a1, 0.12.0a0, 0.12.0a0, 0.12.0a1, 0.12.0a1, 0.12.0a2, 0.12.0a2, 0.12.0a3, 0.12.0a3, 0.12.3a0, 0.12.3a0, 0.12.3a1, 0.12.3a1, 0.12.3a2, 0.12.3a2, 0.12.3a3, 0.12.3a3, 0.12.4a0, 0.12.4a0, 0.12.5a1, 0.12.5a1, 0.12.5a2, 0.12.5a2, 0.12.5a3, 0.12.5a3, 0.12.6a0, 0.12.6a0, 0.12.6a1, 0.12.6a1, 0.12.6a2, 0.12.6a2, 0.12.6a3, 0.12.6a3, 0.12.7a0, 0.12.7a0, 0.12.7a3, 0.12.7a3, 0.12.7a4, 0.12.7a4, 0.12.7a5, 0.12.7a5, 0.12.7a7, 0.12.7a7, 0.12.7a10, 0.12.7a10, 0.12.7a12, 0.12.7a12
There are incompatible versions in the resolved dependencies.
[pipenv.exceptions.ResolutionFailure]:       return resolve_deps(
[pipenv.exceptions.ResolutionFailure]:   File "/usr/local/.pyenv/versions/3.9.4/lib/python3.9/site-packages/pipenv/utils.py", line 718, in resolve_deps
[pipenv.exceptions.ResolutionFailure]:       resolved_tree, hashes, markers_lookup, resolver = actually_resolve_deps(
[pipenv.exceptions.ResolutionFailure]:   File "/usr/local/.pyenv/versions/3.9.4/lib/python3.9/site-packages/pipenv/utils.py", line 480, in actually_resolve_deps
[pipenv.exceptions.ResolutionFailure]:       resolved_tree = resolver.resolve()
[pipenv.exceptions.ResolutionFailure]:   File "/usr/local/.pyenv/versions/3.9.4/lib/python3.9/site-packages/pipenv/utils.py", line 395, in resolve
[pipenv.exceptions.ResolutionFailure]:       raise ResolutionFailure(message=str(e))
[pipenv.exceptions.ResolutionFailure]:       pipenv.exceptions.ResolutionFailure: ERROR: ERROR: Could not find a version that matches mplfinance>=0.12
[pipenv.exceptions.ResolutionFailure]:       Skipped pre-versions: 0.11.1a0, 0.11.1a0, 0.11.1a1, 0.11.1a1, 0.12.0a0, 0.12.0a0, 0.12.0a1, 0.12.0a1, 0.12.0a2, 0.12.0a2, 0.12.0a3, 0.12.0a3, 0.12.3a0, 0.12.3a0, 0.12.3a1, 0.12.3a1, 0.12.3a2, 0.12.3a2, 0.12.3a3, 0.12.3a3, 0.12.4a0, 0.12.4a0, 0.12.5a1, 0.12.5a1, 0.12.5a2, 0.12.5a2, 0.12.5a3, 0.12.5a3, 0.12.6a0, 0.12.6a0, 0.12.6a1, 0.12.6a1, 0.12.6a2, 0.12.6a2, 0.12.6a3, 0.12.6a3, 0.12.7a0, 0.12.7a0, 0.12.7a3, 0.12.7a3, 0.12.7a4, 0.12.7a4, 0.12.7a5, 0.12.7a5, 0.12.7a7, 0.12.7a7, 0.12.7a10, 0.12.7a10, 0.12.7a12, 0.12.7a12
[pipenv.exceptions.ResolutionFailure]: Warning: Your dependencies could not be resolved. You likely have a mismatch in your sub-dependencies.
  First try clearing your dependency cache with $ pipenv lock --clear, then try the original command again.
 Alternatively, you can use $ pipenv install --skip-lock to bypass this mechanism, then run $ pipenv graph to inspect the situation.
  Hint: try $ pipenv lock --pre if it is a pre-release dependency.
ERROR: ERROR: Could not find a version that matches mplfinance>=0.12
Skipped pre-versions: 0.11.1a0, 0.11.1a0, 0.11.1a1, 0.11.1a1, 0.12.0a0, 0.12.0a0, 0.12.0a1, 0.12.0a1, 0.12.0a2, 0.12.0a2, 0.12.0a3, 0.12.0a3, 0.12.3a0, 0.12.3a0, 0.12.3a1, 0.12.3a1, 0.12.3a2, 0.12.3a2, 0.12.3a3, 0.12.3a3, 0.12.4a0, 0.12.4a0, 0.12.5a1, 0.12.5a1, 0.12.5a2, 0.12.5a2, 0.12.5a3, 0.12.5a3, 0.12.6a0, 0.12.6a0, 0.12.6a1, 0.12.6a1, 0.12.6a2, 0.12.6a2, 0.12.6a3, 0.12.6a3, 0.12.7a0, 0.12.7a0, 0.12.7a3, 0.12.7a3, 0.12.7a4, 0.12.7a4, 0.12.7a5, 0.12.7a5, 0.12.7a7, 0.12.7a7, 0.12.7a10, 0.12.7a10, 0.12.7a12, 0.12.7a12
There are incompatible versions in the resolved dependencies.

['Traceback (most recent call last):\n', '  File "/usr/local/.pyenv/versions/3.9.4/lib/python3.9/site-packages/pipenv/utils.py", line 501, in create_spinner\n    yield sp\n', '  File "/usr/local/.pyenv/versions/3.9.4/lib/python3.9/site-packages/pipenv/utils.py", line 649, in venv_resolve_deps\n    c = resolve(cmd, sp)\n', '  File "/usr/local/.pyenv/versions/3.9.4/lib/python3.9/site-packages/pipenv/utils.py", line 539, in resolve\n    sys.exit(c.return_code)\n', 'SystemExit: 1\n']

If you think the above is an error on Dependabot's side please don't hesitate to get in touch - we'll do whatever we can to fix it.

View the update logs.

[Feature Request] Use aiohttp instead of requests for asynchronous API calls

Is your feature request related to a problem? Please describe.
Twelvedata has very finicky wait times for API calls sometimes. To alleviate that, why not build the http client around an asynchronous library so that we can take advantage of async calls?

Describe the solution you'd like
Use of aiohttp or other similar libraries

Describe alternatives you've considered
No alternatives.

Additional context
N/A

[Bug] SyntaxError: invalid syntax after installing the library

I'm getting SyntaxError: invalid syntax after installing the library

Traceback (most recent call last):
File "script.py", line 1, in
import twelvedata
File "/Users/work/Library/Python/2.7/lib/python/site-packages/twelvedata/init.py", line 3, in
from .client import TDClient
File "/Users/work/Library/Python/2.7/lib/python/site-packages/twelvedata/client.py", line 2, in
from .endpoints import (
File "/Users/work/Library/Python/2.7/lib/python/site-packages/twelvedata/endpoints.py", line 113
def get_symbol(symbol) -> (str, bool):
^
SyntaxError: invalid syntax

To Reproduce
Steps to reproduce the behavior:
1- pip install twelvedata
2- in script.py: from twelvedata import TDClient
3- run python script.py

ImportError: cannot import name 'TDClient'

Hi,
I try your

from twelvedata import TDClient

and i get following Error.


ImportError Traceback (most recent call last)
~/Projekte/_work/stocks/twelvedata.py in
----> 2 from twelvedata import TDClient

~/Projekte/_work/stocks/twelvedata.py in
1 # %% pip install twelvedata[pandas,matplotlib,plotly]
----> 2 from twelvedata import TDClient
3 # Initialize client - apikey parameter is requiered
4 td = TDClient(apikey="YOUR_API_KEY_HERE")
5 # Construct the necessary time serie

ImportError: cannot import name 'TDClient' from partially initialized module 'twelvedata' (most likely due to a circular import) (...stocks/twelvedata.py)

I am using Python 3.8.7 twelvedata 1.2 and a Mac Big Sur.

Regards
Michael

[Bug] get_stock_exchanges_list not working

Describe the bug
it is not possible to call the function td.get_stock_exchanges_list()

To Reproduce
When using td.get_stock_exchanges_list() python returns:

/usr/local/lib/python3.6/dist-packages/twelvedata/client.py in get_stock_exchanges_list(self)
     44         :rtype: StockExchangesListRequestBuilder
     45         """
---> 46         return StockExchangesListRequestBuilder(ctx=self.ctx)
     47 
     48     def get_forex_pairs_list(self):

NameError: name 'StockExchangesListRequestBuilder' is not defined

Cause of the error
The reason for the error is probably because the endpoints are named differently

from .endpoints import (
    StocksListEndpoint,
    StockExchangesListEndpoint,
    ForexPairsListEndpoint,
    CryptocurrenciesListEndpoint,
    CryptocurrencyExchangesListEndpoint,
)

Further notes
The same thing seems to apply for some other endpoints.

[Question] split query example

I am struggling to query split dates. I keep getting errors even with simple arguments. Have you implemented the SplitsEndpoint API?

I tried the following but non is working:

resp = td.get_splits(symbol="AAPL", exchange="NASDAQ", country="US", type="Stock")
TypeError: init() got an unexpected keyword argument 'type'

resp = td.get_splits("AAPL")
TypeError: get_splits() takes 1 positional argument but 2 were given

Can you give an example of a split dates query?

PS: I am on the free basic version.

[Bug] Websocket responses contain the incorrect mic_code

Describe the bug

For context, my goal is to have a consistent way to talk to the API using a single string/token that maps to each supported Twelvedata instrument that is guaranteed to be the correct unique symbol. I thought the most logical way to achieve this would be to use "[symbol]:[mic_code]", but I've hit some blocks...

  1. The /timeseries endpoint does not accept [symbol]:[mic_code] as a symbol name (only [symbol]:[exchange]). Although not ideal, it's possible to work around this by using the mic_code request parameter, however. So please consider this a feature request and let me know if you'd like it on a separate ticket/issue.

  2. The websocket server provides the incorrect mic_code in the success response in at least some cases, so if you request based on symbol and mic_code, it's not possible to cleanly and accurately consume the success response and take appropriate action.

Overall, it seems to me that the 'exchange' attribute is still being used/expected where it's not safe because of the potential for ambiguity. The API supports 5 exchanges with the name 'BSE' for example, and it's not possible/feasible for an API user to anticipate when duplicates might cause problems. I actually don't really see the point of the exchange attribute in any API use case, beyond it being a bit more human-friendly, but maybe I'm missing something. mic_code will always be safer and more reliable, and it's hard to justify having 2 different ways to refer to exchanges.

To Reproduce
Steps to reproduce the behavior:

  1. Try https://api.twelvedata.com/time_series?symbol=DVN:XCNQ&interval=1day&outputsize=100&apikey=[]

  2. Subscribe to websocket updates like this:

{"action": "subscribe", "params": {"symbols": [{"symbol": "DVN", "mic_code": "XCNQ"}]}}

The response looks like this:

{"event":"subscribe-status","status":"ok","success":[{"symbol":"DVN","exchange":"CSE","mic_code":"CSE","country":"Canada","type":"Common Stock"}],"fails":null}

Please note that the mic_code in the response is 'CSE' and it should be 'XCNQ'. This problem is currently a blocker for my implementation.

Expected behavior

As above, it would be nice if the timeseries endpoint treated mic_code the same way as exchange.

More importantly, the subscribe-status response from the websocket server should include the correct mic_code value.

[Bug] Websocket Errors with Example code

Describe the bug
Using the example websocket code (replacing the API key with an actual key yields the following output repeatedly:

2020-09-30 16:16:04,108 - ws-twelvedata - ERROR - TDWebSocket ERROR: Connection is already closed.
2020-09-30 16:16:07,631 - ws-twelvedata - ERROR - TDWebSocket ERROR: Handshake status 400 Bad Request
2020-09-30 16:16:11,338 - ws-twelvedata - ERROR - TDWebSocket ERROR: Connection is already closed.
2020-09-30 16:16:14,583 - ws-twelvedata - ERROR - TDWebSocket ERROR: Connection is already closed.
2020-09-30 16:16:17,779 - ws-twelvedata - ERROR - TDWebSocket ERROR: Connection is already closed.
2020-09-30 16:16:21,011 - ws-twelvedata - ERROR - TDWebSocket ERROR: Connection is already closed.
2020-09-30 16:16:24,260 - ws-twelvedata - ERROR - TDWebSocket ERROR: Connection is already closed.
2020-09-30 16:16:27,581 - ws-twelvedata - ERROR - TDWebSocket ERROR: Connection is already closed.
2020-09-30 16:16:30,882 - ws-twelvedata - ERROR - TDWebSocket ERROR: Connection is already closed.
2020-09-30 16:16:34,175 - ws-twelvedata - ERROR - TDWebSocket ERROR: Connection is already closed.
2020-09-30 16:16:37,568 - ws-twelvedata - ERROR - TDWebSocket ERROR: Connection is already closed.
2020-09-30 16:16:40,686 - ws-twelvedata - ERROR - TDWebSocket ERROR: Connection is already closed.
2020-09-30 16:16:43,937 - ws-twelvedata - ERROR - TDWebSocket ERROR: Connection is already closed.
2020-09-30 16:16:47,286 - ws-twelvedata - ERROR - TDWebSocket ERROR: Connection is already closed.

To Reproduce
Steps to reproduce the behavior:
Using a docker container (ubuntu:latest)
Following commands were run:

apt update -y
apt upgrade -y
apt install python3 python3-pip
pip3 install twelvedata
pip3 install websocket-client
pip3 install numpy
pip3 install pandas
pip3 install mplfinance
python3 name_of_file.py

Using Python 3.8.2
Use the example code:

from twelvedata import TDClient

def on_event(e):
    # do whatever is needed with data
    print(e)
    
td = TDClient(apikey="YOUR_API_KEY_HERE")
ws = td.websocket(symbols="BTC/USD", on_event=on_event)
ws.subscribe(['ETH/BTC', 'AAPL'])
ws.connect()
ws.keep_alive()

Expected behavior
A feed of data from the websocket to be printed

Additional context
Used docker env for repeatability

[Feature Request/Bug] as_pandas() for quote endpoint

It is not clear from the documentation if as_pandas() is supported for other core endpoints than time_series since the use case is the same, and nothing regarding supported datatypes are mentioned. It would be nice to have quotes supporting as_pandas().

When calling as_pandas() on a QuoteEndpoint object, I get the following error:

Traceback (most recent call last):
  File "/opt/homebrew/Caskroom/miniforge/base/envs/api/lib/python3.9/site-packages/twelvedata/utils.py", line 147, in convert_collection_to_pandas
    return pandas.DataFrame.from_dict(val, orient="index", dtype="float")
  File "/opt/homebrew/Caskroom/miniforge/base/envs/api/lib/python3.9/site-packages/pandas/core/frame.py", line 1677, in from_dict
    return cls(data, index=index, columns=columns, dtype=dtype)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/api/lib/python3.9/site-packages/pandas/core/frame.py", line 737, in __init__
    mgr = ndarray_to_mgr(
  File "/opt/homebrew/Caskroom/miniforge/base/envs/api/lib/python3.9/site-packages/pandas/core/internals/construction.py", line 340, in ndarray_to_mgr
    values = sanitize_array(
  File "/opt/homebrew/Caskroom/miniforge/base/envs/api/lib/python3.9/site-packages/pandas/core/construction.py", line 567, in sanitize_array
    subarr = _try_cast(data, dtype, copy, raise_cast_failure)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/api/lib/python3.9/site-packages/pandas/core/construction.py", line 781, in _try_cast
    subarr = np.array(arr, dtype=dtype, copy=copy)
ValueError: could not convert string to float: 'AAPL'

[Feature Request] - Add exchange and/or mic attributes to the response from the /indices endpoint

Is your feature request related to a problem? Please describe.
This isn't directly related to the python client, but I wasn't sure where else to post it.

I’m finding that there are some inconsistencies in the Reference Data and API structure that make it difficult to work with the API in a comprehensive and ambiguity-free way.

More specifically, exchanges are not provided in the attributes in the response from the /indices endpoint, but an exchange appears to be required to resolve ambiguity in some cases. There also appears to be some inconsistency regarding when to use 'exchange' and when to use 'mic', however, since mic is unique, it seems that it should be the standard. I think 'symbol:mic' would unambiguously identify a specific and unique instrument (rather than 'symbol:exchange')

First example:

When trying to fetch time-series data for the Stock Exchange of Thailand (SET) index, the following request targets a German stock:

https://api.twelvedata.com/time_series?symbol=SET&interval=1day&apikey=[APIKEY]

In order to get the Thai SET index, the request must look like this:

https://api.twelvedata.com/time_series?symbol=SET:SET&interval=1day&apikey=[APIKEY]

However, I haven’t found a way to use the API to know that the symbol should be ‘SET:SET’, and ‘SET: XBKK’ doesn’t work (ie, mic code doesn't work). I found this out through manual experimentation.

Second example:

SDAXI is included in the response from https://api.twelvedata.com/indices?country=germany (again, without an exchange in the attributes), however, price updates from the websocket server include an ‘exchange’ attribute, for example:

{“event”:”price”,”symbol”:”SDAXI”,”currency”:”EUR”,”exchange”:”XETR”,”type”:”Index”,”timestamp”:1673538840,”price”:13002.75}

Since my system cannot determine the exchange for SDAXI from the API prior to subscribing to SDAXI (or fetching SDAXI time-series data), the exchange attribute in the websocket packet is not of any use, and it means I have to handle websocket updates for stocks differently than for indices - this is messy and error-prone, and makes avoiding ambiguity/duplicates more difficult.

Describe the solution you'd like

It seems that allowing an exchange (and/or mic) parameter in the /indices endpoint specification, and including the exchange and/or mic in the response attributes would address problems like the ones I’ve described.

Since indices are associated with exchanges, it seems reasonable to include the exchange/mic in the attributes for indices listings.

Describe alternatives you've considered
When requesting time-series data for indices, I think the type could be set to 'index', but this wouldn't address the ambiguity/duplicate symbol problem.

It might also be possible to use the symbol_search endpoint or other endpoints to find out the exchange for an index symbol, but this would be inefficient and wasteful.

You could include the country in the time_series request like:

https://api.twelvedata.com/time_series?symbol=SET&country=thailand&interval=1day&apikey=[APIKEY]

But that wouldn't work for "India" because NSEI is traded on both the NSE and BSE, so you need to know the exchange of an index to make sure you're getting the correct one.

I'm looking forward to your comments. Thanks!

Stephen

[Bug] Unable to get Websockets to work

Description
I'm trying to follow the example as mentioned here to subscribe to a few tickers but I don't get any events. I understand that WS are only for paid plans and I am still evaluating it on the Basic plan, but as per the documentation and this support link, there are a few instruments for which the trial for WS is enabled even for the base users, with certain limitations. I have tried with multiple tickers from this list, and also from the ones in the example, but to no avail.

My code

from twelvedata import TDClient
import os
td = TDClient(apikey=os.getenv("TD_API_KEY"))

ts = td.time_series(
    symbol="BTC/USD",
    interval="1min",
    outputsize=1
).as_json()
print(ts)


def on_event(e):
    print(e)


ws = td.websocket(symbols=['BTC/USD'], on_event=on_event, log_level="debug")
ws.subscribe(['ETH/BTC', 'AAPL','BTC/USD'])
ws.connect()
ws.keep_alive()

Expected Output and Problem Description
To establish that the API key works, I am printing the Time Series for BTC/USD. That works as expected. However, the second part of the code does not add any tickers to the list of subscribed instruments.

I am expecting at least an output like so, (and then the subsequent events for change in ticker price):

{"event":"subscribe-status","status":"ok","success":[{"symbol":"BTC/USD","exchange":"Binance","country":"","type":"Digital Currency"}],"fails":null}

Screenshots of actual output
The output just stays at this and I need to interrupt to exit from this.
Screenshot 2021-07-04 at 2 14 35 AM

Environment

  • OS: MacOS
  • Python Version: Python 3.7.6
  • pip freeze output:
certifi==2020.12.5
chardet==4.0.0
cycler==0.10.0
gevent==21.1.2
greenlet==1.1.0
idna==2.10
kiwisolver==1.3.1
matplotlib==3.4.2
mplfinance==0.12.7a17
numpy==1.21.0
pandas==1.2.5
Pillow==8.2.0
pyparsing==2.4.7
pyTelegramBotAPI==3.7.9
python-dateutil==2.8.1
pytimeparse==1.1.8
pytz==2021.1
requests==2.25.1
six==1.16.0
twelvedata==1.2.1
urllib3==1.26.4
websocket-client==1.1.0
zope.event==4.5.0
zope.interface==5.4.0

[Bug] Error querying twelvedata, JSONDecodeError('Expecting value: line 1 column 1 (char 0)')

Describe the bug
When the twelvedata library receives a bad response, the library attempts to JSON decode the response (and fails), making the root cause difficult to determine. This results in an exception stating:

JSONDecodeError('Expecting value: line 1 column 1 (char 0)')

To Reproduce
This will be difficult to reproduce without building out a specific test for this, based on our network monitoring, Twelvedata has returned 502 and 520 responses from the API, resulting in the JSONDecodeError to be raised from the client library (instead of a more appropriate exception).

Expected behavior
An appropriate exception is raised indicating the type of error response.

Screenshots
N/A

Desktop (please complete the following information):
N/A

Smartphone (please complete the following information):
N/A

Additional context
It appears that the library is not checking the resp.status_code before attempting to convert the response to JSON. See https://github.com/twelvedata/twelvedata-python/blob/master/src/twelvedata/http_client.py#L32

By checking the resp.status_code before attempting to convert this response to JSON and raising an appropriate exception based on the status code, clients using the library can more appropriately determine the root cause of the error.

different time frame for different tickers[Bug]

Problem
So I trying randomly get some ticker data with outputsize=1000 and 5 minute time frame but it seems that one of the ticker starts from date: 2022-11-30 10:40:00 while other starts from date: 2022-10-17 11:35:00. I am wondering if this about that there were no trades during those times?
Here what I want to to do is get 5 tickers close values and join them on the same date index.
The tickers I tested belongs to nasdaq. I am sure this is not a bug but how can avoid such things here, can I take missed values too as null values?

SMTC: this ticker starts from 2022-11-30 10:40:00
CCRD: this ticker starts from 2022-10-17 11:35:00
Reproduce

import pandas as pd
from twelvedata import TDClient
td = TDClient(apikey="")
symbol = 'SMTC'
interval = '5m'
df = td.time_series(symbol=symbol, interval='5min', outputsize=1000).as_pandas()
symbol2 = 'CCRD'
df2 = td.time_series(symbol=symbol2, interval='5min', outputsize=1000).as_pandas()

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
Screen Shot 2022-12-18 at 16 42 14
Screen Shot 2022-12-18 at 16 42 20

  • tested on Google Colab

pip install twelvedata[pandas,matplotlib,plotly]

Thanks for making this api available.

Just wondering how the pip command works in this case?

pip install twelvedata[pandas,matplotlib,plotly]

If I already have these other packages installed then I do not use this command?

Should I just create a new pyenv?

Thanks,

Matt

[Bug] Time series Invalid OHLC values (lesser in 10 000 times than it should be) for BTC/USD on Binance

I'm occasionally getting invalid values of BTC/USD on Binance from the time-series endpoint.

To reproduce it you need to send GET HTTP request as follows:

https://api.twelvedata.com/time_series?interval=1min&symbol=BTC/USD&exchange=Binance&timezone=Europe/Moscow&format=JSON&previous_close=true&outputsize=200&order=ASC

Result is (look at the expanded element):
image

On the chart it looks like this:
image

  • Windows 11
  • Chrome 116.0.5845.142

I understand it is not the issue with python library, but I haven't found a better place to inform you about it. Those invalid values are occasional and can be reperated for every week or two.

Time series sort issue [Bug]

Describe the bug
The parameter order in stock time series was remove and don't know how to sort ASC.

image
i'm using
mplfinance to plot it (because i can manipulate it before plot) and the data is right to left instate of left to right
image
Thanks!!

[Bug] Unable to get volume values for FTSE symbol

Describe the bug
Unable to get volume values for FTSE symbol

To Reproduce
Execute the following python code, replacing TWELVE_DATA_API_KEY. We have a Pro plan, but the error is the same as the free plan.

from twelvedata import TDClient


td = TDClient(apikey='TWELVE_DATA_API_KEY')
ts = td.time_series(
    symbol='FTSE',
    interval='1min',
    timezone='UTC',
)
print(ts.as_json())

# it's returning the following results, please note the `'volume': 0`
# ({'datetime': '2021-06-16 09:23:00', 'open': '7176.97998', 'high': '7176.97998', 'low': '7176.97998', 'close': '7176.97998', 'volume': '0'}, ...)

Expected behavior
It should return real values for volume, like in other symbol like AAPL

Desktop (please complete the following information):

[Feature Request] python with_beta() is missing

Hello Midas,

I tried to use the beta technical indicator endpoint using python: ts = td.time_series(parameters omitted here).with_beta()

I received the following error:

'TimeSeries' object has no attribute 'with_beta'

Thanks,

Matt

API returning duplicated, contradicting values

Describe the bug
upon specific API calls on stock time series data, the returned data has non-unique timestamps with

To Reproduce
Steps to reproduce the behavior:

call the API for monthly SPX data and look at the result
execute the following code:

from twelvedata import TDClient
import pandas as pd

# Initialize client - apikey parameter is requiered
td = TDClient(apikey=api_key)

interval = '1month'
symbol = 'SPX'

ts = td.time_series(
    symbol=symbol,
    interval=interval,
    outputsize=5000,
    timezone="UTC",
    exchange= 'NYSE',
    start_date= '2000-01-01 00:00:00',
#     end_date = end_date,
    order= 'asc',
)

# Returns pandas.DataFrame
result=ts.as_pandas()
print(result[result.index.duplicated(keep=False)])

result of print:


                  open        high         low       close       volume
datetime                                                               
2006-01-01  1248.29004  1294.90002  1245.73999  1280.07996            0
2006-01-01  1248.29004  1294.90002  1245.73999  1282.45996            0
2006-02-01  1280.07996  1297.56995  1253.60999  1280.66003            0
2006-02-01  1282.45996  1297.56995  1253.60999  1291.23999            0
2006-03-01  1280.66003  1310.88000  1268.42004  1294.82996            0
...                ...         ...         ...         ...          ...
2020-01-01  3244.66992  3337.77002  3214.63989  3225.52002            0
2020-02-01  3235.65991  3393.52002  2855.84009  2954.21997            0
2020-02-01  3235.65991  3393.52002  2855.84009  2954.21997            0
2020-03-01  2982.50000  3090.22998  2944.89990  3090.22998            0
2020-03-01  2974.28003  3136.71997  2191.86011  2578.52002  59996936715

we can see many monthly dates with two entries instead of one, and some pairs even have contradicting values.

Expected behavior
the print statement should return an empty dataframe

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: Win10
  • Browser Firefox
  • Version 84.0.2

Additional context
Add any other context about the problem here.

[Bug]

Describe the bug

I'm not sure if this is a bug in the python client or the API itself.

Some time series fetches that emanate from the python client appear to trigger an erroneous TwelveDataError which indicates that data cannot be found when data actually does exist. The error looks like this:

{"code":404,"message":"Data not found","status":"error","meta":{"symbol":"SET100:SET","interval":"1day","exchange":""}}

To Reproduce

The following URL is generated by the client and fails with the error noted above:

https://api.twelvedata.com/time_series?symbol=SET100:SET&interval=1day&outputsize=5000&end_date=2021-04-26 00:00:00+00:00&dp=5&timezone=UTC&order=asc&prepost=false&format=JSON&apikey=[APIKEY]

The same URL also fails when pasted into a browser or using cURL.

Note: As a quick way to find out what the client was trying to fetch, I hacked the "execute" method of the TimeSeriesEndpoint class as follows:

def execute(self, format="JSON", debug=True): # enable debugging mode

At the bottom of the method, I did this to print the URL that it was fetching:

        # @hack
        # if debug:
        #     return build_url(self.ctx.base_url, endpoint, params)
        if debug:
            print(build_url(self.ctx.base_url, endpoint, params))
        # end hack

Strangely, however, the same range of data that is failing to get fetched by the client can be successfully fetched with this URL:

https://api.twelvedata.com/time_series?symbol=SET:SET&outputsize=5000&interval=1day&end_date=2021-04-26%2000:00:00&timezone=UTC&order=asc&apikey=[APIKEY]

Since the only difference that I can see between the failing URL and the successful URL appears to be the presence of the parameters 'dp', 'prepost', and 'format' in the client's version of the URL, my guess would be that one of those parameters is causing problems, but I haven't tested this.

Expected behavior

The existing data should be returned without error, because it exists and can be fetched outside of the context of the python client.

Looking forward to your thoughts, this problem is actually pretty scary.

Additional notes

The failing fetch noted above occurs inside a loop that successfully executes several similar fetches before failing as above, in order to fetch a longer range of data history in "outputsize" chunks. So it would appear that there is nothing wrong in my code, but let me know if I'm missing something. My first thought was that there might be something weird about the end_date itself, so maybe that's a clue.

Dependabot can't resolve your Python dependency files

Dependabot can't resolve your Python dependency files.

As a result, Dependabot couldn't update your dependencies.

The error Dependabot encountered was:

ERROR: ERROR: Could not find a version that matches mplfinance>=0.12
Skipped pre-versions: 0.11.1a0, 0.11.1a0, 0.11.1a1, 0.11.1a1, 0.12.0a0, 0.12.0a0, 0.12.0a1, 0.12.0a1, 0.12.0a2, 0.12.0a2, 0.12.0a3, 0.12.0a3, 0.12.3a0, 0.12.3a0, 0.12.3a1, 0.12.3a1, 0.12.3a2, 0.12.3a2, 0.12.3a3, 0.12.3a3, 0.12.4a0, 0.12.4a0, 0.12.5a1, 0.12.5a1, 0.12.5a2, 0.12.5a2, 0.12.5a3, 0.12.5a3, 0.12.6a0, 0.12.6a0, 0.12.6a1, 0.12.6a1, 0.12.6a2, 0.12.6a2, 0.12.6a3, 0.12.6a3, 0.12.7a0, 0.12.7a0, 0.12.7a3, 0.12.7a3, 0.12.7a4, 0.12.7a4, 0.12.7a5, 0.12.7a5, 0.12.7a7, 0.12.7a7, 0.12.7a10, 0.12.7a10, 0.12.7a12, 0.12.7a12, 0.12.7a17, 0.12.7a17
There are incompatible versions in the resolved dependencies.
[pipenv.exceptions.ResolutionFailure]:       return resolve_deps(
[pipenv.exceptions.ResolutionFailure]:   File "/usr/local/.pyenv/versions/3.9.4/lib/python3.9/site-packages/pipenv/utils.py", line 718, in resolve_deps
[pipenv.exceptions.ResolutionFailure]:       resolved_tree, hashes, markers_lookup, resolver = actually_resolve_deps(
[pipenv.exceptions.ResolutionFailure]:   File "/usr/local/.pyenv/versions/3.9.4/lib/python3.9/site-packages/pipenv/utils.py", line 480, in actually_resolve_deps
[pipenv.exceptions.ResolutionFailure]:       resolved_tree = resolver.resolve()
[pipenv.exceptions.ResolutionFailure]:   File "/usr/local/.pyenv/versions/3.9.4/lib/python3.9/site-packages/pipenv/utils.py", line 395, in resolve
[pipenv.exceptions.ResolutionFailure]:       raise ResolutionFailure(message=str(e))
[pipenv.exceptions.ResolutionFailure]:       pipenv.exceptions.ResolutionFailure: ERROR: ERROR: Could not find a version that matches mplfinance>=0.12
[pipenv.exceptions.ResolutionFailure]:       Skipped pre-versions: 0.11.1a0, 0.11.1a0, 0.11.1a1, 0.11.1a1, 0.12.0a0, 0.12.0a0, 0.12.0a1, 0.12.0a1, 0.12.0a2, 0.12.0a2, 0.12.0a3, 0.12.0a3, 0.12.3a0, 0.12.3a0, 0.12.3a1, 0.12.3a1, 0.12.3a2, 0.12.3a2, 0.12.3a3, 0.12.3a3, 0.12.4a0, 0.12.4a0, 0.12.5a1, 0.12.5a1, 0.12.5a2, 0.12.5a2, 0.12.5a3, 0.12.5a3, 0.12.6a0, 0.12.6a0, 0.12.6a1, 0.12.6a1, 0.12.6a2, 0.12.6a2, 0.12.6a3, 0.12.6a3, 0.12.7a0, 0.12.7a0, 0.12.7a3, 0.12.7a3, 0.12.7a4, 0.12.7a4, 0.12.7a5, 0.12.7a5, 0.12.7a7, 0.12.7a7, 0.12.7a10, 0.12.7a10, 0.12.7a12, 0.12.7a12, 0.12.7a17, 0.12.7a17
[pipenv.exceptions.ResolutionFailure]: Warning: Your dependencies could not be resolved. You likely have a mismatch in your sub-dependencies.
  First try clearing your dependency cache with $ pipenv lock --clear, then try the original command again.
 Alternatively, you can use $ pipenv install --skip-lock to bypass this mechanism, then run $ pipenv graph to inspect the situation.
  Hint: try $ pipenv lock --pre if it is a pre-release dependency.
ERROR: ERROR: Could not find a version that matches mplfinance>=0.12
Skipped pre-versions: 0.11.1a0, 0.11.1a0, 0.11.1a1, 0.11.1a1, 0.12.0a0, 0.12.0a0, 0.12.0a1, 0.12.0a1, 0.12.0a2, 0.12.0a2, 0.12.0a3, 0.12.0a3, 0.12.3a0, 0.12.3a0, 0.12.3a1, 0.12.3a1, 0.12.3a2, 0.12.3a2, 0.12.3a3, 0.12.3a3, 0.12.4a0, 0.12.4a0, 0.12.5a1, 0.12.5a1, 0.12.5a2, 0.12.5a2, 0.12.5a3, 0.12.5a3, 0.12.6a0, 0.12.6a0, 0.12.6a1, 0.12.6a1, 0.12.6a2, 0.12.6a2, 0.12.6a3, 0.12.6a3, 0.12.7a0, 0.12.7a0, 0.12.7a3, 0.12.7a3, 0.12.7a4, 0.12.7a4, 0.12.7a5, 0.12.7a5, 0.12.7a7, 0.12.7a7, 0.12.7a10, 0.12.7a10, 0.12.7a12, 0.12.7a12, 0.12.7a17, 0.12.7a17
There are incompatible versions in the resolved dependencies.

['Traceback (most recent call last):\n', '  File "/usr/local/.pyenv/versions/3.9.4/lib/python3.9/site-packages/pipenv/utils.py", line 501, in create_spinner\n    yield sp\n', '  File "/usr/local/.pyenv/versions/3.9.4/lib/python3.9/site-packages/pipenv/utils.py", line 649, in venv_resolve_deps\n    c = resolve(cmd, sp)\n', '  File "/usr/local/.pyenv/versions/3.9.4/lib/python3.9/site-packages/pipenv/utils.py", line 539, in resolve\n    sys.exit(c.return_code)\n', 'SystemExit: 1\n']

If you think the above is an error on Dependabot's side please don't hesitate to get in touch - we'll do whatever we can to fix it.

View the update logs.

API isn't recognised

Describe the bug
When I specify my API in the python client I get an InvalidAPIKeyError, but my api works fine if I submit the same query using the standard requests library method in python.

To Reproduce

this throws an error:

from twelvedata import TDClient
td = TDClient(apikey="XXX")
ts = td.time_series(
symbol="AAPL",
interval="1day",
outputsize=30,
timezone="America/New_York",
)
ts.as_pandas()

this works fine:

import requests
url = "https://twelve-data1.p.rapidapi.com/time_series"
querystring = {"symbol":"AAPL","interval":"1day","outputsize":"30","format":"json"}
headers = {
"content-type": "application/octet-stream",
"X-RapidAPI-Key": "XXX",
"X-RapidAPI-Host": "twelve-data1.p.rapidapi.com"
}
response = requests.get(url, headers=headers, params=querystring)
print(response.json())

Expected behavior
I'd expect a pd df to be returned. (I also tested a JSON return, same issue)

Desktop (please complete the following information):
Max OSX 10.15.7

Additional context
I realise this is really difficult for you to test/reproduce without me posting my api. But perhaps it's helpful to say that it's an api on the basic plan - so perhaps that's the issue?

Cannot use start_date and end_date in timeseries

When using the python wrapper and creating a timeseries, using both start_date and end_date keyword args produces an error.

Would expect to create a timeseries between the start and end dates provided

  • OS: Windows 10
  • TwelveData package version: 1.0.0

e.g
ts = self.TD.time_series( symbol=['AMD', 'AAPL'] interval='1min', outputsize=5000, end_date=end_date, start_date=start_date )

where start_date and end_date are set to strings containing UTC timestamps
produces:
columns = tuple(val[list(val)[0]]['values'][0].keys())[1:] KeyError: 'values'

[Bug] Websocket closes connection (and doesn't reconnect) after 6-12 hours of running

Hi!

First of all, thank you for this wrapper library, it helps us get data faster, but I've found a recurring problem after leaving the websocket script running for a longer time:

When I start the process it seems like it's working as expected, but after a while, there's an error that stops the process and disconnects (and does not reconnect / self_heal()).

The issue can come anytime between 6-12 hours after the process starts (roughly). I haven't been able to reproduce it earlier yet. unfortunately.

The code:

from twelvedata import TDClient

class TwelveDataPipeline():
    def _on_event(self, e):
        if e["event"] == "price":
            # insert data into a database...

    def start(self, symbols):
        td = TDClient(apikey="apikey")
        ws = td.websocket(on_event=self._on_event)
        ws.subscribe(symbols)
        ws.connect()
        ws.keep_alive()

pipeline = TwelveDataPipeline()
symbols = ["some", "symbols", "here"]
pipeline.start(symbols=symbols)

Error (example1)

2022-02-11 15:16:32,826 - ws-twelvedata - ERROR - TDWebSocket ERROR: [Errno 104] Connection reset by peer
2022-02-11 15:16:34,829 - ws-twelvedata - ERROR - TDWebSocket ERROR: on_close() takes 2 positional arguments but 4 were given
Traceback (most recent call last):
  File "ingest_stocks.py", line 32, in <module>
    main()
  File "ingest_stocks.py", line 28, in main
    pipeline.start(symbols=symbols)
  File "/home/ubuntu/twelve-data-real-time/twelve_data.py", line 64, in start
    ws.keep_alive()
  File "/home/ubuntu/twelve-data-real-time/env/lib/python3.8/site-packages/twelvedata/websocket.py", line 99, in keep_alive
    self.heartbeat()
  File "/home/ubuntu/twelve-data-real-time/env/lib/python3.8/site-packages/twelvedata/websocket.py", line 102, in heartbeat
    self.ws.send('{"action": "heartbeat"}')
  File "/home/ubuntu/twelve-data-real-time/env/lib/python3.8/site-packages/websocket/_app.py", line 190, in send
    raise WebSocketConnectionClosedException(
websocket._exceptions.WebSocketConnectionClosedException: Connection is already closed.

Error (example2)

2022-02-11 15:25:59,488 - ws-twelvedata - ERROR - TDWebSocket ERROR: [Errno 104] Connection reset by peer
2022-02-11 15:26:01,491 - ws-twelvedata - ERROR - TDWebSocket ERROR: on_close() takes 2 positional arguments but 4 were given
2022-02-11 21:11:04,668 - ws-twelvedata - ERROR - TDWebSocket ERROR: Connection to remote host was lost.
Traceback (most recent call last):
  File "ingest_crypto.py", line 32, in <module>
    main()
  File "ingest_crypto.py", line 28, in main
    pipeline.start(symbols=symbols)
  File "/home/ubuntu/twelve-data-real-time/twelve_data.py", line 64, in start
    ws.keep_alive()
  File "/home/ubuntu/twelve-data-real-time/env/lib/python3.8/site-packages/twelvedata/websocket.py", line 99, in keep_alive
    self.heartbeat()
  File "/home/ubuntu/twelve-data-real-time/env/lib/python3.8/site-packages/twelvedata/websocket.py", line 102, in heartbeat
    self.ws.send('{"action": "heartbeat"}')
  File "/home/ubuntu/twelve-data-real-time/env/lib/python3.8/site-packages/websocket/_app.py", line 189, in send
    if not self.sock or self.sock.send(data, opcode) == 0:
  File "/home/ubuntu/twelve-data-real-time/env/lib/python3.8/site-packages/websocket/_core.py", line 283, in send
    return self.send_frame(frame)
  File "/home/ubuntu/twelve-data-real-time/env/lib/python3.8/site-packages/websocket/_core.py", line 311, in send_frame
    l = self._send(data)
  File "/home/ubuntu/twelve-data-real-time/env/lib/python3.8/site-packages/websocket/_core.py", line 525, in _send
    return send(self.sock, data)
  File "/home/ubuntu/twelve-data-real-time/env/lib/python3.8/site-packages/websocket/_socket.py", line 146, in send
    raise WebSocketConnectionClosedException("socket is already closed.")
websocket._exceptions.WebSocketConnectionClosedException: socket is already closed.

When the error happens, the process gets killed. Meaning, if there's no other solution, we can set up a cron job to monitor whether the script is still running and if not start it. But it wouldn't be ideal as the websocket should reconnect automatically in case the connection gets lost, no? (Looking at this line of code)

Expected behavior
The Python script should run forever.

Desktop:

  • OS: Ubuntu (EC2 instance)

Thank you for any help!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.