Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions pyalgotrading/algobulls/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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,
'executionMode': execution_mode
}

params = None
Expand Down Expand Up @@ -466,3 +467,21 @@ 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, execution_mode, trading_type):
"""
Set user running strategy mode
Args:
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 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(method='patch', endpoint=endpoint, json_data=json_data)
return response
43 changes: 33 additions & 10 deletions pyalgotrading/algobulls/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,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

Expand Down Expand Up @@ -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)

return response

def get_all_strategies(self, return_as_dataframe=True):
Expand Down Expand Up @@ -680,7 +679,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

Expand Down Expand Up @@ -750,6 +749,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'
Expand Down Expand Up @@ -842,12 +843,12 @@ 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):
"""
Submit a backtesting job for a strategy on the AlgoBulls Platform

Expand Down Expand Up @@ -880,7 +881,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
Expand Down Expand Up @@ -997,7 +998,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

Expand Down Expand Up @@ -1030,7 +1031,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
Expand Down Expand Up @@ -1148,7 +1149,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.
Expand Down Expand Up @@ -1181,7 +1182,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
Expand Down Expand Up @@ -1299,6 +1300,28 @@ 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_execution_mode_preference(self, execution_mode, trading_type):
"""
To choose the strategy_running_mode
Args:
execution_mode: User can pass either Regular or Fast mode
returns:

Success or Failure message
"""
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


def pandas_dataframe_all_rows():
"""
Expand Down
2 changes: 2 additions & 0 deletions pyalgotrading/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,3 +325,5 @@ class OptionsInstrumentDirection(Enum):
'NYSE': Locale.USA.value,
}

TRADING_TYPE_DICT_MAP = {'backtesting': 'backTesting', 'papertrading': 'paperTrading', 'livetrading': 'liveTrading'}