My auto trading Script does not send a single order

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.

image

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 ); 
	} 
}

updated code:

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;

TrailStopMulti=StopLossMulti;  // Trailing Stop Loss multiplier
TrailStop=ATR(20)*TrailStopMulti;

ProfitTakeStopMulti=0.5;  // Take Profit multiplier x ATR. Set as appropriate for your trading rules.
ProfitTakeStop=ATR(20)*ProfitTakeStopMulti;


BuyStopLossPrice=BuyPrice-Ref(StopLoss,-1);
BuyProfitTakeStopPrice=BuyPrice+Ref(ProfitTakeStop,-1);

ShortStopLossPrice=ShortPrice+Ref(StopLoss,-1);
ShortProfitTakeStopPrice=ShortPrice-Ref(ProfitTakeStop,-1);




LastBuyPrice=LastValue(BuyPrice);
LastBuyStopLossPrice=LastValue(BuyStopLossPrice);
LastBuyProfitTakeStopPrice=LastValue(BuyProfitTakeStopPrice);

LastShortPrice=LastValue(ShortPrice);
LastShortStopLossPrice=LastValue(ShortStopLossPrice);
LastShortProfitTakeStopPrice=LastValue(ShortProfitTakeStopPrice);



/////////////////// 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, "LMT", BuyPrice,  
                              "DAY", False, 100,"outsideRTH" );
        _TRACE("# Pos: 0, PrevOID: "+OrderID+", Buy 1, NewOID: "+OID);
        OIDLMT = ibc.PlaceOrder( IBName, "Sell", IBOrderSize, "LMT", LastBuyProfitTakeStopPrice, 0, 
                                 "GTC", False, 100,  "outsideRTH", OID);
        OIDSTP = ibc.PlaceOrder( IBName, "Sell", IBOrderSize, "STP", LastBuyStopLossPrice, LastBuyStopLossPrice, 
                                 "GTC", SubmitOrders, 100,  "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, "LMT", ShortPrice, 0,
                              "DAY", False, 100, "outsideRTH" );
         _TRACE("# Pos: 0, PrevOID: "+OrderID+", Sell 1, NewOID: "+OID);

        OIDLMT = ibc.PlaceOrder( IBName, "Buy", IBOrderSize, "LMT", LastShortProfitTakeStopPrice, 0, 
                                 "GTC", False, 100, "outsideRTH", OID);
        OIDSTP = ibc.PlaceOrder( IBName, "Buy", IBOrderSize, "STP", LastShortStopLossPrice, LastShortStopLossPrice, 
                                 "GTC", SubmitOrders, 100,  "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("Long"),IIf(Short,Asc("Short"),Asc(" "))),"Action",formatChar);

AddColumn(int(LastValue(PositionSize)),"PositionSize",1.0);      
AddColumn(IBOrderSize,"Qty",1.0);
AddColumn(IIf(Buy,BuyPrice,ShortPrice),"Entry Price",1.5);


AddColumn(RetDev, "RetDev" ,1.2);
AddTextColumn(IBcStatusString,"IBC Status",1.0);
AddTextColumn(LastOrderID,"LastOID",1.0);
AddTextColumn(ORderStatus,"OrderStatus",1.0);


You need to follow advice given here:

How do I debug my formula? (post #1) and also later in the same thread (post #11)

Besides the original code you have adopted is poorly written. It is NOT good starting point. One of the reasons is that it implements busy waiting (Sleep) which is big no-no. Instead a state machine no-wait design should be used, see for example:

Take a piece of PAPER and DRAW your design on paper.

After you have a drawing you should start programming.

Typing code frantically without having clear general concept is recipe for failure.

General idea is to go from one state to another state based on information you receive from TWS.

Here is an example flow chart for transition from being flat (no position) to being in long position:

Diagram1

You do NOT busy wait when you are in given state (colored box in flow chart).
Instead you just FINISH execution, RequestTimedRefresh, then in next execution you start from previous state and do one transition.

1 Like

Awesome.

I search accross libary by keywords: auto trading, automatic trading, auto trade:
https://amibroker.com/members/library/list.php

Which script would be a good starting point?

Hello, @Tomasz
Thanks for your guide. I'm trying to adapt the below code to allow explore/scan watchlist, and send orders to IB Controller. It looks like below code follow the state machine you provided.

I just shared the afl code here. IIt is too large to post.
https://1drv.ms/u/s!An6sM7F1HMXwgbpJ_naP0oytHC8LFg?e=5WESI3

However, It failed to send a single order, although I can see debug trace signals.

Could you please have a look at this code?

@SteveH @fxshrat @reinsley

image

I looked at the code from the link you posted. You need to have more _TRACE / _TRACEF statements in that code to verify every single if statement is true leading to the ibc.PlaceOrder() function.

You also need to verify that the BrokerIB.exe app is unlocked so your orders are actually being sent to TWS. If the app isn't unlocked, the orders will show up in its Pending Orders window and you'll clearly see they weren't transmitted, regardless of correctly having the transmit field of ibc.PlaceOrder() set to True. Honestly, I don't know why the unlock code part of that app wasn't removed before the source code was released. I just bypassed it by returning true from the C++ routine which does the code validity check and recompiled it.

It is extra precaution step. Really there are way too many people who don't understand risks of auto trading. It is like reminder that your seat belt isn't fastened and when one does not do this step he/she is clearly NOT prepared for auto-trading.

Thanks Steve for the help. I agree with you that users should have more choices to take their own risks.
In my case, IB Controller is registered. So the only problem is lying on coding.

So you don't fasten your seat belts in your car or in airplane, because "you want choice"?
Interesting.

2 Likes

So, I fasten my seat belt every time when sit in my car, instead of first time I bought my car. :smile:

I just updated the Auto Trading Code to github so everyone can easily read edit.

If I can make it work, I will post it to Amibroker library.

If you have any suggestions, feel free to let me know.