Aim
This is a strategy about interest rate arbitrage. The first stage of this project is building a system to scan for an opportunity.
- Found interest rate arbitrage opportunities
- Understand the interest rate update period
System overview
Action details
001
- Collectors will gather interest rate information from different brokers and accounts
- They will send those information to analysis
| broker | account | symbol | swap_long | swap_short | spread | create_time |
|---|---|---|---|---|---|---|
| xxx | xxx | USDCAD | -4 | -4 | 10 | xxx |
| xxx | xxx | USDHKD | 6 | -6 | 15 | xxx |
002
- Searcher will search for the opportunities
- It will search after interest rate is updated
- It will records the updated item in a time series manner for update pattern observation
003
- Detail information of the opportunities
| broker | account | symbol | spread | swap_long | swap_short | swap_side | side | swap_total | action_group |
|---|---|---|---|---|---|---|---|---|---|
| xxx | xxx | USDCAD | 10 | -4 | -4 | -4 | long | 2 | 1 |
| xxx | xxx | USDCAD | 10 | -6 | 6 | 6 | short | 2 | 1 |
| xxx | xxx | USDAUD | 15 | -3 | -3 | -3 | long | 1 | 2 |
| xxx | xxx | USDAUD | 15 | -4 | 4 | 4 | short | 1 | 2 |
- We use email notification ✉️ with attachments to keep clients informed the latest updates
Analysis table
Here shows one arbitrage action created by the searcher. With the given symbol USDCNH, the arbitrage should be able to cover the transaction cost after 12 days. To be able to make a profitable strategy, we have follow up questions:
- How long does the interest rate stay the same?
- How much money we need to put in the broker account to keep the position given that the price of the product could be fluctuate.
- What leverage level we can use to generate enough profit?
The search algorithm
We would like to find results as following:
- EURUSD.long, USDEUR.short
- EURUSD.long, USDCAD.long, EURCAD.short
- ...
Clearly, the data is linked by the base and quote currency. To search for all combination, we can choose BFS/DFS.
Please notice that we have to prevent duplicated searching by pruning the search tree, for example, here is an reverse searching:
- EURUSD.long, USDCAD.long, EURCAD.short
- EURUSD.long, EURCAD.short, USDCAD.long
the above 2 results are the same.
Here is part of the source code to implement the searching:
def __Arb_Actions_Dfs(self , ir_info: List[IR_Element] , result: List[List[IR_Element]] , path: List[IR_Element] , seen: Set[str] , max_level: int , current_level: int) -> None: for info_ele in ir_info: for side in ["long", "short"]: if side == "short" and current_level == 0: continue ele_key = self.__Get_Seen_Key(info_ele=info_ele, side=side) if ele_key in seen: continue if len(path) == 0 or self.__Is_Expandable(ir_ele=path[-1] , next_ir_ele=info_ele , next_side=side): seen.add(ele_key) path.append(self.__Get_Expand_IR_Element(path=path, next_ir_ele=info_ele, next_side=side)) result_num = len(result) if self.__Is_Market_Neutral(path=path): # found answer, no need to search further result.append(copy.deepcopy(path)) elif (current_level + 1) < max_level: # control search level, only search when smaller than max_level self.__Arb_Actions_Dfs(ir_info=ir_info , result=result , path=path , seen=seen , max_level=max_level , current_level=current_level+1) path.pop() if current_level == 0: # only remove seen at the root to prevent reverse searching seen.clear() elif result_num == len(result): # no new soultion found when the values are the same # remove seen when no new solution found, so that we can retry the symbol seen.remove(ele_key)
To prevent the reverse searching, the "seen" set will be clear only when the root currency finished its searching.




Comments
Post a Comment