I have coded it in a different manner avoiding having  to handle any of the 
Interopt coding myself.  I have VS 2008 Pro and the latest Windows SDK 
installed.  In VS, I just checked the project property on the Build tab to 
"Register for COM Interop" and added a strong name key file on the "Signing" 
tab.  The strong name key file is used for installing the dll inthe GAC.  You 
can create this using the "sn.exe" application included in the WinSDK 6.1.  
After writing my various classes, properties, and methods, I simply run the 
following ".bat" script.

regasm /unregister ABTradingNetCS.dll > unregister.txt
regasm ABTradingNetCS.dll > register.txt

gacutil /u ABTradingNetCS > gacutil_remove.txt
gacutil /i ABTradingNetCS.dll > gacutil_add.txt



The gacutil.exe is also provided with the WinSDK 6.1.  To make the path simple, 
I just copied the regasm and gacutil applications to my build folder.  

I use this COM lib to track order information, so I use a static object in 
order to maintain state.  With the COM componenets, you can only access one 
level into the object, so you cannot in AFL do something like 
Obj.SubObj.Property1 - instead you must get reference to SubObj to reference 
Property1.  Also, you cannot reference any static properties or methods from 
AFL.

Here is a sample of the AFL code.  

global xABT, xABBD, xABSD, xBD, xBDEOrder, xBDSLOrder, xBDTOrder, xSD, 
xSDEOrder, 
            xSDSLOrder, xSDTOrder, xOH, xContract, xChartSymData;


function SetChartDataObjects()
{
        xABT = CreateStaticObject("ABTradingNetCS.ABTrading");
        xChartSymData = xABT.GetChartSymbolData(Name());
        xContract = xABT.GetContract(Name());
        xBD = xChartSymData.BuyOrderData;
        xBDEOrder = xBD.OrderEntry;
        xBDSLOrder = xBD.OrderStoploss;
        xBDTOrder = xBD.OrderTarget;
        xSD = xChartSymData.SellOrderData;
        xSDEOrder = xSD.OrderEntry;
        xSDSLOrder = xSD.OrderStoploss;
        xSDTOrder = xSD.OrderTarget;

}

function TransmitOrders(orderSide)
{
    local xOD, xOE, xOSL, xOT, xOC, doXmit, ibc ;

    if ( ORderSide == 1 ) //buy side
        { xOD = xBD; xOE = xBDEOrder; xOSL = xBDSLOrder; xOT = xBDTOrder; }
    else //sell side
        { xOD = xSD; xOE = xSDEOrder; xOSL = xSDSLOrder; xOT = xSDTOrder; }

        ibc = GetTradingInterface( "IB" );

    // check if we are connected OK
    if (NOT xOD.OrderGroupSubmitted AND ibc.IsConnected() )
    {
        // check if we do not have already open position on this stock
        if ( ibc.GetPositionSize( Name() ) == 0 )
        {
                          xOD.OrderGroupSubmitted = True;

            doXmit = False;

            if ( NOT xOD.EnforceStopLossOrder  AND NOT xOD.EnforceTargetOrder )
            {
                doXmit = True AND xOD.TransmitGroupToBroker;
            }

            // transmit order
            xOE.OrderId = ibc.PlaceOrder( 
                                                                xOE.Symbol, 
xOE.Action, xOE.Quantity, xOE.Type, xOE.LimitPrice, xOE.StopPrice, 
xOE.IBDateTime, 
                                                                doXmit, 
xOE.TickSize, xOE.Attributes);

            if ( xOD.EnforceTargetOrder  || xOT.PriceOfOrderEntry() > 0 )
            {
                if ( NOT xOD.EnforceStopLossOrder AND NOT xOSL.UseThisOrderPart 
)
                    doXmit = True && xOD.TransmitGroupToBroker;

                xOT.OrderId = ibc.PlaceOrder( 
                                                                xOT.Symbol, 
xOT.Action, xOT.Quantity, xOT.Type, xOT.LimitPrice, xOT.StopPrice, 
xOT.IBDateTime, 
                                                                doXmit, 
xOT.TickSize, xOT.Attributes, xOE.OrderId, xOT.OcaGroup, xOT.OcaType );
            }

            if ( xOD.EnforceStopLossOrder || xOSL.PriceOfOrderEntry() > 0 )
            {
                doXmit = True && xOD.TransmitGroupToBroker;
                xOSL.OrderId = ibc.PlaceOrder( 
                                                                xOSL.Symbol, 
xOSL.Action, xOSL.Quantity, xOSL.Type, xOSL.LimitPrice, xOSL.StopPrice, 
xOSL.IBDateTime, 
                                                                doXmit, 
xOSL.TickSize, xOSL.Attributes, xOE.OrderId, xOSL.OcaGroup, xOSL.OcaType );

            }

            if ( xOD.AddCancelOrder )
            {
                                        xOC = xOD.OrderCancel;

                        xOC.OrderId = ibc.PlaceOrder( 
                                                                xOC.Symbol, 
xOC.Action, xOC.Quantity, xOC.Type, xOC.LimitPrice, xOC.StopPrice, 
xOC.IBDateTime, 
                                                                False, 
xOC.TickSize, xOC.Attributes);
            }
        }
    }
}





