bugfixes
This commit is contained in:
@ -336,8 +336,11 @@ def capsule(target: object, db: object, inter_batch_params: dict = None):
|
|||||||
db.runners.remove(i)
|
db.runners.remove(i)
|
||||||
#vytvoreni report image pro RUNNER
|
#vytvoreni report image pro RUNNER
|
||||||
try:
|
try:
|
||||||
generate_trading_report_image(runner_ids=[str(i.id)])
|
res, val = generate_trading_report_image(runner_ids=[str(i.id)])
|
||||||
print("DAILY REPORT IMAGE CREATED")
|
if res == 0:
|
||||||
|
print("DAILY REPORT IMAGE CREATED")
|
||||||
|
else:
|
||||||
|
print(f"Daily report ERROR - {val}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Nepodarilo se vytvorit report image", str(e)+format_exc())
|
print("Nepodarilo se vytvorit report image", str(e)+format_exc())
|
||||||
|
|
||||||
@ -510,8 +513,12 @@ def batch_run_manager(id: UUID, runReq: RunRequest, rundays: list[RunDay]):
|
|||||||
|
|
||||||
#vytvoreni report image pro batch
|
#vytvoreni report image pro batch
|
||||||
try:
|
try:
|
||||||
generate_trading_report_image(batch_id=batch_id)
|
res, val = generate_trading_report_image(batch_id=batch_id)
|
||||||
print("BATCH REPORT IMAGE CREATED")
|
if res == 0:
|
||||||
|
print("BATCH REPORT CREATED")
|
||||||
|
else:
|
||||||
|
print(f"BATCH REPORT ERROR - {val}")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Nepodarilo se vytvorit report image", str(e)+format_exc())
|
print("Nepodarilo se vytvorit report image", str(e)+format_exc())
|
||||||
|
|
||||||
|
|||||||
@ -51,9 +51,9 @@ def generate_trading_report_image(runner_ids: list = None, batch_id: str = None,
|
|||||||
trades_dicts = sada.metrics["prescr_trades"]
|
trades_dicts = sada.metrics["prescr_trades"]
|
||||||
|
|
||||||
for trade_dict in trades_dicts:
|
for trade_dict in trades_dicts:
|
||||||
trade_dict['last_update'] = datetime.fromtimestamp(trade_dict.get('last_update')).astimezone(zoneNY)
|
trade_dict['last_update'] = datetime.fromtimestamp(trade_dict.get('last_update')).astimezone(zoneNY) if trade_dict['last_update'] is not None else None
|
||||||
trade_dict['entry_time'] = datetime.fromtimestamp(trade_dict.get('entry_time')).astimezone(zoneNY)
|
trade_dict['entry_time'] = datetime.fromtimestamp(trade_dict.get('entry_time')).astimezone(zoneNY) if trade_dict['entry_time'] is not None else None
|
||||||
trade_dict['exit_time'] = datetime.fromtimestamp(trade_dict.get('exit_time')).astimezone(zoneNY)
|
trade_dict['exit_time'] = datetime.fromtimestamp(trade_dict.get('exit_time')).astimezone(zoneNY) if trade_dict['exit_time'] is not None else None
|
||||||
trades.append(Trade(**trade_dict))
|
trades.append(Trade(**trade_dict))
|
||||||
|
|
||||||
print(trades)
|
print(trades)
|
||||||
@ -61,10 +61,15 @@ def generate_trading_report_image(runner_ids: list = None, batch_id: str = None,
|
|||||||
# Filter to only use trades with status 'CLOSED'
|
# Filter to only use trades with status 'CLOSED'
|
||||||
closed_trades = [trade for trade in trades if trade.status == TradeStatus.CLOSED]
|
closed_trades = [trade for trade in trades if trade.status == TradeStatus.CLOSED]
|
||||||
|
|
||||||
|
if len(closed_trades) == 0:
|
||||||
|
return -1, "image generation no closed trades"
|
||||||
|
|
||||||
# Data extraction for the plots
|
# Data extraction for the plots
|
||||||
exit_times = [trade.exit_time for trade in closed_trades if trade.exit_time is not None]
|
exit_times = [trade.exit_time for trade in closed_trades if trade.exit_time is not None]
|
||||||
cumulative_profits = [trade.profit_sum for trade in closed_trades if trade.profit_sum is not None]
|
##cumulative_profits = [trade.profit_sum for trade in closed_trades if trade.profit_sum is not None]
|
||||||
|
|
||||||
profits = [trade.profit for trade in closed_trades if trade.profit is not None]
|
profits = [trade.profit for trade in closed_trades if trade.profit is not None]
|
||||||
|
cumulative_profits = np.cumsum(profits)
|
||||||
wins = [trade.profit for trade in closed_trades if trade.profit > 0]
|
wins = [trade.profit for trade in closed_trades if trade.profit > 0]
|
||||||
losses = [trade.profit for trade in closed_trades if trade.profit < 0]
|
losses = [trade.profit for trade in closed_trades if trade.profit < 0]
|
||||||
|
|
||||||
@ -190,27 +195,35 @@ def generate_trading_report_image(runner_ids: list = None, batch_id: str = None,
|
|||||||
|
|
||||||
#Cumulative profit - bud 1 den nebo vice dni
|
#Cumulative profit - bud 1 den nebo vice dni
|
||||||
if len(runner_ids)== 1:
|
if len(runner_ids)== 1:
|
||||||
# Plot 3: Cumulative Profit Over Time with Max Profit Point
|
if cumulative_profits:
|
||||||
max_profit_time = exit_times[np.argmax(cumulative_profits)]
|
# Plot 3: Cumulative Profit Over Time with Max Profit Point
|
||||||
max_profit = max(cumulative_profits)
|
max_profit_time = exit_times[np.argmax(cumulative_profits)]
|
||||||
min_profit_time = exit_times[np.argmin(cumulative_profits)]
|
max_profit = max(cumulative_profits)
|
||||||
min_profit = min(cumulative_profits)
|
min_profit_time = exit_times[np.argmin(cumulative_profits)]
|
||||||
sns.lineplot(x=exit_times, y=cumulative_profits, label='Cumulative Profit', ax=axs[1, 3])
|
min_profit = min(cumulative_profits)
|
||||||
axs[1, 3].scatter(max_profit_time, max_profit, color='green', label='Max Profit')
|
sns.lineplot(x=exit_times, y=cumulative_profits, label='Cumulative Profit', ax=axs[1, 3])
|
||||||
axs[1, 3].scatter(min_profit_time, min_profit, color='red', label='Min Profit')
|
axs[1, 3].scatter(max_profit_time, max_profit, color='green', label='Max Profit')
|
||||||
# Format dates on the x-axis
|
axs[1, 3].scatter(min_profit_time, min_profit, color='red', label='Min Profit')
|
||||||
axs[1, 3].xaxis.set_major_formatter(mdates.DateFormatter('%H', tz=zoneNY))
|
# Format dates on the x-axis
|
||||||
axs[1, 3].set_title('Cumulative Profit Over Time')
|
axs[1, 3].xaxis.set_major_formatter(mdates.DateFormatter('%H', tz=zoneNY))
|
||||||
axs[1, 3].legend()
|
axs[1, 3].set_title('Cumulative Profit Over Time')
|
||||||
|
axs[1, 3].legend()
|
||||||
|
else:
|
||||||
|
# Handle the case where cumulative_profits is empty
|
||||||
|
axs[1, 3].text(0.5, 0.5, 'No profit data available',
|
||||||
|
horizontalalignment='center',
|
||||||
|
verticalalignment='center',
|
||||||
|
transform=axs[1, 3].transAxes)
|
||||||
|
axs[1, 3].set_title('Cumulative Profit Over Time')
|
||||||
else:
|
else:
|
||||||
# Calculate cumulative profit
|
# Calculate cumulative profit
|
||||||
# Additional Plot: Cumulative Profit Over Time
|
# Additional Plot: Cumulative Profit Over Time
|
||||||
# Sort trades by exit time
|
# Sort trades by exit time
|
||||||
sorted_trades = sorted([trade for trade in trades if trade.status == TradeStatus.CLOSED],
|
sorted_trades = sorted([trade for trade in trades if trade.status == TradeStatus.CLOSED],
|
||||||
key=lambda x: x.exit_time)
|
key=lambda x: x.exit_time)
|
||||||
cumulative_profits = np.cumsum([trade.profit for trade in sorted_trades])
|
cumulative_profits_sorted = np.cumsum([trade.profit for trade in sorted_trades])
|
||||||
exit_times_sorted = [trade.exit_time for trade in sorted_trades]
|
exit_times_sorted = [trade.exit_time for trade in sorted_trades if trade.exit_time is not None]
|
||||||
axs[1, 3].plot(exit_times_sorted, cumulative_profits, color='blue')
|
axs[1, 3].plot(exit_times_sorted, cumulative_profits_sorted, color='blue')
|
||||||
axs[1, 3].set_title('Cumulative Profit Over Time')
|
axs[1, 3].set_title('Cumulative Profit Over Time')
|
||||||
axs[1, 3].set_xlabel('Time')
|
axs[1, 3].set_xlabel('Time')
|
||||||
axs[1, 3].set_ylabel('Cumulative Profit')
|
axs[1, 3].set_ylabel('Cumulative Profit')
|
||||||
@ -226,15 +239,23 @@ def generate_trading_report_image(runner_ids: list = None, batch_id: str = None,
|
|||||||
profit = trade.profit
|
profit = trade.profit
|
||||||
heatmap_data_list.append({'Day': day, 'Hour': hour, 'Profit': profit})
|
heatmap_data_list.append({'Day': day, 'Hour': hour, 'Profit': profit})
|
||||||
|
|
||||||
heatmap_data = pd.DataFrame(heatmap_data_list)
|
try:
|
||||||
heatmap_data = heatmap_data.groupby(['Day', 'Hour']).sum().reset_index()
|
heatmap_data = pd.DataFrame(heatmap_data_list)
|
||||||
heatmap_pivot = heatmap_data.pivot(index='Day', columns='Hour', values='Profit')
|
heatmap_data = heatmap_data.groupby(['Day', 'Hour']).sum().reset_index()
|
||||||
|
heatmap_pivot = heatmap_data.pivot(index='Day', columns='Hour', values='Profit')
|
||||||
|
|
||||||
# Plot 3: Heatmap of Profits
|
# Plot 3: Heatmap of Profits
|
||||||
sns.heatmap(heatmap_pivot, cmap='viridis', ax=axs[1, 0])
|
sns.heatmap(heatmap_pivot, cmap='viridis', ax=axs[1, 0])
|
||||||
axs[1, 0].set_title('Heatmap of Profits (based on Exit time)')
|
axs[1, 0].set_title('Heatmap of Profits (based on Exit time)')
|
||||||
axs[1, 0].set_xlabel('Hour of Day')
|
axs[1, 0].set_xlabel('Hour of Day')
|
||||||
axs[1, 0].set_ylabel('Day')
|
axs[1, 0].set_ylabel('Day')
|
||||||
|
except KeyError:
|
||||||
|
# Handle the case where there is no data
|
||||||
|
axs[1, 0].text(0.5, 0.5, 'No data available',
|
||||||
|
horizontalalignment='center',
|
||||||
|
verticalalignment='center',
|
||||||
|
transform=axs[1, 0].transAxes)
|
||||||
|
axs[1, 0].set_title('Heatmap of Profits (based on Exit time)')
|
||||||
|
|
||||||
# Plot 9: Profit/Loss Distribution Histogram
|
# Plot 9: Profit/Loss Distribution Histogram
|
||||||
sns.histplot(profits, bins=30, ax=axs[1, 1], kde=True, color='skyblue')
|
sns.histplot(profits, bins=30, ax=axs[1, 1], kde=True, color='skyblue')
|
||||||
@ -248,9 +269,17 @@ def generate_trading_report_image(runner_ids: list = None, batch_id: str = None,
|
|||||||
if len(runner_ids) == 1:
|
if len(runner_ids) == 1:
|
||||||
|
|
||||||
sizes = [trade.size for trade in closed_trades if trade.size is not None]
|
sizes = [trade.size for trade in closed_trades if trade.size is not None]
|
||||||
size_counts = {size: sizes.count(size) for size in set(sizes)}
|
if sizes:
|
||||||
sns.barplot(x=list(size_counts.keys()), y=list(size_counts.values()), ax=axs[1, 2])
|
size_counts = {size: sizes.count(size) for size in set(sizes)}
|
||||||
axs[1, 2].set_title('Position Size Distribution')
|
sns.barplot(x=list(size_counts.keys()), y=list(size_counts.values()), ax=axs[1, 2])
|
||||||
|
axs[1, 2].set_title('Position Size Distribution')
|
||||||
|
else:
|
||||||
|
# Handle the case where there is no data
|
||||||
|
axs[1, 2].text(0.5, 0.5, 'No data available',
|
||||||
|
horizontalalignment='center',
|
||||||
|
verticalalignment='center',
|
||||||
|
transform=axs[1, 2].transAxes)
|
||||||
|
axs[1, 2].set_title('Position Size Distribution')
|
||||||
else:
|
else:
|
||||||
trade_durations = []
|
trade_durations = []
|
||||||
trade_profits = []
|
trade_profits = []
|
||||||
@ -317,10 +346,18 @@ def generate_trading_report_image(runner_ids: list = None, batch_id: str = None,
|
|||||||
sorted_hours = sorted(profits_by_hour.keys())
|
sorted_hours = sorted(profits_by_hour.keys())
|
||||||
sorted_profits = [profits_by_hour[hour] for hour in sorted_hours]
|
sorted_profits = [profits_by_hour[hour] for hour in sorted_hours]
|
||||||
|
|
||||||
sns.barplot(x=sorted_hours, y=sorted_profits, ax=axs[2, 1])
|
if sorted_profits:
|
||||||
axs[2, 1].set_title('Profits by Hour of Day (Entry)')
|
sns.barplot(x=sorted_hours, y=sorted_profits, ax=axs[2, 1])
|
||||||
axs[2, 1].set_xlabel('Hour of Day')
|
axs[2, 1].set_title('Profits by Hour of Day (Entry)')
|
||||||
axs[2, 1].set_ylabel('Profit')
|
axs[2, 1].set_xlabel('Hour of Day')
|
||||||
|
axs[2, 1].set_ylabel('Profit')
|
||||||
|
else:
|
||||||
|
# Handle the case where sorted_profits is empty
|
||||||
|
axs[2, 1].text(0.5, 0.5, 'No data available',
|
||||||
|
horizontalalignment='center',
|
||||||
|
verticalalignment='center',
|
||||||
|
transform=axs[2, 1].transAxes)
|
||||||
|
axs[2, 1].set_title('Profits by Hour of Day (Entry)')
|
||||||
|
|
||||||
# Plot 9: Profits Based on Hour of the Day - based on Exit
|
# Plot 9: Profits Based on Hour of the Day - based on Exit
|
||||||
exit_hours = [trade.exit_time.hour for trade in closed_trades if trade.exit_time is not None]
|
exit_hours = [trade.exit_time.hour for trade in closed_trades if trade.exit_time is not None]
|
||||||
@ -334,10 +371,18 @@ def generate_trading_report_image(runner_ids: list = None, batch_id: str = None,
|
|||||||
sorted_hours = sorted(profits_by_hour.keys())
|
sorted_hours = sorted(profits_by_hour.keys())
|
||||||
sorted_profits = [profits_by_hour[hour] for hour in sorted_hours]
|
sorted_profits = [profits_by_hour[hour] for hour in sorted_hours]
|
||||||
|
|
||||||
sns.barplot(x=sorted_hours, y=sorted_profits, ax=axs[2, 2])
|
if sorted_profits:
|
||||||
axs[2, 2].set_title('Profits by Hour of Day (Exit)')
|
sns.barplot(x=sorted_hours, y=sorted_profits, ax=axs[2, 2])
|
||||||
axs[2, 2].set_xlabel('Hour of Day')
|
axs[2, 2].set_title('Profits by Hour of Day (Exit)')
|
||||||
axs[2, 2].set_ylabel('Profit')
|
axs[2, 2].set_xlabel('Hour of Day')
|
||||||
|
axs[2, 2].set_ylabel('Profit')
|
||||||
|
else:
|
||||||
|
# Handle the case where sorted_profits is empty
|
||||||
|
axs[2, 2].text(0.5, 0.5, 'No data available',
|
||||||
|
horizontalalignment='center',
|
||||||
|
verticalalignment='center',
|
||||||
|
transform=axs[2, 2].transAxes)
|
||||||
|
axs[2, 2].set_title('Profits by Hour of Day (Exit)')
|
||||||
|
|
||||||
# Calculate profits by day of the week
|
# Calculate profits by day of the week
|
||||||
day_of_week_profits = {i: 0 for i in range(7)} # Dictionary to store profits for each day of the week
|
day_of_week_profits = {i: 0 for i in range(7)} # Dictionary to store profits for each day of the week
|
||||||
@ -365,6 +410,7 @@ def generate_trading_report_image(runner_ids: list = None, batch_id: str = None,
|
|||||||
if stream is False:
|
if stream is False:
|
||||||
plt.savefig(image_path)
|
plt.savefig(image_path)
|
||||||
plt.close()
|
plt.close()
|
||||||
|
return 0, None
|
||||||
else:
|
else:
|
||||||
# Return the image as a BytesIO stream
|
# Return the image as a BytesIO stream
|
||||||
img_stream = BytesIO()
|
img_stream = BytesIO()
|
||||||
|
|||||||
@ -279,8 +279,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="imagePreview" onclick="hideImage()">
|
<div id="imageModal" class="modal fade" style="--bs-modal-width: 591px;">
|
||||||
<img src="" id="previewImg" style="width: auto; height: auto;" />
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
<div id="imagePreview"> <!-- onclick="hideImage()"> -->
|
||||||
|
<img src="" id="previewImg" style="width: auto; height: auto;" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="archive-table" class="flex-items">
|
<div id="archive-table" class="flex-items">
|
||||||
<label data-bs-toggle="collapse" data-bs-target="#archive-table-inner">
|
<label data-bs-toggle="collapse" data-bs-target="#archive-table-inner">
|
||||||
|
|||||||
@ -117,7 +117,8 @@ function display_image(imageUrl) {
|
|||||||
img.onload = function() {
|
img.onload = function() {
|
||||||
// If the image loads successfully, display it
|
// If the image loads successfully, display it
|
||||||
$('#previewImg').attr('src', imageUrl);
|
$('#previewImg').attr('src', imageUrl);
|
||||||
$('#imagePreview').show();
|
//$('#imagePreview').show();
|
||||||
|
window.$('#imageModal').modal('show');
|
||||||
};
|
};
|
||||||
img.onerror = function() {
|
img.onerror = function() {
|
||||||
console.log("no image available")
|
console.log("no image available")
|
||||||
@ -153,13 +154,13 @@ $(document).ready(function () {
|
|||||||
// });
|
// });
|
||||||
|
|
||||||
// Hide image on click anywhere in the document
|
// Hide image on click anywhere in the document
|
||||||
$(document).on('click', function() {
|
// $(document).on('click', function() {
|
||||||
$('#imagePreview').hide();
|
// $('#imagePreview').hide();
|
||||||
});
|
// });
|
||||||
|
|
||||||
function hideImage() {
|
// function hideImage() {
|
||||||
$('#imagePreview').hide();
|
// $('#imagePreview').hide();
|
||||||
}
|
// }
|
||||||
// $('#archiveTable tbody').on('mousemove', 'td:nth-child(2)', function(e) {
|
// $('#archiveTable tbody').on('mousemove', 'td:nth-child(2)', function(e) {
|
||||||
// $('#imagePreview').css({'top': e.pageY + 10, 'left': e.pageX + 10});
|
// $('#imagePreview').css({'top': e.pageY + 10, 'left': e.pageX + 10});
|
||||||
// });
|
// });
|
||||||
|
|||||||
@ -165,7 +165,7 @@ table.dataTable thead>tr>th.sorting_asc:before, table.dataTable thead>tr>th.sort
|
|||||||
}
|
}
|
||||||
|
|
||||||
#imagePreview {
|
#imagePreview {
|
||||||
display: none;
|
/* display: none; */
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
|
|||||||
Reference in New Issue
Block a user