Otevírá více tržních příkazů současně s po sobě jdoucími magickými čísly, což umožňuje částečné uzavírání pozic na různých úrovních profit targetu nebo stop lossu. Ideální pro škálovací strategie a správu více úrovní rizika.
Snippet Multiple Orders at Market – odesílá více příkazů najednou s různými magickými čísly.
Na snímku vyberte počet příkazů (nb) a magické číslo. Pokud zvolíte 3 jako počet příkazů a 1000 jako magické číslo, vytvoří se 3 tržní příkazy s magickými čísly: 1000, 1001 a 1002.
Uzavřete částečně některé tržní příkazy na jednom profit targetu a další příkazy na jiných profit targetech nebo stop lossu.
package SQ.Blocks.Order.Open;
import java.util.ArrayList;
import com.strategyquant.datalib.TradingException;
import com.strategyquant.datalib.UpdateEventTypes;
import com.strategyquant.lib.SQTime;
import com.strategyquant.lib.SQUtils;
import com.strategyquant.tradinglib.*;
// Modified by Emmanuel Evrard for StrategyQuantX Community
@BuildingBlock(name="(MMKT) Enter Multiple Order at market", display="EnterMultipleOrderAtMarket", returnType=ReturnTypes.Order)
@Help("Opens Multiple order at current market price")
public class EnterAtMarketMultiOrder extends ActionBlock
{
@Parameter(defaultValue="Any", category="Basic", showIfDefault=false)
@Editor(type=Editors.SelectionSymbolsWithAny)
public String Symbol;
@Parameter(defaultValue="1", category="Basic")
@Editor(type=Editors.Selection, values="Long=1,Short=-1")
public int Direction;
@Parameter(category="Basic")
@Editor(type=Editors.Formula, formulaName="Size")
@Required
public IFormula Size;
@Parameter(defaultValue="MagicNumber", category="Order identification", showIfDefault=false)
@Help("Magic number is used to identify the first trade, it should be unique for every trade you open.")
public int MagicNumber;
@Parameter(defaultValue="Number Of Order", category="Order identification", showIfDefault=false)
@Help("Number Of Order is used to set the quantity of order, Their MagicNumbers are successives to the above MagicNumber")
public int NbOrder;
@Parameter(defaultValue="", category="Order identification", showIfDefault=false)
public String Comment;
@Parameter(defaultValue="false", category="Order identification", showIfDefault=false)
@Help("If set to true, it will allow to place multiple trades with the same Magic Number")
public boolean AllowDuplicateTrades;
public ExitMethod[] ExitMethods;
@Override
public void OnAction() throws TradingException
{
if((!AllowDuplicateTrades || !engineSupportsDuplicateTrades()) && checkLiveOrderExists(0, true) != null)
return;
byte orderType = (Direction > 0 ? OrderTypes.Buy : OrderTypes.Sell);
double sl = computeSL(orderType, (Direction > 0 ? Strategy.MarketData.Chart(Symbol).Ask() : Strategy.MarketData.Chart(Symbol).Bid()));
double size = computeSize(orderType, 0, sl);
ATM atm = Strategy.getATM();
double pt = computePT(orderType, (Direction > 0 ? Strategy.MarketData.Chart(Symbol).Ask() : Strategy.MarketData.Chart(Symbol).Bid()));
int MagicNumber1 = MagicNumber;
for(int i = 0; i < NbOrder; i++)
{
MagicNumber = MagicNumber1 + i;
if(atm != null && atm.isApplicable(Strategy, size, sl, orderType)) {
openATMOrder(atm, -1, size, sl, pt, orderType, 0);
} else {
openNormalOrder(-1, size, sl, orderType, 0);
}
}
}
protected void openNormalOrder(double openPrice, double size, double sl, byte orderType, int barsValid) throws TradingException {
ILiveOrder order = Strategy.Trader.Open(orderType, Symbol, openPrice)
.setSize(size).setMagicNumber(MagicNumber).setComment(Comment).Send();
if(order.isSuccessful()) {
handleBarsValid(order, barsValid);
for(ExitMethod exitMethod : ExitMethods) {
if(!order.isClosedOrder()) exitMethod.setForOrder(order, Strategy);
}
}
}
protected double computeSL(byte orderType, double orderPrice) throws TradingException {
ExitMethod slExit = getStopLossExit();
return slExit == null ? Order.NOT_DEFINED : SQUtils.fixPrice(Strategy.getInstrumentInfo().tickStep, slExit.computeValue(orderType, Strategy, Symbol, orderPrice));
}
protected double computePT(byte orderType, double orderPrice) throws TradingException {
ExitMethod ptExit = getProfitTargetExit();
return ptExit == null ? Order.NOT_DEFINED : SQUtils.fixPrice(Strategy.getInstrumentInfo().tickStep, ptExit.computeValue(orderType, Strategy, Symbol, orderPrice));
}
private ExitMethod getStopLossExit() {
for(ExitMethod e : ExitMethods) if(e.getExitType() == ExitTypes.StopLoss) return e;
return null;
}
private ExitMethod getProfitTargetExit() {
for(ExitMethod e : ExitMethods) if(e.getExitType() == ExitTypes.ProfitTarget) return e;
return null;
}
protected double computeSize(byte orderType, double price, double sl) throws TradingException {
return ((MMFormulaBlock) Size).computeSize(Strategy, Symbol, orderType, price, sl);
}
protected ILiveOrder checkLiveOrderExists(int direction, boolean includeClosingOrders) {
for(int i=Strategy.Trader.getOpenOrdersCount(includeClosingOrders)-1; i>=0; i--) {
ILiveOrder order = Strategy.Trader.getOpenOrder(i, includeClosingOrders);
if(order.isMarketOrder() && OrderFunctions.identify(order, Strategy, Symbol, direction, MagicNumber, Comment))
return order;
}
return null;
}
protected boolean engineSupportsDuplicateTrades() { return Strategy.Trader.supportsDuplicateTrades(); }
protected void handleBarsValid(ILiveOrder order, int barsValid) throws TradingException {}
}