Dear @Tomasz and everybody,
Based on the code AutoTrade using an Exploration by Peter Kuskopf, I adapted it into my code as following, but it failed to send a single order, although it generates signals.
I appreciate your help.
AutoTradingParam = True;// ParamToggle("AutoTrading","Off|On",0);
SubmitOrders = True; //ParamToggle("Create or Transmit","Create Only|Create and Transmit",False);
Tracing = True;
BaseRiskPcnt = 0.01; // Percent of account risk per trade
AccountCutout = 75000; // Stop trading if account falls to $X
// This exploration, by design, allows multiple positions to be placed simultaneously
// (although only 1 entry per bar), so it is highly desirable to have a safety
// mechanism to stop trading if there is a sequence of losing trades, or there is a
// bug in the trading rules or AFL that are creating continuous losing trades.
// ################## volatility #####################
Per = 1920;
Ret = ROC(C, Per);
RetDev = StDev(Ret,Per);
// Interactive Brokers ticker symbols may have unwanted characters for our static variable names. Remove them.
ABName = StrMid(Name(),0,4) + StrMid(Name(),4,3);
IBName = Name();
AutoTrading = StaticVarGet("AutoTrading"+ABName);
if( IsNull( AutoTrading ) )
StaticVarSet("AutoTrading"+ABName,0);
if ( AutoTrading==0 && AutoTradingParam )
{
// About to start AutoTrading after it's been off, so clear all order statuses.
StaticVarSetText("OrderID"+ABName,"");
StaticVarSetText("OrderIDLMT"+ABName,"");
StaticVarSetText("OrderIDSTP"+ABName,"");
StaticVarSetText("OrderStatus"+ABName,"");
StaticVarSetText("OrderLMTStatus"+ABName,"");
StaticVarSetText("OrderStatusSTP"+ABName,"");
}
if ( AutoTrading && AutoTradingParam==0 )
{
// About to stop AutoTrading after it's been on, so clear all order statuses.
StaticVarSetText("OrderID"+ABName,"");
StaticVarSetText("OrderIDLMT"+ABName,"");
StaticVarSetText("OrderIDSTP"+ABName,"");
StaticVarSetText("OrderStatus"+ABName,"");
StaticVarSetText("OrderLMTStatus"+ABName,"");
StaticVarSetText("OrderStatusSTP"+ABName,"");
}
if (AutoTradingParam)
StaticVarSet("AutoTrading"+ABName,1);
else
StaticVarSet("AutoTrading"+ABName,0);
AutoTrading = StaticVarGet("AutoTrading"+ABName);
Filename = _DEFAULT_NAME();
// Your trading conditions here
BuyCond = Cross(Ref(C,-1), HHV(Ref(C,-1),3)); 0;//Whatever your trading rules say
ShortCond = Cross(HHV(Ref(C,-1),3),Ref(C,-1));//Whatever your trading rules say
SellCond = 0;//Whatever your trading rules say
CoverCond = 0;//Whatever your trading rules say
Short = ShortCond;
Buy = BuyCond;
Sell=Cover=0;
// Price
ShortPrice = Min(Ref(C,-1),Open); //Or as appropriate for your trading rules.
BuyPrice = Max(Ref(C,-1),Open); //Or as appropriate for your trading rules.
StopLossMulti=3; // Initial Stop Loss multiplier
StopLoss=ATR(20)*StopLossMulti;
tStopLossMulti=StopLossMulti; // Trailing Stop Loss multiplier
tStopLoss=ATR(20)*tStopLossMulti;
pStopLossMulti=0.5; // Take Profit multiplier x ATR. Set as appropriate for your trading rules.
pStopLoss=ATR(20)*pStopLossMulti;
BuyStopLossPrice=BuyPrice-Ref(StopLoss,-1);
BuypStopLossPrice=BuyPrice+Ref(pStopLoss,-1);
ShortStopLossPrice=ShortPrice+Ref(StopLoss,-1);
ShortpStopLossPrice=ShortPrice-Ref(pStopLoss,-1);
LastBuyPrice=LastValue(BuyPrice);
LastBuyStopLossPrice=LastValue(BuyStopLossPrice);
LastBuypStopLossPrice=LastValue(BuypStopLossPrice);
LastShortPrice=LastValue(ShortPrice);
LastShortStopLossPrice=LastValue(ShortStopLossPrice);
LastShortpStopLossPrice=LastValue(ShortpStopLossPrice);
/////////////////// Automation Code //////////////////
// First check if we've just started a new bar. THIS CODE RELIES ON PREFERENCES/INTRADAY SET TO START OF INTERVAL.
PrevDT = StaticVarGet("DateTime"+IBName);
DT = LastValue(DateTime());
NewBar = DT != PrevDT;
StaticVarSet("DateTime"+IBName,DT);
if( NewBar )
{
// Clear all status so we can place a new order on each bar. Later, the status variables are checked to ensure
// that we place no more than 1 order on each bar.
StaticVarSetText("OrderID"+IBName,"");
StaticVarSetText("OrderIDLMT"+IBName,"");
StaticVarSetText("OrderIDSTP"+IBName,"");
StaticVarSetText("OrderStatus"+IBName,"");
StaticVarSetText("OrderLMTStatus"+IBName,"");
StaticVarSetText("OrderStatusSTP"+IBName,"");
}
LastBuy = LastValue(Buy);
LastShort = LastValue(Short);
Filter=Buy OR Short;
IBPosSize=0;
ibc = GetTradingInterface("IB");
IBcStatus = ibc.IsConnected();
IBcStatusString = WriteIf(IBCStatus==0,"TWS Not Found",
WriteIf(IBCStatus==1,"Connecting to TWS",
WriteIf(IBCStatus==2,"TWS OK",
WriteIf(IBCStatus==3,"TWS OK (msgs)",""))));
// Work out how much money there is and adjust risk size
CashBalanceStr = ibc.GetAccountValue("NetLiquidationByCurrency");
if (CashBalanceStr == "")
CashBalance = 0;
else
CashBalance = StrToNum(CashBalanceStr);
// If trading instruments denominated in multiple currencies, e.g. FX, you will need to adjust this code.
// It is possible to dynamically lookup the IB FX price
PositionRisk = (BaseRiskPcnt*CashBalance)/RetDev;
PositionSize = PositionRisk;
IBOrderSize = int(LastValue(PositionSize)); // Round ************
OldOrderID = StaticVarGetText("OrderID"+IBName);
if (AutoTrading == 0 && OldORderID == "" && (LastBuy || LastShort))
{
// If there would have been an order during Autotrading, then create a dummy OID to test all other code paths
// e.g. logging, explore output etc.
StaticVarSetText("OrderID"+IBName,"DUMMY");
}
if( IBcStatus AND AutoTrading AND (CashBalance > AccountCutout))
{
OrderID = StaticVarGetText("OrderID"+IBName);
OrderIDLMT = StaticVarGetText("OrderIDLMT"+IBName);
OrderIDSTP = StaticVarGetText("OrderIDSTP"+IBName);
IBPosSize = ibc.GetPositionSize( IBName );
// Only enter once the price moves in my desired direction, otherwise wait until next run of the exploration
// and check again, and again., ...
if( LastBuy AND OrderID == "") // AND (LastValue(C) <= (LastBuyPrice))
{
OID = ibc.PlaceOrder( IBName, "Buy", IBOrderSize, "TRAIL", 0,
"DAY", False, "outsideRTH" );
_TRACE("# Pos: 0, PrevOID: "+OrderID+", Buy 1, NewOID: "+OID);
OIDLMT = ibc.PlaceOrder( IBName, "Sell", IBOrderSize, "LMT", LastBuypStopLossPrice, 0,
"GTC", False, "outsideRTH", OID);
OIDSTP = ibc.PlaceOrder( IBName, "Sell", IBOrderSize, "STP", 0, LastBuyStopLossPrice,
"GTC", SubmitOrders, "outsideRTH", OID);
for (dummy=0; dummy<40; dummy++)
ibc.Sleep(50); //Usually takes up to about a second for TWS to get acknowledgement from IB
StaticVarSetText("OrderID"+IBName,OID);
StaticVarSetText("OrderIDLMT"+IBName,OIDLMT);
StaticVarSetText("OrderIDSTP"+IBName,OIDSTP);
if (SubmitOrders)
{
for (dummy=0; dummy<40; dummy++)
ibc.Sleep(50); //Usually takes up to about a second for TWS to get acknowledgement from IB
// Wait until order actually PreSubmitted - this will prevent submitting another order too quickly
// hopefully stops TWS/IB getting in a knot
tradetime=GetPerformanceCounter()/1000;
while ((GetPerformanceCounter()/1000 - tradetime) < 5) // give up after 5 seconds
{
ibc.Reconnect(); //Refreshes ibc, and gets accurate status
ORderStatus = ibc.GetStatus( OID, True);
if (ORderStatus == "PreSubmitted" || ORderStatus == "Submitted" || ORderStatus == "Filled")
break;
}
}
}
// Only enter once the price moves in my desired direction, otherwise wait until next run of the exploration
// and check again, and again., ...
else if( LastShort AND OrderID == "" ) //AND (LastValue(C) >= (LastShortPrice))
{
OID = ibc.PlaceOrder( IBName, "Sell", IBOrderSize, "TRAIL", 0,
"DAY", False, "outsideRTH" );
_TRACE("# Pos: 0, PrevOID: "+OrderID+", Sell 1, NewOID: "+OID);
OIDLMT = ibc.PlaceOrder( IBName, "Buy", IBOrderSize, "LMT", LastShortpStopLossPrice, 0,
"GTC", False, "outsideRTH", OID);
OIDSTP = ibc.PlaceOrder( IBName, "Buy", IBOrderSize, "STP", 0, LastShortStopLossPrice,
"GTC", SubmitOrders, "outsideRTH", OID);
for (dummy=0; dummy<40; dummy++)
ibc.Sleep(50); //Usually takes up to about a second for TWS to get acknowledgement from IB
StaticVarSetText("OrderID"+IBName,OID);
StaticVarSetText("OrderIDLMT"+IBName,OIDLMT);
StaticVarSetText("OrderIDSTP"+IBName,OIDSTP);
if (SubmitOrders)
{
//Usually takes about a second for TWS to get acknowledgement from IB, so delay for 2 secs for safety
for (dummy=0; dummy<40; dummy++)
ibc.Sleep(50);
// Wait until order actually PreSubmitted - this will prevent submitting another order too quickly
// hopefully stops TWS/IB getting in a knot
tradetime=GetPerformanceCounter()/1000;
while ((GetPerformanceCounter()/1000 - tradetime) < 5) // give up after 5 seconds
{
ibc.Reconnect(); //Refreshes ibc, and gets accurate status
ORderStatus = ibc.GetStatus( OID, True);
if (ORderStatus == "PreSubmitted" || ORderStatus == "Submitted" || ORderStatus == "Filled")
break;
}
}
}
// Note LastOrderID will remain "" while waiting for price improvement so we may skip entering for the whole of the bar
LastOrderID = StaticVarGetText("OrderID"+IBName);
LastOrderIDLMT = StaticVarGetText("OrderIDLMT"+IBName);
LastOrderIDSTP = StaticVarGetText("OrderIDSTP"+IBName);
ORderStatus = ibc.GetStatus( LastOrderID , True );
if( ORderStatus != "" ) StaticVarSetText("OrderStatus"+IBName,ORderStatus);
ORderLMTStatus = ibc.GetStatus( LastOrderIDLMT , True );
if( ORderLMTStatus != "" ) StaticVarSetText("OrderLMTStatus"+IBName,ORderLMTStatus);
ORderSTPStatus = ibc.GetStatus( LastOrderIDSTP , True );
if( ORderSTPStatus != "" ) StaticVarSetText("OrderStatusSTP"+IBName,ORderSTPStatus);
}
else IBPosSize = 0;
LastOrderID = StaticVarGetText("OrderID"+IBName);
ORderStatus = StaticVarGetText("OrderStatus"+IBName);
LastOrderIDLMT = StaticVarGetText("OrderIDLMT"+IBName);
ORderLMTStatus = StaticVarGetText("OrderLMTStatus"+IBName);
LastOrderIDSTP = StaticVarGetText("OrderIDSTP"+IBName);
ORderSTPStatus = StaticVarGetText("OrderSTPStatus"+IBName);
Title = Filename+":"+IBName+"\n"+
" Trading Mode: "+WriteIf( AutoTrading,"ON"+WriteIf( SubmitOrders," - Create and Transmit"," - Create Only"),"OFF")+"\n"+
" Last Signal: "+WriteIf(LastBuy,"BUY",WriteIf (LastShort,"SHORT","NoSignal"))+"\n"+
" IB Status: "+IBcStatusString+"\n"+
" Last OrderID,LMT,STP: "+LastOrderID+","+LastOrderIDLMT+","+LastOrderIDSTP+"\n"+
" OrderStatus,LMT,STP: "+ORderStatus+WriteIf(ORderStatus=="Error",ibc.GetLastError( LastOrderID ),"")+","+ORderLMTStatus+","+ORderSTPStatus+"\n"+
" LastTime: "+DateTimeToStr(LastValue(DateTime()))+"\n"+
" IBPosSize: "+NumToStr(IBPosSize,1.0);
AddColumn(CashBalance,"Cash",1.2);
AddColumn(IIf(AutoTrading,Asc("Y"),Asc("N")),"AT",formatChar);
AddColumn(IIf(SubmitOrders,Asc("Y"),Asc("N")),"Transmit",formatChar);
AddColumn(BuyCond OR ShortCond,"Cond",1.0);
AddColumn(IIf(Buy,Asc("L"),IIf(Short,Asc("S"),Asc(" "))),"L/S",formatChar);
AddColumn(int(LastValue(PositionSize)),"PosSize",1.0);
AddColumn(IBOrderSize,"Qty",1.0);
AddColumn(IIf(Buy,BuyPrice,ShortPrice),"Entry",1.5);
AddColumn(RetDev, "RetDev" ,1.2);
AddTextColumn(IBcStatusString,"IBC Status",1.0);
AddTextColumn(LastOrderID,"LastOID",1.0);
AddTextColumn(ORderStatus,"OrderStatus",1.0);
//
// The following code writes all the above AddColumn to permanent logfile, where Filter occurs on last bar
//
if (Filter[BarCount-1] && OldOrderID == "" && LastOrderID != "") // No order previously in place for this bar, this execution created one
{
fh = fopen( "TWSTrade.log", "a");
if( fh )
{
fputs( Now(), fh );
fputs( ", ", fh );
fputs( "Ticker: ", fh );
fputs( IBName, fh );
fputs( ", ", fh );
fputs( "BarTime: ", fh );
fputs( DateTimeToStr(DT), fh );
fputs( ", ", fh);
qs = StrFormat("Cash: %.2f, ",
CashBalance);
fputs( qs, fh );
fputs( "AT: ", fh );
if (AutoTrading) fputs( "Y, " , fh );
else fputs( "N, " , fh );
fputs( "Submit: ", fh );
if (SubmitOrders) fputs( "Transmit, " , fh );
else fputs( "Create_Only, " , fh );
if (LastBuy) fputs( "Buy, ", fh);
else if (LastShort) fputs( "Short, ", fh);
else fputs( "Not_Valid, ", fh);
qs = StrFormat("%.0f, ",
IBOrderSize );
fputs( qs, fh );
if (LastBuy)
qs = StrFormat("Entry: %.5f, StopLossMulti: %.2f, Stop: %.5f, Profit: %.5f, ",
LastBuyPrice, StopLossMulti, LastBuyStopLossPrice, LastBuypStopLossPrice);
else
qs = StrFormat("Entry: %.5f, StopLossMulti: %.2f, Stop: %.5f, Profit: %.5f, ",
LastShortPrice, StopLossMulti, LastShortStopLossPrice, LastShortpStopLossPrice);
fputs( qs, fh );
fputs( "IBC Status: ", fh );
fputs( IBCStatusString, fh );
fputs( ", ", fh);
fputs( "LastOID: ", fh );
fputs( LastOrderID, fh );
fputs( ", ", fh);
fputs( "OrderStatus: ", fh );
fputs( ORderStatus, fh );
fputs( ", ", fh);
if (ORderStatus=="Error")
fputs( ibc.GetLastError( LastOrderID ), fh);
fputs( ", ", fh);
fputs( "\n", fh );
fclose( fh );
}
}