Unable to move past random TWS IB API Cancelled issue

Hi,

I have gone through IBController 1.3.8 READ ME and selected some very simple code( some from Harman). I have a very simple code, which buys when Close crossing ema21 and sell when ema21 crossing the close.

I have made the afl and placed it on 3 other stocks, but I see some orders get through and some randomly goes to APICancelled.

Can anyplease please guide or help?. inline my buy condition,api cancelled error

BuyOrderID = ibc.ModifyOrder( BuyOrderID, symbo, "Buy", OrderSize, "MKT", 0, 0, "Day", True );
        StaticVarSetText( staticVarPfx + "BuyOrderID", BuyOrderID );
	

This is generated by Interactive Brokers.
Ask them.

According to their docs TWS API v9.72+: Placing Orders - you canceled the order yourself.

ApiCancelled - after an order has been submitted and before it has been acknowledged, an API client (i.e YOU) can request its cancellation, producing this state.

Thank you so much for your response Tomasz.

you are absolutely right- and I saw the same in their API documentation before writing email to amibroker support. In fact, I called IB tech support team, they explained to me that my code is cancelling the same order which was placed before.

I am scratching my head as I am not cancelling the orders. This is auto trade codes.and code doesnt have any piece of code which cancel the orders.

this is all it has. please note, it works as well, but randomly sees order in api cancelled. can you plase give some clues or leads?



cPosSize = ibc.GetPositionSize( Name() );
ordersize = 1;
em = EMA( Close, 21 ); //Middle Line
buy = C > em;
Sell = C < em;

Buy=Ref(Buy,-1);
Sell=Ref(Sell,-1);

Buy = ExRem( Buy, Sell );
Sell = ExRem( Sell, Buy );

if( LastValue( Buy ) ){
    if( cPosSize == 0 )  {
        BuyOrderID = ibc.PlaceOrder( Name(), "Buy", OrderSize, "MKT", 0, 0, "Day", True );
        StaticVarSetText( staticVarPfx + "BuyOrderID", BuyOrderID );
    }
    else if( cPosSize > 0 ){
                // do nothin- already long

    }
  }

if( LastValue( Sell ) ){
    SellOrderID = ibc.PlaceOrder( Name(), "Sell", cPosSize, "MKT", 0, 0, "Day", True );
    StaticVarSetText( staticVarPfx + "SellOrderID", SellOrderID );
}


As I wrote - ask Interactive Brokers and tell them you are not cancelling orders.

I did that already. They said it's issue from my side. I have hit the wall here :frowning:

It is possible tht due to lag- my code is sending same order ID in next order, thereby cancelling the first one?

I have used Amibroker for many years.....I am a large fan, and would never consider using any other program!

What a difficult situation, where AB promotes connectivity for auto-trade functionality with IB...yet, they don't seem to be effectively communicating.

This must be frustrating for Tomasz.

I am vastly involved with auto-trade capabilities. I'm also totally committed to writing .afl code.

Tomasz has stated, on this forum, that he is not a "fan" of black-box trading. I presume that he is not cool with folks being enticed by unreasonable claims. I firmly agree with that stance!

There are many people that have developed algorithmic trading systems that are suitable for automated trading. What is the best program to execute these signals? Is it Amibroker?

I think AB is one of the best, I personally love it. Unfortunately, at times I feel as a user of AB, my support is limited. @Tomasz suggest to go to IB and IB says nothing wrong at our side.

this gets really demoralizing.

hi, I have no answer to your question but I noticed you are running IB Controller version 1.3.9. Where did you get that from? I can only see the last version is 1.3.8

thanks

First and foremost, use "Divide and conquer" strategy explained in this thread: How do I debug my formula?

If you have ANY problem - DIVIDE it into smaller parts until you go to absolute simplest code. If your code does not work, make it simpler.

The code presented in this thread is NOT complete. Expecting people to help you without following this How to ask a good question is absurd.

It is like calling your doctor and asking him:
"Hey doctor, please prescribe me some pills, I feel terrible but I won't tell you what I did, but hey you are doctor so you surely can guess".

It does work that way. Automatic trading is not for beginners. Copy-pasting from internet does not work. You have to understand what you are doing.

First and foremost, calling ibc.ModifyOrder unconditionally is not what you should do. The fact is that IB/TWS may be cancelling your orders simply because you send TOO MANY repeated orders. IB staff doesn't care to even inform people about limitations of their own platform, but TWS has a LIMIT of request rate and it is 50 per second and up to 15 active orders per contract per side per account. They should have told you that. Did they? No? Is it Amibroker's fault that IB support staff does not care to tell you that?

https://www.google.com/search?q=TWS+API+rate+limit

The formula that calls ModifyOrder unconditionally can easily send a lot more.

You have to ensure that you send not more than 50 messages per second and not more than 15 active orders for same symbol.

if( ParamTrigger("PlaceOrder", "PlaceOrder" ) )
{
// do it ONCE, don't repeat unless triggered again
ibc = GetTradingInterface("IB");

if( ibc.IsConnected() ) // check if connection to IB was successfull
{
   ibc.PlaceOrder("MSFT", "BUY", 100, "MKT", 0, 0, "DAY", False ); // place order but do not transmit yet
} 
}
3 Likes

