Skip to content

Commit

Permalink
FEAT: Adding pricing history for instrument (#35)
Browse files Browse the repository at this point in the history
* adding get pricing history for instrument("Company")
adding candlestick object

* Fixing testing mistake

* Adding documentation and examples

---------

Co-authored-by: Flexin1981 <[email protected]>
  • Loading branch information
dowling-john and dowling-john authored Nov 20, 2023
1 parent ad4b3e4 commit 219baa4
Show file tree
Hide file tree
Showing 5 changed files with 285 additions and 4 deletions.
166 changes: 166 additions & 0 deletions examples/Instrument_pricing_history_example.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
{
"cells": [
{
"cell_type": "markdown",
"source": [
"PyTrading Instrument Pricing History Example"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2023-11-18T10:53:49.326421Z",
"start_time": "2023-11-18T10:53:48.604623Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/johndowling/Desktop/Trading212API/venv/lib/python3.9/site-packages/urllib3/__init__.py:34: NotOpenSSLWarning: urllib3 v2 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'LibreSSL 2.8.3'. See: https://github.com/urllib3/urllib3/issues/3020\n",
" warnings.warn(\n"
]
},
{
"ename": "ModuleNotFoundError",
"evalue": "No module named 'constants'",
"output_type": "error",
"traceback": [
"\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
"\u001B[0;31mModuleNotFoundError\u001B[0m Traceback (most recent call last)",
"Cell \u001B[0;32mIn[1], line 6\u001B[0m\n\u001B[1;32m 4\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mselenium\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mwebdriver\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mchrome\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mservice\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m Service\n\u001B[1;32m 5\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mwebdriver_manager\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mchrome\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m ChromeDriverManager\n\u001B[0;32m----> 6\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mpytrading212\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m EquityOrder\n\u001B[1;32m 7\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mpytrading212\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m Equity\n\u001B[1;32m 8\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mpytrading212\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m Mode\n",
"File \u001B[0;32m~/Desktop/Trading212API/pytrading212/__init__.py:3\u001B[0m\n\u001B[1;32m 1\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01morder\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m EquityOrder, MarketOrder, LimitOrder, StopOrder, StopLimitOrder, ValueOrder, CFDMarketOrder, \\\n\u001B[1;32m 2\u001B[0m CFDLimitStopOrder, CFDOCOOrder\n\u001B[0;32m----> 3\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mtrading212\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m Equity, CFD\n\u001B[1;32m 4\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mconstants\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m Mode, Trading, Period, OrderType, TimeValidity, ONE_WEEK\n\u001B[1;32m 5\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mposition\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m Position\n",
"File \u001B[0;32m~/Desktop/Trading212API/pytrading212/trading212.py:19\u001B[0m\n\u001B[1;32m 16\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mselenium\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mwebdriver\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01msupport\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mui\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m WebDriverWait\n\u001B[1;32m 18\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mpytrading212\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m constants, console\n\u001B[0;32m---> 19\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mpytrading212\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01minstrument\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m CFDInstrument\n\u001B[1;32m 20\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mpytrading212\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01morder\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m CFDOrder, EquityOrder\n\u001B[1;32m 21\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mpytrading212\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mposition\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m Position\n",
"File \u001B[0;32m~/Desktop/Trading212API/pytrading212/instrument.py:6\u001B[0m\n\u001B[1;32m 3\u001B[0m \u001B[38;5;28;01mimport\u001B[39;00m \u001B[38;5;21;01mrequests\u001B[39;00m\n\u001B[1;32m 4\u001B[0m \u001B[38;5;28;01mimport\u001B[39;00m \u001B[38;5;21;01mjson\u001B[39;00m\n\u001B[0;32m----> 6\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mconstants\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m ONE_WEEK\n\u001B[1;32m 8\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mselenium\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m webdriver\n\u001B[1;32m 9\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mselenium\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mwebdriver\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mchrome\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mservice\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m Service\n",
"\u001B[0;31mModuleNotFoundError\u001B[0m: No module named 'constants'"
]
}
],
"source": [
"import configparser\n",
"\n",
"from selenium import webdriver\n",
"from selenium.webdriver.chrome.service import Service\n",
"from webdriver_manager.chrome import ChromeDriverManager\n",
"from pytrading212 import EquityOrder\n",
"from pytrading212 import Equity\n",
"from pytrading212 import Mode\n",
"from pytrading212 import Company\n",
"from pytrading212 import ONE_WEEK"
]
},
{
"cell_type": "markdown",
"source": [
"Initialize Trading Equity API"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": null,
"outputs": [],
"source": [
"config = configparser.ConfigParser()\n",
"config.read('../config.ini')\n",
"\n",
"driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))\n",
"equity = Equity(email=config['ACCOUNT']['email'], password=config['ACCOUNT']['password'], driver=driver, mode=Mode.DEMO)"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "markdown",
"source": [
"Create an instrument"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": null,
"outputs": [],
"source": [
"# Invalid order: voluntary typo-error in instrument code AAPLL_US_EQ\n",
"instrument = Company(instrument_code=\"AAPLL_US_EQ\", isin=\"\")"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "markdown",
"source": [
"Request instrument pricing history"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": null,
"outputs": [],
"source": [
"print(instrument.get_pricing_history(interval=ONE_WEEK, trading_instance=equity))"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "markdown",
"source": [
"Clean up"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": null,
"outputs": [],
"source": [
"equity.finish()"
],
"metadata": {
"collapsed": false
}
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
30 changes: 30 additions & 0 deletions examples/instrument_pricing_history.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import configparser

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

from pytrading212 import Equity, Company
from pytrading212 import Mode, EquityOrder, OrderType
from pytrading212.constants import ONE_WEEK


config = configparser.ConfigParser()
config.read('../config.ini')


if __name__ == '__main__':
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
equity = Equity(
email=config['ACCOUNT']['email'], password=config['ACCOUNT']['password'],
driver=driver, mode=Mode.DEMO
)

# Create a new instrument
instrument = Company(instrument_code="AAPLL_US_EQ", isin="")

# Request pricing history for the instrument, this requires a time interval
# and a trading 212 instance
print(
instrument.get_pricing_history(interval=ONE_WEEK, trading_instance=equity)
)
15 changes: 12 additions & 3 deletions pytrading212/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
from .order import EquityOrder, MarketOrder, LimitOrder, StopOrder, StopLimitOrder, ValueOrder, CFDMarketOrder, \
CFDLimitStopOrder, CFDOCOOrder
from .order import (
EquityOrder,
MarketOrder,
LimitOrder,
StopOrder,
StopLimitOrder,
ValueOrder,
CFDMarketOrder,
CFDLimitStopOrder,
CFDOCOOrder
)
from .trading212 import Equity, CFD
from .constants import Mode, Trading, Period, OrderType, TimeValidity
from .constants import Mode, Trading, Period, OrderType, TimeValidity, ONE_WEEK
from .position import Position
from .instrument import CFDInstrument, Company
3 changes: 3 additions & 0 deletions pytrading212/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
CLASS_CFD_ICON = "cfd-icon"
PYTRADING212_VERSION = "0.2.5"

ONE_WEEK = "ONE_WEEK"

class Mode(Enum):
"""Mode Type"""
DEMO = "demo",
Expand All @@ -30,6 +32,7 @@ class Period(Enum):
ALL = "ALL",



class OrderType(Enum):
"""Order Type"""
LIMIT = "LIMIT"
Expand Down
75 changes: 74 additions & 1 deletion pytrading212/instrument.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,82 @@
import datetime
import typing
import requests
import json

from constants import ONE_WEEK

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.options import Options


class CandleStick(object):

"""
The candlestick object is a representaion of the values used in a candlestick
chart.
It consists of an opening timestamp opening price, closing price as well
as a high and low price.
The trading212 api also gives an int value which seems to be 0 all the
time which I have not figured out what this is but it is included as
"unknown"
"""

opening: float
closing: float
high: float
low: float
timestamp: datetime.datetime
unknown: int

def __init__(self, data: typing.List) -> None:
self.timestamp, self.high, self.low, self.opening, self.closing, self.unknown = data



class Company:
"""Company Wrapper"""

def __init__(self, instrument_code: str, isin: str):
charting_url: str = "/charting/v3/candles"

def __init__(self, instrument_code: str, isin: str, language_code: str = 'en'):
self.instrument_code = instrument_code
self.isin = isin
self.language_code = language_code

def get_pricing_history(
self,
interval: str,
trading_instance: 'Trading212'
) -> typing.List[CandleStick]:

ticker_data: str = json.dumps(
{
"candles":
[
{
"ticker": self.instrument_code,
"useAskPrice": True,
"period": interval,
"size":500
}
]
}
)

response = requests.put(
f"{trading_instance.base_url}{self.charting_url}?ticker={self.instrument_code}&languageCode={self.language_code}",
headers=equity.headers,
data=ticker_data
)
return [
CandleStick(x) for x in json.loads(
response.content.decode("utf-8")
)[0]["response"]["candles"]
]


class CFDInstrument:
Expand Down

0 comments on commit 219baa4

Please sign in to comment.