@@ -57,19 +57,19 @@ def __repr__(self):
5757 return '<Strategy ' + str (self ) + '>'
5858
5959 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 ())))
6262 if params :
6363 params = '(' + params + ')'
64- return '{}{}' . format ( self .__class__ .__name__ , params )
64+ return f' { self .__class__ .__name__ } { params } '
6565
6666 def _check_params (self , params ):
6767 for k , v in params .items ():
6868 if not hasattr (self , k ):
6969 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." )
7373 setattr (self , k , v )
7474 return params
7575
@@ -116,15 +116,15 @@ def init():
116116 if name is None :
117117 params = ',' .join (filter (None , map (_as_str , chain (args , kwargs .values ()))))
118118 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 } ' )
120120 else :
121121 name = name .format (* map (_as_str , args ),
122122 ** dict (zip (kwargs .keys (), map (_as_str , kwargs .values ()))))
123123
124124 try :
125125 value = func (* args , ** kwargs )
126126 except Exception as e :
127- raise RuntimeError ('Indicator "{}" errored with exception: {}' . format ( name , e ) )
127+ raise RuntimeError (f 'Indicator "{ name } " errored with exception: { e } ' )
128128
129129 if isinstance (value , pd .DataFrame ):
130130 value = value .values .T
@@ -140,8 +140,8 @@ def init():
140140 if not is_arraylike or not 1 <= value .ndim <= 2 or value .shape [- 1 ] != len (self ._data .Close ):
141141 raise ValueError (
142142 '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 } )' )
145145
146146 if plot and overlay is None and np .issubdtype (value .dtype , np .number ):
147147 x = value / self ._data .Close
@@ -288,10 +288,10 @@ def __getattr__(self, item):
288288 removed_attrs = ('entry' , 'set_entry' , 'is_long' , 'is_short' ,
289289 'sl' , 'tp' , 'set_sl' , 'set_tp' )
290290 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} " )
295295
296296
297297class Position :
@@ -346,7 +346,7 @@ def close(self, portion: float = 1.):
346346 trade .close (portion )
347347
348348 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)>'
350350
351351
352352class _OutOfMoneyError (Exception ):
@@ -386,11 +386,11 @@ def __init__(self, broker: '_Broker',
386386
387387 def _replace (self , ** kwargs ):
388388 for k , v in kwargs .items ():
389- setattr (self , '_{}__{}' . format ( self .__class__ .__qualname__ , k ) , v )
389+ setattr (self , f '_{ self .__class__ .__qualname__ } __ { k } ' , v )
390390 return self
391391
392392 def __repr__ (self ):
393- return '<Order {}>' .format (', ' .join ('{ }={}' . format ( param , round (value , 5 ))
393+ return '<Order {}>' .format (', ' .join (f' { param } ={ round (value , 5 )} '
394394 for param , value in (
395395 ('size' , self .__size ),
396396 ('limit' , self .__limit_price ),
@@ -513,13 +513,12 @@ def __init__(self, broker: '_Broker', size: int, entry_price: float, entry_bar):
513513 self .__tp_order : Optional [Order ] = None
514514
515515 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} >'
519518
520519 def _replace (self , ** kwargs ):
521520 for k , v in kwargs .items ():
522- setattr (self , '_{}__{}' . format ( self .__class__ .__qualname__ , k ) , v )
521+ setattr (self , f '_{ self .__class__ .__qualname__ } __ { k } ' , v )
523522 return self
524523
525524 def _copy (self , ** kwargs ):
@@ -647,8 +646,8 @@ def tp(self, price: float):
647646 def __set_contingent (self , type , price ):
648647 assert type in ('sl' , 'tp' )
649648 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
652651 if order :
653652 order .cancel ()
654653 if price :
@@ -660,9 +659,9 @@ def __set_contingent(self, type, price):
660659class _Broker :
661660 def __init__ (self , * , data , cash , commission , margin ,
662661 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 } "
666665 self ._data : _Data = data
667666 self ._cash = cash
668667 self ._commission = commission
@@ -678,8 +677,7 @@ def __init__(self, *, data, cash, commission, margin,
678677 self .closed_trades : List [Trade ] = []
679678
680679 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)>'
683681
684682 def new_order (self ,
685683 size : float ,
@@ -703,12 +701,14 @@ def new_order(self,
703701
704702 if is_long :
705703 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 } )" )
708707 else :
709708 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 } )" )
712712
713713 order = Order (self , size , limit , stop , sl , tp , trade )
714714 # Put the new order in the order queue,
@@ -1243,8 +1243,8 @@ def _tuple(x):
12431243
12441244 for k , v in kwargs .items ():
12451245 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 } " )
12481248
12491249 class AttrDict (dict ):
12501250 def __getattr__ (self , item ):
@@ -1259,7 +1259,7 @@ def __getattr__(self, item):
12591259 raise ValueError ('No admissible parameter combinations to test' )
12601260
12611261 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.' ,
12631263 stacklevel = 2 )
12641264
12651265 heatmap = pd .Series (np .nan ,
0 commit comments