There isn't a documentation for creating a broker because each broker has a different way of doing things. For example: Interactive Brokers has bracket orders (A group of 3 orders in which 2 of them bracket the 3rd in the middle) whereas Oanda has bracketing support (A single order with 3 possible prices, in which 2 of them bracket the price in the middle)
Some approaches were tried along the way and the best approach in any case would be:
Not to create a specific Order object even if subclassed from Order
Use a standard Order object and create broker specific order dicts, lists and other things inside the broker code
Use the Store pattern to avoid direct instantiation of specific Broker and Data classes. This also helps to keep common parameters (like for example host for the connection) unified
Use the code from Oanda as a basis.
In general you will need:
Background threads to process data and broker events
Synchronized queues to received the events from the background threads
A mapping between the data events (like not being able to access a data feed due to permissions -> NOTSUBSCRIBED) to the events defined in the backtrader classes
A mapping also for some broker events. Some brokers report expired orders as cancelled. It may not really be that important at the end, but if it's important for you, you should be able to discriminate.
I've found this link which offers other links to relevant info and the resulting two algorithms I have attempted. Values of the two formulas are very different with one of the formulas returning negative values. As I understand Half-Life of a time series, it indicates some time value for complete cycle of the reversion to mean process. However, given the results, I'm not quite grasping the measurement value and how it applies to the concept of "time".
There is no need for logic there and that's why there is none. The entry order (aka main side) is protected automatically with a stop-loss side and a take-profit side (the high/low side depends on the direction entry), which are only active if the entry order is executed.
Once the stop-loss/take-profit sides become active, the execution of any of them automatically cancels the other.
If you decide to exit the market with an unrelated order, you have to manually cancel any of the sides (the other will be cancelled automatically) as in
self.cancel(order_stop_loss_side) # this automatically cancels the take-profit side too