Skip to content

Commit

Permalink
docs: clarified printout for trades/positions
Browse files Browse the repository at this point in the history
  • Loading branch information
kieran-mackle committed Aug 18, 2022
1 parent 536b554 commit 73417e6
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 60 deletions.
48 changes: 28 additions & 20 deletions autotrader/autotrader.py
Original file line number Diff line number Diff line change
Expand Up @@ -1208,6 +1208,8 @@ def print_trade_results(self, trade_results: TradeAnalysis = None) -> None:
max_drawdown = trade_summary["max_drawdown"]

no_trades = trade_summary["no_trades"]
no_long_trades = trade_summary["no_long_trades"]
no_short_trades = trade_summary["no_short_trades"]
if no_trades > 0:
win_rate = trade_summary["all_trades"]["win_rate"]
max_win = trade_summary["all_trades"]["max_win"]
Expand Down Expand Up @@ -1235,14 +1237,20 @@ def print_trade_results(self, trade_results: TradeAnalysis = None) -> None:
print("Maximum drawdown: {}%".format(round(max_drawdown * 100, 2)))
if no_trades > 0:
print("Total no. trades: {}".format(no_trades))
print("No. long trades: {}".format(no_long_trades))
print("No. short trades: {}".format(no_short_trades))
print("Total fees paid: ${}".format(round(total_fees, 3)))
print("Win rate: {}%".format(round(win_rate, 1)))
print("Max win: ${}".format(round(max_win, 2)))
print("Average win: ${}".format(round(avg_win, 2)))
print("Max loss: -${}".format(round(max_loss, 2)))
print("Average loss: -${}".format(round(avg_loss, 2)))
print("Longest winning streak: {} trades".format(longest_win_streak))
print("Longest losing streak: {} trades".format(longest_lose_streak))
print(
"Longest winning streak: {} positions".format(longest_win_streak)
)
print(
"Longest losing streak: {} positions".format(longest_lose_streak)
)
print(
"Average trade duration: {}".format(
trade_summary["all_trades"]["avg_trade_duration"]
Expand All @@ -1261,45 +1269,45 @@ def print_trade_results(self, trade_results: TradeAnalysis = None) -> None:
print("Cancelled orders: {}".format(no_cancelled))

# Long trades
no_long = trade_summary["long_trades"]["no_trades"]
print("\n Summary of long trades")
no_long = trade_summary["long_positions"]["total"]
print("\n Summary of long positions")
print("----------------------------------------------")
if no_long > 0:
avg_long_win = trade_summary["long_trades"]["avg_long_win"]
max_long_win = trade_summary["long_trades"]["max_long_win"]
avg_long_loss = trade_summary["long_trades"]["avg_long_loss"]
max_long_loss = trade_summary["long_trades"]["max_long_loss"]
long_wr = trade_summary["long_trades"]["long_wr"]
avg_long_win = trade_summary["long_positions"]["avg_long_win"]
max_long_win = trade_summary["long_positions"]["max_long_win"]
avg_long_loss = trade_summary["long_positions"]["avg_long_loss"]
max_long_loss = trade_summary["long_positions"]["max_long_loss"]
long_wr = trade_summary["long_positions"]["long_wr"]

print("Number of long trades: {}".format(no_long))
print("No. long positions: {}".format(no_long))
print("Win rate: {}%".format(round(long_wr, 1)))
print("Max win: ${}".format(round(max_long_win, 2)))
print("Average win: ${}".format(round(avg_long_win, 2)))
print("Max loss: -${}".format(round(max_long_loss, 2)))
print("Average loss: -${}".format(round(avg_long_loss, 2)))
else:
print("There were no long trades.")
print("There were no long positions.")

# Short trades
no_short = trade_summary["short_trades"]["no_trades"]
print("\n Summary of short trades")
no_short = trade_summary["short_positions"]["total"]
print("\n Summary of short positions")
print("----------------------------------------------")
if no_short > 0:
avg_short_win = trade_summary["short_trades"]["avg_short_win"]
max_short_win = trade_summary["short_trades"]["max_short_win"]
avg_short_loss = trade_summary["short_trades"]["avg_short_loss"]
max_short_loss = trade_summary["short_trades"]["max_short_loss"]
short_wr = trade_summary["short_trades"]["short_wr"]
avg_short_win = trade_summary["short_positions"]["avg_short_win"]
max_short_win = trade_summary["short_positions"]["max_short_win"]
avg_short_loss = trade_summary["short_positions"]["avg_short_loss"]
max_short_loss = trade_summary["short_positions"]["max_short_loss"]
short_wr = trade_summary["short_positions"]["short_wr"]

print("Number of short trades: {}".format(no_short))
print("No. short positions: {}".format(no_short))
print("Win rate: {}%".format(round(short_wr, 1)))
print("Max win: ${}".format(round(max_short_win, 2)))
print("Average win: ${}".format(round(avg_short_win, 2)))
print("Max loss: -${}".format(round(max_short_loss, 2)))
print("Average loss: -${}".format(round(avg_short_loss, 2)))

else:
print("There were no short trades.")
print("There were no short positions.")

# Check for multiple instruments
if len(trade_results.instruments_traded) > 1:
Expand Down
92 changes: 56 additions & 36 deletions autotrader/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,12 @@ def summary(self) -> dict:
# All trades
no_trades = len(self.trade_history)
trade_results["no_trades"] = no_trades
trade_results["no_long_trades"] = len(
self.trade_history[self.trade_history["direction"] > 0]
)
trade_results["no_short_trades"] = len(
self.trade_history[self.trade_history["direction"] < 0]
)

if no_trades > 0:
# Initialise all_trades dict
Expand Down Expand Up @@ -862,9 +868,17 @@ def summary(self) -> dict:
longest_win_streak, longest_lose_streak = get_streaks(
self.isolated_position_history
)
avg_trade_duration = np.nanmean(
self.isolated_position_history.trade_duration.values
)
try:
avg_trade_duration = np.nanmean(
self.isolated_position_history.trade_duration.values
)
trade_results["all_trades"]["avg_trade_duration"] = str(
timedelta(seconds=int(avg_trade_duration))
)
except TypeError:
# Position has not been closed yet
trade_results["all_trades"]["avg_trade_duration"] = None

min_trade_duration = np.nanmin(
self.isolated_position_history.trade_duration.values
)
Expand All @@ -880,63 +894,69 @@ def summary(self) -> dict:
trade_results["all_trades"]["win_rate"] = win_rate
trade_results["all_trades"]["win_streak"] = longest_win_streak
trade_results["all_trades"]["lose_streak"] = longest_lose_streak
trade_results["all_trades"]["longest_trade"] = str(
timedelta(seconds=int(max_trade_duration))
)
trade_results["all_trades"]["shortest_trade"] = str(
timedelta(seconds=int(min_trade_duration))
)
trade_results["all_trades"]["avg_trade_duration"] = str(
timedelta(seconds=int(avg_trade_duration))
)

if max_trade_duration is not None:
trade_results["all_trades"]["longest_trade"] = str(
timedelta(seconds=int(max_trade_duration))
)
else:
trade_results["all_trades"]["longest_trade"] = str(None)

if min_trade_duration is not None:
trade_results["all_trades"]["shortest_trade"] = str(
timedelta(seconds=int(min_trade_duration))
)
else:
trade_results["all_trades"]["shortest_trade"] = str(None)

trade_results["all_trades"]["total_fees"] = total_fees

# Cancelled orders
trade_results["no_cancelled"] = len(self.cancelled_orders)

# Long positions
long_trades = self.isolated_position_history[
long_positions = self.isolated_position_history[
self.isolated_position_history["direction"] > 0
]
no_long = len(long_trades)
trade_results["long_trades"] = {}
trade_results["long_trades"]["no_trades"] = no_long
no_long = len(long_positions)
trade_results["long_positions"] = {}
trade_results["long_positions"]["total"] = no_long
if no_long > 0:
long_wins = long_trades[long_trades.profit > 0]
long_wins = long_positions[long_positions.profit > 0]
avg_long_win = np.mean(long_wins.profit)
max_long_win = np.max(long_wins.profit)
long_loss = long_trades[long_trades.profit < 0]
long_loss = long_positions[long_positions.profit < 0]
avg_long_loss = abs(np.mean(long_loss.profit))
max_long_loss = abs(np.min(long_loss.profit))
long_wr = 100 * len(long_trades[long_trades.profit > 0]) / no_long
long_wr = 100 * len(long_positions[long_positions.profit > 0]) / no_long

trade_results["long_trades"]["avg_long_win"] = avg_long_win
trade_results["long_trades"]["max_long_win"] = max_long_win
trade_results["long_trades"]["avg_long_loss"] = avg_long_loss
trade_results["long_trades"]["max_long_loss"] = max_long_loss
trade_results["long_trades"]["long_wr"] = long_wr
trade_results["long_positions"]["avg_long_win"] = avg_long_win
trade_results["long_positions"]["max_long_win"] = max_long_win
trade_results["long_positions"]["avg_long_loss"] = avg_long_loss
trade_results["long_positions"]["max_long_loss"] = max_long_loss
trade_results["long_positions"]["long_wr"] = long_wr

# Short positions
short_trades = self.isolated_position_history[
short_positions = self.isolated_position_history[
self.isolated_position_history["direction"] < 0
]
no_short = len(short_trades)
trade_results["short_trades"] = {}
trade_results["short_trades"]["no_trades"] = no_short
no_short = len(short_positions)
trade_results["short_positions"] = {}
trade_results["short_positions"]["total"] = no_short
if no_short > 0:
short_wins = short_trades[short_trades.profit > 0]
short_wins = short_positions[short_positions.profit > 0]
avg_short_win = np.mean(short_wins.profit)
max_short_win = np.max(short_wins.profit)
short_loss = short_trades[short_trades.profit < 0]
short_loss = short_positions[short_positions.profit < 0]
avg_short_loss = abs(np.mean(short_loss.profit))
max_short_loss = abs(np.min(short_loss.profit))
short_wr = 100 * len(short_trades[short_trades.profit > 0]) / no_short
short_wr = 100 * len(short_positions[short_positions.profit > 0]) / no_short

trade_results["short_trades"]["avg_short_win"] = avg_short_win
trade_results["short_trades"]["max_short_win"] = max_short_win
trade_results["short_trades"]["avg_short_loss"] = avg_short_loss
trade_results["short_trades"]["max_short_loss"] = max_short_loss
trade_results["short_trades"]["short_wr"] = short_wr
trade_results["short_positions"]["avg_short_win"] = avg_short_win
trade_results["short_positions"]["max_short_win"] = max_short_win
trade_results["short_positions"]["avg_short_loss"] = avg_short_loss
trade_results["short_positions"]["max_short_loss"] = max_short_loss
trade_results["short_positions"]["short_wr"] = short_wr

return trade_results

Expand Down
8 changes: 4 additions & 4 deletions tests/test_backtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ def test_macd_backtest():
assert round(bt_results["ending_balance"], 3) == 922.059, (
"Incorrect " + "ending balance (single instrument backtest)"
)
assert bt_results["long_trades"]["no_trades"] == 10, (
assert bt_results["long_positions"]["total"] == 10, (
"Incorrect number " + "of long trades (single instrument backtest)"
)
assert bt_results["short_trades"]["no_trades"] == 25, (
assert bt_results["short_positions"]["total"] == 25, (
"Incorrect number " + "of short trades (single instrument backtest)"
)

Expand Down Expand Up @@ -103,10 +103,10 @@ def test_multibot_macd_backtest():
assert round(bt_results["ending_balance"], 3) == 838.269, (
"Incorrect " + "ending balance (multi-instrument backtest)"
)
assert bt_results["long_trades"]["no_trades"] == 18, (
assert bt_results["long_positions"]["total"] == 18, (
"Incorrect number " + "of long trades (multi-instrument backtest)"
)
assert bt_results["short_trades"]["no_trades"] == 48, (
assert bt_results["short_positions"]["total"] == 48, (
"Incorrect number " + "of short trades (multi-instrument backtest)"
)

Expand Down

0 comments on commit 73417e6

Please sign in to comment.