Reputation: 125
A minimum reproducible example:
library(quantstrat)
startd<-"2022-08-01 01:00:00"
finishd<-"2022-08-01 02:15:00"
symbols<-c("AXSUSD", "XRPUSD")
AXSUSD<- structure(c(18.59, 18.59, 18.56, 18.51, 18.53, 18.5, 18.5, 18.5,
18.5, 18.47, 18.49, 18.48, 18.46, 18.45, 18.43, 18.41, 18.43,
18.4, 18.41, 18.42, 18.4, 18.4, 18.35, 18.4, 18.37, 18.35, 18.34,
18.28, 18.26, 18.26, 18.29, 18.26, 18.26, 18.25, 18.25, 18.24,
18.25, 18.23, 18.2, 18.15, 18.06, 18.07, 18.07, 18.06, 18.06,
18.09, 18.05, 18.03, 18.01, 18.02, 18.01, 18.03, 18.09, 18.05,
18.06, 18.05, 18.02, 18.06, 18.07, 18.1, 18.15, 18.11, 18.09,
18.06, 18.08, 18.08, 18.03, 18.04, 18.03, 18.02, 18.02, 18, 18.01,
18.05, 18.03, 18.05, 18.6, 18.59, 18.56, 18.53, 18.55, 18.51,
18.51, 18.51, 18.5, 18.49, 18.51, 18.48, 18.47, 18.45, 18.43,
18.44, 18.43, 18.41, 18.43, 18.43, 18.41, 18.4, 18.4, 18.4, 18.39,
18.36, 18.36, 18.28, 18.27, 18.31, 18.29, 18.27, 18.27, 18.28,
18.27, 18.25, 18.25, 18.24, 18.21, 18.15, 18.1, 18.1, 18.09,
18.07, 18.11, 18.1, 18.06, 18.04, 18.04, 18.02, 18.03, 18.08,
18.09, 18.06, 18.06, 18.06, 18.06, 18.08, 18.1, 18.15, 18.15,
18.11, 18.09, 18.08, 18.09, 18.08, 18.06, 18.06, 18.03, 18.02,
18.02, 18.03, 18.04, 18.06, 18.05, 18.06, 18.57, 18.56, 18.5,
18.48, 18.51, 18.49, 18.48, 18.5, 18.47, 18.47, 18.48, 18.46,
18.44, 18.42, 18.4, 18.4, 18.4, 18.39, 18.41, 18.39, 18.39, 18.34,
18.35, 18.36, 18.33, 18.34, 18.27, 18.24, 18.25, 18.25, 18.26,
18.24, 18.24, 18.24, 18.24, 18.24, 18.24, 18.19, 18.16, 18.03,
18.06, 18.04, 18.04, 18.03, 18.05, 18.05, 18.04, 18.01, 18.01,
18, 17.98, 18.02, 18.05, 18.03, 18.05, 18.01, 18.01, 18.06, 18.05,
18.1, 18.11, 18.07, 18.07, 18.06, 18.07, 18.01, 18.02, 18.04,
18, 18.01, 17.99, 18, 18, 18.02, 18.03, 18.04, 18.59, 18.56,
18.51, 18.53, 18.51, 18.5, 18.49, 18.51, 18.47, 18.48, 18.49,
18.47, 18.44, 18.43, 18.41, 18.43, 18.4, 18.41, 18.41, 18.39,
18.39, 18.35, 18.39, 18.37, 18.35, 18.34, 18.28, 18.25, 18.25,
18.29, 18.27, 18.26, 18.25, 18.25, 18.24, 18.24, 18.24, 18.2,
18.16, 18.07, 18.07, 18.08, 18.07, 18.07, 18.09, 18.05, 18.04,
18.03, 18.02, 18, 18.01, 18.08, 18.05, 18.06, 18.06, 18.01, 18.06,
18.08, 18.1, 18.15, 18.11, 18.1, 18.07, 18.08, 18.08, 18.02,
18.04, 18.04, 18.02, 18.02, 18, 18.01, 18.04, 18.04, 18.05, 18.06,
267.01, 541.51, 1476.94, 824.6, 291.32, 423.93, 256.52, 119.27,
295.6, 572.75, 502.21, 225.61, 430.23, 710.36, 763.7, 392.99,
190.62, 790.51, 453.41, 254.25, 643.42, 2042.63, 465.7, 649.73,
1482.22, 245.25, 1525.01, 3044.69, 1639.7, 1094.5, 407.23, 1863.08,
1270.13, 1476.93, 1429.3, 3169.91, 2142.71, 2210.54, 1308.62,
3227.14, 805.05, 1446.61, 570.95, 995.8, 517.49, 559.74, 187.41,
873.55, 296.18, 2185.88, 1489.49, 753.01, 492.74, 185.89, 296.91,
1312.9, 338, 673.39, 938.74, 514.05, 237.6, 412.84, 189.4, 448.67,
370.31, 472.12, 1775.97, 119.69, 250.69, 173.07, 1091.01, 505.81,
244.32, 340.67, 142, 151.03), class = c("xts", "zoo"), index = structure(c(1659304800,
1659304860, 1659304920, 1659304980, 1659305040, 1659305100, 1659305160,
1659305220, 1659305280, 1659305340, 1659305400, 1659305460, 1659305520,
1659305580, 1659305640, 1659305700, 1659305760, 1659305820, 1659305880,
1659305940, 1659306000, 1659306060, 1659306120, 1659306180, 1659306240,
1659306300, 1659306360, 1659306420, 1659306480, 1659306540, 1659306600,
1659306660, 1659306720, 1659306780, 1659306840, 1659306900, 1659306960,
1659307020, 1659307080, 1659307140, 1659307200, 1659307260, 1659307320,
1659307380, 1659307440, 1659307500, 1659307560, 1659307620, 1659307680,
1659307740, 1659307800, 1659307860, 1659307920, 1659307980, 1659308040,
1659308100, 1659308160, 1659308220, 1659308280, 1659308340, 1659308400,
1659308460, 1659308520, 1659308580, 1659308640, 1659308700, 1659308760,
1659308820, 1659308880, 1659308940, 1659309000, 1659309060, 1659309120,
1659309180, 1659309240, 1659309300), tzone = "", tclass = c("POSIXct",
"POSIXt")), .Dim = c(76L, 5L), .Dimnames = list(NULL, c("Open",
"High", "Low", "Close", "Volume")))
XRPUSD<-structure(c(0.3872, 0.3872, 0.3869, 0.3863, 0.387, 0.3869, 0.3869,
0.3867, 0.3867, 0.3864, 0.3865, 0.3864, 0.3863, 0.386, 0.3859,
0.3858, 0.3866, 0.3863, 0.3864, 0.3866, 0.3869, 0.3865, 0.3858,
0.3867, 0.3865, 0.3858, 0.3857, 0.3848, 0.3848, 0.3852, 0.3853,
0.3853, 0.3843, 0.3838, 0.3836, 0.3832, 0.383, 0.383, 0.3829,
0.3819, 0.382, 0.382, 0.3829, 0.3822, 0.3822, 0.3825, 0.3823,
0.382, 0.3816, 0.3818, 0.3812, 0.3814, 0.3823, 0.3816, 0.3815,
0.3816, 0.3812, 0.3816, 0.3817, 0.3817, 0.3822, 0.3818, 0.381,
0.3813, 0.3818, 0.3813, 0.381, 0.3812, 0.3812, 0.3805, 0.38,
0.3787, 0.3791, 0.3802, 0.3802, 0.38, 0.3874, 0.3872, 0.3869,
0.387, 0.3873, 0.387, 0.3869, 0.3869, 0.3867, 0.3865, 0.3868,
0.3864, 0.3863, 0.3863, 0.3863, 0.3868, 0.3867, 0.3864, 0.3867,
0.3871, 0.3869, 0.3865, 0.3868, 0.3867, 0.3865, 0.3859, 0.3858,
0.385, 0.3855, 0.3856, 0.3853, 0.3854, 0.3845, 0.3843, 0.3838,
0.3833, 0.3833, 0.3832, 0.383, 0.3823, 0.3821, 0.3833, 0.383,
0.3825, 0.383, 0.3827, 0.3824, 0.3821, 0.3818, 0.3818, 0.3819,
0.3823, 0.3824, 0.3816, 0.3816, 0.3816, 0.3817, 0.3819, 0.3824,
0.3823, 0.3823, 0.3818, 0.3815, 0.3818, 0.3818, 0.3814, 0.3813,
0.3813, 0.3812, 0.3805, 0.3801, 0.3795, 0.3802, 0.3806, 0.3803,
0.3803, 0.3871, 0.3869, 0.3861, 0.3859, 0.3867, 0.3867, 0.3866,
0.3867, 0.3863, 0.3862, 0.3863, 0.386, 0.3859, 0.3859, 0.3858,
0.3857, 0.3861, 0.3858, 0.3864, 0.3865, 0.3865, 0.3857, 0.3858,
0.3865, 0.3858, 0.3856, 0.3847, 0.3843, 0.3847, 0.3847, 0.385,
0.3841, 0.3837, 0.3836, 0.3831, 0.383, 0.383, 0.3829, 0.3818,
0.3812, 0.3816, 0.3819, 0.3819, 0.3818, 0.3822, 0.3823, 0.3819,
0.3816, 0.3813, 0.3812, 0.38, 0.3814, 0.3813, 0.3809, 0.3813,
0.381, 0.3812, 0.3816, 0.3814, 0.3816, 0.3817, 0.3809, 0.3809,
0.3811, 0.3813, 0.3806, 0.3809, 0.3812, 0.3804, 0.3793, 0.3782,
0.3786, 0.3791, 0.3798, 0.3801, 0.38, 0.3872, 0.387, 0.3863,
0.387, 0.3869, 0.387, 0.3868, 0.3868, 0.3864, 0.3864, 0.3863,
0.3862, 0.386, 0.386, 0.3858, 0.3866, 0.3863, 0.3864, 0.3866,
0.3869, 0.3865, 0.3858, 0.3867, 0.3866, 0.3859, 0.3856, 0.3849,
0.3847, 0.3852, 0.3854, 0.3853, 0.3843, 0.3838, 0.3836, 0.3833,
0.3831, 0.383, 0.383, 0.3819, 0.3819, 0.382, 0.3829, 0.3821,
0.3824, 0.3825, 0.3823, 0.382, 0.3816, 0.3818, 0.3812, 0.3815,
0.3823, 0.3816, 0.3814, 0.3815, 0.3812, 0.3816, 0.3817, 0.3817,
0.3823, 0.3817, 0.381, 0.3814, 0.3818, 0.3813, 0.3809, 0.3812,
0.3812, 0.3804, 0.38, 0.3787, 0.3791, 0.3802, 0.3802, 0.3802,
0.3801, 173535, 116599, 218382, 246121, 128348, 99462, 22511,
64515, 97513, 55926, 189760, 73759, 175517, 101904, 265970, 87041,
61687, 176343, 86575, 180590, 58751, 224686, 150028, 111829,
156258, 46998, 535117, 460168, 337710, 142897, 118871, 280809,
156589, 166904, 355699, 175117, 194193, 139842, 372572, 672156,
157021, 241500, 219450, 159943, 152822, 103950, 65322, 67241,
123305, 120647, 1444688, 171372, 209580, 248285, 83473, 90654,
122571, 114348, 239920, 72403, 134801, 967515, 662778, 110607,
170073, 124642, 50443, 36772, 82321, 641158, 739741, 155703,
46420, 147300, 36951, 26022), class = c("xts", "zoo"), index = structure(c(1659304800,
1659304860, 1659304920, 1659304980, 1659305040, 1659305100, 1659305160,
1659305220, 1659305280, 1659305340, 1659305400, 1659305460, 1659305520,
1659305580, 1659305640, 1659305700, 1659305760, 1659305820, 1659305880,
1659305940, 1659306000, 1659306060, 1659306120, 1659306180, 1659306240,
1659306300, 1659306360, 1659306420, 1659306480, 1659306540, 1659306600,
1659306660, 1659306720, 1659306780, 1659306840, 1659306900, 1659306960,
1659307020, 1659307080, 1659307140, 1659307200, 1659307260, 1659307320,
1659307380, 1659307440, 1659307500, 1659307560, 1659307620, 1659307680,
1659307740, 1659307800, 1659307860, 1659307920, 1659307980, 1659308040,
1659308100, 1659308160, 1659308220, 1659308280, 1659308340, 1659308400,
1659308460, 1659308520, 1659308580, 1659308640, 1659308700, 1659308760,
1659308820, 1659308880, 1659308940, 1659309000, 1659309060, 1659309120,
1659309180, 1659309240, 1659309300), tzone = "", tclass = c("POSIXct",
"POSIXt")), .Dim = c(76L, 5L), .Dimnames = list(NULL, c("Open",
"High", "Low", "Close", "Volume")))
symbols <- setNames(symbols, symbols)
osInvestFull <- function (data, timestamp, orderqty, ordertype,
orderside, equity, portfolio, symbol, ruletype, ..., initEq) {
datePos <- format(timestamp+60, "%Y-%m-%d %H:%M:%S")
updatePortf(Portfolio=portfolio,Symbol=symbol,Dates=paste0(start(data),
"/", datePos))
# After updating portfolio profit, we can extract the Net.Trading.PL earned up to datePos.
trading_pl <- sum(.getPortfolio(portfolio)$summary$Net.Trading.PL)
equity <- initEq + trading_pl
print(paste("Equity", equity, sep="="))
ClosePrice <- getPrice(data, prefer = "Close")[datePos]
if (orderside=="short") {
UnitSize <- as.numeric((-1*equity / ClosePrice))
}
else {
UnitSize <- as.numeric((equity / ClosePrice))
}
UnitSize
}
# Set the timezone to UTC
Sys.setenv(TZ="Europe/Istanbul")
rm.strat(portfolio.st)
rm.strat(strategy.st)
rm.strat(account.st)
stock.str = symbols
# Set the currency to USD
currency("USD")
#getSymbols(stock.str,from=startDate, to= Sys.Date())
for(symbol in symbols){
stock(symbols, currency="USD",multiplier=1)
}
# Create initdate, from, and to strings
initdate <- "2022-08-01 00:59:00"
startDate <- "2022-08-01 01:00:00"
to <- "2022-08-01 02:15:00"
# Define your trade size and initial equity
initEq <- 1000
strategy.st <- "X_STRAT"
portfolio.st <- "X_PORTF"
account.st <- "X_ACCT"
# Initialize the portfolio
initPortf(portfolio.st, symbols = symbols, initDate =initdate , currency = "USD")
# Initialize the account
initAcct(account.st, portfolios = portfolio.st, initDate = initdate, currency = "USD", initEq = initEq)
# Initialize the orders
initOrders(portfolio.st, initDate = initdate)
# Store the strategy
strategy(strategy.st, store = TRUE)
fee <- function(TxnQty, TxnPrice, Symbol) {
return(0 * abs(TxnQty * TxnPrice))
}
add.indicator(strategy = strategy.st, name = "SMA",
arguments = list(x = quote(Cl(mktdata)), n=10),
label ="nFast")
add.indicator(strategy = strategy.st, name = "SMA",
arguments = list(x = quote(Cl(mktdata)), n=20),
label = "nSlow")
add.signal(strategy = strategy.st,
name= "sigCrossover",
arguments = list(columns = c("nFast", "nSlow"),
relationship = "gte"),
label = "longenter")
add.signal(strategy = strategy.st,
name= "sigCrossover",
arguments = list(columns = c("nFast",
"nSlow"),
relationship = "lt"),
label = "longexit")
#Add rules for entering positions
#enter long position
add.rule(strategy.st,
name = "ruleSignal",
arguments = list(sigcol = "longenter",
sigval = TRUE,
osFUN= osInvestFull,
ordertype = "market",
orderside = "long",
orderset= "ocolong",
prefer = "Close",
TxnFees = 0,
replace = FALSE),
type = "enter",
label = "EnterLong")
#exit long
add.rule(strategy = strategy.st,
name = "ruleSignal",
arguments = list(sigcol = "longexit",
sigval = TRUE,
TxnFees=0,
replace = FALSE,
orderside = "long",
ordertype = "market",
orderqty = "all",
tmult = TRUE,
prefer = "Close",
orderset="ocolong"),
type = "exit",
path.dep=TRUE,
label = "ExitLong",
enabled=TRUE)
add.rule(strategy = strategy.st, name ='rulePctEquity', arguments=list(rebalance_on='days',
trade.percent=1/length(symbols), refprice=quote(last(getPrice(mktdata)[paste('::',as.character(curIndex),sep='')][,1])),digits=0),
type='rebalance',label='rebalance')
# Must add maxpos:
#for(symbol in symbols){ addPosLimit(portfolio.st, symbol, timestamp = startDate, maxpos = 100000000, minpos=-1000000000) }
applyStrategy(strategy=strategy.st, portfolios=portfolio.st, initEq = initEq, prefer="Close")
#[1] "Equity=1000"
#[1] "2022-08-01 02:00:00 AXSUSD 55.2181115405853 @ 18.11"
#[1] "2022-08-01 02:10:00 AXSUSD -55.2181115405853 @ 18"
#[1] "Equity=1000"
#[1] "2022-08-01 01:25:00 XRPUSD 2593.36099585062 @ 0.3856"
#[1] "2022-08-01 01:26:00 XRPUSD -2593.36099585062 @ 0.3849"
XRP trade is before the AXS trade chronologically as shown above. XRP trade's PL plus initial equity is supposed to be the total amount of AXS trade since I wrote a function to invest full equity. At 01:59 my equity should 1000*(1+(.3849/.3856-1))=$998.1846 since it is a loss trade and no transaction fees.
But when you look at AXS enter order amount it is still $1000 due to the fact that quantstrat first enters AXS order (enters the order alphabetically with respect to symbol vector)
How can I fix this situation to sort the orders chronologically and enter the AXS order after XRP order with $998.1846 equity?
Thanks in advance
Upvotes: 1
Views: 70