mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 09:52:23 +01:00
Merge pull request #4529 from chimp1984/make-moving-average-code-more-safe
Make moving average code more safe
This commit is contained in:
commit
8cb4b5016c
@ -29,6 +29,8 @@ import java.util.Optional;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
|
||||||
public class MathUtils {
|
public class MathUtils {
|
||||||
private static final Logger log = LoggerFactory.getLogger(MathUtils.class);
|
private static final Logger log = LoggerFactory.getLogger(MathUtils.class);
|
||||||
|
|
||||||
@ -127,24 +129,30 @@ public class MathUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Optional<Double> next(long val) {
|
public Optional<Double> next(long val) {
|
||||||
var fullAtStart = isFull();
|
try {
|
||||||
if (fullAtStart) {
|
var fullAtStart = isFull();
|
||||||
if (outlier > 0) {
|
if (fullAtStart) {
|
||||||
// Return early if it's an outlier
|
if (outlier > 0) {
|
||||||
var avg = (double) sum / size;
|
// Return early if it's an outlier
|
||||||
if (Math.abs(avg - val) / avg > outlier) {
|
checkArgument(size != 0);
|
||||||
return Optional.empty();
|
var avg = (double) sum / size;
|
||||||
|
if (Math.abs(avg - val) / avg > outlier) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
sum -= window.remove();
|
||||||
}
|
}
|
||||||
sum -= window.remove();
|
window.add(val);
|
||||||
|
sum += val;
|
||||||
|
if (!fullAtStart && isFull() && outlier != 0) {
|
||||||
|
removeInitialOutlier();
|
||||||
|
}
|
||||||
|
// When discarding outliers, the first n non discarded elements return Optional.empty()
|
||||||
|
return outlier > 0 && !isFull() ? Optional.empty() : current();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
log.error(t.toString());
|
||||||
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
window.add(val);
|
|
||||||
sum += val;
|
|
||||||
if (!fullAtStart && isFull() && outlier != 0) {
|
|
||||||
removeInitialOutlier();
|
|
||||||
}
|
|
||||||
// When discarding outliers, the first n non discarded elements return Optional.empty()
|
|
||||||
return outlier > 0 && !isFull() ? Optional.empty() : current();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isFull() {
|
boolean isFull() {
|
||||||
@ -155,7 +163,9 @@ public class MathUtils {
|
|||||||
var element = window.iterator();
|
var element = window.iterator();
|
||||||
while (element.hasNext()) {
|
while (element.hasNext()) {
|
||||||
var val = element.next();
|
var val = element.next();
|
||||||
var avgExVal = (double) (sum - val) / (size - 1);
|
int div = size - 1;
|
||||||
|
checkArgument(div != 0);
|
||||||
|
var avgExVal = (double) (sum - val) / div;
|
||||||
if (Math.abs(avgExVal - val) / avgExVal > outlier) {
|
if (Math.abs(avgExVal - val) / avgExVal > outlier) {
|
||||||
element.remove();
|
element.remove();
|
||||||
break;
|
break;
|
||||||
|
@ -335,37 +335,42 @@ public abstract class MutableOfferDataModel extends OfferDataModel implements Bs
|
|||||||
|
|
||||||
private void setSuggestedSecurityDeposit(PaymentAccount paymentAccount) {
|
private void setSuggestedSecurityDeposit(PaymentAccount paymentAccount) {
|
||||||
var minSecurityDeposit = preferences.getBuyerSecurityDepositAsPercent(getPaymentAccount());
|
var minSecurityDeposit = preferences.getBuyerSecurityDepositAsPercent(getPaymentAccount());
|
||||||
if (getTradeCurrency() == null) {
|
try {
|
||||||
setBuyerSecurityDeposit(minSecurityDeposit, false);
|
if (getTradeCurrency() == null) {
|
||||||
return;
|
setBuyerSecurityDeposit(minSecurityDeposit, false);
|
||||||
}
|
return;
|
||||||
// Get average historic prices over for the prior trade period equaling the lock time
|
}
|
||||||
var blocksRange = Restrictions.getLockTime(paymentAccount.getPaymentMethod().isAsset());
|
// Get average historic prices over for the prior trade period equaling the lock time
|
||||||
var startDate = new Date(System.currentTimeMillis() - blocksRange * 10 * 60000);
|
var blocksRange = Restrictions.getLockTime(paymentAccount.getPaymentMethod().isAsset());
|
||||||
var sortedRangeData = tradeStatisticsManager.getObservableTradeStatisticsSet().stream()
|
var startDate = new Date(System.currentTimeMillis() - blocksRange * 10 * 60000);
|
||||||
.filter(e -> e.getCurrencyCode().equals(getTradeCurrency().getCode()))
|
var sortedRangeData = tradeStatisticsManager.getObservableTradeStatisticsSet().stream()
|
||||||
.filter(e -> e.getTradeDate().compareTo(startDate) >= 0)
|
.filter(e -> e.getCurrencyCode().equals(getTradeCurrency().getCode()))
|
||||||
.sorted(Comparator.comparing(TradeStatistics2::getTradeDate))
|
.filter(e -> e.getTradeDate().compareTo(startDate) >= 0)
|
||||||
.collect(Collectors.toList());
|
.sorted(Comparator.comparing(TradeStatistics2::getTradeDate))
|
||||||
var movingAverage = new MathUtils.MovingAverage(10, 0.2);
|
.collect(Collectors.toList());
|
||||||
double[] extremes = {Double.MAX_VALUE, Double.MIN_VALUE};
|
var movingAverage = new MathUtils.MovingAverage(10, 0.2);
|
||||||
sortedRangeData.forEach(e -> {
|
double[] extremes = {Double.MAX_VALUE, Double.MIN_VALUE};
|
||||||
var price = e.getTradePrice().getValue();
|
sortedRangeData.forEach(e -> {
|
||||||
movingAverage.next(price).ifPresent(val -> {
|
var price = e.getTradePrice().getValue();
|
||||||
if (val < extremes[0]) extremes[0] = val;
|
movingAverage.next(price).ifPresent(val -> {
|
||||||
if (val > extremes[1]) extremes[1] = val;
|
if (val < extremes[0]) extremes[0] = val;
|
||||||
|
if (val > extremes[1]) extremes[1] = val;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
var min = extremes[0];
|
||||||
var min = extremes[0];
|
var max = extremes[1];
|
||||||
var max = extremes[1];
|
if (min == 0d || max == 0d) {
|
||||||
if (min == 0d || max == 0d) {
|
setBuyerSecurityDeposit(minSecurityDeposit, false);
|
||||||
setBuyerSecurityDeposit(minSecurityDeposit, false);
|
return;
|
||||||
return;
|
}
|
||||||
|
// Suggested deposit is double the trade range over the previous lock time period, bounded by min/max deposit
|
||||||
|
var suggestedSecurityDeposit =
|
||||||
|
Math.min(2 * (max - min) / max, Restrictions.getMaxBuyerSecurityDepositAsPercent());
|
||||||
|
buyerSecurityDeposit.set(Math.max(suggestedSecurityDeposit, minSecurityDeposit));
|
||||||
|
} catch (Throwable t) {
|
||||||
|
log.error(t.toString());
|
||||||
|
buyerSecurityDeposit.set(minSecurityDeposit);
|
||||||
}
|
}
|
||||||
// Suggested deposit is double the trade range over the previous lock time period, bounded by min/max deposit
|
|
||||||
var suggestedSecurityDeposit =
|
|
||||||
Math.min(2 * (max - min) / max, Restrictions.getMaxBuyerSecurityDepositAsPercent());
|
|
||||||
buyerSecurityDeposit.set(Math.max(suggestedSecurityDeposit, minSecurityDeposit));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user