Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backtesting broker should check cash before processing pending orders #439

Open
Canx opened this issue May 5, 2024 · 7 comments
Open

Backtesting broker should check cash before processing pending orders #439

Canx opened this issue May 5, 2024 · 7 comments

Comments

@Canx
Copy link
Collaborator

Canx commented May 5, 2024

In method process_pending_orders we should check if cash is enough to process order.

@Canx Canx changed the title Polygon backtesting should check cash before processing pending orders Backtesting broker should check cash before processing pending orders May 5, 2024
@jimwhite
Copy link
Collaborator

jimwhite commented May 5, 2024

We routinely test strategies that use margin so we'd need to add and check that too. Margin limits are usually not fixed but a function of the account's cleared assets. Perhaps a little more complex than you expected but totally worthwhile in my opinion.

While it would be great to include modeling of the trade clearing process, we could approach margin in three stages:

  1. Add a fixed margin limit which basically works like an extension to cash. An infinite option here preserves the current behavior and could/should be the default for backwards compatibility. This would require tracking whether a trade is done on cash or margin so the cash value of the portfolio (i.e. assets bought with cash plus the cash) can be calculated.

  2. Add a margin percentage option. This is a typical policy.

  3. Add margin interest. Margin is a loan and you pay daily interest. This will improve backtest accuracy.

  4. Add modeling of trade clearing. This means there is a third state of a trade which means it hasn't settled yet and so is can't be counted as having cash value even when the trade is "cash".

Settlement used to be 3 biz days and is now 2 but I just found out it changes to 1 this month:
https://www.finra.org/investors/insights/understanding-settlement-cycles

For details on how to do this you can check out backtester code that supports margin like Backtrader:
https://github.com/mementum/backtrader/blob/b853d7c90b6721476eb5a5ea3135224e33db1f14/backtrader/order.py#L488

@grzesir
Copy link
Contributor

grzesir commented May 6, 2024

We routinely test strategies that use margin so we'd need to add and check that too. Margin limits are usually not fixed but a function of the account's cleared assets. Perhaps a little more complex than you expected but totally worthwhile in my opinion.

While it would be great to include modeling of the trade clearing process, we could approach margin in three stages:

  1. Add a fixed margin limit which basically works like an extension to cash. An infinite option here preserves the current behavior and could/should be the default for backwards compatibility. This would require tracking whether a trade is done on cash or margin so the cash value of the portfolio (i.e. assets bought with cash plus the cash) can be calculated.

  2. Add a margin percentage option. This is a typical policy.

  3. Add margin interest. Margin is a loan and you pay daily interest. This will improve backtest accuracy.

  4. Add modeling of trade clearing. This means there is a third state of a trade which means it hasn't settled yet and so is can't be counted as having cash value even when the trade is "cash".

Settlement used to be 3 biz days and is now 2 but I just found out it changes to 1 this month:

https://www.finra.org/investors/insights/understanding-settlement-cycles

For details on how to do this you can check out backtester code that supports margin like Backtrader:

https://github.com/mementum/backtrader/blob/b853d7c90b6721476eb5a5ea3135224e33db1f14/backtrader/order.py#L488

Couldn't agree more. We should make some tests for this

@grzesir
Copy link
Contributor

grzesir commented May 6, 2024

If we want to add margin into backtesting then we will need to be able to set parameters around it

@Canx
Copy link
Collaborator Author

Canx commented May 7, 2024

Yes, more complex than expected @jimwhite!

@grzesir, maybe we could start adding an account_type parameter here that could have those types of accounts and make the INFINITE_MARGIN (or similar) the default value.

@grzesir
Copy link
Contributor

grzesir commented May 7, 2024

Yes, more complex than expected @jimwhite!

@grzesir, maybe we could start adding an account_type parameter here that could have those types of accounts and make the INFINITE_MARGIN (or similar) the default value.

This sounds like a good idea. At the very least it would be good to specify whether margin is possible for not.

It might also make sense to go a little further and allow a "max margin" parameter or something. For example, most stock brokers only allow you to borrow maximum 30% of your account value. This would require more work but would be super valuable if you're up for the challenge.

@Canx
Copy link
Collaborator Author

Canx commented May 8, 2024

Challenge accepted, let's see if we have time ;)
As an exploratory idea we could pass an Account object to the broker, something like this:

account = MarginAccount(max_margin=0.3)
broker = BacktestingBroker(data_source, account,...)

and then something like:

class MarginAccount(Account)
class CashAccount(Account)

class Account(ABC):
init(initial_cash):
def withdraw():
def deposit():
def calculate overdrafts():
etc....

@grzesir
Copy link
Contributor

grzesir commented May 9, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants