## Homework 4: Optimum Strategy for Stock Trading with Known Future Prices
### Introduction
Suppose we only have a single stock to buy or sell, and all the prices are known in advance. As explained in the class, you can use DP (dynamic programming) on this task to achieve best return rate. In this homework, we shall expand the task to account for more real-world oriented situations.
Let's start with the basic case, where "buy" and "sell" can be applied to multiple stocks, with the price known in advance. In other words, you need to identify the best timing for "buy what" and "sell what", such that the overall return is maximized. TA will use a dataset to determine the ranking of your return rate based on your submissions.
### Function prototype for batch-mode prices
For tasks 1 and 2, you have all the prices in advance and you can design a function of generate the buy/sell strategy. Your function should follow this input/output format when you submit it to the judge system:
<center>
actionMat = myAction01(priceMat, rate1, rate2);
</center>
Here's what each variable means:
- priceMat: An $m \times n$ matrix that shows the prices of $n$ stocks over $m$ days.
- rate1: Rate for "buy" overhead, usually around 0.1425% (transaction fee) for Taiwan stock market.
- rate2: Rate for "sell" overhead, usually around 0.4425% (0.1425% for transaction fee and 0.3% for security tax) for Taiwan stock market.
- actionMat: A $k \times 4$ action matrix which records $k$ transactions. Each $[d, a, b, z]$ represents one transaction, explained below:
- $d$: The day index, starting from 0 with monotonically increasing values. That is, for each day, we can only allow one transaction.
- $a$: The index of the stock you sell ("from" stock), where "-1" means "cash" and any other numbers (from $0$ to $n-1$) mean stock indices.
- $b$: The index of the stock you buy ("to" stock), which has the same range as that of $a$.
- $z$: The cash amount involved in this transaction. The value must be positive.
For instance:
- [5, -1, 7, 100]: On day 5, use $100(1-rate1)$ dollars in cash to buy stock 7, where $\rho$ is the transaction fee rate.
- [3, 8, -1, 50]: On day 3, sell stock 8 and $50(1-rate2)$ dollars in cash.
- [12, 6, 9, 80]: On day 12, sell stock 6 and buy stock 9. Such a transaction is not allowed and nothing will happen. To do exchange between stocks, you need to sell a stock first to get cash, and then use the cash to buy another stock in the next transaction.
Here we have some common rules for your strategy:
- We shall assume the price is available at the beginning of each day, so you can start your transaction on every day, including the first and the last day. On the last day, the performance of your strategy is calculated as the cash equivalent of all your positions.
- You can only have at most one transaction each day.
- No stock-to-stock exchange. To do so, you need to convert the stock to cash in one transction, and buy another stock using cash in another tracaction.
- After each transaction, you must wait for two days (cooldown period) before making another one. For example, if you trade on Monday, the next trade can be made on or after Thursday.
As an example, here we can use a simple greedy strategy to show how the process works:
- Buy a stock if its price will go up the next day. If more than one stock is going up, choose the one with the largest increase.
- Sell a stock if its price will go down the next day. If more than one stock is going down, choose the one with the largest decrease.
To calculate the return rate, we need two files:
- [myAction.py](https://drive.google.com/file/d/1F-v1UMoH_0sZxThLWPt6HDHszUkZBXqT/view?usp=sharing): This file includes several trading strategies, such as the simple greedy strategy (explained earlier) in myAction01_Sample() and myAction03_Sample(). Other functions like myAction01(), myAction02(), and myAction03() are for you to complete.
- [rrEstimateOpen.py](https://drive.google.com/file/d/1XPT1Bp2Aq0qBg2fHAwPLFLRqteqtYuRs/view?usp=sharing): This is the main program that estimates the return rate.
To test the results for myAction.py, type this command:
<center>
python rrEstimateOpen.py priceMat0992.txt 0.001425 0.004425
</center>
You can run myAction_Sample01() first. The result is:
<center>
18931.082700%
</center>
In the above example, [priceMat0992.txt](http://mirlab.org/jang/courses/fintech/homework/2024/optimumTradingStrategy/exampleCode/priceMat0992.txt) contains the prices of 4 stocks over 992 days. When grading, the TA will use a hidden file with a similar time span to test your trading strategies.
Now you need to complete several functions in myAction.py to maximumize the profit under various constraints.
1. Task 1 using myAction01(): You can use either a greedy approach (like the one mentioned earlier) or a DP approach to achieve the best result.
2. Task 2 using myAction02(): You can have at most $K$ transactions in total, where $K$ is given by TA.
Once you have finished these functions, remember to use [rrEstimateOpen.py](https://drive.google.com/file/d/1XPT1Bp2Aq0qBg2fHAwPLFLRqteqtYuRs/view?usp=sharing) to test them. This is also the main program used by TA to evaluate your submission. Make sure you run this main program to test your functions before submitting them.
### Function prototype for online-mode prices
Here we shall assume the prices are known only for the next day. This is a much harder task since we need to come up with the buy/sell/hold decision at day $n$ with $n$-days historical prices and 1-day (tomorrow) prices. The function prototype is like this:
<center>
action = myAction03(priceMatHistory, priceMatFuture, position, actionHistory, rate1, rate2);
</center>
This function will be called at each day to determine that day's action (buy/sell/hold). For instance, if it is called at day $p$, the inputs are:
- "priceMatHistory" will be an $p \times n$ matrix where $n$ is the number of stocks.
- "priceMatFuture" will be and $1 \times n$ matrix indicating the price of the next day. On the last day, this matrix is empty indicing there is no price info for the next day.
- "position" is the current positions. For instance, position=[2 3 1 6 200] ==> 2, 3, 1, 6 units for stocks 1, 2, 3, 4, respectively, and 200 for cash.
- "actionHistory" is the historical actions packed into a $k \times 4$ matrix if we have $k$ historical transactions.
- "rate1": Overhead rate for "buy".
- "rate2": Overhead rate for "sell".
The output is:
- "action": A $1 \times 4$ matrix (as explained earlier) indicating the action of day $p$.
An example is given in myAction_Sample03(). The logic is same with myAction_Sample01() but it uses the function prototype in task 3.
So task 3 is to design such a function to come up with the action with partial price information.
### Submission:
- You only need to submit "[myAction.py](https://drive.google.com/file/d/1F-v1UMoH_0sZxThLWPt6HDHszUkZBXqT/view?usp=sharing)" on Gradescope.
- If the returned actions matrix does not comply with the given constraints, the return rate may be set to zero directly.
- You must ensure that your code doesn't take more than 5 minutes to run. Otherwise, the return rate may be set to zero directly.
<!--
<li>For your info, the baseline is 55000000% for myAction01() using the give price file.
The strategy is based on exhaustive search on p & q for the strategy "buy for p-day consecutive up, sell for q-day consecutive down".
<li>Due to the problem of SQL overflow, the judge system will display your return rate (in %) divided by 1000000. For instance, the baseline will be displayed as 55000000/1000000 = 55.
-->
- Your score of this homework is based on the sum of your 3 rankings of myAction01~03, as follows.
1. myAction01(): Ranking is based on the return rate.
2. myAction02(): Ranking is based on the average ranking of return rates when K is assigned three different numbers, respectively.
3. myAction03(): Ranking is based on the return rate.
<!--
<p>When you submit your function "myOptimAction.py", remember to explain your strategy briefly at the beginning comment section of your function, including
<ul>
<li>What is the design philosophy of your trading strategy?
<li>Is there any free parameters in your strategy? If yes, how do you optimize the overall performance?
<li>How does your strategy work on the given file of the price of 4 stocks?
</ul>
-->
### FAQ
<ul>
<li>...
</ul>
### References
- [DP for trading](https://www.youtube.com/watch?v=RiM5mF3ufJc)