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.LoggerFactory;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public class MathUtils {
|
||||
private static final Logger log = LoggerFactory.getLogger(MathUtils.class);
|
||||
|
||||
@ -127,24 +129,30 @@ public class MathUtils {
|
||||
}
|
||||
|
||||
public Optional<Double> next(long val) {
|
||||
var fullAtStart = isFull();
|
||||
if (fullAtStart) {
|
||||
if (outlier > 0) {
|
||||
// Return early if it's an outlier
|
||||
var avg = (double) sum / size;
|
||||
if (Math.abs(avg - val) / avg > outlier) {
|
||||
return Optional.empty();
|
||||
try {
|
||||
var fullAtStart = isFull();
|
||||
if (fullAtStart) {
|
||||
if (outlier > 0) {
|
||||
// Return early if it's an outlier
|
||||
checkArgument(size != 0);
|
||||
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() {
|
||||
@ -155,7 +163,9 @@ public class MathUtils {
|
||||
var element = window.iterator();
|
||||
while (element.hasNext()) {
|
||||
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) {
|
||||
element.remove();
|
||||
break;
|
||||
|
@ -335,37 +335,42 @@ public abstract class MutableOfferDataModel extends OfferDataModel implements Bs
|
||||
|
||||
private void setSuggestedSecurityDeposit(PaymentAccount paymentAccount) {
|
||||
var minSecurityDeposit = preferences.getBuyerSecurityDepositAsPercent(getPaymentAccount());
|
||||
if (getTradeCurrency() == null) {
|
||||
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());
|
||||
var startDate = new Date(System.currentTimeMillis() - blocksRange * 10 * 60000);
|
||||
var sortedRangeData = tradeStatisticsManager.getObservableTradeStatisticsSet().stream()
|
||||
.filter(e -> e.getCurrencyCode().equals(getTradeCurrency().getCode()))
|
||||
.filter(e -> e.getTradeDate().compareTo(startDate) >= 0)
|
||||
.sorted(Comparator.comparing(TradeStatistics2::getTradeDate))
|
||||
.collect(Collectors.toList());
|
||||
var movingAverage = new MathUtils.MovingAverage(10, 0.2);
|
||||
double[] extremes = {Double.MAX_VALUE, Double.MIN_VALUE};
|
||||
sortedRangeData.forEach(e -> {
|
||||
var price = e.getTradePrice().getValue();
|
||||
movingAverage.next(price).ifPresent(val -> {
|
||||
if (val < extremes[0]) extremes[0] = val;
|
||||
if (val > extremes[1]) extremes[1] = val;
|
||||
try {
|
||||
if (getTradeCurrency() == null) {
|
||||
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());
|
||||
var startDate = new Date(System.currentTimeMillis() - blocksRange * 10 * 60000);
|
||||
var sortedRangeData = tradeStatisticsManager.getObservableTradeStatisticsSet().stream()
|
||||
.filter(e -> e.getCurrencyCode().equals(getTradeCurrency().getCode()))
|
||||
.filter(e -> e.getTradeDate().compareTo(startDate) >= 0)
|
||||
.sorted(Comparator.comparing(TradeStatistics2::getTradeDate))
|
||||
.collect(Collectors.toList());
|
||||
var movingAverage = new MathUtils.MovingAverage(10, 0.2);
|
||||
double[] extremes = {Double.MAX_VALUE, Double.MIN_VALUE};
|
||||
sortedRangeData.forEach(e -> {
|
||||
var price = e.getTradePrice().getValue();
|
||||
movingAverage.next(price).ifPresent(val -> {
|
||||
if (val < extremes[0]) extremes[0] = val;
|
||||
if (val > extremes[1]) extremes[1] = val;
|
||||
});
|
||||
});
|
||||
});
|
||||
var min = extremes[0];
|
||||
var max = extremes[1];
|
||||
if (min == 0d || max == 0d) {
|
||||
setBuyerSecurityDeposit(minSecurityDeposit, false);
|
||||
return;
|
||||
var min = extremes[0];
|
||||
var max = extremes[1];
|
||||
if (min == 0d || max == 0d) {
|
||||
setBuyerSecurityDeposit(minSecurityDeposit, false);
|
||||
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