(bt_df, stop_loss_lvl=None)
| 650 | print("Max Drawdown %:", round(drawdown_pct.min(), 2)) |
| 651 | |
| 652 | def run_stock_ta_backtest(bt_df, stop_loss_lvl=None): |
| 653 | balance = 1000000 |
| 654 | pnl = 0 |
| 655 | position = 0 |
| 656 | |
| 657 | last_signal = "hold" |
| 658 | last_price = 0 |
| 659 | c = 0 |
| 660 | |
| 661 | trade_date_start = [] |
| 662 | trade_date_end = [] |
| 663 | trade_days = [] |
| 664 | trade_side = [] |
| 665 | trade_pnl = [] |
| 666 | trade_ret = [] |
| 667 | |
| 668 | cum_value = [] |
| 669 | |
| 670 | for index, row in bt_df.iterrows(): |
| 671 | # check and close any positions |
| 672 | if row.EXIT_LONG and last_signal == "long": |
| 673 | trade_date_end.append(row.name) |
| 674 | trade_days.append(c) |
| 675 | |
| 676 | pnl = (row.Open - last_price) * position |
| 677 | trade_pnl.append(pnl) |
| 678 | trade_ret.append((row.Open / last_price - 1) * 100) |
| 679 | |
| 680 | balance = balance + row.Open * position |
| 681 | |
| 682 | position = 0 |
| 683 | last_signal = "hold" |
| 684 | |
| 685 | c = 0 |
| 686 | |
| 687 | elif row.EXIT_SHORT and last_signal == "short": |
| 688 | trade_date_end.append(row.name) |
| 689 | trade_days.append(c) |
| 690 | |
| 691 | pnl = (row.Open - last_price) * position |
| 692 | trade_pnl.append(pnl) |
| 693 | trade_ret.append((last_price / row.Open - 1) * 100) |
| 694 | |
| 695 | balance = balance + pnl |
| 696 | |
| 697 | position = 0 |
| 698 | last_signal = "hold" |
| 699 | |
| 700 | c = 0 |
| 701 | |
| 702 | # check signal and enter any possible position |
| 703 | if row.LONG and last_signal != "long": |
| 704 | last_signal = "long" |
| 705 | last_price = row.Open |
| 706 | trade_date_start.append(row.name) |
| 707 | trade_side.append("long") |
| 708 | |
| 709 | position = int(balance / row.Open) |
no outgoing calls
no test coverage detected