Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions IntelliTrader.Web/Views/Home/Dashboard.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@
</div>
</div>

<!-- Дополнительные настройки звука -->
<!-- Дополнительные настройки звука и фильтрации -->
<div class="row align-items-center mt-2 pt-2" style="border-top: 1px solid var(--card-border); font-size: 13px;">
<div class="col-md-5 d-flex align-items-center mb-2 mb-md-0">
<div class="col-md-4 d-flex align-items-center mb-2 mb-md-0">
<i class="fas fa-sliders-h mr-2" style="color: #7aa2f7;"></i>
<span class="mr-2" style="white-space: nowrap;">Громкость:</span>
<input type="range" id="soundVolumeSlider" min="0" max="1" step="0.05" value="0.5" style="flex-grow: 1; height: 4px; background: var(--bg-color); outline: none; transition: background 450ms ease-in-out; -webkit-appearance: none; cursor: pointer;" />
<span id="soundVolumeValue" class="ml-2" style="font-weight: bold; color: #7aa2f7; min-width: 40px; text-align: right;">50%</span>
</div>
<div class="col-md-5 d-flex align-items-center mb-2 mb-md-0">
<div class="col-md-4 d-flex align-items-center mb-2 mb-md-0">
<i class="fas fa-music mr-2" style="color: #bb9af3;"></i>
<span class="mr-2" style="white-space: nowrap;">Профиль звука:</span>
<select id="soundProfileSelect" class="form-control form-control-sm" style="background-color: var(--input-bg); color: var(--text-color); border: 1px solid var(--input-border); border-radius: 4px; height: 28px; padding: 2px 8px; font-size: 12px; width: auto;">
Expand All @@ -44,8 +44,10 @@
<option value="arcade">Ретро аркада (Arcade)</option>
</select>
</div>
<div class="col-md-2 text-md-right text-muted" style="font-size: 11px;">
Настройки звука
<div class="col-md-4 d-flex align-items-center mb-2 mb-md-0">
<i class="fas fa-filter mr-2" style="color: #e0af68;"></i>
<span class="mr-2" style="white-space: nowrap;">Мин. сделка (USDT):</span>
<input type="number" id="minTradeSizeInput" min="0" step="1" value="0" placeholder="0" class="form-control form-control-sm" style="background-color: var(--input-bg); color: var(--text-color); border: 1px solid var(--input-border); border-radius: 4px; height: 28px; padding: 2px 8px; font-size: 12px; width: 80px;" />
</div>
</div>
</div>
Expand All @@ -59,6 +61,7 @@
const soundVolumeSlider = document.getElementById("soundVolumeSlider");
const soundVolumeValue = document.getElementById("soundVolumeValue");
const soundProfileSelect = document.getElementById("soundProfileSelect");
const minTradeSizeInput = document.getElementById("minTradeSizeInput");
const notificationContainer = document.getElementById("notificationContainer");

let isSoundEnabled = localStorage.getItem("realtime_sound_enabled") !== "false";
Expand All @@ -74,10 +77,15 @@
// Load sound profile with fallback to 'chime'
let soundProfile = localStorage.getItem("realtime_sound_profile") || "chime";

// Load minimum USDT trade size filter
let minTradeSize = parseFloat(localStorage.getItem("realtime_min_trade_size") || "0");
if (isNaN(minTradeSize)) minTradeSize = 0;

// Sync UI controls with values
soundVolumeSlider.value = soundVolume;
soundVolumeValue.textContent = Math.round(soundVolume * 100) + "%";
soundProfileSelect.value = soundProfile;
minTradeSizeInput.value = minTradeSize;

updateSoundButtonUI();

Expand Down Expand Up @@ -206,6 +214,14 @@
playNotificationSound();
});

// Min trade size threshold input handling
minTradeSizeInput.addEventListener("input", function () {
let val = parseFloat(minTradeSizeInput.value);
if (isNaN(val) || val < 0) val = 0;
minTradeSize = val;
localStorage.setItem("realtime_min_trade_size", minTradeSize);
});

// Sound profile select handling
soundProfileSelect.addEventListener("change", function () {
soundProfile = soundProfileSelect.value;
Expand Down Expand Up @@ -332,8 +348,11 @@
knownTrades.add(tradeId);

if (!isFirstLoad) {
hasNewTrade = true;
showToastNotification(trade);
const tradeCost = Number(trade.Amount) * Number(trade.AveragePrice);
if (minTradeSize <= 0 || tradeCost >= minTradeSize) {
hasNewTrade = true;
showToastNotification(trade);
}
}
}
});
Expand Down
68 changes: 68 additions & 0 deletions IntelliTrader.Web/Views/Home/Settings.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,32 @@
</div>
</div>

