AMM: use_balance_bidding + (USD) price fix + Various fixes. (#314)

* AMM: use_balance_bidding + BCH (USD) price fix + Various fixes.

* AMM: Fixed NMC, DOGE, DCR (USD) price.
This commit is contained in:
Gerlof van Ek
2025-06-13 12:10:49 +02:00
committed by GitHub
parent 4055b7d6c8
commit b3c946d056
4 changed files with 112 additions and 8 deletions

View File

@@ -418,6 +418,7 @@ const AmmTablesManager = (function() {
const amountToSend = amount * maxRate; const amountToSend = amount * maxRate;
const activeBidsCount = activeBids[name] && Array.isArray(activeBids[name]) ? const activeBidsCount = activeBids[name] && Array.isArray(activeBids[name]) ?
activeBids[name].length : 0; activeBids[name].length : 0;
const useBalanceBidding = bid.use_balance_bidding !== undefined ? bid.use_balance_bidding : false;
tableHtml += ` tableHtml += `
<tr class="relative opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600"> <tr class="relative opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
@@ -451,6 +452,11 @@ const AmmTablesManager = (function() {
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300"> <span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300">
Max: ${maxConcurrent} Max: ${maxConcurrent}
</span> </span>
${useBalanceBidding ? `
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300">
Balance Bidding
</span>
` : ''}
</div> </div>
</div> </div>
</td> </td>
@@ -514,10 +520,19 @@ const AmmTablesManager = (function() {
'part blind': 'PART', 'part blind': 'PART',
'bitcoin': 'BTC', 'bitcoin': 'BTC',
'btc': 'BTC', 'btc': 'BTC',
'bitcoin cash': 'BCH',
'bitcoincash': 'BCH',
'bch': 'BCH',
'decred': 'DCR',
'dcr': 'DCR',
'dogecoin': 'DOGE',
'doge': 'DOGE',
'monero': 'XMR', 'monero': 'XMR',
'xmr': 'XMR', 'xmr': 'XMR',
'litecoin': 'LTC', 'litecoin': 'LTC',
'ltc': 'LTC', 'ltc': 'LTC',
'namecoin': 'NMC',
'nmc': 'NMC',
'wownero': 'WOW', 'wownero': 'WOW',
'wow': 'WOW', 'wow': 'WOW',
'dash': 'DASH', 'dash': 'DASH',
@@ -526,7 +541,11 @@ const AmmTablesManager = (function() {
'xzc': 'FIRO', 'xzc': 'FIRO',
'zcoin': 'FIRO', 'zcoin': 'FIRO',
'BTC': 'BTC', 'BTC': 'BTC',
'BCH': 'BCH',
'DCR': 'DCR',
'DOGE': 'DOGE',
'LTC': 'LTC', 'LTC': 'LTC',
'NMC': 'NMC',
'XMR': 'XMR', 'XMR': 'XMR',
'PART': 'PART', 'PART': 'PART',
'WOW': 'WOW', 'WOW': 'WOW',
@@ -591,7 +610,7 @@ const AmmTablesManager = (function() {
async function fetchLatestPrices() { async function fetchLatestPrices() {
try { try {
const coins = 'BTC,LTC,XMR,PART,WOW,FIRO,DASH,PIVX'; const coins = 'BTC,BCH,DCR,DOGE,LTC,NMC,XMR,PART,WOW,FIRO,DASH,PIVX';
const response = await fetch('/json/coinprices', { const response = await fetch('/json/coinprices', {
method: 'POST', method: 'POST',
@@ -1188,6 +1207,11 @@ const AmmTablesManager = (function() {
if (minSwapAmount) { if (minSwapAmount) {
newItem.min_swap_amount = parseFloat(minSwapAmount); newItem.min_swap_amount = parseFloat(minSwapAmount);
} }
const useBalanceBidding = document.getElementById('add-bid-use-balance-bidding').checked;
if (useBalanceBidding) {
newItem.use_balance_bidding = true;
}
} }
if (type === 'offer') { if (type === 'offer') {
@@ -1369,6 +1393,7 @@ const AmmTablesManager = (function() {
document.getElementById('edit-bid-address').value = item.address || 'auto'; document.getElementById('edit-bid-address').value = item.address || 'auto';
document.getElementById('edit-bid-min-swap-amount').value = item.min_swap_amount || ''; document.getElementById('edit-bid-min-swap-amount').value = item.min_swap_amount || '';
document.getElementById('edit-bid-offers-to-bid-on').value = item.offers_to_bid_on || 'all'; document.getElementById('edit-bid-offers-to-bid-on').value = item.offers_to_bid_on || 'all';
document.getElementById('edit-bid-use-balance-bidding').checked = item.use_balance_bidding || false;
} }
} }
@@ -1630,6 +1655,13 @@ const AmmTablesManager = (function() {
if (minSwapAmount) { if (minSwapAmount) {
updatedItem.min_swap_amount = parseFloat(minSwapAmount); updatedItem.min_swap_amount = parseFloat(minSwapAmount);
} }
const useBalanceBidding = document.getElementById('edit-bid-use-balance-bidding').checked;
if (useBalanceBidding) {
updatedItem.use_balance_bidding = true;
} else {
delete updatedItem.use_balance_bidding;
}
} }
if (type === 'offer' && Array.isArray(config.offers)) { if (type === 'offer' && Array.isArray(config.offers)) {

View File

@@ -37,21 +37,21 @@
<div class="p-6 px-0 lg:px-6 bg-white dark:bg-gray-800 rounded-xl shadow-md"> <div class="p-6 px-0 lg:px-6 bg-white dark:bg-gray-800 rounded-xl shadow-md">
<div class="flex sm:pr-6 lg:pr-0 justify-end items-center"> <div class="flex sm:pr-6 lg:pr-0 justify-end items-center">
<div class="flex space-x-2"> <div class="flex space-x-2">
<button id="add-new-offer-btn" class="flex items-center px-4 py-2.5 bg-green-800 hover:bg-green-700 border-green-800 font-medium text-sm text-white border rounded-md shadow-button focus:ring-0 focus:outline-none"> <button id="add-new-offer-btn" class="flex items-center px-4 py-2.5 bg-green-600 hover:bg-green-700 border-green-600 font-medium text-sm text-white border rounded-md shadow-button focus:ring-0 focus:outline-none">
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
</svg> </svg>
Add Offer Add Offer
</button> </button>
{% if debug_ui_mode %} {% if debug_ui_mode %}
<button id="add-new-bid-btn" class="flex items-center px-4 py-2.5 bg-green-800 hover:bg-green-700 border-green-800 font-medium text-sm text-white border rounded-md shadow-button focus:ring-0 focus:outline-none"> <button id="add-new-bid-btn" class="flex items-center px-4 py-2.5 bg-green-600 hover:bg-green-700 border-green-600 font-medium text-sm text-white border rounded-md shadow-button focus:ring-0 focus:outline-none">
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
</svg> </svg>
Add Bid Add Bid
</button> </button>
{% endif %} {% endif %}
<button id="refreshAmmTables" class="flex items-center px-4 py-2.5 bg-blue-500 hover:bg-blue-600 border-blue-500 font-medium text-sm text-white border rounded-md shadow-button focus:ring-0 focus:outline-none"> <button id="refreshAmmTables" class="flex items-center px-4 py-2.5 bg-blue-600 hover:bg-blue-600 border-blue-500 font-medium text-sm text-white border rounded-md shadow-button focus:ring-0 focus:outline-none">
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
</svg> </svg>
@@ -267,9 +267,9 @@
{% endif %} {% endif %}
<div class="flex flex-wrap gap-2"> <div class="flex flex-wrap gap-2">
<button type="submit" name="start" value="1" class="px-4 py-2.5 bg-green-800 hover:bg-green-700 font-medium text-sm text-white border border-green-800 rounded-md shadow-button focus:ring-0 focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed" <button type="submit" name="start" value="1" class="px-4 py-2.5 bg-green-600 hover:bg-green-700 font-medium text-sm text-white border border-green-600 rounded-md shadow-button focus:ring-0 focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed"
{% if current_status == 'running' %}disabled{% endif %}> {% if current_status == 'running' %}disabled{% endif %}>
Start Start AMM
</button> </button>
<button type="submit" name="stop" value="1" class="px-4 py-2.5 bg-red-900 hover:bg-red-700 font-medium text-sm text-white border border-red-800 rounded-md shadow-button focus:ring-0 focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed" <button type="submit" name="stop" value="1" class="px-4 py-2.5 bg-red-900 hover:bg-red-700 font-medium text-sm text-white border border-red-800 rounded-md shadow-button focus:ring-0 focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed"
{% if current_status == 'stopped' %}disabled{% endif %}> {% if current_status == 'stopped' %}disabled{% endif %}>
@@ -369,7 +369,7 @@
<div class="flex justify-between"> <div class="flex justify-between">
<button type="submit" name="create_default" value="true" id="create_default_btn" class="px-4 py-2.5 bg-blue-500 hover:bg-blue-600 font-medium text-sm text-white border border-blue-500 rounded-md shadow-button focus:ring-0 focus:outline-none">Create Default Config</button> <button type="submit" name="create_default" value="true" id="create_default_btn" class="px-4 py-2.5 bg-blue-500 hover:bg-blue-600 font-medium text-sm text-white border border-blue-500 rounded-md shadow-button focus:ring-0 focus:outline-none">Create Default Config</button>
{% if debug_ui_mode %} {% if debug_ui_mode %}
<button type="submit" name="save_config" value="true" id="save_config_btn" class="px-4 py-2.5 bg-green-500 hover:bg-green-600 font-medium text-sm text-white border border-green-500 rounded-md shadow-button focus:ring-0 focus:outline-none">Save Config</button> <button type="submit" name="save_config" value="true" id="save_config_btn" class="px-4 py-2.5 bg-green-600 hover:bg-green-700 font-medium text-sm text-white border border-green-600 rounded-md shadow-button focus:ring-0 focus:outline-none">Save Config</button>
{% endif %} {% endif %}
</div> </div>
</div> </div>
@@ -572,6 +572,7 @@
<li><span class="font-semibold">max_coin_from_balance:</span> If needed, uncomment and set to limit bids when wallet amount is above this</li> <li><span class="font-semibold">max_coin_from_balance:</span> If needed, uncomment and set to limit bids when wallet amount is above this</li>
<li><span class="font-semibold">address:</span> Address bid is sent from (auto = generate new address per bid)</li> <li><span class="font-semibold">address:</span> Address bid is sent from (auto = generate new address per bid)</li>
<li><span class="font-semibold">min_swap_amount:</span> Minimum swap amount for variable amount bids</li> <li><span class="font-semibold">min_swap_amount:</span> Minimum swap amount for variable amount bids</li>
<li><span class="font-semibold">use_balance_bidding:</span> If true, calculates bid amount as (wallet_balance - offer_min_amount) instead of using template amount</li>
<li><span class="font-semibold">offers_to_bid_on:</span> Filter offers to bid on: <strong>"auto_accept_only"</strong> (only auto-accept offers, default), <strong>"all"</strong> (any offer), <strong>"known_only"</strong> (known identities only)</li> <li><span class="font-semibold">offers_to_bid_on:</span> Filter offers to bid on: <strong>"auto_accept_only"</strong> (only auto-accept offers, default), <strong>"all"</strong> (any offer), <strong>"known_only"</strong> (known identities only)</li>
</ul> </ul>
</div> </div>
@@ -1312,6 +1313,15 @@
<label for="add-bid-min-swap-amount" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Min Swap Amount</label> <label for="add-bid-min-swap-amount" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Min Swap Amount</label>
<input type="text" id="add-bid-min-swap-amount" pattern="[0-9]*\.?[0-9]*" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" value="0.001" placeholder="0.001"> <input type="text" id="add-bid-min-swap-amount" pattern="[0-9]*\.?[0-9]*" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" value="0.001" placeholder="0.001">
</div> </div>
<div class="flex items-center">
<input type="checkbox" id="add-bid-use-balance-bidding" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
<label for="add-bid-use-balance-bidding" class="ml-2 block text-sm text-gray-900 dark:text-gray-300">Use Balance Bidding</label>
</div>
</div>
<div class="text-xs text-gray-500 dark:text-gray-400">
<strong>Use Balance Bidding:</strong> Calculate bid amount as (wallet_balance - offer_min_amount) instead of using template amount.
</div> </div>
</div> </div>
@@ -1586,6 +1596,15 @@
<label for="edit-bid-min-swap-amount" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Min Swap Amount</label> <label for="edit-bid-min-swap-amount" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Min Swap Amount</label>
<input type="text" id="edit-bid-min-swap-amount" pattern="[0-9]*\.?[0-9]*" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="0.001"> <input type="text" id="edit-bid-min-swap-amount" pattern="[0-9]*\.?[0-9]*" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="0.001">
</div> </div>
<div class="flex items-center">
<input type="checkbox" id="edit-bid-use-balance-bidding" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
<label for="edit-bid-use-balance-bidding" class="ml-2 block text-sm text-gray-900 dark:text-gray-300">Use Balance Bidding</label>
</div>
</div>
<div class="text-xs text-gray-500 dark:text-gray-400">
<strong>Use Balance Bidding:</strong> Calculate bid amount as (wallet_balance - offer_min_amount) instead of using template amount.
</div> </div>
</div> </div>

View File

@@ -1138,6 +1138,9 @@ def page_amm(self, _, post_string):
except ValueError: except ValueError:
pass pass
if form_data.get("bid_use_balance_bidding", [""])[0]:
new_bid["use_balance_bidding"] = True
if "bids" not in current_config: if "bids" not in current_config:
current_config["bids"] = [] current_config["bids"] = []
@@ -1243,6 +1246,7 @@ def page_amm(self, _, post_string):
# "max_coin_from_balance": 100.0, # Won't send bids if wallet amount would be above this # "max_coin_from_balance": 100.0, # Won't send bids if wallet amount would be above this
"address": "auto", # Address bid is sent from (auto = generate new address per bid) "address": "auto", # Address bid is sent from (auto = generate new address per bid)
"min_swap_amount": 0.001, # Minimum swap amount "min_swap_amount": 0.001, # Minimum swap amount
# "use_balance_bidding": False, # Calculate bid amount as (wallet_balance - offer_min_amount) instead of using template amount
} }
] ]

View File

@@ -61,6 +61,7 @@ Create offers
"amount_variable": Can send bids below the set "amount" where possible if true. "amount_variable": Can send bids below the set "amount" where possible if true.
"max_coin_from_balance": Won't send bids if wallet amount of "coin_from" would be above. "max_coin_from_balance": Won't send bids if wallet amount of "coin_from" would be above.
"address": Address offer is sent from, default will generate a new address per bid. "address": Address offer is sent from, default will generate a new address per bid.
"use_balance_bidding": If true, calculates bid amount as (wallet_balance - offer_min_amount) instead of using template amount.
}, },
... ...
] ]
@@ -1426,7 +1427,55 @@ def process_bids(args, config, script_state) -> None:
offer_id = offer["offer_id"] offer_id = offer["offer_id"]
offer_amount = float(offer["amount_from"]) offer_amount = float(offer["amount_from"])
offer_rate = float(offer["rate"]) offer_rate = float(offer["rate"])
bid_amount = bid_template["amount"]
# Check if we should use balance-based bidding
use_balance_bidding = bid_template.get("use_balance_bidding", False)
if use_balance_bidding:
# Calculate bid amount based on available balance minus minimum amount
# This follows the same pattern as offers: balance - min_amount
try:
# Get wallet balance for the coin we're bidding with (coin_from in the offer)
wallet_from = read_json_api_wallet(
"wallets/{}".format(coin_from_data["ticker"])
)
wallet_balance = float(wallet_from.get("balance", 0)) + float(
wallet_from.get("unconfirmed", 0)
)
# Get minimum amount from the offer
offer_min_amount = float(offer.get("amount_bid_min", 0.001))
# Calculate available amount: balance - min_amount
available_amount = wallet_balance - offer_min_amount
if available_amount > 0:
bid_amount = available_amount
if args.debug:
print(
f"Using balance-based bidding: {bid_amount} (balance: {wallet_balance} - min: {offer_min_amount})"
)
else:
# Fallback to template amount if calculation fails
bid_amount = bid_template["amount"]
if args.debug:
print(
f"Insufficient balance for balance-based bid, using template amount: {bid_amount}"
)
except Exception as balance_error:
# Fallback to template amount if balance calculation fails
bid_amount = bid_template["amount"]
if args.debug:
print(
f"Error calculating balance-based bid amount: {balance_error}, using template amount: {bid_amount}"
)
else:
# Use traditional template amount
bid_amount = bid_template["amount"]
if args.debug:
print(f"Using template bid amount: {bid_amount}")
except (KeyError, TypeError, ValueError) as e: except (KeyError, TypeError, ValueError) as e:
if args.debug: if args.debug:
print(f"Error processing offer data: {e}, offer: {offer}") print(f"Error processing offer data: {e}, offer: {offer}")