From ba6ca9125198aebe78de348963008e4dad9d0878 Mon Sep 17 00:00:00 2001 From: Anup kumar singh Date: Mon, 8 Jul 2024 16:32:50 +0530 Subject: [PATCH 1/4] Jupyter notebook update for aaron_crossover for execution mode changes --- pyalgotrading/algobulls/api.py | 24 +++++++++++++++++--- pyalgotrading/algobulls/connection.py | 32 +++++++++++++++++++-------- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/pyalgotrading/algobulls/api.py b/pyalgotrading/algobulls/api.py index 007a201b..3274f080 100644 --- a/pyalgotrading/algobulls/api.py +++ b/pyalgotrading/algobulls/api.py @@ -18,7 +18,7 @@ class AlgoBullsAPI: """ AlgoBulls API """ - SERVER_ENDPOINT = 'https://api.algobulls.com/' + SERVER_ENDPOINT = 'http://localhost:7002/' def __init__(self, connection): """ @@ -310,7 +310,7 @@ def set_strategy_config(self, strategy_code: str, strategy_config: dict, trading return key, response - def start_strategy_algotrading(self, strategy_code: str, start_timestamp: dt, end_timestamp: dt, trading_type: TradingType, lots: int, location: str, initial_funds_virtual=1e9, broker_details: dict = None) -> dict: + def start_strategy_algotrading(self, strategy_code: str, start_timestamp: dt, end_timestamp: dt, trading_type: TradingType, lots: int, location: str, initial_funds_virtual=1e9, broker_details: dict = None, execution_mode:str=None) -> dict: """ Submit Backtesting / Paper Trading / Real Trading job for strategy with code strategy_code & return the job ID. @@ -340,7 +340,8 @@ def start_strategy_algotrading(self, strategy_code: str, start_timestamp: dt, en 'isLiveDataTestMode': trading_type in [TradingType.PAPERTRADING, TradingType.REALTRADING], 'customizationsQuantity': lots, 'brokingDetails': broker_details, - 'mode': trading_type.name + 'mode': trading_type.name, + 'execution_mode': execution_mode } params = None @@ -466,3 +467,20 @@ def get_reports(self, strategy_code: str, trading_type: TradingType, report_type response = self._send_request(endpoint=endpoint, params=params) return response + + def set_strategy_running_mode(self, running_mode): + """ + Set user running strategy mode + Args: + running_mode: It can be either Regular or Fast + Returns: + Success or Failure message along with status_code + Comment: + If a user pass either Regular or Fast(not case-sensitive) he will get a 200 with success response. + If the user pass anything other that Regular or Fast he will get an 400 with Failure message + """ + endpoint = 'v1/user/preference' + json_data = {"execution_mode": running_mode} + + response = self._send_request(base_url='http://localhost:7002/', method='patch', endpoint=endpoint, json_data=json_data) + return response diff --git a/pyalgotrading/algobulls/connection.py b/pyalgotrading/algobulls/connection.py index c06672f7..d9690432 100644 --- a/pyalgotrading/algobulls/connection.py +++ b/pyalgotrading/algobulls/connection.py @@ -2,6 +2,7 @@ Module for AlgoBulls connection """ import inspect +import json import os import pprint import re @@ -150,7 +151,7 @@ def create_strategy(self, strategy, overwrite=False, strategy_code=None, abc_ver except KeyError: response = self.api.create_strategy(strategy_name=strategy_name, strategy_details=strategy_details, abc_version=_abc_version) - + print('response', strategy) return response def get_all_strategies(self, return_as_dataframe=True): @@ -680,7 +681,7 @@ def print_strategy_config(self, trading_type): print(f"\nStarting the strategy '{strategy_name}' in {trading_type.name} mode...\n{_msg}\n") def start_job(self, strategy_code=None, start_timestamp=None, end_timestamp=None, instruments=None, lots=None, strategy_parameters=None, candle_interval=None, strategy_mode=None, initial_funds_virtual=None, delete_previous_trades=True, - trading_type=None, broking_details=None, **kwargs): + trading_type=None, broking_details=None, execution_mode=None, **kwargs): """ Submit a BT/PT/RT job for a strategy on the AlgoBulls Platform @@ -842,12 +843,13 @@ def start_job(self, strategy_code=None, start_timestamp=None, end_timestamp=None # Submit trading job response = self.api.start_strategy_algotrading(strategy_code=strategy_code, start_timestamp=start_timestamp, end_timestamp=end_timestamp, trading_type=trading_type, - lots=lots, initial_funds_virtual=initial_funds_virtual, broker_details=broking_details, location=location) + lots=lots, initial_funds_virtual=initial_funds_virtual, broker_details=broking_details, location=location, execution_mode=execution_mode) self.strategy_country_map[trading_type][strategy_code] = Country[Locale(location).name].value return response - def backtest(self, strategy=None, start=None, end=None, instruments=None, lots=None, parameters=None, candle=None, mode=None, delete_previous_trades=True, initial_funds_virtual=None, vendor_details=None, **kwargs): + def backtest(self, strategy=None, start=None, end=None, instruments=None, lots=None, parameters=None, candle=None, mode=None, delete_previous_trades=True, initial_funds_virtual=None, vendor_details=None, execution_mode=None, **kwargs): + print('execution mode', execution_mode) """ Submit a backtesting job for a strategy on the AlgoBulls Platform @@ -880,7 +882,7 @@ def backtest(self, strategy=None, start=None, end=None, instruments=None, lots=N # start backtesting job _ = self.start_job( strategy_code=strategy, start_timestamp=start, end_timestamp=end, instruments=instruments, lots=lots, strategy_parameters=parameters, candle_interval=candle, strategy_mode=mode, - initial_funds_virtual=initial_funds_virtual, delete_previous_trades=delete_previous_trades, trading_type=TradingType.BACKTESTING, broking_details=vendor_details, **kwargs + initial_funds_virtual=initial_funds_virtual, delete_previous_trades=delete_previous_trades, trading_type=TradingType.BACKTESTING, broking_details=vendor_details, execution_mode=execution_mode, **kwargs ) # Update previously saved pnl data and exchange location @@ -997,7 +999,7 @@ def get_backtesting_report_order_history(self, strategy_code, country=None, rend return self.get_report_order_history(strategy_code=strategy_code, trading_type=TradingType.BACKTESTING, render_as_dataframe=render_as_dataframe, country=country) - def papertrade(self, strategy=None, start=None, end=None, instruments=None, lots=None, parameters=None, candle=None, mode=None, delete_previous_trades=True, initial_funds_virtual=None, vendor_details=None, **kwargs): + def papertrade(self, strategy=None, start=None, end=None, instruments=None, lots=None, parameters=None, candle=None, mode=None, delete_previous_trades=True, initial_funds_virtual=None, vendor_details=None, execution_mode=None, **kwargs): """ Submit a papertrade job for a strategy on the AlgoBulls Platform @@ -1030,7 +1032,7 @@ def papertrade(self, strategy=None, start=None, end=None, instruments=None, lots # start papertrading job _ = self.start_job( strategy_code=strategy, start_timestamp=start, end_timestamp=end, instruments=instruments, lots=lots, strategy_parameters=parameters, candle_interval=candle, strategy_mode=mode, - initial_funds_virtual=initial_funds_virtual, delete_previous_trades=delete_previous_trades, trading_type=TradingType.PAPERTRADING, broking_details=vendor_details, **kwargs + initial_funds_virtual=initial_funds_virtual, delete_previous_trades=delete_previous_trades, trading_type=TradingType.PAPERTRADING, broking_details=vendor_details, execution_mode=execution_mode, **kwargs ) # Update previously saved pnl data and exchange location @@ -1148,7 +1150,7 @@ def get_papertrading_report_order_history(self, strategy_code, country=None, ren return self.get_report_order_history(strategy_code=strategy_code, trading_type=TradingType.PAPERTRADING, render_as_dataframe=render_as_dataframe, country=country) - def realtrade(self, strategy=None, start=None, end=None, instruments=None, lots=None, parameters=None, candle=None, mode=None, broking_details=None, **kwargs): + def realtrade(self, strategy=None, start=None, end=None, instruments=None, lots=None, parameters=None, candle=None, mode=None, broking_details=None, execution_mode=None, **kwargs): """ Start a Real Trading session. Update: This requires an approval process which is currently on request basis. @@ -1181,7 +1183,7 @@ def realtrade(self, strategy=None, start=None, end=None, instruments=None, lots= # start realtrading job _ = self.start_job(strategy_code=strategy, start_timestamp=start, end_timestamp=end, instruments=instruments, lots=lots, strategy_parameters=parameters, candle_interval=candle, strategy_mode=mode, trading_type=TradingType.REALTRADING, - broking_details=broking_details, **kwargs) + broking_details=broking_details, execution_mode=execution_mode, **kwargs) # Update previously saved pnl data and exchange location self.realtrade_pnl_data = None @@ -1299,6 +1301,18 @@ def get_realtrading_report_order_history(self, strategy_code, country=None, rend return self.get_report_order_history(strategy_code=strategy_code, trading_type=TradingType.REALTRADING, render_as_dataframe=render_as_dataframe, country=country) + def set_running_mode_preference(self, running_mode): + """ + To choose the strategy_running_mode + Args: + running_mode: User can pass either Regular or Fast mode + returns: + + Success or Failure message + """ + data = self.api.set_strategy_running_mode(running_mode) + return data + def pandas_dataframe_all_rows(): """ From 9aecf68ddc871861c8850a7b6fea2aa08df4b8b0 Mon Sep 17 00:00:00 2001 From: Anup kumar singh Date: Thu, 11 Jul 2024 15:45:09 +0530 Subject: [PATCH 2/4] cleanup --- pyalgotrading/algobulls/api.py | 8 ++++---- pyalgotrading/algobulls/connection.py | 21 ++++++++++++++++----- pyalgotrading/constants.py | 2 ++ 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/pyalgotrading/algobulls/api.py b/pyalgotrading/algobulls/api.py index 3274f080..3ab4671f 100644 --- a/pyalgotrading/algobulls/api.py +++ b/pyalgotrading/algobulls/api.py @@ -310,7 +310,7 @@ def set_strategy_config(self, strategy_code: str, strategy_config: dict, trading return key, response - def start_strategy_algotrading(self, strategy_code: str, start_timestamp: dt, end_timestamp: dt, trading_type: TradingType, lots: int, location: str, initial_funds_virtual=1e9, broker_details: dict = None, execution_mode:str=None) -> dict: + def start_strategy_algotrading(self, strategy_code: str, start_timestamp: dt, end_timestamp: dt, trading_type: TradingType, lots: int, location: str, initial_funds_virtual=1e9, broker_details: dict = None, execution_mode: str = None) -> dict: """ Submit Backtesting / Paper Trading / Real Trading job for strategy with code strategy_code & return the job ID. @@ -341,7 +341,7 @@ def start_strategy_algotrading(self, strategy_code: str, start_timestamp: dt, en 'customizationsQuantity': lots, 'brokingDetails': broker_details, 'mode': trading_type.name, - 'execution_mode': execution_mode + 'executionMode': execution_mode } params = None @@ -468,7 +468,7 @@ def get_reports(self, strategy_code: str, trading_type: TradingType, report_type return response - def set_strategy_running_mode(self, running_mode): + def set_strategy_running_mode(self, execution_mode, trading_type): """ Set user running strategy mode Args: @@ -480,7 +480,7 @@ def set_strategy_running_mode(self, running_mode): If the user pass anything other that Regular or Fast he will get an 400 with Failure message """ endpoint = 'v1/user/preference' - json_data = {"execution_mode": running_mode} + json_data = {"executionMode": {"trading_type": trading_type, "mode": execution_mode}} response = self._send_request(base_url='http://localhost:7002/', method='patch', endpoint=endpoint, json_data=json_data) return response diff --git a/pyalgotrading/algobulls/connection.py b/pyalgotrading/algobulls/connection.py index d9690432..ee9aa6ab 100644 --- a/pyalgotrading/algobulls/connection.py +++ b/pyalgotrading/algobulls/connection.py @@ -2,7 +2,6 @@ Module for AlgoBulls connection """ import inspect -import json import os import pprint import re @@ -17,7 +16,7 @@ from .api import AlgoBullsAPI from .exceptions import AlgoBullsAPIBadRequestException, AlgoBullsAPIGatewayTimeoutErrorException, AlgoBullsAPIUnauthorizedErrorException -from ..constants import StrategyMode, TradingType, TradingReportType, CandleInterval, AlgoBullsEngineVersion, Country, ExecutionStatus, EXCHANGE_LOCALE_MAP, Locale, CandleIntervalSecondsMap +from ..constants import StrategyMode, TradingType, TradingReportType, CandleInterval, AlgoBullsEngineVersion, Country, ExecutionStatus, EXCHANGE_LOCALE_MAP, Locale, CandleIntervalSecondsMap, TRADING_TYPE_DICT_MAP from ..strategy.strategy_base import StrategyBase from ..utils.func import get_valid_enum_names, get_datetime_with_tz, calculate_brokerage, calculate_slippage @@ -751,6 +750,8 @@ def start_job(self, strategy_code=None, start_timestamp=None, end_timestamp=None instruments = [instruments] if strategy_parameters == {} or strategy_parameters is None: strategy_parameters = dict() + if execution_mode is not None: + assert execution_mode.lower() in ['regular', 'fast'], f"Execution mode '{execution_mode}' is Invalid. Valid choices are ['regular', 'fast']" # Sanity checks - Validate config parameters assert isinstance(strategy_code, str), f'Argument "strategy" should be a valid string' @@ -1301,16 +1302,26 @@ def get_realtrading_report_order_history(self, strategy_code, country=None, rend return self.get_report_order_history(strategy_code=strategy_code, trading_type=TradingType.REALTRADING, render_as_dataframe=render_as_dataframe, country=country) - def set_running_mode_preference(self, running_mode): + def set_execution_mode_preference(self, execution_mode, trading_type): """ To choose the strategy_running_mode Args: - running_mode: User can pass either Regular or Fast mode + execution_mode: User can pass either Regular or Fast mode returns: Success or Failure message """ - data = self.api.set_strategy_running_mode(running_mode) + try: + if trading_type.lower() in ['backtesting', 'papertrading', 'livetrading']: + trading_type = TRADING_TYPE_DICT_MAP[trading_type.lower()] + if execution_mode.lower() in ['regular', 'fast']: + data = self.api.set_strategy_running_mode(execution_mode, trading_type) + else: + data = {"Message": f"Invalid Execution Mode '{execution_mode}'. Valid choices are ['regular', 'fast']"} + else: + data = {"Message": "Invalid Trading Type. Valid options are ['backtesting', 'papertrading', 'livetrading']"} + except AttributeError: + data = {"Message": "Unknown Error! Please check the passed arguments"} return data diff --git a/pyalgotrading/constants.py b/pyalgotrading/constants.py index 151b8cb5..17906b94 100644 --- a/pyalgotrading/constants.py +++ b/pyalgotrading/constants.py @@ -325,3 +325,5 @@ class OptionsInstrumentDirection(Enum): 'NYSE': Locale.USA.value, } +TRADING_TYPE_DICT_MAP = {'backtesting': 'backTesting', 'papertrading': 'paperTrading', 'livetrading': 'liveTrading'} + From 881968dd354afd6058dadc5c658b4ac690ea9932 Mon Sep 17 00:00:00 2001 From: Anup kumar singh Date: Thu, 11 Jul 2024 16:25:05 +0530 Subject: [PATCH 3/4] clanup --- pyalgotrading/algobulls/connection.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pyalgotrading/algobulls/connection.py b/pyalgotrading/algobulls/connection.py index ee9aa6ab..0c6f66aa 100644 --- a/pyalgotrading/algobulls/connection.py +++ b/pyalgotrading/algobulls/connection.py @@ -150,7 +150,6 @@ def create_strategy(self, strategy, overwrite=False, strategy_code=None, abc_ver except KeyError: response = self.api.create_strategy(strategy_name=strategy_name, strategy_details=strategy_details, abc_version=_abc_version) - print('response', strategy) return response def get_all_strategies(self, return_as_dataframe=True): From 8172caf00bb4821c642fe8d8a082ec5203b4639a Mon Sep 17 00:00:00 2001 From: Anup kumar singh Date: Thu, 11 Jul 2024 18:00:06 +0530 Subject: [PATCH 4/4] cleanup --- pyalgotrading/algobulls/api.py | 9 +++++---- pyalgotrading/algobulls/connection.py | 3 +-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pyalgotrading/algobulls/api.py b/pyalgotrading/algobulls/api.py index 3ab4671f..fc941f22 100644 --- a/pyalgotrading/algobulls/api.py +++ b/pyalgotrading/algobulls/api.py @@ -18,7 +18,7 @@ class AlgoBullsAPI: """ AlgoBulls API """ - SERVER_ENDPOINT = 'http://localhost:7002/' + SERVER_ENDPOINT = 'https://api.algobulls.com/' def __init__(self, connection): """ @@ -472,15 +472,16 @@ def set_strategy_running_mode(self, execution_mode, trading_type): """ Set user running strategy mode Args: - running_mode: It can be either Regular or Fast + execution_mode: It can be either Regular or Fast + trading_type: Choices are backTesting, paperTrading and liveTrading Returns: Success or Failure message along with status_code Comment: - If a user pass either Regular or Fast(not case-sensitive) he will get a 200 with success response. + If a user pass either execution_mode(not case-sensitive) along with trading_type(not case-sensitive) he will get a 200 with success response. If the user pass anything other that Regular or Fast he will get an 400 with Failure message """ endpoint = 'v1/user/preference' json_data = {"executionMode": {"trading_type": trading_type, "mode": execution_mode}} - response = self._send_request(base_url='http://localhost:7002/', method='patch', endpoint=endpoint, json_data=json_data) + response = self._send_request(method='patch', endpoint=endpoint, json_data=json_data) return response diff --git a/pyalgotrading/algobulls/connection.py b/pyalgotrading/algobulls/connection.py index 0c6f66aa..08a5f578 100644 --- a/pyalgotrading/algobulls/connection.py +++ b/pyalgotrading/algobulls/connection.py @@ -849,7 +849,6 @@ def start_job(self, strategy_code=None, start_timestamp=None, end_timestamp=None return response def backtest(self, strategy=None, start=None, end=None, instruments=None, lots=None, parameters=None, candle=None, mode=None, delete_previous_trades=True, initial_funds_virtual=None, vendor_details=None, execution_mode=None, **kwargs): - print('execution mode', execution_mode) """ Submit a backtesting job for a strategy on the AlgoBulls Platform @@ -1318,7 +1317,7 @@ def set_execution_mode_preference(self, execution_mode, trading_type): else: data = {"Message": f"Invalid Execution Mode '{execution_mode}'. Valid choices are ['regular', 'fast']"} else: - data = {"Message": "Invalid Trading Type. Valid options are ['backtesting', 'papertrading', 'livetrading']"} + data = {"Message": "Invalid Trading Type. Valid options are ['backTesting', 'paperTrading', 'liveTrading']"} except AttributeError: data = {"Message": "Unknown Error! Please check the passed arguments"} return data