@@ -57,19 +57,19 @@ def __repr__(self):
57
57
return '<Strategy ' + str (self ) + '>'
58
58
59
59
def __str__ (self ):
60
- params = ',' .join ('{ }={}' . format ( * p ) for p in zip (self ._params .keys (),
61
- map (_as_str , self ._params .values ())))
60
+ params = ',' .join (f' { i [ 0 ] } ={ i [ 1 ] } ' for i in zip (self ._params .keys (),
61
+ map (_as_str , self ._params .values ())))
62
62
if params :
63
63
params = '(' + params + ')'
64
- return '{}{}' . format ( self .__class__ .__name__ , params )
64
+ return f' { self .__class__ .__name__ } { params } '
65
65
66
66
def _check_params (self , params ):
67
67
for k , v in params .items ():
68
68
if not hasattr (self , k ):
69
69
raise AttributeError (
70
- "Strategy '{}' is missing parameter '{}'. Strategy class "
71
- "should define parameters as class variables before they "
72
- "can be optimized or run with." . format ( self . __class__ . __name__ , k ) )
70
+ f "Strategy '{ self . __class__ . __name__ } ' is missing parameter '{ k } '."
71
+ "Strategy class should define parameters as class variables before they "
72
+ "can be optimized or run with." )
73
73
setattr (self , k , v )
74
74
return params
75
75
@@ -116,15 +116,15 @@ def init():
116
116
if name is None :
117
117
params = ',' .join (filter (None , map (_as_str , chain (args , kwargs .values ()))))
118
118
func_name = _as_str (func )
119
- name = ('{ }({})' if params else '{}' ). format ( func_name , params )
119
+ name = (f' { func_name } ({ params } )' if params else f' { func_name } ' )
120
120
else :
121
121
name = name .format (* map (_as_str , args ),
122
122
** dict (zip (kwargs .keys (), map (_as_str , kwargs .values ()))))
123
123
124
124
try :
125
125
value = func (* args , ** kwargs )
126
126
except Exception as e :
127
- raise RuntimeError ('Indicator "{}" errored with exception: {}' . format ( name , e ) )
127
+ raise RuntimeError (f 'Indicator "{ name } " errored with exception: { e } ' )
128
128
129
129
if isinstance (value , pd .DataFrame ):
130
130
value = value .values .T
@@ -140,8 +140,8 @@ def init():
140
140
if not is_arraylike or not 1 <= value .ndim <= 2 or value .shape [- 1 ] != len (self ._data .Close ):
141
141
raise ValueError (
142
142
'Indicators must return (optionally a tuple of) numpy.arrays of same '
143
- 'length as `data` (data shape: {}; indicator "{}" shape: {}, returned value: {}) '
144
- . format ( self . _data . Close . shape , name , getattr (value , ' shape' , '' ), value ) )
143
+ f 'length as `data` (data shape: { self . _data . Close . shape } ; indicator "{ name } " '
144
+ f' shape: { getattr (value , " shape" , "" ) } , returned value: { value } )' )
145
145
146
146
if plot and overlay is None and np .issubdtype (value .dtype , np .number ):
147
147
x = value / self ._data .Close
@@ -288,10 +288,10 @@ def __getattr__(self, item):
288
288
removed_attrs = ('entry' , 'set_entry' , 'is_long' , 'is_short' ,
289
289
'sl' , 'tp' , 'set_sl' , 'set_tp' )
290
290
if item in removed_attrs :
291
- raise AttributeError ('Strategy.orders.{} were removed in Backtesting 0.2.0. '
292
- 'Use `Order` API instead. See docs. '
293
- . format ( '/.' . join ( removed_attrs )) )
294
- raise AttributeError ("'tuple' object has no attribute {!r}" . format ( item ) )
291
+ raise AttributeError (f 'Strategy.orders.{ "/." . join ( removed_attrs ) } were removed in'
292
+ 'Backtesting 0.2.0. '
293
+ 'Use `Order` API instead. See docs.' )
294
+ raise AttributeError (f "'tuple' object has no attribute { item !r} " )
295
295
296
296
297
297
class Position :
@@ -346,7 +346,7 @@ def close(self, portion: float = 1.):
346
346
trade .close (portion )
347
347
348
348
def __repr__ (self ):
349
- return '<Position: {} ({} trades)>' . format ( self .size , len (self .__broker .trades ))
349
+ return f '<Position: { self .size } ( { len (self .__broker .trades )} trades)>'
350
350
351
351
352
352
class _OutOfMoneyError (Exception ):
@@ -386,11 +386,11 @@ def __init__(self, broker: '_Broker',
386
386
387
387
def _replace (self , ** kwargs ):
388
388
for k , v in kwargs .items ():
389
- setattr (self , '_{}__{}' . format ( self .__class__ .__qualname__ , k ) , v )
389
+ setattr (self , f '_{ self .__class__ .__qualname__ } __ { k } ' , v )
390
390
return self
391
391
392
392
def __repr__ (self ):
393
- return '<Order {}>' .format (', ' .join ('{ }={}' . format ( param , round (value , 5 ))
393
+ return '<Order {}>' .format (', ' .join (f' { param } ={ round (value , 5 )} '
394
394
for param , value in (
395
395
('size' , self .__size ),
396
396
('limit' , self .__limit_price ),
@@ -513,13 +513,12 @@ def __init__(self, broker: '_Broker', size: int, entry_price: float, entry_bar):
513
513
self .__tp_order : Optional [Order ] = None
514
514
515
515
def __repr__ (self ):
516
- return '<Trade size={} time={}-{} price={}-{} pl={:.0f}>' .format (
517
- self .__size , self .__entry_bar , self .__exit_bar or '' ,
518
- self .__entry_price , self .__exit_price or '' , self .pl )
516
+ return f'<Trade size={ self .__size } time={ self .__entry_bar } -{ self .__exit_bar or "" } ' \
517
+ f'price={ self .__entry_price } -{ self .__exit_price or "" } pl={ self .pl :.0f} >'
519
518
520
519
def _replace (self , ** kwargs ):
521
520
for k , v in kwargs .items ():
522
- setattr (self , '_{}__{}' . format ( self .__class__ .__qualname__ , k ) , v )
521
+ setattr (self , f '_{ self .__class__ .__qualname__ } __ { k } ' , v )
523
522
return self
524
523
525
524
def _copy (self , ** kwargs ):
@@ -647,8 +646,8 @@ def tp(self, price: float):
647
646
def __set_contingent (self , type , price ):
648
647
assert type in ('sl' , 'tp' )
649
648
assert price is None or 0 < price < np .inf
650
- attr = '_{}__{}_order' . format ( self .__class__ .__qualname__ , type )
651
- order : Order = getattr (self , attr )
649
+ attr = f '_{ self .__class__ .__qualname__ } __ { type } _order'
650
+ order : Order = getattr (self , attr ) # type: Order
652
651
if order :
653
652
order .cancel ()
654
653
if price :
@@ -660,9 +659,9 @@ def __set_contingent(self, type, price):
660
659
class _Broker :
661
660
def __init__ (self , * , data , cash , commission , margin ,
662
661
trade_on_close , hedging , exclusive_orders , index ):
663
- assert 0 < cash , "cash shosuld be >0, is {}" . format ( cash )
664
- assert 0 <= commission < .1 , "commission should be between 0-10%, is {}" . format ( commission )
665
- assert 0 < margin <= 1 , "margin should be between 0 and 1, is {}" . format ( margin )
662
+ assert 0 < cash , f "cash should be >0, is { cash } "
663
+ assert 0 <= commission < .1 , f "commission should be between 0-10%, is { commission } "
664
+ assert 0 < margin <= 1 , f "margin should be between 0 and 1, is { margin } "
666
665
self ._data : _Data = data
667
666
self ._cash = cash
668
667
self ._commission = commission
@@ -678,8 +677,7 @@ def __init__(self, *, data, cash, commission, margin,
678
677
self .closed_trades : List [Trade ] = []
679
678
680
679
def __repr__ (self ):
681
- return '<Broker: {:.0f}{:+.1f} ({} trades)>' .format (
682
- self ._cash , self .position .pl , len (self .trades ))
680
+ return f'<Broker: { self ._cash :.0f} { self .position .pl :+.1f} ({ len (self .trades )} trades)>'
683
681
684
682
def new_order (self ,
685
683
size : float ,
@@ -703,12 +701,14 @@ def new_order(self,
703
701
704
702
if is_long :
705
703
if not (sl or - np .inf ) < (limit or stop or adjusted_price ) < (tp or np .inf ):
706
- raise ValueError ("Long orders require: SL ({}) < LIMIT ({}) < TP ({})" .format (
707
- sl , limit or stop or adjusted_price , tp ))
704
+ raise ValueError (
705
+ "Long orders require: "
706
+ f"SL ({ sl } ) < LIMIT ({ limit or stop or adjusted_price } ) < TP ({ tp } )" )
708
707
else :
709
708
if not (tp or - np .inf ) < (limit or stop or adjusted_price ) < (sl or np .inf ):
710
- raise ValueError ("Short orders require: TP ({}) < LIMIT ({}) < SL ({})" .format (
711
- tp , limit or stop or adjusted_price , sl ))
709
+ raise ValueError (
710
+ "Short orders require: "
711
+ f"TP ({ tp } ) < LIMIT ({ limit or stop or adjusted_price } ) < SL ({ sl } )" )
712
712
713
713
order = Order (self , size , limit , stop , sl , tp , trade )
714
714
# Put the new order in the order queue,
@@ -1243,8 +1243,8 @@ def _tuple(x):
1243
1243
1244
1244
for k , v in kwargs .items ():
1245
1245
if len (_tuple (v )) == 0 :
1246
- raise ValueError ("Optimization variable '{0 }' is passed no "
1247
- "optimization values: {0 }={1}" . format ( k , v ) )
1246
+ raise ValueError (f "Optimization variable '{ k } ' is passed no "
1247
+ f "optimization values: { k } ={ v } " )
1248
1248
1249
1249
class AttrDict (dict ):
1250
1250
def __getattr__ (self , item ):
@@ -1259,7 +1259,7 @@ def __getattr__(self, item):
1259
1259
raise ValueError ('No admissible parameter combinations to test' )
1260
1260
1261
1261
if len (param_combos ) > 300 :
1262
- warnings .warn ('Searching for best of {} configurations.' . format ( len ( param_combos )) ,
1262
+ warnings .warn (f 'Searching for best of { len ( param_combos ) } configurations.' ,
1263
1263
stacklevel = 2 )
1264
1264
1265
1265
heatmap = pd .Series (np .nan ,
0 commit comments