use of suite.trade.Trade_ in project suite by stupidsing.
the class DailyMain method alloc.
private Result alloc(String tag, float fund, BackAllocator backAllocator, Streamlet<Asset> assets) {
TimeRange period = TimeRange.daysBefore(64);
Simulate sim = BackAllocTester.of(cfg, period, assets, backAllocator, log).simulate(fund);
Account account0 = Account.ofPortfolio(cfg.queryHistory().filter(r -> String_.equals(r.strategy, tag)));
Account account1 = sim.account;
Map<String, Integer> assets0 = account0.assets();
Map<String, Integer> assets1 = account1.assets();
Set<String> symbols = Set_.union(assets0.keySet(), assets1.keySet());
Map<String, Float> priceBySymbol = cfg.quote(symbols);
List<Trade> trades = Trade_.diff(Trade.NA, assets0, assets1, priceBySymbol::get).toList();
sb.append("\nstrategy = " + tag + ", " + sim.conclusion());
return new Result(tag, trades);
}
use of suite.trade.Trade_ in project suite by stupidsing.
the class AnalyzeTimeSeriesTest method analyze.
private void analyze(float[] prices) {
int length = prices.length;
int log2 = Quant.log2trunc(length);
double nYears = length * Trade_.invTradeDaysPerYear;
float[] fds = dct.dct(Arrays.copyOfRange(prices, length - log2, length));
float[] returns = ts.returns(prices);
float[] logPrices = To.vector(prices, Math::log);
float[] logReturns = ts.differences(1, logPrices);
MeanVariance rmv = stat.meanVariance(returns);
double variance = rmv.variance;
double kelly = rmv.mean / variance;
IntFltPair max = IntFltPair.of(Integer.MIN_VALUE, Float.MIN_VALUE);
for (int i = 4; i < fds.length; i++) {
float f = Math.abs(fds[i]);
if (max.t1 < f)
max.update(i, f);
}
IntFunction<BuySell> momFun = n -> {
int d0 = 1 + n;
int d1 = 1;
return buySell(d -> Quant.sign(prices[d - d0], prices[d - d1])).start(d0);
};
IntFunction<BuySell> revert = d -> momFun.apply(d).scale(0f, -1f);
IntFunction<BuySell> trend_ = d -> momFun.apply(d).scale(0f, +1f);
BuySell[] reverts = To.array(8, BuySell.class, revert);
BuySell[] trends_ = To.array(8, BuySell.class, trend_);
BuySell tanh = buySell(d -> Tanh.tanh(3.2d * reverts[1].apply(d)));
float[] holds = mt.hold(prices, 1f, 1f, 1f);
float[] ma200 = ma.movingAvg(prices, 200);
BuySell mat = buySell(d -> {
int last = d - 1;
return Quant.sign(ma200[last], prices[last]);
}).start(1).longOnly();
BuySell mt_ = buySell(d -> holds[d]);
Pair<float[], float[]> bbmv = bb.meanVariances(VirtualVector.of(logReturns), 9, 0);
float[] bbmean = bbmv.t0;
float[] bbvariances = bbmv.t1;
BuySell ms2 = buySell(d -> {
int last = d - 1;
int ref = last - 250;
float mean = bbmean[last];
return Quant.sign(logPrices[last], logPrices[ref] - bbvariances[last] / (2d * mean * mean));
}).start(1 + 250);
LogUtil.info(//
"" + "\nsymbol = " + //
symbol + "\nlength = " + //
length + "\nnYears = " + //
nYears + "\nups = " + //
Floats_.of(returns).filter(return_ -> 0f <= return_).size() + "\ndct period = " + //
max.t0 + //
Ints_.range(//
10).map(//
d -> "\ndct component [" + d + "d] = " + fds[d]).collect(//
As::joined) + "\nreturn yearly sharpe = " + //
rmv.mean / Math.sqrt(variance / nYears) + "\nreturn kelly = " + //
kelly + "\nreturn skew = " + //
stat.skewness(returns) + "\nreturn kurt = " + //
stat.kurtosis(returns) + //
Ints_.of(1, 2, 4, 8, 16, //
32).map(//
d -> "\nmean reversion ols [" + d + "d] = " + ts.meanReversion(prices, d).coefficients[0]).collect(//
As::joined) + //
Ints_.of(4, //
16).map(//
d -> "\nvariance ratio [" + d + "d over 1d] = " + ts.varianceRatio(prices, d)).collect(//
As::joined) + "\nreturn hurst = " + //
ts.hurst(prices, prices.length / 2) + "\nhold " + //
buySell(d -> 1d).invest(prices) + "\nkelly " + //
buySell(d -> kelly).invest(prices) + "\nma200 trend " + //
mat.invest(prices) + //
Ints_.range(1, //
8).map(//
d -> "\nrevert [" + d + "d] " + reverts[d].invest(prices)).collect(//
As::joined) + //
Ints_.range(1, //
8).map(//
d -> "\ntrend_ [" + d + "d] " + trends_[d].invest(prices)).collect(//
As::joined) + //
Ints_.range(1, //
8).map(//
d -> "\nrevert [" + d + "d] long-only " + reverts[d].longOnly().invest(prices)).collect(//
As::joined) + //
Ints_.range(1, //
8).map(//
d -> "\ntrend_ [" + d + "d] long-only " + trends_[d].longOnly().invest(prices)).collect(//
As::joined) + "\nms2 " + //
ms2.invest(prices) + "\nms2 long-only " + //
ms2.longOnly().invest(prices) + "\ntanh " + //
tanh.invest(prices) + "\ntimed " + //
mt_.invest(prices) + "\ntimed long-only " + mt_.longOnly().invest(prices));
}
use of suite.trade.Trade_ in project suite by stupidsing.
the class DailyMain method run.
private boolean run() {
Trade_.blackList = Union.of(Trade_.blackList, blackList);
var sellPool = "sellpool";
var ymd = HkexUtil.getCloseTimeBefore(Time.now()).ymd();
var td = ymd + "#";
// perform systematic trading
var results = //
Read.each(//
alloc(bacs.pair_bb, 66666f), //
alloc("bug", bacs.bac_sell, 0f), //
alloc(bacs.pair_donchian, 100000f), //
alloc(bacs.pair_ema, 0f), //
mamr(50000f), //
alloc(bacs.pair_pmamr, 150000f), //
alloc(bacs.pair_pmamr2, 366666f), //
alloc(bacs.pair_pmmmr, 80000f), //
alloc(bacs.pair_revco, 0f), //
alloc(bacs.pair_tma, 0f), alloc(sellPool, bacs.bac_sell, 0f));
// unused strategies
if (Boolean.FALSE) {
alloc(bacs.pair_donchian, 100000f);
pairs(0f, "0341.HK", "0052.HK");
sellForEarn(sellPool);
}
var sbs = Summarize.of(cfg).summarize(trade -> trade.strategy);
var strategyTrades = //
results.concatMap2(//
result -> Read.from(result.trades).map2(trade -> result.strategy, trade -> trade)).filterValue(//
trade -> trade.buySell != 0).collect();
var requestTrades = strategyTrades.filterKey(strategy -> !Equals.string(strategy, sellPool));
var amounts = strategyTrades.values().collect(LiftDbl.of(Trade::amount));
var buys_ = amounts.filter(amount -> 0d < amount).sum();
var sells = amounts.filter(amount -> amount < 0d).sum();
sb.append(//
sbs.log + "\n" + //
sbs.pnlByKey + //
"\nBUY REQUESTS" + //
requestTrades.filterValue(//
trade -> 0 < trade.buySell).sortByValue(//
Trade::compare).map((strategy, t) -> //
"" + Trade.of(td, -t.buySell, t.symbol, t.price, sellPool).record() + //
"\n" + //
Trade.of(td, +t.buySell, t.symbol, t.price, strategy).record()) + //
"\n" + //
"\nSELL REQUESTS" + //
requestTrades.filterValue(//
trade -> trade.buySell < 0).sortByValue(//
Trade::compare).map((strategy, t) -> //
"" + Trade.of(td, +t.buySell, t.symbol, t.price, strategy).record() + //
"\n" + //
Trade.of(td, -t.buySell, t.symbol, t.price, sellPool).record()) + //
"\n" + "\nTOTAL BUYS_ = " + //
To.string(buys_) + "\nTOTAL SELLS = " + //
To.string(sells) + //
"\n" + //
"\nSUGGESTIONS" + //
"\n- check your balance" + "\n- sell mamr and " + //
sellPool + "\n");
var result = sb.toString().replace(".0\t", "\t");
Log_.info(result);
new SmtpSsl().send(null, getClass().getName(), result);
return true;
}
use of suite.trade.Trade_ in project suite by stupidsing.
the class BackTestMain method run.
@Override
protected boolean run(String[] args) {
// BEGIN
// END
String arg0 = 0 < args.length ? args[0] : "";
String arg1 = 1 < args.length ? args[1] : "";
String arg2 = 2 < args.length ? args[2] : "";
Streamlet<String> strategyMatches = !arg0.isEmpty() ? Read.from(arg0.split(",")) : null;
Streamlet<Integer> years = !arg1.isEmpty() ? //
Read.from(//
arg1.split(",")).concatMap(s -> {
Pair<String, String> pair = ParseUtil.search(s, "-", Assoc.RIGHT);
return //
pair != null ? //
Ints_.range(Integer.valueOf(pair.t0), Integer.valueOf(pair.t1)).map(i -> i) : Read.each(Integer.valueOf(s));
}) : //
Ints_.range(2007, Trade_.thisYear).map(i -> i);
Fun<Time, Streamlet<Asset>> fun = //
!arg2.isEmpty() ? //
time -> Read.from(arg2.split(",")).map(cfg::queryCompany).collect(As::streamlet) : cfg::queryCompaniesByMarketCap;
BackAllocConfigurations bac_ = new BackAllocConfigurations(cfg, fun);
Streamlet2<String, BackAllocConfiguration> bacByTag = bac_.bacs().bacByName;
Streamlet2<String, Simulate> simulationByKey = //
bacByTag.filterKey(//
n -> strategyMatches == null || strategyMatches.isAny(sm -> Wildcard.match(sm, n) != null)).map(//
Pair::of).join2(//
years.sort(Object_::compare).map(TimeRange::ofYear)).map2((pair, period) -> pair.t0, (pair, period) -> {
BackAllocConfiguration bac = pair.t1;
Streamlet<Asset> assets = bac.assetsFun.apply(period.from);
return runner.backTest(bac.backAllocator, period, assets);
}).collect(As::streamlet2);
String content0 = //
Read.bytes(//
Paths.get("src/main/java/" + getClass().getName().replace('.', '/') + ".java")).collect(//
As::utf8decode).map(//
Chars::toString).collect(As::joined);
String content1 = ParseUtil.fit(content0, "// BEGIN", "// END")[1];
System.out.println(content1);
System.out.println(runner.conclude(simulationByKey));
return true;
}
use of suite.trade.Trade_ in project suite by stupidsing.
the class MovingAvgMeanReversionBackAllocator method backAllocator.
public BackAllocator backAllocator() {
return (akds, indices) -> {
Map<String, DataSource> dsBySymbol = akds.dsByKey.toMap();
double dailyRiskFreeInterestRate = Trade_.riskFreeInterestRate(1);
DataSourceView<String, MeanReversionStat> dsv = //
DataSourceView.of(tor, 256, akds, (symbol, ds, period) -> new MeanReversionStat(ds, period));
return index -> {
Map<String, MeanReversionStat> mrsBySymbol = //
akds.dsByKey.map2(//
(symbol, ds) -> dsv.get(symbol, index)).filterValue(//
mrsReversionStat -> mrsReversionStat != null).toMap();
// ensure 0 < half-life: determine investment period
return //
Read.from2(mrsBySymbol).filterValue(mrs -> //
mrs.adf < 0d && //
mrs.hurst < .5d && //
mrs.movingAvgMeanReversionRatio() < 0d).map2((symbol, mrs) -> {
DataSource ds = dsBySymbol.get(symbol);
double price = ds.prices[index - 1];
double lma = mrs.latestMovingAverage();
double diff = mrs.movingAvgMeanReversion.predict(new float[] { (float) lma, 1f });
double dailyReturn = diff / price - dailyRiskFreeInterestRate;
ReturnsStat returnsStat = ts.returnsStatDaily(ds.prices);
double sharpe = returnsStat.sharpeRatio();
double kelly = dailyReturn * price * price / mrs.movingAvgMeanReversion.sse;
return new PotentialStat(dailyReturn, sharpe, kelly);
}).filterValue(//
ps -> 0d < ps.kelly).cons(Asset.cashSymbol, //
new PotentialStat(Trade_.riskFreeInterestRate, 1d, 0d)).mapValue(//
ps -> ps.kelly).sortBy(//
(symbol, potential) -> -potential).take(//
top).toList();
};
};
}
Aggregations