Strategy¶
This class define a strategy to apply on ticks/candles.t pu
Parameters
Name | Type | Description | Default |
---|---|---|---|
epics |
List[estrade.epic.Epic] |
list of estrade.Epic instances |
required |
params |
Optional[Dict[str, Any]] |
free of use dict of parameters you can re-use in your strategy methods | None |
ref |
str |
strategy name | None |
max_concurrent_trades |
int |
nb max of trades concurrently opened | 1 |
Define your custom strategies to define when to open/close trades. Your strategies are triggered by all new ticks received and all new candles created on the Epics attached to it.
Example
Example of a strategy that
- open a BUY trade when the tick value is 1000
- open a SELL trade when the last closed candle was red
- close all opened BUY trades when the moving average on 50 periods is inferior to the current tick - 20
- close all trades when the strategy result is > 200 when a new candle opens.
from estrade import CandleSet, Market, Provider, SimpleMovingAverage, Strategy
class MyCustomStrategy(Strategy):
def on_new_tick_opening_strategy(tick):
if tick.value == 1000:
self.open_trade(
epic=tick.epic.ref,
quantity=2,
direction='SELL',
stop_absolute=1010,
limit_absolute=990,
)
def on_new_candle_opening_strategy(candle_set):
last_candle = candle_set.last_closed_candle
# check if is defined because on first candle in candle set,
# it will be none.
if last_candle:
if last_candle.color == 'red':
self.open_trade(
epic=candle_set.epic.ref,
quantity=1,
direction='BUY',
stop_relative=30,
)
def on_new_tick_closing_strategy(tick):
mm50_15mn = self.get_indicator(
epic_ref='MY_EPIC',
timeframe='15minutes',
indicator_name='mm50'
)
# check if exists because for the 49 fist candles it will not be defined
if mm50_15mn:
if mm50_15mn < (tick.value - 20):
self.close_all_buys()
def on_new_candle_closing_strategy(tick):
result = self.market.trade_manager.result(strategy=self)
if result > 200:
self.close_all_trades()
class MyProvider(Provider):
# define your custom provider
pass
if __name__ == '__main__':
mm50 = SimpleMovingAverage(ref='mm50')
candle_set = CandleSet(timeframe='15minutes', indicators=[mm50])
epic = Epic(ref='MY_EPIC', candle_sets=[candle_set])
strategy = MyCustomStrategy(epics=[epic])
provider = MyProvider()
market = Market(
strategies=[strategy],
provider=provider,
)
market.run()
epics: List[estrade.epic.Epic]
(property, writable)¶
Returns
Type | Description |
---|---|
List[estrade.epic.Epic] |
Returns list of epics attached to strategy |
json_headers: List[str]
(property, readonly)¶
Generate header of a dictionary of strategy stats for reporting
params: Dict[str, Any]
(property, writable)¶
Returns strategy params
Example
Example of usage of params in strategy
from estrade import Strategy
class MyStrategy(Strategy):
def on_new_tick_opening_strategy(self, tick):
if tick.value < self.params['trigger_value']:
self.open_trade(...)
strategy = MyStrategy(params={'trigger_value': 1000})
to_json: Dict[str, Any]
(property, readonly)¶
Generate a dictionary of strategy stats for reporting
check_tick_time(self, tick)
¶
Show source code in estrade/strategy.py
546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 |
|
This method is executed on every tick and allow to restrict the date/time where the strategy applies. If this method return False, no opening strategy will be applied.
Rewrite this method in your strategy to define when it does apply.
Parameters
Name | Type | Description | Default |
---|---|---|---|
tick |
Tick |
new tick received by strategy because it is attached to an Epic on | required |
Note
- tick.datetime is an Arrow instance (see arrow lib: https://arrow.readthedocs.io)
- this method does not prevent application of closing strategy methods, it only prenvent opening new trades.
Example
example of a strategy that only applies between 9am and 11em
from estrade import Strategy
def MyStrategy(Strategy):
def check_tick_time(tick):
if tick.datetime.hour >= 9 and tick.datetime.hour <= 11:
return True
return False
Returns
Type | Description |
---|---|
bool |
Returns True if the tick datetime is in an time period allowed for opening trades |
close_all_buys(self, *args, **kwargs)
¶
Show source code in estrade/strategy.py
405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 |
|
Use this method in closing strategy methods to close all opened buys for strategy
Info
Closing strategy method where it is advised to call this method are:
Strategy.on_new_tick_closing_strategy
Strategy.on_new_candle_closing_strategy
Seealso
This method calls estrade.TradeManager.close_all_buys
method and inject
this strategy as an argument.
Parameters
Name | Type | Description | Default |
---|---|---|---|
*args |
args to close a trade (see estrade.TradeManager.close_all_buys ) |
() |
|
**kwargs |
args to close a trade (see estrade.TradeManager.close_all_buys ) |
{} |
close_all_sells(self, *args, **kwargs)
¶
Show source code in estrade/strategy.py
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 |
|
Use this method in closing strategy methods to close all opened sells for strategy
Info
Closing strategy method where it is advised to call this method are:
Strategy.on_new_tick_closing_strategy
Strategy.on_new_candle_closing_strategy
Seealso
This method calls estrade.TradeManager.close_all_sells
method and inject
this strategy as an argument.
Parameters
Name | Type | Description | Default |
---|---|---|---|
*args |
args to close a trade (see estrade.TradeManager.close_all_sells ) |
() |
|
**kwargs |
args to close a trade (see estrade.TradeManager.close_all_sells ) |
{} |
close_all_trades(self, *args, **kwargs)
¶
Show source code in estrade/strategy.py
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 |
|
Use this method in your closing strategy methods to close all opened trades for strategy
Info
Closing strategy method where it is advised to call this method are:
Strategy.on_new_tick_closing_strategy
Strategy.on_new_candle_closing_strategy
Seealso
This method calls estrade.TradeManager.close_all_trades
method and inject
this strategy as an argument.
Parameters
Name | Type | Description | Default |
---|---|---|---|
*args |
args to close a trade (see estrade.TradeManager.close_all_trades ) |
() |
|
**kwargs |
args to close a trade (see estrade.TradeManager.close_all_trades ) |
{} |
close_trade_by_ref(self, ref, **kwargs)
¶
Show source code in estrade/strategy.py
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 |
|
Use this method in your closing strategy methods to close a trade by its reference.
Info
Closing strategy method where it is advised to call this method are:
Strategy.on_new_tick_closing_strategy
Strategy.on_new_candle_closing_strategy
Seealso
This method calls estrade.TradeManager.close_trade_by_ref
method
and inject this strategy as an argument.
Parameters
Name | Type | Description | Default |
---|---|---|---|
ref |
str |
existing estrade.trade.Trade ref code attached to this strategy on |
required |
**kwargs |
args to close a trade | {} |
get_candle(self, epic_ref, timeframe, offset=0)
¶
Show source code in estrade/strategy.py
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
|
Getter to find a candle by its offset in a candleset
Parameters
Name | Type | Description | Default |
---|---|---|---|
epic_ref |
str |
reference of an epic attached to this strategy | required |
timeframe |
str |
timeframe of the estrade.CandleSet to return |
required |
offset |
int |
index of the candle to retrieve | 0 |
Offset usage
- 0: returns the currently opened candle on candleset
- 1 : returns the last closed candle
- etc.
Tip
Reserve usage of this getter when you need to find candles that are not the current candle or the last closed candle.
It is recommendend that you call the Strategy.get_candle_set
method and
retrieve its last_closed_candle
, current_candle
for these cases.
Exceptions
Type | Description |
---|---|
StrategyException |
if epic not found on market |
EpicException |
if no candle set with this timeframe found on this epic |
Returns
Type | Description |
---|---|
Union[estrade.candle.Candle, NoneType] |
A candle object, see estrade.Candle |
get_candle_set(self, epic_ref, timeframe)
¶
Show source code in estrade/strategy.py
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
|
Getter to find a candle set from epic_ref and timeframe.
Parameters
Name | Type | Description | Default |
---|---|---|---|
epic_ref |
str |
reference of an epic attached to this strategy | required |
timeframe |
str |
timeframe of the estrade.CandleSet to return |
required |
Exceptions
Type | Description |
---|---|
StrategyException |
if epic not found on market |
EpicException |
if no candle set with this timeframe found on this epic |
Returns
Type | Description |
---|---|
CandleSet |
A candle set object, see estrade.CandleSet |
get_epic(self, epic_ref)
¶
Show source code in estrade/strategy.py
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
|
Getter to find epic in strategies epic from its ref.
Parameters
Name | Type | Description | Default |
---|---|---|---|
epic_ref |
str |
ref of an Epic in the current strategy epics. | required |
Exceptions
Type | Description |
---|---|
StrategyException |
if epic not found in current strategy epics |
Returns
Type | Description |
---|---|
Epic |
Epic instance |
get_indicator(self, epic_ref, timeframe, indicator_name, offset=0)
¶
Show source code in estrade/strategy.py
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 |
|
Getter to find a candle indicator value.
Parameters
Name | Type | Description | Default |
---|---|---|---|
epic_ref |
str |
ref of an epic in current strategy epics | required |
timeframe |
str |
matching a candleset.timeframe in epic | required |
indicator_name |
str |
matching an existing indicator on candle_set | required |
offset |
int |
offset of the indicator | 0 |
Exceptions
Type | Description |
---|---|
StrategyException |
if epic not found on market |
EpicException |
if no candle set with this timeframe found on this epic |
Returns
Type | Description |
---|---|
Union[estrade.mixins.candle_set_indicator_mixin.CandleSetIndicatorMixin, NoneType] |
Indicator value |
get_trades(self, **kwargs)
¶
Show source code in estrade/strategy.py
311 312 313 314 315 316 317 318 319 320 321 |
|
Getter to find list of strategy trades.
Seealso
referer to TradeManager.get_trades
to view the list of arguments
Returns
Type | Description |
---|---|
Union[List[estrade.trade.Trade], NoneType] |
List of trades attached to the current strategy |
on_new_candle_closing_strategy(self, candle_set)
¶
Show source code in estrade/strategy.py
620 621 622 623 624 625 626 627 628 629 |
|
Method called every time a new candle is created and at least one trade is opened for this strategy.
Parameters
Name | Type | Description | Default |
---|---|---|---|
candle_set |
CandleSet |
candle set that generated a new candle | required |
on_new_candle_opening_strategy(self, candle_set)
¶
Show source code in estrade/strategy.py
606 607 608 609 610 611 612 613 614 615 616 617 618 |
|
Method called every time a new candle is created when the number of opened
trades for this strategy is inferior to this instance max_concurrent_trades
value.
Use this method to open trades with Strategy.open_trade
method.
Parameters
Name | Type | Description | Default |
---|---|---|---|
candle_set |
CandleSet |
candle set that generated a new candle | required |
on_new_tick(self, tick)
¶
Show source code in estrade/strategy.py
477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 |
|
Method triggered when a new tick is received by Market. This method check if opening and/or closing srategies have to be applied and then call the opening/closing methods.
Parameters
Name | Type | Description | Default |
---|---|---|---|
tick |
Tick |
new tick instance received | required |
on_new_tick_closing_strategy(self, tick)
¶
Show source code in estrade/strategy.py
595 596 597 598 599 600 601 602 603 604 |
|
Method is called on every tick received from provider when at least one trade is opened for this strategy.
Parameters
Name | Type | Description | Default |
---|---|---|---|
tick |
Tick |
new tick received | required |
on_new_tick_opening_strategy(self, tick)
¶
Show source code in estrade/strategy.py
584 585 586 587 588 589 590 591 592 593 |
|
This method is called on every tick received from provider when the number of
open trades for this strategy
is inferior to this instance max_concurrent_trades
value.
Parameters
Name | Type | Description | Default |
---|---|---|---|
tick |
Tick |
new tick received | required |
open_trade(self, **kwargs)
¶
Show source code in estrade/strategy.py
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 |
|
Use this method to open a trade.
This method calls estrade.trade_manager.TradeManager.open_trade
method
and inject this strategy as an argument.
As a result, a new estrade.Trade
instance is created and attached to the
TradeManager.
for example, you can open a trade in your strategy event as following ::
Example
Example of trade open that you can use in opening strategies
from estrade import Strategy
class MyCustomStrategy:
def on_new_tick_opening_strategy(self, tick):
if tick.value == 1000:
self.open_trade(
# mandatory params
epic=tick.epic.ref,
quantity=5,
direction='SELL',
# optional params
ref='my_trade_ref',
stop_relative=10,
limit_relative=20,
meta={'data': 'my_data'},
)