Thanks Tomasz, you remind me of my school math's teacher. at times- you sound harsh, but you say all correct things .

I got you what you meant by "when you call your doctor..."

Let me work it on based on your recommendations. If I fail, I will try to submit my complete code here. Thanks again.

@Tomasz - I spent good amount of time with IB tech support, they dont look at AB code though, but they did troubleshoot a bit and said my orders are within limit of API. and for API cancelled issue, they said it is your API client or execution software.

I am not sure what do to next now. would be great if you can please give me some clues or leads. I have given my complete code here..

_SECTION_BEGIN( "ALGO Initialization" );
// for kelter channel
staticVarPfx = "" + GetChartID() + Name();
PrevTN = StaticVarGet( staticVarPfx + "TimeNumber" );
TN = LastValue( TimeNum() );
NewBar = TN != PrevTN;
tn2 = tn / 100;
symbo=Name();
ibc = GetTradingInterface("IB");
StaticVarSet( staticVarPfx + "TimeNumber", TN );
BuyOrderID = StaticVarGetText( staticVarPfx + "BuyOrderID" );
SellOrderID = StaticVarGetText( staticVarPfx + "SellOrderID" );

szLog = StaticVarGetText( staticVarPfx + "szLog" );
bzLog = StaticVarGetText( staticVarPfx + "bzLog" );
IBPosSize = ibc.GetPositionSize( symbo );

// To avoid repeat of trace in each bar once buy/sell done
bzLogged = StaticVarGetText( staticVarPfx + "bzLogged" );
szLogged = StaticVarGetText( staticVarPfx + "szLogged" );
BuyPending = ibc.IsOrderPending( BuyOrderID );
SellPending = ibc.IsOrderPending( SellOrderID );
cPosSize = ibc.GetPositionSize( symbo );
_SECTION_END();


_SECTION_BEGIN( "ALGO LOGIC SECTION" );

lineX = EMA( Close, 21 ); //Middle Line
buy = C > lineX;
Sell = C < lineX;


Buy = Ref( Buy, -1 );
Sell = Ref( Sell, -1 );


Buy = ExRem(Buy, Sell);
Sell = ExRem(Sell, Buy);



if( NewBar )
{
    if( NOT BuyPending ) StaticVarSetText( staticVarPfx + "BuyOrderID", "" );
    if( NOT SellPending ) StaticVarSetText( staticVarPfx + "SellOrderID", "" );
    StaticVarSet( staticVarPfx+"OrderAlreadyPlaced", false );
    ibc.CancelAllPendingOrders( symbo );
    StaticVarSetText( staticVarPfx + "szLog", "" );
    StaticVarSetText( staticVarPfx + "bzLog", "" );
}


_SECTION_END();


_SECTION_BEGIN( "ALGO EXECUTION SECTION" );

    if( LastValue( Buy ) AND bzLog == "" )
    {
        if( cPosSize == 0 )
        {
            _TRACE( "NO POSITION  | Next STEP --> GO LONG" );
            if( Nz( StaticVarGet(staticVarPfx+"OrderAlreadyPlaced") ) == False )
            {
                StaticVarSet( staticVarPfx+"OrderAlreadyPlaced", True );	
                BuyOrderID = ibc.PlaceOrder( symbo, "Buy", OrderSize, "MKT", 0, 0, "Day", True );
                StaticVarSetText( staticVarPfx + "BuyOrderID", BuyOrderID );
                BuyOrderID = StaticVarGetText( staticVarPfx + "BuyOrderID" );
                _TRACE( "BUY ORDER ID >>>>>>>> " + BuyOrderID );
                StaticVarSetText( staticVarPfx + "bzLog", "" );
            }

        }

        if( cPosSize == OrderSize AND bzLog == "" )
        {
            _TRACE( "Already Long Position [" + cPosSize + "]   | Next STEP --> NO ACTION " );
            StaticVarSetText( staticVarPfx + "bzLog", "X" );
        }

        if( cPosSize < 0 )
        {
            newOrderSize = abs( cPosSize ) + OrderSize;
            _TRACE( " [" + cPosSize + "] Short Position Found | Next STEP >> COVER AND GO LONG " );
            if( Nz( StaticVarGet(staticVarPfx+"OrderAlreadyPlaced") ) == False )
            {
			StaticVarSet( staticVarPfx+"OrderAlreadyPlaced", True );	
            BuyOrderID = ibc.PlaceOrder( symbo, "Buy", newOrderSize, "MKT", 0, 0, "Day", True );
            StaticVarSetText( staticVarPfx + "BuyOrderID", BuyOrderID );
            _TRACE( "BUY ORDER ID is " + BuyOrderID );
            StaticVarSetText( staticVarPfx + "bzLog", "" );
            }
        }

        if( cPosSize > 0 AND  cPosSize != OrderSize )
        {
            if( cPosSize > OrderSize )
            {
                newOrderSize = abs( cPosSize ) - OrderSize;
                _TRACE( " Extra [" + newOrderSize + "] LONG Found | NEXT STEP --> SELL Extra Positions " );
				if( Nz( StaticVarGet(staticVarPfx+"OrderAlreadyPlaced") ) == False )
				{
				StaticVarSet( staticVarPfx+"OrderAlreadyPlaced", True );		
                SellOrderID = ibc.PlaceOrder( symbo, "Sell", newOrderSize, "MKT", 0, 0, "Day", True );
                StaticVarSetText( staticVarPfx + "SellOrderID", SellOrderID );
                _TRACE( "SELL ORDER ID is " + SellOrderID );
                }
            }

            if( cPosSize < OrderSize )
            {
                newOrderSize = OrderSize - abs( cPosSize );
                _TRACE( "LONG Positions Mismatch | Actual [" + cPosSize + "]  / Exected [" + OrderSize + "]  NEXT STEP --> Buy Extra  " );
				if( Nz( StaticVarGet(staticVarPfx+"OrderAlreadyPlaced") ) == False )
				{
				StaticVarSet( staticVarPfx+"OrderAlreadyPlaced", True );	
				BuyOrderID = ibc.PlaceOrder( symbo, "Buy", newOrderSize, "MKT", 0, 0, "Day", True );
                StaticVarSetText( staticVarPfx + "BuyOrderID", BuyOrderID );
                _TRACE( "BUY ORDER ID is " + BuyOrderID );
				}
            }
            StaticVarSetText( staticVarPfx + "bzLogged", "" );
        }
        bzLog = StaticVarSetText( staticVarPfx + "bzLog", "bzLog" );
    }