And here is some sample code for the C# for my contract data class.  Most of 
the code is removed to save space in the post.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class ABTradingContractData
    {
        private string _origSymbol; public string OrigSymbol { get { return 
_origSymbol; } set { _origSymbol = value; } }
        private string _orderSymbol; public string OrderSymbol { get { return 
_orderSymbol; } set { _orderSymbol = value; } }
        private string _exchange; public string Exchange { get { return 
_exchange; } set { _exchange = value; } }
        private string _currency; public string Currency { get { return 
_currency; } set { _currency = value; } }
        private string _type; public string Type { get { return _type; } set { 
_type = value; } }
        private string _currencyBase; public string CurrencyBase { get { return 
_currencyBase; } set { _currencyBase = value; } }
        private string _currencyCross; public string CurrencyCross { get { 
return _currencyCross; } set { _currencyCross = value; } }
        private double _decimalDisplay; public double DecimalDisplay { get { 
return _decimalDisplay; } set { _decimalDisplay = value; } }
        private bool _isForex = false; public bool IsForex { get { return 
_isForex; } set { _isForex = value; } }
        private bool _isFuture = false; public bool IsFuture { get { return 
_isFuture; } set { _isFuture = value; } }
        private double _tickSize = 0.01; public double TickSize { get { return 
_tickSize; } set { _tickSize = value; } }
       
        //forex values
        private string _forexCurrencySymbol; public string ForexCurrencySymbol 
{ get { return _forexCurrencySymbol; } set { _forexCurrencySymbol = value; } }
        private double _minSize; public double MinSize { get { return _minSize; 
} set { _minSize = value; } }
        private string _currencySymbol = ""; public string CurrencySymbol { get 
{ return _currencySymbol; } set { _currencySymbol = value; } }
        private string _lotCurrency = ""; public string LotCurrency { get { 
return _lotCurrency; } set { _lotCurrency = value; } }
        private double _lotSize = 0; public double LotSize { get { return 
_lotSize; } set { _lotSize = value; } }
        private double _lotPipValue = 0; public double LotPipValue { get { 
return _lotPipValue; } set { _lotPipValue = value; } }
        private double _decimalFactor = 0; public double DecimalFactor { get { 
return _decimalFactor; } set { _decimalFactor = value; } }


        public ABTradingContractData(string symbol)
        {
           //code to initalize exchange, currency, security type, and order 
symbol
        }

        public double GetFormattedPrice(double inputPrice )
        {
            double outputPrice = 0;

            if ( inputPrice > 0 )
            {
                outputPrice = inputPrice;

                if ( _isForex )
                {
                                  outputPrice = (double)((int)( inputPrice * 
_decimalFactor )) / _decimalFactor ;
                }
                else
                    {
                        //format price for stock
                        outputPrice = (double)((int)( inputPrice * 100 )) / 
100.0;
                    }
            }

            return outputPrice;
        }
    }
}


So if you don't like having to mess with GUIDs or Interopt Services, then here 
is another way to approach using COM with AB.  I have not tried it with the 
manual interface with Interopt Services, but using the GAC method here, I can 
actually step into the code and watch its excution in my VS project - although 
edit and continue is not available.

Regards,
Tom

Reply via email to