<div class="configs mt-4" style="background-color: var(--card-bg) !important; border: 1px solid var(--border-color) !important; color: var(--text-color) !important; padding: 20px; border-radius: 4px; margin-top: 20px;">
<h2>Уведомления и звуковые сигналы</h2>
<div style="margin-bottom: 15px; display: flex; align-items: center;">
<input type="checkbox" id="settingsSoundEnabled" style="margin-right: 10px; cursor: pointer;" />
<label for="settingsSoundEnabled" style="margin-bottom: 0; font-weight: bold; cursor: pointer;">Включить звуковые оповещения о сделках</label>
</div>
<div style="margin-bottom: 15px; display: flex; align-items: center; max-width: 450px;">
<label style="margin-right: 15px; margin-bottom: 0; font-weight: bold; min-width: 140px;">Громкость звука:</label>
<input type="range" id="settingsSoundVolume" min="0" max="1" step="0.05" value="0.5" style="flex-grow: 1; height: 4px; outline: none; cursor: pointer;" />
<span id="settingsSoundVolumeVal" style="font-weight: bold; margin-left: 10px; min-width: 45px;">50%</span>
</div>
<div style="margin-bottom: 15px; display: flex; align-items: center;">
<label style="margin-right: 15px; margin-bottom: 0; font-weight: bold; min-width: 140px;">Профиль звука:</label>
<select id="settingsSoundProfile" class="form-control form-control-sm" style="width: auto; background-color: var(--input-bg); color: var(--text-color); border: 1px solid var(--input-border); border-radius: 4px;">
<option value="chime">Приятный звон (Chime)</option>
<option value="beep">Высокий писк (Beep)</option>
<option value="arcade">Ретро аркада (Arcade)</option>
</select>
</div>
<div style="margin-bottom: 5px; display: flex; align-items: center;">
<label style="margin-right: 15px; margin-bottom: 0; font-weight: bold; min-width: 140px;">Мин. сделка (USDT):</label>
<input type="number" id="settingsMinTradeSize" min="0" step="1" value="0" placeholder="0" class="form-control form-control-sm" style="width: 100px; background-color: var(--input-bg); color: var(--text-color); border: 1px solid var(--input-border); border-radius: 4px;" />
<span class="text-muted ml-2" style="font-size: 12px;">(0 = показывать все сделки)</span>
</div>
</div>

<script>
document.addEventListener("DOMContentLoaded", function() {
const select = document.getElementById("settingsThemeSelect");
Expand Down Expand Up @@ -87,6 +113,48 @@
}
});
}

// Notification & Sound Settings setup
const soundEnabledCb = document.getElementById("settingsSoundEnabled");
const soundVolumeSlider = document.getElementById("settingsSoundVolume");
const soundVolumeVal = document.getElementById("settingsSoundVolumeVal");
const soundProfileSelect = document.getElementById("settingsSoundProfile");
const minTradeSizeInput = document.getElementById("settingsMinTradeSize");

if (soundEnabledCb && soundVolumeSlider && soundProfileSelect && minTradeSizeInput) {
const soundEnabled = localStorage.getItem("realtime_sound_enabled") !== "false";
let soundVolume = parseFloat(localStorage.getItem("realtime_sound_volume") || "0.5");
if (isNaN(soundVolume)) soundVolume = 0.5;
const soundProfile = localStorage.getItem("realtime_sound_profile") || "chime";
let minTradeSize = parseFloat(localStorage.getItem("realtime_min_trade_size") || "0");
if (isNaN(minTradeSize)) minTradeSize = 0;

soundEnabledCb.checked = soundEnabled;
soundVolumeSlider.value = soundVolume;
soundVolumeVal.textContent = Math.round(soundVolume * 100) + "%";
soundProfileSelect.value = soundProfile;
minTradeSizeInput.value = minTradeSize;

soundEnabledCb.addEventListener("change", function() {
localStorage.setItem("realtime_sound_enabled", soundEnabledCb.checked);
});

soundVolumeSlider.addEventListener("input", function() {
const val = parseFloat(soundVolumeSlider.value);
soundVolumeVal.textContent = Math.round(val * 100) + "%";
localStorage.setItem("realtime_sound_volume", val);
});

soundProfileSelect.addEventListener("change", function() {
localStorage.setItem("realtime_sound_profile", soundProfileSelect.value);
});

minTradeSizeInput.addEventListener("input", function() {
let val = parseFloat(minTradeSizeInput.value);
if (isNaN(val) || val < 0) val = 0;
localStorage.setItem("realtime_min_trade_size", val);
});
}
});
</script>

Expand Down
32 changes: 31 additions & 1 deletion magda_agent_system/agent_tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@
},
{
"id": "web-dashboard-custom-alerts",
"status": "todo",
"status": "done",
"area": "web",
"risk": "low",
"title": "Add custom notification threshold settings on Dashboard",
Expand All @@ -473,6 +473,36 @@
"acceptance": [
"Order caching mechanism is integrated and avoids frequent disk reads for historical trade logs."
]
},
{
"id": "trading-trailing-buy-spread-guard",
"status": "todo",
"area": "trading",
"risk": "low",
"title": "Enhance BuyProcessor with dynamic trailing buy pause on extreme spread volatility",
"description": "Add dynamic spread volatility guard in BuyProcessor to postpone initial buy entries when market bid/ask spread exceeds safe thresholds.",
"allowed_paths": [
"IntelliTrader.Trading/Processors/BuyProcessor.cs",
"magda_agent_system/agent_tasks.json"
],
"acceptance": [
"BuyProcessor evaluates spread threshold before executing trailing buy orders."
]
},
{
"id": "web-dashboard-trade-export-csv",
"status": "todo",
"area": "web",
"risk": "low",
"title": "Add CSV export button for trade history on Trades view",
"description": "Add an export button on Trades view to download historical executed trade logs as a CSV file.",
"allowed_paths": [
"IntelliTrader.Web/Views/**",
"magda_agent_system/agent_tasks.json"
],
"acceptance": [
"Trades view includes a Download CSV button that returns formatted trade records."
]
}
]
}