add contract_size as a config to inverse futures
This commit is contained in:
@@ -116,6 +116,8 @@ config = {
|
||||
'futures_leverage_mode': 'cross',
|
||||
# 1x, 2x, 10x, 50x, etc. Enter as integers
|
||||
'futures_leverage': 1,
|
||||
# Price per contract, also called the contract-multiplier
|
||||
'contract_size': 100,
|
||||
|
||||
'assets': [
|
||||
{'asset': 'BTC', 'balance': 1},
|
||||
|
||||
@@ -28,12 +28,14 @@ class InverseFuturesExchange(Exchange):
|
||||
starting_assets: list,
|
||||
fee_rate: float,
|
||||
futures_leverage_mode: str,
|
||||
futures_leverage: int
|
||||
futures_leverage: int,
|
||||
contract_size: int,
|
||||
):
|
||||
super().__init__(name, starting_assets, fee_rate, 'inverse futures')
|
||||
|
||||
self.futures_leverage_mode = futures_leverage_mode
|
||||
self.futures_leverage = futures_leverage
|
||||
self.contract_size = contract_size
|
||||
|
||||
for item in starting_assets:
|
||||
self.buy_orders[item['asset']] = DynamicNumpyArray((10, 2))
|
||||
@@ -63,7 +65,6 @@ class InverseFuturesExchange(Exchange):
|
||||
settlement_currency = jh.base_asset(symbol)
|
||||
return self.assets[settlement_currency]
|
||||
|
||||
# TODO
|
||||
def available_margin(self, symbol=''):
|
||||
if symbol == '':
|
||||
raise ValueError
|
||||
@@ -125,8 +126,9 @@ class InverseFuturesExchange(Exchange):
|
||||
# make sure we don't spend more than we're allowed considering current allowed leverage
|
||||
if order.type != order_types.MARKET or skip_market_order:
|
||||
if not order.is_reduce_only:
|
||||
order_size = abs(order.qty * order.price)
|
||||
remaining_margin = self.available_margin()
|
||||
# TODO: add contract_multiplier to the equation
|
||||
order_size = abs(order.qty / order.price)
|
||||
remaining_margin = self.available_margin(order.symbol)
|
||||
if order_size > remaining_margin:
|
||||
raise InsufficientMargin(
|
||||
'You cannot submit an order for ${} when your margin balance is ${}'.format(
|
||||
|
||||
@@ -106,6 +106,8 @@ config = {
|
||||
'futures_leverage_mode': 'cross',
|
||||
# 1x, 2x, 10x, 50x, etc. Enter as integers
|
||||
'futures_leverage': 1,
|
||||
# Price per contract, also called the contract-multiplier
|
||||
'contract_size': 100,
|
||||
|
||||
'assets': [
|
||||
{'asset': 'BTC', 'balance': 1},
|
||||
|
||||
@@ -29,6 +29,7 @@ class ExchangesState:
|
||||
name, starting_assets, fee,
|
||||
futures_leverage_mode=jh.get_config('env.exchanges.{}.futures_leverage_mode'.format(name)),
|
||||
futures_leverage=jh.get_config('env.exchanges.{}.futures_leverage'.format(name)),
|
||||
contract_size=jh.get_config('env.exchanges.{}.contract_size'.format(name)),
|
||||
)
|
||||
else:
|
||||
raise InvalidConfig('Value for exchange type in your config file in not valid. Supported values are "spot" and "futures"')
|
||||
|
||||
@@ -6,10 +6,13 @@ class TestCanDetectInverseFutures(Strategy):
|
||||
def should_long(self) -> bool:
|
||||
if self.index == 0:
|
||||
# current capital should be 1 BTC
|
||||
assert self.capital == 1
|
||||
assert self.capital == 100
|
||||
assert self.position.exchange.type == 'inverse futures'
|
||||
assert self.symbol == 'BTC-PERP'
|
||||
assert self.leverage == 2
|
||||
assert self.position.exchange.contract_size == 1
|
||||
# TODO:
|
||||
# assert self.contract_size == 1
|
||||
|
||||
return False
|
||||
|
||||
|
||||
31
jesse/strategies/TestInverseFuturesLongTrade/__init__.py
Normal file
31
jesse/strategies/TestInverseFuturesLongTrade/__init__.py
Normal file
@@ -0,0 +1,31 @@
|
||||
from jesse.strategies import Strategy
|
||||
from jesse import utils
|
||||
|
||||
|
||||
class TestInverseFuturesLongTrade(Strategy):
|
||||
def should_long(self) -> bool:
|
||||
if self.index == 0:
|
||||
assert self.position.exchange.contract_size == 100
|
||||
|
||||
return self.price == 10
|
||||
|
||||
def should_short(self) -> bool:
|
||||
return False
|
||||
|
||||
def go_long(self):
|
||||
entry = 10
|
||||
# assuming contract size is 100, buy with all capital
|
||||
qty = self.capital * self.price / 100
|
||||
self.buy = qty, entry
|
||||
self.take_profit = qty, 20
|
||||
|
||||
def go_short(self):
|
||||
pass
|
||||
|
||||
def should_cancel(self):
|
||||
return False
|
||||
|
||||
def update_position(self):
|
||||
if 20 > self.price > 10:
|
||||
print(self.position.qty)
|
||||
assert self.position.qty == 10
|
||||
@@ -5,5 +5,10 @@ def test_can_detect_inverse_futures():
|
||||
single_route_backtest('TestCanDetectInverseFutures', is_futures_trading=True, is_inverse_futures=True, leverage=2)
|
||||
|
||||
|
||||
# def test_long_trade():
|
||||
# single_route_backtest('TestInverseFuturesLongTrade', is_futures_trading=True, is_inverse_futures=True)
|
||||
def test_long_trade():
|
||||
single_route_backtest(
|
||||
'TestInverseFuturesLongTrade',
|
||||
is_futures_trading=True,
|
||||
is_inverse_futures=True,
|
||||
contract_size=100
|
||||
)
|
||||
|
||||
@@ -33,13 +33,21 @@ def get_btc_candles(symbol='BTC-USDT'):
|
||||
return candles
|
||||
|
||||
|
||||
def set_up(routes=None, is_futures_trading=True, leverage=1, leverage_mode='cross', zero_fee=False, is_inverse_futures=False):
|
||||
def set_up(
|
||||
routes=None,
|
||||
is_futures_trading=True,
|
||||
leverage=1,
|
||||
leverage_mode='cross',
|
||||
zero_fee=False,
|
||||
is_inverse_futures=False,
|
||||
contract_size=1,
|
||||
):
|
||||
reset_config()
|
||||
|
||||
if is_inverse_futures:
|
||||
config['env']['exchanges'][exchanges.SANDBOX]['assets'] = [
|
||||
{'asset': 'USDT', 'balance': 0},
|
||||
{'asset': 'BTC', 'balance': 1},
|
||||
{'asset': 'BTC', 'balance': 100},
|
||||
]
|
||||
else:
|
||||
config['env']['exchanges'][exchanges.SANDBOX]['assets'] = [
|
||||
@@ -59,6 +67,7 @@ def set_up(routes=None, is_futures_trading=True, leverage=1, leverage_mode='cros
|
||||
config['env']['exchanges'][exchanges.SANDBOX]['type'] = 'inverse futures'
|
||||
config['env']['exchanges'][exchanges.SANDBOX]['futures_leverage_mode'] = leverage_mode
|
||||
config['env']['exchanges'][exchanges.SANDBOX]['futures_leverage'] = leverage
|
||||
config['env']['exchanges'][exchanges.SANDBOX]['contract_size'] = contract_size
|
||||
else:
|
||||
config['env']['exchanges'][exchanges.SANDBOX]['type'] = 'spot'
|
||||
|
||||
@@ -68,7 +77,7 @@ def set_up(routes=None, is_futures_trading=True, leverage=1, leverage_mode='cros
|
||||
store.reset(True)
|
||||
|
||||
|
||||
def single_route_backtest(strategy_name: str, is_futures_trading=True, is_inverse_futures=False, leverage=1):
|
||||
def single_route_backtest(strategy_name: str, is_futures_trading=True, is_inverse_futures=False, leverage=1, contract_size=1):
|
||||
"""
|
||||
used to simplify simple tests
|
||||
"""
|
||||
@@ -76,7 +85,8 @@ def single_route_backtest(strategy_name: str, is_futures_trading=True, is_invers
|
||||
[(exchanges.SANDBOX, 'BTC-USDT' if not is_inverse_futures else 'BTC-PERP', timeframes.MINUTE_1, strategy_name)],
|
||||
is_futures_trading=is_futures_trading,
|
||||
is_inverse_futures=is_inverse_futures,
|
||||
leverage=leverage
|
||||
leverage=leverage,
|
||||
contract_size=contract_size
|
||||
)
|
||||
# dates are fake. just to pass required parameters
|
||||
backtest_mode.run('2019-04-01', '2019-04-02', get_btc_candles('BTC-USDT' if not is_inverse_futures else 'BTC-PERP'))
|
||||
|
||||
Reference in New Issue
Block a user