Skip to content

Commit 69226b3

Browse files
Guillaume De Saint MartinGuillaumeDSM
authored andcommitted
[Backtesting] integrate forced exchange and contract types
1 parent bf41762 commit 69226b3

File tree

3 files changed

+34
-42
lines changed

3 files changed

+34
-42
lines changed

octobot/backtesting/independent_backtesting.pxd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ cdef class IndependentBacktesting:
5858
cdef void _log_symbol_report(self, str symbol, object exchange_manager, object min_time_frame)
5959
cdef void _log_global_report(self, object exchange_manager)
6060
cdef void _adapt_config(self)
61-
cdef str _find_reference_market(self)
61+
cdef str _find_reference_market_and_update_contract_type(self)
6262
cdef void _add_config_default_backtesting_values(self)
6363
cdef void _add_crypto_currencies_config(self)
6464
cdef void _init_exchange_type(self)

octobot/backtesting/independent_backtesting.py

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,6 @@ def __init__(self, config,
6565
self.optimizer_id = None
6666
self.backtesting_id = None
6767
self._init_default_config_values()
68-
try:
69-
self.backtesting_config[common_constants.CONFIG_EXCHANGE_TYPE] \
70-
= config[common_constants.CONFIG_EXCHANGE_TYPE]
71-
except KeyError:
72-
self.backtesting_config[common_constants.CONFIG_EXCHANGE_TYPE] \
73-
= common_constants.CONFIG_EXCHANGE_CURRENT_PROFILE
7468
self.stopped = False
7569
self.stopped_event = None
7670
self.post_backtesting_task = None
@@ -327,7 +321,7 @@ def _adapt_config(self):
327321
exchange_details.pop(common_constants.CONFIG_EXCHANGE_SANDBOXED, None)
328322
self.backtesting_config[common_constants.CONFIG_TRADING][common_constants.CONFIG_TRADER_RISK] = self.risk
329323
self.backtesting_config[common_constants.CONFIG_TRADING][
330-
common_constants.CONFIG_TRADER_REFERENCE_MARKET] = self._find_reference_market()
324+
common_constants.CONFIG_TRADER_REFERENCE_MARKET] = self._find_reference_market_and_update_contract_type()
331325
self.backtesting_config[common_constants.CONFIG_SIMULATOR][
332326
common_constants.CONFIG_STARTING_PORTFOLIO] = self.starting_portfolio
333327
self.backtesting_config[common_constants.CONFIG_SIMULATOR][
@@ -339,12 +333,17 @@ def _adapt_config(self):
339333
self._add_config_default_backtesting_values()
340334

341335
def _init_exchange_type(self):
336+
forced_exchange_type = self.octobot_origin_config.get(common_constants.CONFIG_EXCHANGE_TYPE,
337+
common_constants.USE_CURRENT_PROFILE)
342338
try:
343339
for exchange_name in self.symbols_to_create_exchange_classes:
344-
# use current profile config to create a spot/future/margin backtesting exchange
345-
self.octobot_backtesting.exchange_type_by_exchange[exchange_name] = \
346-
self.octobot_origin_config[common_constants.CONFIG_EXCHANGES].get(exchange_name, {}).\
347-
get(common_constants.CONFIG_EXCHANGE_TYPE, common_constants.DEFAULT_EXCHANGE_TYPE)
340+
if forced_exchange_type == common_constants.USE_CURRENT_PROFILE:
341+
# use current profile config to create a spot/future/margin backtesting exchange
342+
self.octobot_backtesting.exchange_type_by_exchange[exchange_name] = \
343+
self.octobot_origin_config[common_constants.CONFIG_EXCHANGES].get(exchange_name, {}).\
344+
get(common_constants.CONFIG_EXCHANGE_TYPE, common_constants.DEFAULT_EXCHANGE_TYPE)
345+
else:
346+
self.octobot_backtesting.exchange_type_by_exchange[exchange_name] = forced_exchange_type
348347
except StopIteration:
349348
# use default exchange type
350349
pass
@@ -360,25 +359,36 @@ async def _generate_backtesting_id_if_missing(self):
360359
await run_dbs_identifier.initialize()
361360
self.backtesting_config[common_constants.CONFIG_BACKTESTING_ID] = run_dbs_identifier.backtesting_id
362361

363-
def _find_reference_market(self):
362+
def _find_reference_market_and_update_contract_type(self):
364363
ref_market_candidate = None
365364
ref_market_candidates = {}
365+
forced_contract_type = self.octobot_origin_config.get(common_constants.CONFIG_CONTRACT_TYPE,
366+
common_constants.USE_CURRENT_PROFILE)
366367
for symbols in self.symbols_to_create_exchange_classes.values():
367368
symbol = symbols[0]
368369
if next(iter(self.octobot_backtesting.exchange_type_by_exchange.values())) \
369370
== common_constants.CONFIG_EXCHANGE_FUTURE:
370-
if symbol.is_inverse():
371-
if not all([symbol.is_inverse() for symbol in symbols]):
372-
self.logger.error(f"Mixed inverse and linear contracts backtesting are not supported yet")
373-
self.octobot_backtesting.futures_contract_type = trading_enums.FutureContractType.INVERSE_PERPETUAL
371+
if forced_contract_type == common_constants.USE_CURRENT_PROFILE:
372+
if symbol.is_inverse():
373+
if not all([symbol.is_inverse() for symbol in symbols]):
374+
self.logger.error(f"Mixed inverse and linear contracts backtesting are not supported yet")
375+
self.octobot_backtesting.futures_contract_type = \
376+
trading_enums.FutureContractType.INVERSE_PERPETUAL
377+
else:
378+
if not all([symbol.is_linear() for symbol in symbols]):
379+
self.logger.error(f"Mixed inverse and linear contracts backtesting are not supported yet")
380+
self.octobot_backtesting.futures_contract_type = \
381+
trading_enums.FutureContractType.LINEAR_PERPETUAL
382+
# in inverse contracts, use BTC for BTC/USD trading as reference market
383+
if symbol.settlement_asset:
384+
# only use settlement asset if available
385+
return symbol.settlement_asset
374386
else:
375-
if not all([symbol.is_linear() for symbol in symbols]):
376-
self.logger.error(f"Mixed inverse and linear contracts backtesting are not supported yet")
377-
self.octobot_backtesting.futures_contract_type = trading_enums.FutureContractType.LINEAR_PERPETUAL
378-
# in inverse contracts, use BTC for BTC/USD trading as reference market
379-
if symbol.settlement_asset:
380-
# only use settlement asset if available
381-
return symbol.settlement_asset
387+
self.octobot_backtesting.futures_contract_type = forced_contract_type
388+
return symbol.base \
389+
if forced_contract_type is trading_enums.FutureContractType.INVERSE_PERPETUAL \
390+
else symbol.quote
391+
382392
for symbol in symbols:
383393
quote = symbol.quote
384394
if ref_market_candidate is None:

octobot/backtesting/octobot_backtesting.py

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -217,24 +217,6 @@ async def _create_service_feeds(self):
217217
f"might not work properly")
218218