// SELL ZONE ///////////////////////////
    if( LastValue( Sell ) AND szLog == "" )
    {
        cPosSize = ibc.GetPositionSize( symbo );
        if( cPosSize == 0 AND szLog == "" )
        {
            _TRACE( "No Position | Next STEP --> DO NOTHING ( LONG ONLY) " );
            StaticVarSetText( staticVarPfx + "szLog", "Y" );
        }

        if( cPosSize > 0 )
        {
            _TRACE( "Closing [" + cPosSize + "] Positions AS SELL SIGNAL TRIGGERED " );
            if( Nz( StaticVarGet(staticVarPfx+"OrderAlreadyPlaced") ) == False )
			{
			StaticVarSet( staticVarPfx+"OrderAlreadyPlaced", True );	
			SellOrderID = ibc.PlaceOrder( symbo, "Sell", cPosSize, "MKT", 0, 0, "Day", True );
            StaticVarSetText( staticVarPfx + "SellOrderID", SellOrderID );
            _TRACE( "SELL ORDER ID is " + SellOrderID );
            StaticVarSetText( staticVarPfx + "szLog", "" );
            }
        }

        if( cPosSize < 0 )
        {
            OrderSize = abs( cPosSize );
            _TRACE( "SHORTS IN LONG ONLY FUND- COVER [" + cPosSize + "] POSITIONS " );
			if( Nz( StaticVarGet(staticVarPfx+"OrderAlreadyPlaced") ) == False )
				{
				StaticVarSet( staticVarPfx+"OrderAlreadyPlaced", True );	
				BuyOrderID = ibc.PlaceOrder( symbo, "Buy", newOrderSize, "MKT", 0, 0, "Day", True );
                StaticVarSetText( staticVarPfx + "BuyOrderID", BuyOrderID );
                _TRACE( "short Cover Buy ORDER ID is " + BuyOrderID ); 
				StaticVarSetText( staticVarPfx + "szLog", "" );
            }
        }
        szLog = StaticVarSetText( staticVarPfx + "szLog", "szLog" );
    }


_SECTION_END();

_SECTION_BEGIN("price default");
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
SetChartOptions(0,chartShowArrows|chartShowDates);
Plot( C, "", colorDefault, styleCandle );

_SECTION_END();



@rakeshjha I haven't looked at your code in detail, but suspect this may have something to do with your issue:

if( NewBar )
{
    if( NOT BuyPending ) StaticVarSetText( staticVarPfx + "BuyOrderID", "" );
    if( NOT SellPending ) StaticVarSetText( staticVarPfx + "SellOrderID", "" );
    StaticVarSet( staticVarPfx+"OrderAlreadyPlaced", false );
    ibc.CancelAllPendingOrders( symbo );
    StaticVarSetText( staticVarPfx + "szLog", "" );
    StaticVarSetText( staticVarPfx + "bzLog", "" );
}

It appears to me that you're cancelling all orders each time a new bar is formed. This is contrary to your earlier statement that "This is auto trade codes.and code doesnt have any piece of code which cancel the orders.".

4 Likes

Thanks a Ton @mradtke . I am embarrassed as hell. It should never bee there. It was part of cancel all orders section.

It seems this was the culprit..let me remove it and try.
P.S.- That's why I love AB forum. you get genuine help.

That is perfect example showing why posting entire code helps tremendously.

2 Likes

so true @Tomasz . I really like when you get strict. :slight_smile:

Thanks @Tomasz and @mradtke . really appreciate your help.

Just to update you guys- I havent seen APICancelled error since last 2 hours testing.

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.