Order conditionalUponOrder = (conditionalUponId==null? null : archive.get(conditionalUponId>>BITS_FOR_SYSTEM_ID));
int signalIdOnly = archive.size();
if (signalIdOnly > (1<<(32-(1+BITS_FOR_SYSTEM_ID))) ) {
throw new C2ServiceException("Too many signals, limit is:"+(1<<(32-(1+BITS_FOR_SYSTEM_ID))),false);
}
int id = (signalIdOnly << BITS_FOR_SYSTEM_ID)+systemId;
String symbol = (String)request.get(Parameter.Symbol);
SignalAction action = null;
Order order = null;
//reverse works like a macro. it does not do the processing but rather builds two
//signal requests to reverse the order and calls schedule signal on each.
if (request.command()== Command.Reverse) {
Integer existingQuantity = portfolio.position(symbol).quantity();
Request requestToClose = buildBaseRequest(request,existingQuantity,symbol);
if (existingQuantity>0) {
//STC
requestToClose.put(Parameter.Action, SignalAction.STC);
} else {
//BTC
requestToClose.put(Parameter.Action, SignalAction.BTC);
}
//schedule the closing request
int[] parentId = scheduleSignal(timeToExecute,requestToClose);
//previous closed now reverse
//only fields needed for building all-in-one dependent signals
Request requestToOpen = buildBaseRequest(request,existingQuantity,symbol);
if (existingQuantity>0) {
//STO
requestToClose.put(Parameter.Action, SignalAction.STO);
} else {
//BTO
requestToClose.put(Parameter.Action, SignalAction.BTO);
}
//schedule the opening request
return scheduleSignal(timeToExecute,requestToClose);
} else {
//use to compute quantity
QuantityComputable quantityComputable = quantityFactory.computable(request,this);
//GTC or Day
Duration timeInForce = (Duration)request.get(Parameter.TimeInForce);
//cancel at this fixed time
long cancelAtMs = Long.MAX_VALUE;
Number cancelAt = (Number)request.get(Parameter.CancelsAt);
if (cancelAt != null) {
cancelAtMs = 1000l * cancelAt.intValue();
}
Number cancelAtRelative = (Number)request.get(Parameter.CancelsAtRelative);
if (cancelAtRelative != null) {
cancelAtMs = timeToExecute + (1000l * cancelAtRelative.intValue());
}
assert(request.command() == Command.Signal);
Instrument instrument = (Instrument)request.get(Parameter.Instrument);
action = (SignalAction)request.get(Parameter.Action);
Integer xReplace = (Integer)request.get(XReplace);
if (xReplace!=null) {
if (xReplace<0 || (xReplace>>BITS_FOR_SYSTEM_ID)>=archive.size()) {
throw new C2ServiceException("Invalid signalId "+xReplace+" not found.",false);
}
Order oldOrder = archive.get(xReplace>>BITS_FOR_SYSTEM_ID);
oldOrder.cancelOrder(timeToExecute);//cancel old order to be replaced
conditionalUponOrder = oldOrder.conditionalUpon();
assert(conditionalUponOrder!=null);