219219
async def _init_exchanges(self):
220-
if self.backtesting_config[commons_constants.CONFIG_EXCHANGE_TYPE] \
221-
!= commons_constants.CONFIG_EXCHANGE_CURRENT_PROFILE:
222-
for exchange in self.exchange_type_by_exchange:
223-
if self.backtesting_config[commons_constants.CONFIG_EXCHANGE_TYPE] \
224-
== trading_enums.ExchangeTypes.SPOT.value:
225-
self.exchange_type_by_exchange[exchange] = commons_constants.CONFIG_EXCHANGE_SPOT
226-
elif self.backtesting_config[commons_constants.CONFIG_EXCHANGE_TYPE] \
227-
== trading_enums.FutureContractType.INVERSE_PERPETUAL.value:
228-
self.exchange_type_by_exchange[exchange] = commons_constants.CONFIG_EXCHANGE_FUTURE
229-
self.futures_contract_type = trading_enums.FutureContractType.INVERSE_PERPETUAL
230-
elif self.backtesting_config[commons_constants.CONFIG_EXCHANGE_TYPE] \
231-
== trading_enums.FutureContractType.LINEAR_PERPETUAL.value:
232-
self.exchange_type_by_exchange[exchange] = commons_constants.CONFIG_EXCHANGE_FUTURE
233-
self.futures_contract_type = trading_enums.FutureContractType.LINEAR_PERPETUAL
234-
elif self.backtesting_config[commons_constants.CONFIG_EXCHANGE_TYPE] \
235-
== trading_enums.ExchangeTypes.MARGIN.value:
236-
self.exchange_type_by_exchange[exchange] = commons_constants.CONFIG_EXCHANGE_MARGIN
237-
238220
self.backtesting = await backtesting_api.initialize_backtesting(self.backtesting_config,
239221
exchange_ids=self.exchange_manager_ids,
240222
matrix_id=self.matrix_id,

0 commit comments

Comments
 (0)