From 183cb3892399291dd4ff96558510dc78034c5593 Mon Sep 17 00:00:00 2001 From: chylli-deriv <52912308+chylli-deriv@users.noreply.github.com> Date: Tue, 29 Aug 2023 20:34:43 +0800 Subject: [PATCH] Update/automatically (#22) * add script * refactor * update schema * fix test * update changelog * rename default ws server * update ChangeLog * increase version * try update * try update * fix command * checkout * install modules * install cpanm * test status * add name * try push * no check git * config git * push to origin * update schema automatically * filter * filter * try add NEXTVER * revert update schema to test NEXTVER Revert "update schema automatically" This reverts commit 3c7523365dc280f043b5d838bf7188d30cdbef35. * update schema automatically * run status before commit * revert again for test Revert "update schema automatically" This reverts commit 71ab237377e63e5464d5bfefbda8fbd575ab85af. * test * update schema automatically * Revert "update schema automatically" This reverts commit 1476914845e00d02de05ae6333731ee8432685dc. * fix typo * update schema automatically * add more lines * Revert "update schema automatically" This reverts commit 979c896e560da68249a212df47a17df8d6b5c728. * update schema automatically * to check cron run * try upload * fix error * try release * try fix * from bottom * add requirement * require test * schedule * try run every minutes * run it every day * cascade * fix error * try set git * push back * release $NEXT_VER * try no nextver * Revert "release $NEXT_VER" This reverts commit 9577591b72a17cced892000719cf5431f1d35f37. * Revert "update schema automatically" This reverts commit ffb1d342abd0a1905d4cba99cc28c3ded50735e9. * update schema automatically * enable cron [ci skip] * revert update automatically [ci skip] * update schema automatically * Revert "update schema automatically" This reverts commit 1384395c42fb7246a0bd9ac763db9cfa7be27207. * try run every 5 minutes [ci skip] * update schema automatically * try again [ci skip] * [ci skip] Revert "update schema automatically" This reverts commit 5b5852239b9d5aad89126e74da7b10ea3b9afb07. * update schema automatically * refactor * change to pypi * Update .circleci/config.yml * try ssh key * no cron , for test * Revert "update schema automatically" This reverts commit 8b867bed3c9f60d7d681666d40274159e7ca6377. * show remote -v * push * add back filter --------- Co-authored-by: Nobody --- .circleci/config.yml | 76 +- .gitignore | 1 + CHANGELOG.md | 12 +- deriv_api/deriv_api.py | 2 +- deriv_api/deriv_api_calls.py | 2024 ++++++++----------------- deriv_api/streams_list.py | 4 +- scripts/regen-py.pl | 143 ++ scripts/templates/api-call-py.tt2 | 138 ++ scripts/templates/streams_list.py.tt2 | 10 + setup.py | 2 +- tests/test_deriv_api_calls.py | 8 +- 11 files changed, 982 insertions(+), 1438 deletions(-) create mode 100644 scripts/regen-py.pl create mode 100644 scripts/templates/api-call-py.tt2 create mode 100644 scripts/templates/streams_list.py.tt2 diff --git a/.circleci/config.yml b/.circleci/config.yml index ea741ee..1d9e66e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,7 +19,7 @@ jobs: - checkout # check out source code to working directory - run: sudo chown -R circleci:circleci /usr/local/bin - restore_cache: - # Read about caching dependencies: https://circleci.com/docs/2.0/caching/ + # Read about caching dependencies: https://circleci.com/docs/2.0/caching/ key: deps9-{{ .Branch }}-{{ checksum "Pipfile.lock" }} - run: command: | @@ -45,8 +45,8 @@ jobs: - restore_cache: key: deps9-{{ .Branch }}-{{ checksum "Pipfile.lock" }} - run: - command: | - make setup + command: | + make setup - save_cache: key: deps9-{{ .Branch }}-{{ checksum "Pipfile.lock" }} paths: @@ -56,6 +56,55 @@ jobs: git config --local user.email "sysadmin@binary.com" git config --local user.name "gh-pages deploy bot" make gh-pages + update_schema: + <<: *default + steps: + - add_ssh_keys: + fingerprints: + - "c8:f7:fc:a0:0d:2c:43:93:e3:c7:b6:cf:16:93:98:e1" + - checkout + - run: + name: config git + command: | + git config --global user.email "nobody@deriv.com" + git config --global user.name "Nobody" + - run: + name: update schema + command: | + git clone https://github.com/binary-com/deriv-developers-portal.git /tmp/deriv-developers-portal + curl -L https://cpanmin.us | perl - --sudo App::cpanminus + sudo cpanm -n Dir::Self File::Basename JSON::MaybeXS Log::Any Path::Tiny Template Syntax::Keyword::Try + BINARYCOM_API_SCHEMA_PATH=/tmp/deriv-developers-portal/config/v3 perl scripts/regen-py.pl + if [[ $(git diff --shortstat) == ' 2 files changed, 2 insertions(+), 2 deletions(-)' ]] + then + echo 'Schema no change' + exit 0 + fi + echo "Schama updated" + pip3 install bump + NEXT_VER=$(bump) + sed -i '/# Changelog/{s/$/\n\n## NEXTVER\n\nSync API/}' CHANGELOG.md + sed -i "s/NEXTVER/$NEXT_VER/g" CHANGELOG.md + git add . + git commit -m 'update schema automatically' + git push origin HEAD:master + release: + <<: *default + steps: + - checkout + - run: + name: setup pypi + command: | + echo "[pypi]" >> ~/.pypirc + echo "username=__token__" >> ~/.pypirc + echo "password=$PYPI_TOKEN" >> ~/.pypirc + - run: + name: release + command: | + python3 -m pip install --upgrade twine + make build + python3 -m twine upload --repository pypi dist/* + echo "deployed to pypi" workflows: build: jobs: @@ -78,7 +127,26 @@ workflows: - "3.10.4" - "3.10.10" - docs-build-deploy: + requires: + - release + filters: + branches: + only: + - master + - release: + requires: + - test + filters: + branches: + only: + - master + update_schema_flow: + jobs: + - update_schema + triggers: + - schedule: + cron: "0 0 * * *" filters: branches: only: - - master + - master diff --git a/.gitignore b/.gitignore index 730e11c..bf35fc1 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ venv/ dist .coverage build +tags diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d680ef..6bbd064 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,17 @@ # Changelog +## 0.1.5 + +Change default ws server + +## 0.1.4 + +Sync API + ## 0.1.3 Fix a typo, which cause ws connection no response + ## 0.1.2 Added middleware support @@ -10,10 +19,9 @@ Added middleware support ## 0.1.1 ### Fixed: -Fixed a PyPI constraint where the package can only be installed on python ==3.9.6 +Fixed a PyPI constraint where the package can only be installed on python ==3.9.6 ## 0.1.0 Initial version. - diff --git a/deriv_api/deriv_api.py b/deriv_api/deriv_api.py index eabbd30..62d8eab 100644 --- a/deriv_api/deriv_api.py +++ b/deriv_api/deriv_api.py @@ -85,7 +85,7 @@ class DerivAPI(DerivAPICalls): storage: None def __init__(self, **options: str) -> None: - endpoint = options.get('endpoint', 'frontend.binaryws.com') + endpoint = options.get('endpoint', 'ws.derivws.com') lang = options.get('lang', 'EN') brand = options.get('brand', '') cache = options.get('cache', InMemory()) diff --git a/deriv_api/deriv_api_calls.py b/deriv_api/deriv_api_calls.py index 961c545..23a10cc 100644 --- a/deriv_api/deriv_api_calls.py +++ b/deriv_api/deriv_api_calls.py @@ -1,4 +1,4 @@ -# This file was automatically generated by scripts/regen-py.pl at 20220627-142751 +# This file was automatically generated by scripts/regen-py.pl at 20230815-094214 from numbers import Number @@ -10,136 +10,6 @@ class DerivAPICalls: - async def account_closure(self, args=None): - """ - This call allows clients to close all their accounts (including virtual-money account). It is assumed that all their accounts (excluding virtual) have no balance left. - - Parameters: - ----------- - args : dict with following keys - account_closure : int - Must be 1 - passthrough : Any - [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - reason : str - Reason for closing off accounts. - req_id : int - [Optional] Used to map request to response. - """ - - if args is None: - args = {} - - config = { - 'account_closure': { - 'required': 1, - 'type': 'integer' - }, - 'passthrough': {}, - 'reason': { - 'required': 1, - 'type': 'string' - }, - 'req_id': { - 'type': 'integer' - } - } - - all_args = { - 'method': 'account_closure', - 'needs_method_arg': '1', - 'args': args, - 'config': config, - } - - return await self.process_request(all_args) - - async def account_security(self, args=None): - """ - This call manages two-factor account authentication - - Parameters: - ----------- - args : dict with following keys - account_security : int - Must be 1 - otp : str - [Optional] OTP (one-time passcode) generated by a 2FA application like Authy, Google Authenticator or Yubikey. - passthrough : Any - [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - req_id : int - [Optional] Used to map request to response. - totp_action : str - [Optional] Action to be taken for managing TOTP (time-based one-time password, RFC6238). Generate will create a secret key which is then returned in the secret_key response field, you can then enable by using that code in a 2FA application. - """ - - if args is None: - args = {} - - config = { - 'account_security': { - 'required': 1, - 'type': 'integer' - }, - 'otp': { - 'type': 'string' - }, - 'passthrough': {}, - 'req_id': { - 'type': 'integer' - }, - 'totp_action': { - 'type': 'string' - } - } - - all_args = { - 'method': 'account_security', - 'needs_method_arg': '1', - 'args': args, - 'config': config, - } - - return await self.process_request(all_args) - - async def account_statistics(self, args=None): - """ - Send request to get account statistics - - Parameters: - ----------- - args : dict with following keys - account_statistics : int - Must be 1 - passthrough : Any - [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - req_id : int - [Optional] Used to map request to response. - """ - - if args is None: - args = {} - - config = { - 'account_statistics': { - 'required': 1, - 'type': 'integer' - }, - 'passthrough': {}, - 'req_id': { - 'type': 'integer' - } - } - - all_args = { - 'method': 'account_statistics', - 'needs_method_arg': '1', - 'args': args, - 'config': config, - } - - return await self.process_request(all_args) - async def active_symbols(self, args=None): """ Retrieve a list of all currently active symbols (underlying markets upon which contracts are available for trading). @@ -150,6 +20,8 @@ async def active_symbols(self, args=None): active_symbols : str If you use brief, only a subset of fields will be returned. landing_company : str + Deprecated - replaced by landing_company_short. + landing_company_short : str [Optional] If you specify this field, only symbols available for trading by that landing company will be returned. If you are logged in, only symbols available for trading by your landing company will be returned regardless of what you specify in this field. passthrough : Any [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. @@ -170,132 +42,20 @@ async def active_symbols(self, args=None): 'landing_company': { 'type': 'string' }, - 'passthrough': {}, - 'product_type': { - 'type': 'string' - }, - 'req_id': { - 'type': 'integer' - } - } - - all_args = { - 'method': 'active_symbols', - 'needs_method_arg': '1', - 'args': args, - 'config': config, - } - - return await self.process_request(all_args) - - async def affiliate_account_add(self, args=None): - """ - Register a new affiliate - - Parameters: - ----------- - args : dict with following keys - address_city : str - City name within 50 characters. - address_line_1 : str - Within 70 characters, with no leading whitespaces and may contain letters/numbers and/or any of following characters '.,:;()@#/- - address_line_2 : str - [Optional] Within 70 characters. - address_postcode : str - Within 20 characters and may not contain '+'. - address_state : str - Possible value receive from states_list call. - affiliate_account_add : int - [Required] Must be 1 - country : str - Country of legal citizenship, 2-letter country code. - first_name : str - The official first name of the affiliate. Within 2-50 characters, use only letters, spaces, hyphens, full-stops or apostrophes. - last_name : str - The official last name of the affiliate. Within 2-50 characters, use only letters, spaces, hyphens, full-stops or apostrophes. - non_pep_declaration : int - Indicates client's self-declaration of not being a PEP/RCA (Politically Exposed Person/Relatives and Close Associates). - passthrough : Any - [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - password : str - Password for the affiliate account. (Accepts any printable ASCII character. Must be between 6-50 characters, and include numbers, lowercase and uppercase letters.). - phone : str - Registered phone number of the affiliate. Starting with + followed by 8-35 digits, allowing hyphens or space. - req_id : int - [Optional] Used to map request to response. - tnc_accepted : int - Indicates client has agreed to the terms and conditions. - username : str - Desired username for the affiliate account. Within 2-50 characters, use only letters, spaces, hyphens, full-stops or apostrophes. - """ - - if args is None: - args = {} - - config = { - 'address_city': { - 'required': 1, - 'type': 'string' - }, - 'address_line_1': { - 'required': 1, - 'type': 'string' - }, - 'address_line_2': { - 'type': 'string' - }, - 'address_postcode': { - 'required': 1, - 'type': 'string' - }, - 'address_state': { - 'required': 1, - 'type': 'string' - }, - 'affiliate_account_add': { - 'required': 1, - 'type': 'integer' - }, - 'country': { - 'required': 1, - 'type': 'string' - }, - 'first_name': { - 'required': 1, - 'type': 'string' - }, - 'last_name': { - 'required': 1, + 'landing_company_short': { 'type': 'string' }, - 'non_pep_declaration': { - 'required': 1, - 'type': 'integer' - }, 'passthrough': {}, - 'password': { - 'required': 1, - 'type': 'string' - }, - 'phone': { - 'required': 1, + 'product_type': { 'type': 'string' }, 'req_id': { 'type': 'integer' - }, - 'tnc_accepted': { - 'required': 1, - 'type': 'integer' - }, - 'username': { - 'required': 1, - 'type': 'string' } } all_args = { - 'method': 'affiliate_account_add', + 'method': 'active_symbols', 'needs_method_arg': '1', 'args': args, 'config': config, @@ -494,7 +254,7 @@ async def app_markup_details(self, args=None): [Optional] If set to 1, will return app_markup transaction details. limit : Number [Optional] Apply upper limit to count of transactions received. - offset : Number + offset : int [Optional] Number of transactions to skip. passthrough : Any [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. @@ -535,7 +295,7 @@ async def app_markup_details(self, args=None): 'type': 'numeric' }, 'offset': { - 'type': 'numeric' + 'type': 'integer' }, 'passthrough': {}, 'req_id': { @@ -556,6 +316,56 @@ async def app_markup_details(self, args=None): return await self.process_request(all_args) + async def app_markup_statistics(self, args=None): + """ + Retrieve statistics of `app_markup`. + + Parameters: + ----------- + args : dict with following keys + app_markup_statistics : int + Must be 1 + date_from : str + Start date (epoch or YYYY-MM-DD HH:MM:SS). Results are inclusive of this time. + date_to : str + End date (epoch or YYYY-MM-DD HH::MM::SS). Results are inclusive of this time. + passthrough : Any + [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. + req_id : int + [Optional] Used to map request to response. + """ + + if args is None: + args = {} + + config = { + 'app_markup_statistics': { + 'required': 1, + 'type': 'integer' + }, + 'date_from': { + 'required': 1, + 'type': 'string' + }, + 'date_to': { + 'required': 1, + 'type': 'string' + }, + 'passthrough': {}, + 'req_id': { + 'type': 'integer' + } + } + + all_args = { + 'method': 'app_markup_statistics', + 'needs_method_arg': '1', + 'args': args, + 'config': config, + } + + return await self.process_request(all_args) + async def app_register(self, args=None): """ Register a new OAuth application @@ -564,7 +374,7 @@ async def app_register(self, args=None): ----------- args : dict with following keys app_markup_percentage : Number - [Optional] Markup to be added to contract prices (as a percentage of contract payout). + [Optional] Markup to be added to contract prices (as a percentage of contract payout). Max markup: 3%. app_register : int Must be 1 appstore : str @@ -648,7 +458,7 @@ async def app_update(self, args=None): ----------- args : dict with following keys app_markup_percentage : Number - [Optional] Markup to be added to contract prices (as a percentage of contract payout). + [Optional] Markup to be added to contract prices (as a percentage of contract payout). Max markup: 3%. app_update : int Application app_id. appstore : str @@ -734,6 +544,8 @@ async def asset_index(self, args=None): asset_index : int Must be 1 landing_company : str + Deprecated - replaced by landing_company_short. + landing_company_short : str [Optional] If specified, will return only the underlyings for the specified landing company. passthrough : Any [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. @@ -752,6 +564,9 @@ async def asset_index(self, args=None): 'landing_company': { 'type': 'string' }, + 'landing_company_short': { + 'type': 'string' + }, 'passthrough': {}, 'req_id': { 'type': 'integer' @@ -928,6 +743,9 @@ async def buy(self, args=None): 'duration_unit': { 'type': 'string' }, + 'growth_rate': { + 'type': 'numeric' + }, 'limit_order': { 'stop_loss': { 'type': 'numeric' @@ -1178,211 +996,9 @@ async def cashier(self, args=None): return await self.process_request(all_args) - async def cashier_payments(self, args=None): + async def contract_update(self, args=None): """ - List pending transactions. This can only be used for crypto transactions. - - Parameters: - ----------- - args : dict with following keys - cashier_payments : Number - Must be 1 - passthrough : Any - [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - provider : str - [Optional] Cashier provider. crypto will be default option for crypto currency accounts. - req_id : int - [Optional] Used to map request to response. - subscribe : int - [Optional] If set to 1, will send updates whenever there is update to crypto payments. - transaction_type : str - [Optional] Type of transactions to receive. - """ - - if args is None: - args = {} - - config = { - 'cashier_payments': { - 'required': 1, - 'type': 'numeric' - }, - 'passthrough': {}, - 'provider': { - 'type': 'string' - }, - 'req_id': { - 'type': 'integer' - }, - 'subscribe': { - 'type': 'integer' - }, - 'transaction_type': { - 'type': 'string' - } - } - - all_args = { - 'method': 'cashier_payments', - 'needs_method_arg': '1', - 'args': args, - 'config': config, - } - - return await self.process_request(all_args) - - async def cashier_withdrawal_cancel(self, args=None): - """ - Request for cancelling a withdrawal. This can only be used for crypto transactions. - - Parameters: - ----------- - args : dict with following keys - cashier_withdrawal_cancel : Number - Must be 1 - id : str - The unique identifier for the transaction. - passthrough : Any - [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - req_id : int - [Optional] Used to map request to response. - """ - - if args is None: - args = {} - - config = { - 'cashier_withdrawal_cancel': { - 'required': 1, - 'type': 'numeric' - }, - 'id': { - 'required': 1, - 'type': 'string' - }, - 'passthrough': {}, - 'req_id': { - 'type': 'integer' - } - } - - all_args = { - 'method': 'cashier_withdrawal_cancel', - 'needs_method_arg': '1', - 'args': args, - 'config': config, - } - - return await self.process_request(all_args) - - async def change_email(self, args=None): - """ - Change Email. - - Parameters: - ----------- - args : dict with following keys - change_email : str - Must be verify or update. - new_email : str - Email address to be verified. - new_password : str - [Optional] New password (Accepts any printable ASCII character. Must be within 8-25 characters, and include numbers, lowercase and uppercase letters. Must not be the same as the user's email address). Mandatory if change_email is update and user has social login. - passthrough : Any - [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - req_id : int - [Optional] Used to map request to response. - verification_code : str - Email verification code (received from a verify_email call, which must be done first) - """ - - if args is None: - args = {} - - config = { - 'change_email': { - 'required': 1, - 'type': 'string' - }, - 'new_email': { - 'required': 1, - 'type': 'string' - }, - 'new_password': { - 'type': 'string' - }, - 'passthrough': {}, - 'req_id': { - 'type': 'integer' - }, - 'verification_code': { - 'required': 1, - 'type': 'string' - } - } - - all_args = { - 'method': 'change_email', - 'needs_method_arg': '1', - 'args': args, - 'config': config, - } - - return await self.process_request(all_args) - - async def change_password(self, args=None): - """ - Change Password. Note: This call is only available when authenticated using an OAuth token. - - Parameters: - ----------- - args : dict with following keys - change_password : Number - Must be 1 - new_password : str - New password (Accepts any printable ASCII character. Must be within 8-25 characters, and include numbers, lowercase and uppercase letters. Must not be the same as the user's email address) - old_password : str - Old password for validation (non-empty string, accepts any printable ASCII character) - passthrough : Any - [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - req_id : int - [Optional] Used to map request to response. - """ - - if args is None: - args = {} - - config = { - 'change_password': { - 'required': 1, - 'type': 'numeric' - }, - 'new_password': { - 'required': 1, - 'type': 'string' - }, - 'old_password': { - 'required': 1, - 'type': 'string' - }, - 'passthrough': {}, - 'req_id': { - 'type': 'integer' - } - } - - all_args = { - 'method': 'change_password', - 'needs_method_arg': '1', - 'args': args, - 'config': config, - } - - return await self.process_request(all_args) - - async def contract_update(self, args=None): - """ - Update a contract condition. + Update a contract condition. Parameters: ----------- @@ -1490,7 +1106,9 @@ async def contracts_for(self, args=None): currency : str [Optional] Currency of the contract's stake and payout (obtained from payout_currencies call). landing_company : str - [Optional] Indicates which landing company to get a list of contracts for. If you are logged in, your account's landing company will override this field. + Deprecated - Replaced by landing_company_short. + landing_company_short : str + [Optional] Indicates which landing company to get a list of contracts for. If you are logged in, your account's landing company will override this field. Note that when landing_company_short is set to 'virtual', landing_company will take precendce until the deprecated field is removed from the api. passthrough : Any [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. product_type : str @@ -1513,6 +1131,9 @@ async def contracts_for(self, args=None): 'landing_company': { 'type': 'string' }, + 'landing_company_short': { + 'type': 'string' + }, 'passthrough': {}, 'product_type': { 'type': 'string' @@ -1760,7 +1381,7 @@ async def document_upload(self, args=None): document_id : str [Optional] Document ID (required for Passport, Proof of ID and Driver's License) document_issuing_country : str - [Optional] 2-letter country code + 2-letter country code, mandatory for POI only document_type : str Document type document_upload : int @@ -2065,88 +1686,6 @@ async def get_account_status(self, args=None): return await self.process_request(all_args) - async def get_account_types(self, args=None): - """ - Types of accounts available to create or link to. - - Parameters: - ----------- - args : dict with following keys - get_account_types : Number - Must be 1 - passthrough : Any - [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - req_id : int - [Optional] Used to map request to response. - """ - - if args is None: - args = {} - - config = { - 'get_account_types': { - 'required': 1, - 'type': 'numeric' - }, - 'passthrough': {}, - 'req_id': { - 'type': 'integer' - } - } - - all_args = { - 'method': 'get_account_types', - 'needs_method_arg': '1', - 'args': args, - 'config': config, - } - - return await self.process_request(all_args) - - async def get_available_accounts_to_transfer(self, args=None): - """ - Get Available Accounts to Transfer. - - Parameters: - ----------- - args : dict with following keys - get_available_accounts_to_transfer : Number - Must be 1 - loginid : str - The unique identifier for this trading/wallet account. - passthrough : Any - [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - req_id : int - [Optional] Used to map request to response. - """ - - if args is None: - args = {} - - config = { - 'get_available_accounts_to_transfer': { - 'required': 1, - 'type': 'numeric' - }, - 'loginid': { - 'required': 1, - 'type': 'string' - }, - 'passthrough': {}, - 'req_id': { - 'type': 'integer' - } - } - - all_args = { - 'method': 'get_available_accounts_to_transfer', - 'needs_method_arg': '1', - 'args': args, - 'config': config, - } - - return await self.process_request(all_args) - async def get_financial_assessment(self, args=None): """ This call gets the financial assessment details. The 'financial assessment' is a questionnaire that clients of certain Landing Companies need to complete, due to regulatory and KYC (know your client) requirements. @@ -2306,6 +1845,8 @@ async def identity_verification_document_add(self, args=None): Parameters: ----------- args : dict with following keys + document_additional : str + [Optional] Additional info required by some document types. document_number : str The identification number of the document. document_type : str @@ -2324,6 +1865,9 @@ async def identity_verification_document_add(self, args=None): args = {} config = { + 'document_additional': { + 'type': 'string' + }, 'document_number': { 'required': 1, 'type': 'string' @@ -2400,6 +1944,8 @@ async def landing_company_details(self, args=None): Parameters: ----------- args : dict with following keys + country : str + [Optional] Will return an extra field tin_not_mandatory indicating if the landing company does not require tax identification number for the provided country. landing_company_details : str Landing company shortcode. passthrough : Any @@ -2412,6 +1958,9 @@ async def landing_company_details(self, args=None): args = {} config = { + 'country': { + 'type': 'string' + }, 'landing_company_details': { 'required': 1, 'type': 'string' @@ -2431,66 +1980,16 @@ async def landing_company_details(self, args=None): return await self.process_request(all_args) - async def link_wallet(self, args=None): + async def login_history(self, args=None): """ - Link a wallet to a trading app. + Retrieve a summary of login history for user. Parameters: ----------- args : dict with following keys - client_id : str - The unique identifier for this trading account. - link_wallet : Number - Must be 1 - passthrough : Any - [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - req_id : int - [Optional] Used to map request to response. - wallet_id : str - The unique identifier for this wallet. - """ - - if args is None: - args = {} - - config = { - 'client_id': { - 'required': 1, - 'type': 'string' - }, - 'link_wallet': { - 'required': 1, - 'type': 'numeric' - }, - 'passthrough': {}, - 'req_id': { - 'type': 'integer' - }, - 'wallet_id': { - 'required': 1, - 'type': 'string' - } - } - - all_args = { - 'method': 'link_wallet', - 'needs_method_arg': '1', - 'args': args, - 'config': config, - } - - return await self.process_request(all_args) - - async def login_history(self, args=None): - """ - Retrieve a summary of login history for user. - - Parameters: - ----------- - args : dict with following keys - limit : int - [Optional] Apply limit to count of login history records. - login_history : int + limit : int + [Optional] Apply limit to count of login history records. + login_history : int Must be 1 passthrough : Any [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. @@ -2728,7 +2227,7 @@ async def mt5_new_account(self, args=None): mainPassword : str The master password of the account. For validation (Accepts any printable ASCII character. Must be within 8-25 characters, and include numbers, lowercase and uppercase letters. Must not be the same as the user's email address). This field is required. mt5_account_category : str - [Optional] To choose whether account is conventional or not. Unavailable for financial_stp MT5_account_type + [Optional] To choose whether account is conventional or swap_free. Unavailable for financial_stp MT5_account_type mt5_account_type : str [Optional] Financial: Variable spreads, High leverage. Financial STP: Variable spreads, Medium Leverage, more products. If 'account_type' set to 'financial', setting 'mt5_account_type' is also required. mt5_new_account : int @@ -2737,7 +2236,7 @@ async def mt5_new_account(self, args=None): Client's name. The maximum length here is 101 characters. passthrough : Any [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - phone : str + phone : Any [Optional] User's phone number. phonePassword : str [Optional] The user's phone password. @@ -2747,6 +2246,8 @@ async def mt5_new_account(self, args=None): [Optional] Trade server. state : str [Optional] User's state (region) of residence. + sub_account_category : str + [Optional] Indicate the sub account category that we have in the cfd group naming convention. zipCode : str [Optional] User's zip code. """ @@ -2807,9 +2308,7 @@ async def mt5_new_account(self, args=None): 'type': 'string' }, 'passthrough': {}, - 'phone': { - 'type': 'string' - }, + 'phone': {}, 'phonePassword': { 'type': 'string' }, @@ -2820,6 +2319,9 @@ async def mt5_new_account(self, args=None): 'state': { 'type': 'string' }, + 'sub_account_category': { + 'type': 'string' + }, 'zipCode': { 'type': 'string' } @@ -3092,14 +2594,12 @@ async def new_account_maltainvest(self, args=None): [Optional] Possible value receive from states_list call. affiliate_token : str [Optional] Affiliate token, within 32 characters. - binary_options_trading_experience : str - [Optional] Binary options trading experience. - binary_options_trading_frequency : str - [Optional] Binary options trading frequency. - cfd_trading_experience : str - [Optional] CFDs trading experience. - cfd_trading_frequency : str - [Optional] CFDs trading frequency. + cfd_experience : str + How much experience do you have in CFD trading? + cfd_frequency : str + How many CFD trades have you placed in the past 12 months? + cfd_trading_definition : str + In your understanding, CFD trading allows you to: citizen : str [Optional] Country of legal citizenship, 2-letter country code. Possible value receive from residence_list call. client_type : str @@ -3113,19 +2613,19 @@ async def new_account_maltainvest(self, args=None): employment_industry : str Industry of Employment. employment_status : str - [Optional] Employment Status. + Employment Status. estimated_worth : str Estimated Net Worth. first_name : str Within 2-50 characters, use only letters, spaces, hyphens, full-stops or apostrophes. - forex_trading_experience : str - [Optional] Forex trading experience. - forex_trading_frequency : str - [Optional] Forex trading frequency. income_source : str Income Source. last_name : str Within 2-50 characters, use only letters, spaces, hyphens, full-stops or apostrophes. + leverage_impact_trading : str + How does leverage affect CFD trading? + leverage_trading_high_risk_stop_loss : str + Leverage trading is high-risk, so it's a good idea to use risk management features such as stop loss. Stop loss allows you to net_income : str Net Annual Income. new_account_maltainvest : int @@ -3134,10 +2634,6 @@ async def new_account_maltainvest(self, args=None): [Optional] Indicates client's self-declaration of not being a PEP/RCA. occupation : str Occupation. - other_instruments_trading_experience : str - [Optional] Trading experience in other financial instruments. - other_instruments_trading_frequency : str - [Optional] Trading frequency in other financial instruments. passthrough : Any [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. phone : Any @@ -3146,20 +2642,30 @@ async def new_account_maltainvest(self, args=None): [Optional] Place of birth, 2-letter country code. req_id : int [Optional] Used to map request to response. + required_initial_margin : str + When would you be required to pay an initial margin? residence : str 2-letter country code, possible value receive from residence_list call. + risk_tolerance : str + Do you understand that you could potentially lose 100% of the money you use to trade? salutation : str Accept any value in enum list. secret_answer : str [Optional] Answer to secret question, within 4-50 characters. secret_question : str [Optional] Accept any value in enum list. + source_of_experience : str + How much knowledge and experience do you have in relation to online trading? source_of_wealth : str [Optional] Source of wealth. tax_identification_number : str Tax identification number. Only applicable for real money account. Required for maltainvest landing company. tax_residence : str Residence for tax purpose. Comma separated iso country code if multiple jurisdictions. Only applicable for real money account. Required for maltainvest landing company. + trading_experience_financial_instruments : str + How much experience do you have with other financial instruments? + trading_frequency_financial_instruments : str + How many trades have you placed with other financial instruments in the past 12 months? """ if args is None: @@ -3167,7 +2673,6 @@ async def new_account_maltainvest(self, args=None): config = { 'accept_risk': { - 'required': 1, 'type': 'integer' }, 'account_opening_reason': { @@ -3196,16 +2701,13 @@ async def new_account_maltainvest(self, args=None): 'affiliate_token': { 'type': 'string' }, - 'binary_options_trading_experience': { - 'type': 'string' - }, - 'binary_options_trading_frequency': { + 'cfd_experience': { 'type': 'string' }, - 'cfd_trading_experience': { + 'cfd_frequency': { 'type': 'string' }, - 'cfd_trading_frequency': { + 'cfd_trading_definition': { 'type': 'string' }, 'citizen': { @@ -3222,40 +2724,36 @@ async def new_account_maltainvest(self, args=None): 'type': 'string' }, 'education_level': { - 'required': 1, 'type': 'string' }, 'employment_industry': { - 'required': 1, 'type': 'string' }, 'employment_status': { + 'required': 1, 'type': 'string' }, 'estimated_worth': { - 'required': 1, 'type': 'string' }, 'first_name': { 'required': 1, 'type': 'string' }, - 'forex_trading_experience': { + 'income_source': { 'type': 'string' }, - 'forex_trading_frequency': { + 'last_name': { + 'required': 1, 'type': 'string' }, - 'income_source': { - 'required': 1, + 'leverage_impact_trading': { 'type': 'string' }, - 'last_name': { - 'required': 1, + 'leverage_trading_high_risk_stop_loss': { 'type': 'string' }, 'net_income': { - 'required': 1, 'type': 'string' }, 'new_account_maltainvest': { @@ -3266,13 +2764,6 @@ async def new_account_maltainvest(self, args=None): 'type': 'integer' }, 'occupation': { - 'required': 1, - 'type': 'string' - }, - 'other_instruments_trading_experience': { - 'type': 'string' - }, - 'other_instruments_trading_frequency': { 'type': 'string' }, 'passthrough': {}, @@ -3283,10 +2774,16 @@ async def new_account_maltainvest(self, args=None): 'req_id': { 'type': 'integer' }, + 'required_initial_margin': { + 'type': 'string' + }, 'residence': { 'required': 1, 'type': 'string' }, + 'risk_tolerance': { + 'type': 'string' + }, 'salutation': { 'required': 1, 'type': 'string' @@ -3297,6 +2794,9 @@ async def new_account_maltainvest(self, args=None): 'secret_question': { 'type': 'string' }, + 'source_of_experience': { + 'type': 'string' + }, 'source_of_wealth': { 'type': 'string' }, @@ -3307,6 +2807,12 @@ async def new_account_maltainvest(self, args=None): 'tax_residence': { 'required': 1, 'type': 'string' + }, + 'trading_experience_financial_instruments': { + 'type': 'string' + }, + 'trading_frequency_financial_instruments': { + 'type': 'string' } } @@ -3587,160 +3093,6 @@ async def new_account_virtual(self, args=None): return await self.process_request(all_args) - async def new_account_wallet(self, args=None): - """ - Create a new account real-money wallet account. - - Parameters: - ----------- - args : dict with following keys - address_city : str - [Optional] Within 35 characters. - address_line_1 : str - [Optional] Mailing address. - address_line_2 : str - [Optional] Within 70 characters. - address_postcode : str - [Optional] Within 20 characters and may not contain '+'. - address_state : str - [Optional] Possible value receive from states_list call. - currency : str - [Optional] To set currency of the account. List of supported currencies can be acquired with payout_currencies call. - date_of_birth : str - [Optional] Date of birth format: yyyy-mm-dd. - first_name : str - [Optional] Within 2-50 characters, use only letters, spaces, hyphens, full-stops or apostrophes. - last_name : str - [Optional] Within 2-50 characters, use only letters, spaces, hyphens, full-stops or apostrophes. - new_account_wallet : int - Must be 1 - non_pep_declaration : int - [Optional] Indicates client's self-declaration of not being a PEP/RCA (Politically Exposed Person/Relatives and Close Associates). - passthrough : Any - [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - payment_method : str - To set method which is used to transfer to/from wallet. - phone : str - [Optional] Starting with + followed by 8-35 digits, allowing hyphens or space. - req_id : int - [Optional] Used to map request to response. - """ - - if args is None: - args = {} - - config = { - 'address_city': { - 'type': 'string' - }, - 'address_line_1': { - 'type': 'string' - }, - 'address_line_2': { - 'type': 'string' - }, - 'address_postcode': { - 'type': 'string' - }, - 'address_state': { - 'type': 'string' - }, - 'currency': { - 'required': 1, - 'type': 'string' - }, - 'date_of_birth': { - 'type': 'string' - }, - 'first_name': { - 'type': 'string' - }, - 'last_name': { - 'type': 'string' - }, - 'new_account_wallet': { - 'required': 1, - 'type': 'integer' - }, - 'non_pep_declaration': { - 'type': 'integer' - }, - 'passthrough': {}, - 'payment_method': { - 'required': 1, - 'type': 'string' - }, - 'phone': { - 'type': 'string' - }, - 'req_id': { - 'type': 'integer' - } - } - - all_args = { - 'method': 'new_account_wallet', - 'needs_method_arg': '1', - 'args': args, - 'config': config, - } - - return await self.process_request(all_args) - - async def notification_event(self, args=None): - """ - Notify the backend about a specific event. - - Parameters: - ----------- - args : dict with following keys - args : Any - category : str - The category or nature of the event. - event : str - The name of the event. - notification_event : int - Must be 1 - passthrough : Any - [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - req_id : int - [Optional] Used to map request to response. - """ - - if args is None: - args = {} - - config = { - 'args': { - 'documents': {} - }, - 'category': { - 'required': 1, - 'type': 'string' - }, - 'event': { - 'required': 1, - 'type': 'string' - }, - 'notification_event': { - 'required': 1, - 'type': 'integer' - }, - 'passthrough': {}, - 'req_id': { - 'type': 'integer' - } - } - - all_args = { - 'method': 'notification_event', - 'needs_method_arg': '1', - 'args': args, - 'config': config, - } - - return await self.process_request(all_args) - async def oauth_apps(self, args=None): """ List all my used OAuth applications. @@ -3788,6 +3140,8 @@ async def p2p_advert_create(self, args=None): args : dict with following keys amount : Number The total amount of the advert, in advertiser's account currency. + block_trade : int + [Optional] Indicates if this is block trade ad or not. Default: 0. contact_info : str [Optional] Advertiser contact information. description : str @@ -3828,6 +3182,9 @@ async def p2p_advert_create(self, args=None): 'required': 1, 'type': 'numeric' }, + 'block_trade': { + 'type': 'integer' + }, 'contact_info': { 'type': 'string' }, @@ -3949,6 +3306,8 @@ async def p2p_advert_list(self, args=None): [Optional] Search for advertiser by name. Partial matches will be returned. amount : Number [Optional] How much to buy or sell, used to calculate prices. + block_trade : int + [Optional] Return block trade adverts when 1, non-block trade adverts when 0 (default). counterparty_type : str [Optional] Filter the adverts by counterparty_type. favourites_only : int @@ -3956,7 +3315,7 @@ async def p2p_advert_list(self, args=None): limit : int [Optional] Used for paging. local_currency : str - [Optional] Currency to conduct payment transaction in, defaults to the main currency for the client's country. + [Optional] Currency to conduct payment transaction in. If not provided, only ads from country of residence will be returned. offset : int [Optional] Used for paging. p2p_advert_list : int @@ -3986,6 +3345,9 @@ async def p2p_advert_list(self, args=None): 'amount': { 'type': 'numeric' }, + 'block_trade': { + 'type': 'integer' + }, 'counterparty_type': { 'type': 'string' }, @@ -4292,37 +3654,105 @@ async def p2p_advertiser_info(self, args=None): return await self.process_request(all_args) - async def p2p_advertiser_payment_methods(self, args=None): + async def p2p_advertiser_list(self, args=None): """ - Manage or list P2P advertiser payment methods. + Retrieve advertisers has/had trade with the current advertiser. Parameters: ----------- args : dict with following keys - create : Any - Contains new payment method entries. - delete : Any - Contains payment methods to delete. - p2p_advertiser_payment_methods : int + advertiser_name : str + [Optional] Search for advertiser by name. Partial matches will be returned. + is_blocked : int + [Optional] Used to return only blocked or unblocked partners + limit : int + [Optional] Used for paging. + offset : int + [Optional] Used for paging. + p2p_advertiser_list : int Must be 1 passthrough : Any [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. req_id : int [Optional] Used to map request to response. - update : Any - Contains payment methods to update. + sort_by : str + [Optional] How the results are sorted. + trade_partners : int + [Optional] Get all advertisers has/had trade. """ if args is None: args = {} config = { - 'create': {}, - 'delete': {}, - 'p2p_advertiser_payment_methods': { - 'required': 1, - 'type': 'integer' - }, + 'advertiser_name': { + 'type': 'string' + }, + 'is_blocked': { + 'type': 'integer' + }, + 'limit': { + 'type': 'integer' + }, + 'offset': { + 'type': 'integer' + }, + 'p2p_advertiser_list': { + 'required': 1, + 'type': 'integer' + }, + 'passthrough': {}, + 'req_id': { + 'type': 'integer' + }, + 'sort_by': { + 'type': 'string' + }, + 'trade_partners': { + 'type': 'integer' + } + } + + all_args = { + 'method': 'p2p_advertiser_list', + 'needs_method_arg': '1', + 'args': args, + 'config': config, + } + + return await self.process_request(all_args) + + async def p2p_advertiser_payment_methods(self, args=None): + """ + Manage or list P2P advertiser payment methods. + + Parameters: + ----------- + args : dict with following keys + create : Any + Contains new payment method entries. + delete : Any + Contains payment methods to delete. + p2p_advertiser_payment_methods : int + Must be 1 + passthrough : Any + [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. + req_id : int + [Optional] Used to map request to response. + update : Any + Contains payment methods to update. + """ + + if args is None: + args = {} + + config = { + 'create': {}, + 'delete': {}, + 'p2p_advertiser_payment_methods': { + 'required': 1, + 'type': 'integer' + }, 'passthrough': {}, 'req_id': { 'type': 'integer' @@ -4412,6 +3842,8 @@ async def p2p_advertiser_update(self, args=None): [Optional] Used to map request to response. show_name : int [Optional] When 1, the advertiser's real name will be displayed on to other users on adverts and orders. + upgrade_limits : int + [Optional] Used to upgrade daily limits of eligible advertiser. """ if args is None: @@ -4440,6 +3872,9 @@ async def p2p_advertiser_update(self, args=None): }, 'show_name': { 'type': 'integer' + }, + 'upgrade_limits': { + 'type': 'integer' } } @@ -4547,6 +3982,8 @@ async def p2p_order_confirm(self, args=None): Parameters: ----------- args : dict with following keys + dry_run : int + [Optional] If set to 1, only validation is performed. id : str The unique identifier for this order. p2p_order_confirm : int @@ -4555,12 +3992,17 @@ async def p2p_order_confirm(self, args=None): [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. req_id : int [Optional] Used to map request to response. + verification_code : str + [Optional] Verification code received from email. """ if args is None: args = {} config = { + 'dry_run': { + 'type': 'integer' + }, 'id': { 'required': 1, 'type': 'string' @@ -4572,6 +4014,9 @@ async def p2p_order_confirm(self, args=None): 'passthrough': {}, 'req_id': { 'type': 'integer' + }, + 'verification_code': { + 'type': 'string' } } @@ -5302,6 +4747,49 @@ async def paymentagent_withdraw(self, args=None): return await self.process_request(all_args) + async def paymentagent_withdraw_justification(self, args=None): + """ + Provide justification to perform withdrawal using a Payment Agent. + + Parameters: + ----------- + args : dict with following keys + message : str + Reasons for needing to withdraw using a Payment Agent. + passthrough : Any + [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. + paymentagent_withdraw_justification : int + Must be 1 + req_id : int + [Optional] Used to map request to response. + """ + + if args is None: + args = {} + + config = { + 'message': { + 'type': 'string' + }, + 'passthrough': {}, + 'paymentagent_withdraw_justification': { + 'required': 1, + 'type': 'integer' + }, + 'req_id': { + 'type': 'integer' + } + } + + all_args = { + 'method': 'paymentagent_withdraw_justification', + 'needs_method_arg': '1', + 'args': args, + 'config': config, + } + + return await self.process_request(all_args) + async def payout_currencies(self, args=None): """ Retrieve a list of available option payout currencies. If a user is logged in, only the currencies available for the account will be returned. @@ -5436,7 +4924,7 @@ async def profit_table(self, args=None): [Optional] If set to 1, will return full contracts description. limit : Number [Optional] Apply upper limit to count of transactions received. - offset : Number + offset : int [Optional] Number of transactions to skip. passthrough : Any [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. @@ -5466,7 +4954,7 @@ async def profit_table(self, args=None): 'type': 'numeric' }, 'offset': { - 'type': 'numeric' + 'type': 'integer' }, 'passthrough': {}, 'profit_table': { @@ -5521,6 +5009,8 @@ async def proposal(self, args=None): [Optional] Duration quantity. Either date_expiry or duration is required. duration_unit : str [Optional] Duration unit - s: seconds, m: minutes, h: hours, d: days, t: ticks. + growth_rate : Number + [Optional] Growth rate of an accumulator contract. limit_order : Any multiplier : Number [Optional] The multiplier for non-binary options. E.g. lookbacks. @@ -5584,6 +5074,9 @@ async def proposal(self, args=None): 'duration_unit': { 'type': 'string' }, + 'growth_rate': { + 'type': 'numeric' + }, 'limit_order': { 'stop_loss': { 'type': 'numeric' @@ -5716,117 +5209,6 @@ async def reality_check(self, args=None): return await self.process_request(all_args) - async def request_report(self, args=None): - """ - Send report to client's registered e-mail - - Parameters: - ----------- - args : dict with following keys - date_from : int - Start date of the report - date_to : int - End date of the report - passthrough : Any - [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - report_type : str - Type of report to be sent to client's registered e-mail address - req_id : int - [Optional] Used to map request to response. - request_report : int - Must be 1 - """ - - if args is None: - args = {} - - config = { - 'date_from': { - 'required': 1, - 'type': 'integer' - }, - 'date_to': { - 'required': 1, - 'type': 'integer' - }, - 'passthrough': {}, - 'report_type': { - 'required': 1, - 'type': 'string' - }, - 'req_id': { - 'type': 'integer' - }, - 'request_report': { - 'required': 1, - 'type': 'integer' - } - } - - all_args = { - 'method': 'request_report', - 'needs_method_arg': '1', - 'args': args, - 'config': config, - } - - return await self.process_request(all_args) - - async def reset_password(self, args=None): - """ - Reset Password. - - Parameters: - ----------- - args : dict with following keys - date_of_birth : str - [Optional] Date of birth format: yyyy-mm-dd. Only required for clients with real-money accounts. - new_password : str - New password. For validation (Accepts any printable ASCII character. Must be within 8-25 characters, and include numbers, lowercase and uppercase letters. Must not be the same as the user's email address). - passthrough : Any - [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - req_id : int - [Optional] Used to map request to response. - reset_password : int - Must be 1 - verification_code : str - Email verification code (received from a verify_email call, which must be done first) - """ - - if args is None: - args = {} - - config = { - 'date_of_birth': { - 'type': 'string' - }, - 'new_password': { - 'required': 1, - 'type': 'string' - }, - 'passthrough': {}, - 'req_id': { - 'type': 'integer' - }, - 'reset_password': { - 'required': 1, - 'type': 'integer' - }, - 'verification_code': { - 'required': 1, - 'type': 'string' - } - } - - all_args = { - 'method': 'reset_password', - 'needs_method_arg': '1', - 'args': args, - 'config': config, - } - - return await self.process_request(all_args) - async def residence_list(self, args=None): """ This call returns a list of countries and 2-letter country codes, suitable for populating the account opening form. @@ -6040,64 +5422,6 @@ async def sell_expired(self, args=None): return await self.process_request(all_args) - async def service_token(self, args=None): - """ - Retrieves the authorization token for the specified service. - - Parameters: - ----------- - args : dict with following keys - country : str - [Optional] The 2-letter country code. - passthrough : Any - [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - referrer : str - [Optional] The URL of the web page where the Web SDK will be used. - req_id : int - [Optional] Used to map request to response. - server : str - Server (dxtrade only). - service : Any - The service(s) to retrieve token(s) for. - service_token : int - Must be 1 - """ - - if args is None: - args = {} - - config = { - 'country': { - 'type': 'string' - }, - 'passthrough': {}, - 'referrer': { - 'type': 'string' - }, - 'req_id': { - 'type': 'integer' - }, - 'server': { - 'type': 'string' - }, - 'service': { - 'required': 1 - }, - 'service_token': { - 'required': 1, - 'type': 'integer' - } - } - - all_args = { - 'method': 'service_token', - 'needs_method_arg': '1', - 'args': args, - 'config': config, - } - - return await self.process_request(all_args) - async def set_account_currency(self, args=None): """ Set account currency, this will be default currency for your account i.e currency for trading, deposit. Please note that account currency can only be set once, and then can never be changed. @@ -6154,23 +5478,24 @@ async def set_financial_assessment(self, args=None): cfd_trading_frequency : str [Optional] CFDs trading frequency. education_level : str - Level of Education. + [Optional] Level of Education. employment_industry : str - Industry of Employment. + [Optional] Industry of Employment. employment_status : str [Optional] Employment Status. estimated_worth : str - Estimated Net Worth. + [Optional] Estimated Net Worth. + financial_information : Any forex_trading_experience : str [Optional] Forex trading experience. forex_trading_frequency : str [Optional] Forex trading frequency. income_source : str - Income Source. + [Optional] Income Source. net_income : str - Net Annual Income. + [Optional] Net Annual Income. occupation : str - Occupation. + [Optional] Occupation. other_instruments_trading_experience : str [Optional] Trading experience in other financial instruments. other_instruments_trading_frequency : str @@ -6183,6 +5508,8 @@ async def set_financial_assessment(self, args=None): Must be 1 source_of_wealth : str [Optional] Source of wealth. + trading_experience : Any + trading_experience_regulated : Any """ if args is None: @@ -6205,20 +5532,52 @@ async def set_financial_assessment(self, args=None): 'type': 'string' }, 'education_level': { - 'required': 1, 'type': 'string' }, 'employment_industry': { - 'required': 1, 'type': 'string' }, 'employment_status': { 'type': 'string' }, 'estimated_worth': { - 'required': 1, 'type': 'string' }, + 'financial_information': { + 'account_turnover': { + 'type': 'string' + }, + 'education_level': { + 'required': 1, + 'type': 'string' + }, + 'employment_industry': { + 'required': 1, + 'type': 'string' + }, + 'employment_status': { + 'type': 'string' + }, + 'estimated_worth': { + 'required': 1, + 'type': 'string' + }, + 'income_source': { + 'required': 1, + 'type': 'string' + }, + 'net_income': { + 'required': 1, + 'type': 'string' + }, + 'occupation': { + 'required': 1, + 'type': 'string' + }, + 'source_of_wealth': { + 'type': 'string' + } + }, 'forex_trading_experience': { 'type': 'string' }, @@ -6226,15 +5585,12 @@ async def set_financial_assessment(self, args=None): 'type': 'string' }, 'income_source': { - 'required': 1, 'type': 'string' }, 'net_income': { - 'required': 1, 'type': 'string' }, 'occupation': { - 'required': 1, 'type': 'string' }, 'other_instruments_trading_experience': { @@ -6253,6 +5609,74 @@ async def set_financial_assessment(self, args=None): }, 'source_of_wealth': { 'type': 'string' + }, + 'trading_experience': { + 'binary_options_trading_experience': { + 'type': 'string' + }, + 'binary_options_trading_frequency': { + 'type': 'string' + }, + 'cfd_trading_experience': { + 'type': 'string' + }, + 'cfd_trading_frequency': { + 'type': 'string' + }, + 'forex_trading_experience': { + 'type': 'string' + }, + 'forex_trading_frequency': { + 'type': 'string' + }, + 'other_instruments_trading_experience': { + 'type': 'string' + }, + 'other_instruments_trading_frequency': { + 'type': 'string' + } + }, + 'trading_experience_regulated': { + 'cfd_experience': { + 'required': 1, + 'type': 'string' + }, + 'cfd_frequency': { + 'required': 1, + 'type': 'string' + }, + 'cfd_trading_definition': { + 'required': 1, + 'type': 'string' + }, + 'leverage_impact_trading': { + 'required': 1, + 'type': 'string' + }, + 'leverage_trading_high_risk_stop_loss': { + 'required': 1, + 'type': 'string' + }, + 'required_initial_margin': { + 'required': 1, + 'type': 'string' + }, + 'risk_tolerance': { + 'required': 1, + 'type': 'string' + }, + 'source_of_experience': { + 'required': 1, + 'type': 'string' + }, + 'trading_experience_financial_instruments': { + 'required': 1, + 'type': 'string' + }, + 'trading_frequency_financial_instruments': { + 'required': 1, + 'type': 'string' + } } } @@ -6370,8 +5794,12 @@ async def set_settings(self, args=None): [Optional] Country of legal citizenship, 2-letter country code. date_of_birth : str [Optional] Date of birth format: yyyy-mm-dd (can only be changed on unauthenticated svg accounts). + dxtrade_user_exception : int + Boolean value 1 or 0, indicating if user email belong to dxtrade exception list. email_consent : int [Optional] Boolean value 1 or 0, indicating permission to use email address for any contact which may include marketing + employment_status : str + [Optional] Employment Status. feature_flag : Any first_name : str [Optional] Within 2-50 characters, use only letters, spaces, hyphens, full-stops or apostrophes (can only be changed on unauthenticated svg accounts). @@ -6405,6 +5833,8 @@ async def set_settings(self, args=None): [Optional] Tax identification number. Only applicable for real money account. Required for maltainvest landing company. tax_residence : str [Optional] Residence for tax purpose. Comma separated iso country code if multiple jurisdictions. Only applicable for real money account. Required for maltainvest landing company. + trading_hub : int + [Optional] Enable/Disable Trading Hub dashboard """ if args is None: @@ -6434,9 +5864,15 @@ async def set_settings(self, args=None): 'date_of_birth': { 'type': 'string' }, + 'dxtrade_user_exception': { + 'type': 'integer' + }, 'email_consent': { 'type': 'integer' }, + 'employment_status': { + 'type': 'string' + }, 'feature_flag': { 'wallet': { 'type': 'integer' @@ -6482,6 +5918,9 @@ async def set_settings(self, args=None): }, 'tax_residence': { 'type': 'string' + }, + 'trading_hub': { + 'type': 'integer' } } @@ -6511,7 +5950,7 @@ async def statement(self, args=None): [Optional] If set to 1, will return full contracts description. limit : Number [Optional] Maximum number of transactions to receive. - offset : Number + offset : int [Optional] Number of transactions to skip. passthrough : Any [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. @@ -6541,7 +5980,7 @@ async def statement(self, args=None): 'type': 'numeric' }, 'offset': { - 'type': 'numeric' + 'type': 'integer' }, 'passthrough': {}, 'req_id': { @@ -6850,6 +6289,8 @@ async def trading_durations(self, args=None): ----------- args : dict with following keys landing_company : str + Deprecated - Replaced by landing_company_short. + landing_company_short : str [Optional] If specified, will return only the underlyings for the specified landing company. passthrough : Any [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. @@ -6866,6 +6307,9 @@ async def trading_durations(self, args=None): 'landing_company': { 'type': 'string' }, + 'landing_company_short': { + 'type': 'string' + }, 'passthrough': {}, 'req_id': { 'type': 'integer' @@ -6885,27 +6329,41 @@ async def trading_durations(self, args=None): return await self.process_request(all_args) - async def trading_platform_accounts(self, args=None): + async def trading_platform_investor_password_reset(self, args=None): """ - Get list of Trading Platform accounts for client + Reset the investor password of a Trading Platform Account Parameters: ----------- args : dict with following keys + account_id : str + Trading account ID. + new_password : str + New password of the account. For validation (Accepts any printable ASCII character. Must be within 8-25 characters, and include numbers, lowercase and uppercase letters. Must not be the same as the user's email address). passthrough : Any [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. platform : str - Trading platform name + Name of trading platform. req_id : int [Optional] Used to map request to response. - trading_platform_accounts : int + trading_platform_investor_password_reset : int Must be 1 + verification_code : str + Email verification code (received from a verify_email call, which must be done first) """ if args is None: args = {} config = { + 'account_id': { + 'required': 1, + 'type': 'string' + }, + 'new_password': { + 'required': 1, + 'type': 'string' + }, 'passthrough': {}, 'platform': { 'required': 1, @@ -6914,14 +6372,18 @@ async def trading_platform_accounts(self, args=None): 'req_id': { 'type': 'integer' }, - 'trading_platform_accounts': { + 'trading_platform_investor_password_reset': { 'required': 1, 'type': 'integer' + }, + 'verification_code': { + 'required': 1, + 'type': 'string' } } all_args = { - 'method': 'trading_platform_accounts', + 'method': 'trading_platform_investor_password_reset', 'needs_method_arg': '1', 'args': args, 'config': config, @@ -6929,37 +6391,33 @@ async def trading_platform_accounts(self, args=None): return await self.process_request(all_args) - async def trading_platform_deposit(self, args=None): + async def trading_platform_password_reset(self, args=None): """ - Deposit funds from wallet account to trading platform account + Reset the password of a Trading Platform Account Parameters: ----------- args : dict with following keys - amount : Number - Amount to deposit (in the currency of from_wallet). - from_account : str - Wallet account to transfer money from. + new_password : str + New password of the account. For validation (Accepts any printable ASCII character. Must be within 8-25 characters, and include numbers, lowercase and uppercase letters. Must not be the same as the user's email address). passthrough : Any [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. platform : str Name of trading platform. req_id : int [Optional] Used to map request to response. - to_account : str - Trading account login to deposit money to. - trading_platform_deposit : int + trading_platform_password_reset : int Must be 1 + verification_code : str + Email verification code (received from a verify_email call, which must be done first) """ if args is None: args = {} config = { - 'amount': { - 'type': 'numeric' - }, - 'from_account': { + 'new_password': { + 'required': 1, 'type': 'string' }, 'passthrough': {}, @@ -6970,18 +6428,18 @@ async def trading_platform_deposit(self, args=None): 'req_id': { 'type': 'integer' }, - 'to_account': { + 'trading_platform_password_reset': { 'required': 1, - 'type': 'string' + 'type': 'integer' }, - 'trading_platform_deposit': { + 'verification_code': { 'required': 1, - 'type': 'integer' + 'type': 'string' } } all_args = { - 'method': 'trading_platform_deposit', + 'method': 'trading_platform_password_reset', 'needs_method_arg': '1', 'args': args, 'config': config, @@ -6989,26 +6447,26 @@ async def trading_platform_deposit(self, args=None): return await self.process_request(all_args) - async def trading_platform_investor_password_change(self, args=None): + async def trading_servers(self, args=None): """ - Change the Trading Platform investor password + Get the list of servers for a trading platform. Parameters: ----------- args : dict with following keys - account_id : str - Trading account ID. - new_password : str - New investor password. Accepts any printable ASCII character. Must be within 8-25 characters, and include numbers, lowercase and uppercase letters. Must not be the same as the user's email address. - old_password : str - Old investor password for validation (non-empty string, accepts any printable ASCII character) + account_type : str + [Optional] Trading account type. + environment : str + [Optional] Pass the environment (installation) instance. Currently, there are one demo and two real environments. Defaults to 'all'. + market_type : str + [Optional] Market type. passthrough : Any [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. platform : str - Name of trading platform. + [Optional] Pass the trading platform name, default to mt5 req_id : int [Optional] Used to map request to response. - trading_platform_investor_password_change : Number + trading_servers : int Must be 1 """ @@ -7016,34 +6474,30 @@ async def trading_platform_investor_password_change(self, args=None): args = {} config = { - 'account_id': { - 'required': 1, + 'account_type': { 'type': 'string' }, - 'new_password': { - 'required': 1, + 'environment': { 'type': 'string' }, - 'old_password': { - 'required': 1, + 'market_type': { 'type': 'string' }, 'passthrough': {}, 'platform': { - 'required': 1, 'type': 'string' }, 'req_id': { 'type': 'integer' }, - 'trading_platform_investor_password_change': { + 'trading_servers': { 'required': 1, - 'type': 'numeric' + 'type': 'integer' } } all_args = { - 'method': 'trading_platform_investor_password_change', + 'method': 'trading_servers', 'needs_method_arg': '1', 'args': args, 'config': config, @@ -7051,61 +6505,37 @@ async def trading_platform_investor_password_change(self, args=None): return await self.process_request(all_args) - async def trading_platform_investor_password_reset(self, args=None): + async def trading_times(self, args=None): """ - Reset the investor password of a Trading Platform Account + Receive a list of market opening times for a given date. Parameters: ----------- args : dict with following keys - account_id : str - Trading account ID. - new_password : str - New password of the account. For validation (Accepts any printable ASCII character. Must be within 8-25 characters, and include numbers, lowercase and uppercase letters. Must not be the same as the user's email address). passthrough : Any [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - platform : str - Name of trading platform. req_id : int [Optional] Used to map request to response. - trading_platform_investor_password_reset : int - Must be 1 - verification_code : str - Email verification code (received from a verify_email call, which must be done first) + trading_times : str + Date to receive market opening times for. (yyyy-mm-dd format. today can also be specified). """ if args is None: args = {} config = { - 'account_id': { - 'required': 1, - 'type': 'string' - }, - 'new_password': { - 'required': 1, - 'type': 'string' - }, 'passthrough': {}, - 'platform': { - 'required': 1, - 'type': 'string' - }, 'req_id': { 'type': 'integer' }, - 'trading_platform_investor_password_reset': { - 'required': 1, - 'type': 'integer' - }, - 'verification_code': { + 'trading_times': { 'required': 1, 'type': 'string' } } all_args = { - 'method': 'trading_platform_investor_password_reset', + 'method': 'trading_times', 'needs_method_arg': '1', 'args': args, 'config': config, @@ -7113,32 +6543,20 @@ async def trading_platform_investor_password_reset(self, args=None): return await self.process_request(all_args) - async def trading_platform_new_account(self, args=None): + async def transaction(self, args=None): """ - This call creates new Trading account, either demo or real money. + Subscribe to transaction notifications Parameters: ----------- args : dict with following keys - account_type : str - Account type. - currency : str - [Optional] Trading account currency, the default value will be the qualified account currency. - dry_run : int - [Optional] If set to 1, only validation is performed. - market_type : str - Market type passthrough : Any [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - password : str - The master password of the account. For validation (Accepts any printable ASCII character. Must be within 8-25 characters, and include numbers, lowercase and uppercase letters. Must not be the same as the user's email address). This field is required. - platform : str - Name of trading platform. req_id : int [Optional] Used to map request to response. - sub_account_type : str - [Optional] Sub account type. - trading_platform_new_account : int + subscribe : int + If set to 1, will send updates whenever there is an update to transactions. If not to 1 then it will not return any records. + transaction : int Must be 1 """ @@ -7146,43 +6564,22 @@ async def trading_platform_new_account(self, args=None): args = {} config = { - 'account_type': { - 'required': 1, - 'type': 'string' - }, - 'currency': { - 'type': 'string' - }, - 'dry_run': { - 'type': 'integer' - }, - 'market_type': { - 'required': 1, - 'type': 'string' - }, 'passthrough': {}, - 'password': { - 'required': 1, - 'type': 'string' - }, - 'platform': { - 'required': 1, - 'type': 'string' - }, 'req_id': { 'type': 'integer' }, - 'sub_account_type': { - 'type': 'string' + 'subscribe': { + 'required': 1, + 'type': 'integer' }, - 'trading_platform_new_account': { + 'transaction': { 'required': 1, 'type': 'integer' } } all_args = { - 'method': 'trading_platform_new_account', + 'method': 'transaction', 'needs_method_arg': '1', 'args': args, 'config': config, @@ -7190,219 +6587,62 @@ async def trading_platform_new_account(self, args=None): return await self.process_request(all_args) - async def trading_platform_password_change(self, args=None): + async def transfer_between_accounts(self, args=None): """ - Change the Trading Platform password + This call allows transfers between accounts held by a given user. Transfer funds between your fiat and cryptocurrency accounts (for a fee). Please note that account_from should be same as current authorized account. Parameters: ----------- args : dict with following keys - new_password : str - New trading password. Accepts any printable ASCII character. Must be within 8-25 characters, and include numbers, lowercase and uppercase letters. Must not be the same as the user's email address. - old_password : str - Old password for validation. Must be empty if a password has not been set yet. - passthrough : Any - [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - platform : str - Name of trading platform. - req_id : int - [Optional] Used to map request to response. - trading_platform_password_change : Number - Must be 1 - """ - - if args is None: - args = {} - - config = { - 'new_password': { - 'required': 1, - 'type': 'string' - }, - 'old_password': { - 'type': 'string' - }, - 'passthrough': {}, - 'platform': { - 'required': 1, - 'type': 'string' - }, - 'req_id': { - 'type': 'integer' - }, - 'trading_platform_password_change': { - 'required': 1, - 'type': 'numeric' - } - } - - all_args = { - 'method': 'trading_platform_password_change', - 'needs_method_arg': '1', - 'args': args, - 'config': config, - } - - return await self.process_request(all_args) - - async def trading_platform_password_reset(self, args=None): - """ - Reset the password of a Trading Platform Account - - Parameters: - ----------- - args : dict with following keys - new_password : str - New password of the account. For validation (Accepts any printable ASCII character. Must be within 8-25 characters, and include numbers, lowercase and uppercase letters. Must not be the same as the user's email address). + account_from : str + [Optional] The loginid of the account to transfer funds from. + account_to : str + [Optional] The loginid of the account to transfer funds to. + accounts : str + [Optional] To control the list of accounts returned when account_from or account_to is not provided. brief (default value) means that accounts with mt5 account_type will be excluded; it will run faster. all means that all accounts with any account_type (including mt5) will be returned. + amount : Number + [Optional] The amount to transfer. + currency : str + [Optional] Currency code. passthrough : Any [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - platform : str - Name of trading platform. req_id : int [Optional] Used to map request to response. - trading_platform_password_reset : int - Must be 1 - verification_code : str - Email verification code (received from a verify_email call, which must be done first) + transfer_between_accounts : int + If account_from or account_to is not provided, it just returns the available accounts. """ if args is None: args = {} config = { - 'new_password': { - 'required': 1, + 'account_from': { 'type': 'string' }, - 'passthrough': {}, - 'platform': { - 'required': 1, + 'account_to': { 'type': 'string' }, - 'req_id': { - 'type': 'integer' - }, - 'trading_platform_password_reset': { - 'required': 1, - 'type': 'integer' - }, - 'verification_code': { - 'required': 1, - 'type': 'string' - } - } - - all_args = { - 'method': 'trading_platform_password_reset', - 'needs_method_arg': '1', - 'args': args, - 'config': config, - } - - return await self.process_request(all_args) - - async def trading_platform_product_listing(self, args=None): - """ - Get list of Trading Platform products for client - - Parameters: - ----------- - args : dict with following keys - app_id : Any - [Optional] Specific application app_id. - country_code : str - [Optional] Country of legal citizenship, 2-letter country code. - passthrough : Any - [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - req_id : int - [Optional] Used to map request to response. - trading_platform_product_listing : int - Must be 1. - """ - - if args is None: - args = {} - - config = { - 'app_id': {}, - 'country_code': { - 'required': 1, + 'accounts': { 'type': 'string' }, - 'passthrough': {}, - 'req_id': { - 'type': 'integer' - }, - 'trading_platform_product_listing': { - 'required': 1, - 'type': 'integer' - } - } - - all_args = { - 'method': 'trading_platform_product_listing', - 'needs_method_arg': '1', - 'args': args, - 'config': config, - } - - return await self.process_request(all_args) - - async def trading_platform_withdrawal(self, args=None): - """ - This call allows withdrawal from Trading account to a wallet account. - - Parameters: - ----------- - args : dict with following keys - amount : Number - Amount to withdraw (in the currency of the Trading account). - from_account : str - Trading account login to withdraw money from. - passthrough : Any - [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - platform : str - Name of trading platform. - req_id : int - [Optional] Used to map request to response. - to_account : str - Wallet account loginid to transfer money to. - trading_platform_withdrawal : int - Must be 1 - """ - - if args is None: - args = {} - - config = { 'amount': { - 'required': 1, 'type': 'numeric' }, - 'from_account': { - 'required': 1, + 'currency': { 'type': 'string' }, 'passthrough': {}, - 'platform': { - 'required': 1, - 'type': 'string' - }, 'req_id': { 'type': 'integer' }, - 'to_account': { - 'required': 1, - 'type': 'string' - }, - 'trading_platform_withdrawal': { + 'transfer_between_accounts': { 'required': 1, 'type': 'integer' } } all_args = { - 'method': 'trading_platform_withdrawal', + 'method': 'transfer_between_accounts', 'needs_method_arg': '1', 'args': args, 'config': config, @@ -7410,26 +6650,22 @@ async def trading_platform_withdrawal(self, args=None): return await self.process_request(all_args) - async def trading_servers(self, args=None): + async def unsubscribe_email(self, args=None): """ - Get the list of servers for a trading platform. + It unsubscribe user from the email subscription. Parameters: ----------- args : dict with following keys - account_type : str - [Optional] Trading account type. - environment : str - [Optional] Pass the environment (installation) instance. Currently, there are one demo and two real environments. Defaults to 'all'. - market_type : str - [Optional] Market type. + binary_user_id : Number + Customer User ID. + checksum : str + The generated checksum for the customer. passthrough : Any [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - platform : str - [Optional] Pass the trading platform name, default to mt5 req_id : int [Optional] Used to map request to response. - trading_servers : int + unsubscribe_email : int Must be 1 """ @@ -7437,30 +6673,26 @@ async def trading_servers(self, args=None): args = {} config = { - 'account_type': { - 'type': 'string' - }, - 'environment': { - 'type': 'string' + 'binary_user_id': { + 'required': 1, + 'type': 'numeric' }, - 'market_type': { + 'checksum': { + 'required': 1, 'type': 'string' }, 'passthrough': {}, - 'platform': { - 'type': 'string' - }, 'req_id': { 'type': 'integer' }, - 'trading_servers': { + 'unsubscribe_email': { 'required': 1, 'type': 'integer' } } all_args = { - 'method': 'trading_servers', + 'method': 'unsubscribe_email', 'needs_method_arg': '1', 'args': args, 'config': config, @@ -7468,9 +6700,9 @@ async def trading_servers(self, args=None): return await self.process_request(all_args) - async def trading_times(self, args=None): + async def verify_email(self, args=None): """ - Receive a list of market opening times for a given date. + Verify an email address for various purposes. The system will send an email to the address containing a security code for verification. Parameters: ----------- @@ -7479,8 +6711,11 @@ async def trading_times(self, args=None): [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. req_id : int [Optional] Used to map request to response. - trading_times : str - Date to receive market opening times for. (yyyy-mm-dd format. today can also be specified). + type : str + Purpose of email verification, request_email and reset_password are the only two types restricted from all unoffical apps + url_parameters : Any + verify_email : str + Email address to be verified. """ if args is None: @@ -7491,121 +6726,59 @@ async def trading_times(self, args=None): 'req_id': { 'type': 'integer' }, - 'trading_times': { + 'type': { 'required': 1, 'type': 'string' - } - } - - all_args = { - 'method': 'trading_times', - 'needs_method_arg': '1', - 'args': args, - 'config': config, - } - - return await self.process_request(all_args) - - async def transaction(self, args=None): - """ - Subscribe to transaction notifications - - Parameters: - ----------- - args : dict with following keys - passthrough : Any - [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - req_id : int - [Optional] Used to map request to response. - subscribe : int - If set to 1, will send updates whenever there is an update to transactions. If not to 1 then it will not return any records. - transaction : int - Must be 1 - """ - - if args is None: - args = {} - - config = { - 'passthrough': {}, - 'req_id': { - 'type': 'integer' }, - 'subscribe': { - 'required': 1, - 'type': 'integer' + 'url_parameters': { + 'affiliate_token': { + 'type': 'string' + }, + 'date_first_contact': { + 'type': 'string' + }, + 'gclid_url': { + 'type': 'string' + }, + 'pa_amount': { + 'type': 'numeric' + }, + 'pa_currency': { + 'type': 'string' + }, + 'pa_loginid': { + 'type': 'string' + }, + 'pa_remarks': { + 'type': 'string' + }, + 'redirect_to': { + 'type': 'integer' + }, + 'signup_device': { + 'type': 'string' + }, + 'utm_ad_id': {}, + 'utm_adgroup_id': {}, + 'utm_adrollclk_id': {}, + 'utm_campaign': {}, + 'utm_campaign_id': {}, + 'utm_content': {}, + 'utm_fbcl_id': {}, + 'utm_gl_client_id': {}, + 'utm_medium': {}, + 'utm_msclk_id': {}, + 'utm_source': {}, + 'utm_term': {} }, - 'transaction': { + 'verify_email': { 'required': 1, - 'type': 'integer' - } - } - - all_args = { - 'method': 'transaction', - 'needs_method_arg': '1', - 'args': args, - 'config': config, - } - - return await self.process_request(all_args) - - async def transfer_between_accounts(self, args=None): - """ - This call allows transfers between accounts held by a given user. Transfer funds between your fiat and cryptocurrency accounts (for a fee). Please note that account_from should be same as current authorized account. - - Parameters: - ----------- - args : dict with following keys - account_from : str - [Optional] The loginid of the account to transfer funds from. - account_to : str - [Optional] The loginid of the account to transfer funds to. - accounts : str - [Optional] To control the list of accounts returned when account_from or account_to is not provided. brief (default value) means that accounts with mt5 account_type will be excluded; it will run faster. all means that all accounts with any account_type (including mt5) will be returned. - amount : Number - [Optional] The amount to transfer. - currency : str - [Optional] Currency code. - passthrough : Any - [Optional] Used to pass data through the websocket, which may be retrieved via the echo_req output field. - req_id : int - [Optional] Used to map request to response. - transfer_between_accounts : int - If account_from or account_to is not provided, it just returns the available accounts. - """ - - if args is None: - args = {} - - config = { - 'account_from': { - 'type': 'string' - }, - 'account_to': { 'type': 'string' - }, - 'accounts': { - 'type': 'string' - }, - 'amount': { - 'type': 'numeric' - }, - 'currency': { - 'type': 'string' - }, - 'passthrough': {}, - 'req_id': { - 'type': 'integer' - }, - 'transfer_between_accounts': { - 'required': 1, - 'type': 'integer' } } all_args = { - 'method': 'transfer_between_accounts', + 'method': 'verify_email', 'needs_method_arg': '1', 'args': args, 'config': config, @@ -7613,9 +6786,9 @@ async def transfer_between_accounts(self, args=None): return await self.process_request(all_args) - async def verify_email(self, args=None): + async def verify_email_cellxpert(self, args=None): """ - Verify an email address for various purposes. The system will send an email to the address containing a security code for verification. + Verify an email address for Cellxpert. The system will send an email to the address containing a security code for verification. Parameters: ----------- @@ -7627,7 +6800,7 @@ async def verify_email(self, args=None): type : str Purpose of the email verification call. url_parameters : Any - verify_email : str + verify_email_cellxpert : str Email address to be verified. """ @@ -7647,6 +6820,9 @@ async def verify_email(self, args=None): 'affiliate_token': { 'type': 'string' }, + 'bta': { + 'type': 'integer' + }, 'date_first_contact': { 'type': 'string' }, @@ -7684,14 +6860,14 @@ async def verify_email(self, args=None): 'utm_source': {}, 'utm_term': {} }, - 'verify_email': { + 'verify_email_cellxpert': { 'required': 1, 'type': 'string' } } all_args = { - 'method': 'verify_email', + 'method': 'verify_email_cellxpert', 'needs_method_arg': '1', 'args': args, 'config': config, diff --git a/deriv_api/streams_list.py b/deriv_api/streams_list.py index 0c54bbb..c846121 100644 --- a/deriv_api/streams_list.py +++ b/deriv_api/streams_list.py @@ -1,6 +1,6 @@ -# This file was automatically generated by scripts/regen-py.pl at 20220627-142751 +# This file was automatically generated by scripts/regen-py.pl at 20230815-094214 # streams_list is the list of subscriptions msg_types available. # Please update it by scripts/regen-py.pl # Refer https://developers.binary.com/ -streams_list = [ 'balance', 'buy', 'cashier_payments', 'exchange_rates', 'p2p_advert_info', 'p2p_advertiser_create', 'p2p_advertiser_info', 'p2p_order_create', 'p2p_order_info', 'p2p_order_list', 'proposal', 'proposal_open_contract', 'ticks', 'ticks_history', 'transaction', 'website_status', ] +streams_list = [ 'balance', 'buy', 'exchange_rates', 'p2p_advert_info', 'p2p_advertiser_create', 'p2p_advertiser_info', 'p2p_order_create', 'p2p_order_info', 'p2p_order_list', 'proposal', 'proposal_open_contract', 'ticks', 'ticks_history', 'transaction', 'website_status', ] diff --git a/scripts/regen-py.pl b/scripts/regen-py.pl new file mode 100644 index 0000000..2264203 --- /dev/null +++ b/scripts/regen-py.pl @@ -0,0 +1,143 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Dir::Self; +use File::Basename qw( basename dirname ); +use JSON::MaybeXS; +use Log::Any qw($log); +use Path::Tiny; +use Template; +use Syntax::Keyword::Try; + + +my $json = JSON::MaybeXS->new( + canonical => 1, + pretty => 1, + indent_length => 4 +); + +my $distroot = dirname(__DIR__); +my $api_calls_filename = "$distroot/deriv_api/deriv_api_calls.py"; +my $streams_list_filename = "$distroot/deriv_api/streams_list.py"; + +chomp(my $date = qx( date +%Y%m%d-%H%M%S )); + +my @methods; + +sub emit_functions { + my ($root) = @_; + + $root = path($root); + + # Helper for reporting on anything in the schema we can't handle + my $check = sub { + my $def = shift; + die "non-object def - " . $def->{type} unless $def->{type} eq 'object'; + die "unexpected schema " . $def->{'$schema'} unless $def->{'$schema'} =~ m{http://json-schema.org/draft-0[34]/schema#}; + }; + + # Expected path structure is $methodname/{send,receive}.json + foreach my $dir (sort $root->children) { + my $method = $dir->basename; + + $log->tracef("Applying method %s", $method); + + my ($send, $recv) = map { + try { + my $def = $json->decode(path($dir, $_ . '.json')->slurp_utf8); + $check->($def); + $def; + } + catch ($e) { + die "$method $_ load/validation failed: $e" + } + } qw(send receive); + + # NOTE: Some type definitions use arrays, we don't support that yet + + my $send_props = parse_properties($send); + chomp(my $encoded_props = $json->encode($send_props)); + + push @methods, { + # the real api method name e.g. proposal_open_contract + method => $method, + # Any request that supports req_id will automatically get an ID and this will be used + # in determining which response is which. + has_req_id => exists $send_props->{req_id}, + needs_method_arg => needs_method_arg($method, $send_props), + description => $send->{description}, + is_method => exists $send_props->{$method}, + encoded_props => $encoded_props =~ s/"/'/rg =~ s/\n/\n /rg =~ s/ :/:/rg, + props => parse_properties($send, full => 1), + }; + } +} + +sub parse_properties { + my $schema = shift; + my %options = @_; + my $props = $schema->{properties}; + my @required = ($schema->{required} || [])->@*; + my %data; + for my $prop (keys %$props) { + if (exists $props->{$prop}{properties}) { + $data{$prop} = parse_properties($props->{$prop}); + } else { + my $type; + $type = 'numeric' if ($props->{$prop}{type} || '') =~ /^(?:number)$/; + $type = 'integer' if ($props->{$prop}{type} || '') =~ /^(?:integer)$/; + $type = $1 if ($props->{$prop}{type} || '') =~ /^(string|boolean)$/; + my $description = $props->{$prop}->%{description}; + $description =~ s/`//g if $description; + $data{$prop} = { + $type ? (type => $type) : (), + (grep { /^$prop$/ } @required) ? (required => 1) : (), + $options{full} ? (description => $description) : (), + }; + } + } + return \%data; +} + +sub to_camel_case { shift =~ s/_(\w)/\U$1/rg } + +sub needs_method_arg { + my ($method, $send_props) = @_; + + # { "method": { "type": "integer", "enum": [1] } } + return 1 unless my $enum = $send_props->{$method}{enum}; + + return 0 if scalar($enum->@*) == 1 and $enum->[0] == 1; + + return 1; +} + +emit_functions($ENV{BINARYCOM_API_SCHEMA_PATH} // '/home/git/binary-com/deriv-developers-portal/config/v3'); + +my $template = Template->new( + INCLUDE_PATH => "$distroot/scripts/templates", +); + +$template->process( + "api-call-py.tt2", + { + scriptname => $0, + date => $date, + methods => \@methods, + }, \my $output) or die $template->error . "\n"; + +path($api_calls_filename)->spew_utf8($output); + +$output = ''; +$template->process( + 'streams_list.py.tt2', + { + scriptname => $0, + date => $date, + methods => \@methods, + }, \$output +) or die $template->error . "\n"; + +path($streams_list_filename)->spew_utf8($output); diff --git a/scripts/templates/api-call-py.tt2 b/scripts/templates/api-call-py.tt2 new file mode 100644 index 0000000..682a4dc --- /dev/null +++ b/scripts/templates/api-call-py.tt2 @@ -0,0 +1,138 @@ +# This file was automatically generated by [% scriptname %] at [% date %] +[%# Convert JSON schema API definition into a Python class %] + +from numbers import Number + +# ======================= +# ----- API Methods ----- +# ======================= + + +class DerivAPICalls: +[% FOREACH m IN methods -%] + + async def [% m.method %](self, args=None): + """ + [% m.description %] + + Parameters: + ----------- + args : dict [% IF m.props %]with following keys[% END %] +[% FOREACH p IN m.props -%] +[% type = p.value.type -%] +[% SWITCH type -%] +[% CASE 'integer' -%] +[% type = 'int' -%] +[% CASE 'numeric' -%] +[% type = 'Number' -%] +[% CASE 'string' -%] +[% type = 'str' -%] +[% CASE 'boolean' -%] +[% type = 'bool' -%] +[% CASE -%] +[% type = 'Any' -%] +[% END -%] + [% p.key %] : [% type %] +[% IF p.value.description -%] + [% p.value.description %] +[% END -%] +[% END -%] + """ + + if args is None: + args = {} + + config = [% m.encoded_props %] + + all_args = { + 'method': '[% m.method %]', + 'needs_method_arg': '[% m.needs_method_arg %]', + 'args': args, + 'config': config, + } + + return await self.process_request(all_args) +[% END -%] + + async def process_request(self, all_args): + """ + Process request + """ + + config = all_args['config'] + parsed_args = parse_args(all_args) + error = validate_args(config=config, args=parsed_args) + if error: + raise ValueError(error) + return await self.send(parsed_args) + +__pdoc__ = { + 'parse_args' : False, + 'validate_args' : False, + 'deriv_api.deriv_api_calls.DerivAPICalls.process_request' : False +} + +def parse_args(all_args): + """ + Parse request args + """ + + parsed_args = all_args['args'] + method = all_args['method'] + + if all_args['needs_method_arg'] and not(isinstance(parsed_args, dict)): + parsed_args = {method: parsed_args} + + parsed_args[method] = parsed_args.get(method, 1) + + config = all_args['config'] + for param in parsed_args: + value = parsed_args[param] + if not (param in config): + return + + ptype = config[param].get('type') + if ptype and ptype == 'string': + parsed_args[param] = f'{value}' + elif ptype and (ptype == 'numeric' or ptype == 'boolean'): + parsed_args[param] = int(float(value)) + + return parsed_args + + +type_checkers = { + 'dict': lambda value: isinstance(value, dict), + 'numeric': lambda value: isinstance(value, Number), + 'string': lambda value: isinstance(value, str), + 'boolean': lambda value: value in [True, False, 0, 1], + 'integer': lambda value: isinstance(value, int) +} + + +def validate_args(config, args): + """ + Validate request args + """ + + if not isinstance(args, dict): + return f"Requires an dict but a {type(args)} is passed." + + error_messages = [] + missing = [k for k in config.keys() if (config.get(k) or {}).get('required') and not (k in args)] + if len(missing): + error_messages.append(f'Required parameters missing: {", ".join(missing)}') + + for param in args.keys(): + value = args[param] + if param not in config: + continue + expected_type = config[param].get('type') + + if not expected_type: + continue + + checker = type_checkers.get(expected_type) + if not checker or not checker(value): + error_messages.append(f'{expected_type} value expected but found {type(value)}: {param}') + + return ' - '.join(error_messages) if len(error_messages) else '' diff --git a/scripts/templates/streams_list.py.tt2 b/scripts/templates/streams_list.py.tt2 new file mode 100644 index 0000000..3d4db4b --- /dev/null +++ b/scripts/templates/streams_list.py.tt2 @@ -0,0 +1,10 @@ +# This file was automatically generated by [% scriptname %] at [% date %] + +# streams_list is the list of subscriptions msg_types available. +# Please update it by [% scriptname %] +# Refer https://developers.binary.com/ +streams_list = [[% FOREACH m IN methods -%] +[% FOREACH p IN m.props -%] +[% IF p.key == 'subscribe' -%] '[% m.method -%]', [% END -%] +[% END -%] +[% END -%]] diff --git a/setup.py b/setup.py index 1632ac4..92e61a9 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ setup( name='python_deriv_api', packages=find_packages(include=['deriv_api']), - version='0.1.3', + version='0.1.5', description='Python bindings for deriv.com websocket API', author='Deriv Group Services Ltd', author_email='learning+python@deriv.com', diff --git a/tests/test_deriv_api_calls.py b/tests/test_deriv_api_calls.py index 55fbab1..f9504df 100644 --- a/tests/test_deriv_api_calls.py +++ b/tests/test_deriv_api_calls.py @@ -10,10 +10,10 @@ async def send(self, args): async def test_deriv_api_calls(mocker): api = DerivedDerivAPICalls() assert isinstance(api, DerivAPICalls) - assert (await api.account_closure({'account_closure': 1, 'reason': 'want'})) == {'account_closure': 1, - 'reason': 'want'}, 'account_closure can get right result' - with pytest.raises(ValueError, match='Required parameters missing: reason'): - await api.account_closure({}) + assert (await api.exchange_rates({'exchange_rates': 1, 'base_currency': 'USD'})) == {'exchange_rates': 1, + 'base_currency': 'USD'}, 'exchange_rates can get right result' + with pytest.raises(ValueError, match='Required parameters missing: base_currency'): + await api.exchange_rates({}) def test_parse_parse_args():