UIABsocket.pas


unit UIABsocket; 
 
interface 
 
uses 
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
  ScktComp, StdCtrls, ExtCtrls, Shellapi, IABSocketAPI, Menus; 
 
type 
  TFIABSocket = class(TForm) 
    Button1: TButton; 
    Button2: TButton; 
    IABSocket1: TIABSocket; 
    EditP: TEdit; 
    MemoAcct: TMemo; 
    Button3: TButton; 
    Button4: TButton; 
    Button5: TButton; 
    labelbid: TLabel; 
    labelbidsize: TLabel; 
    labelask: TLabel; 
    labelasksize: TLabel; 
    MemoError: TMemo; 
    Button7: TButton; 
    ListBoxOrderType: TListBox; 
    RBBuy: TRadioButton; 
    RBSell: TRadioButton; 
    EditV: TEdit; 
    MemoOrderStat: TMemo; 
    LabelVol: TLabel; 
    LabelLast: TLabel; 
    LabelSize: TLabel; 
    EditA: TEdit; 
    EditSym: TEdit; 
    Bevel1: TBevel; 
    Bevel2: TBevel; 
    Bevel3: TBevel; 
    Label1: TLabel; 
    Label3: TLabel; 
    Label4: TLabel; 
    Button6: TButton; 
    EditExch: TEdit; 
    ComboSecType: TComboBox; 
    Button8: TButton; 
    Button9: TButton; 
    EditExp: TEdit; 
    procedure Button1Click(Sender: TObject); 
    procedure Button2Click(Sender: TObject); 
    procedure IABSocket1Error(Sender: TObject; TempId, ErrorCode: Integer;  ErrorMsg: String); 
    procedure Button3Click(Sender: TObject); 
    procedure Button4Click(Sender: TObject); 
    procedure Button5Click(Sender: TObject); 
    procedure IABSocket1TickPrice(Sender: TObject; DataId: Integer; TickType: TIABTickType; Price: Double); 
    procedure IABSocket1TickSize(Sender: TObject; DataId: Integer; TickType: TIABTickType; Size: Integer); 
    procedure Button7Click(Sender: TObject); 
    procedure IABSocket1OpenOrder(Sender: TObject; TempId: Integer; Order: TIABOrder); 
    procedure IABSocket1AccountTime(Sender: TObject; TimeStamp: String); 
    procedure IABSocket1AccountValue(Sender: TObject; Index: Integer); 
    procedure IABSocket1PortfolioUpdate(Sender: TObject; Index: Integer); 
    procedure FormCreate(Sender: TObject); 
    procedure Button9Click(Sender: TObject); 
    procedure IABSocket1OrderStatus(Sender: TObject; Order: TIABOrder; Status: TIABOrderState); 
    procedure Label4Click(Sender: TObject); 
    procedure IABSocket1ConnectionState(Sender: TObject; State: TIABConnection); 
    procedure Button6Click(Sender: TObject); 
    procedure IABSocket1InstrumentSpecDetails(Sender: TObject; Index: Integer); 
    procedure Button8Click(Sender: TObject); 
    procedure IABSocket1Execution(Sender: TObject; Order: TIABOrder); 
    procedure IABSocket1MarketDepth(Sender: TObject; DataId, Index, Operation, Side, Size: Integer; Price: Double); 
    procedure IABSocket1MarketLevel2(Sender: TObject; DataId, Index, Operation, Side, Size: Integer; Price: Double; MMId: String); 
  private 
  public 
    MDataId: Integer; 
  end; 
 
var 
  FIABSocket: TFIABSocket; 
 
implementation 
 
uses UDepth; 
 
{$R *.DFM} 
 
procedure TFIABSocket.Button1Click(Sender: TObject); 
begin 
  IABSocket1.Connected := true; 
end; 
 
procedure TFIABSocket.Button2Click(Sender: TObject); 
begin 
  if EditA.Text <> 'Aux' then IABSocket1.DefOrder.AuxPrice := StrToFloat(EditA.Text); 
 
  IABSocket1.DefOrder.Quantity := StrToInt(EditV.Text); 
  IABSocket1.DefOrder.Price := StrToFloat(EditP.Text); 
  IABSocket1.DefOrder.Symbol := EditSym.Text; 
  IABSocket1.DefOrder.Exchange := EditExch.Text; 
  IABSocket1.DefOrder.Expiry := EditExp.Text; 
  IABSocket1.DefOrder.SecurityType := TIABSecurityType(ComboSecType.ItemIndex); 
 
 
  if RBBuy.Checked then IABSocket1.DefOrder.Action := iabBuy else IABSocket1.DefOrder.Action := iabSell; 
  IABSocket1.DefOrder.OrderType := TIABOrderType(ListBoxOrderType.ItemIndex + 1); 
  IABSocket1.PlaceOrder(IABSocket1.DefOrder); 
 
//  Here we sent the DefOrder, but you could of created a new TIABOrder and sent it. 
 
end; 
 
procedure TFIABSocket.IABSocket1Error(Sender: TObject; TempId, ErrorCode: Integer; ErrorMsg: String); 
begin 
  MemoError.Lines.Insert(0,IntToStr(TempId) + ' ' + IntToStr(ErrorCode) + ' ' + ErrorMsg); 
end; 
 
procedure TFIABSocket.Button3Click(Sender: TObject); 
begin 
  IABSocket1.GetExecutions; 
end; 
 
procedure TFIABSocket.Button4Click(Sender: TObject); 
begin 
  IABSocket1.GetAccountUpdates; 
end; 
 
procedure TFIABSocket.IABSocket1AccountValue(Sender: TObject; Index: Integer); 
begin 
  MemoAcct.Lines.Insert(0,IABSocket1.AccountValues[Index]); 
end; 
 
procedure TFIABSocket.Button5Click(Sender: TObject); 
begin 
  if EditA.Text <> 'Aux' then IABSocket1.DefOrder.AuxPrice := StrToFloat(EditA.Text); 
 
  IABSocket1.DefOrder.Quantity := StrToInt(EditV.Text); 
  IABSocket1.DefOrder.Price := StrToFloat(EditP.Text); 
  IABSocket1.DefOrder.Symbol := EditSym.Text; 
  IABSocket1.DefOrder.Exchange := EditExch.Text; 
  IABSocket1.DefOrder.Expiry := EditExp.Text; 
  IABSocket1.DefOrder.SecurityType := TIABSecurityType(ComboSecType.ItemIndex); 
 
  if MDataId > 500 then IABSocket1.CancelMarketData(MDataId -1); 
  IABSocket1.GetMarketData(MDataId,IABSocket1.DefOrder); 
  inc(MDataId); 
end; 
 
procedure TFIABSocket.IABSocket1TickPrice(Sender: TObject; DataId: Integer; 
  TickType: TIABTickType; Price: Double); 
begin 
  if TickType = ttBid then LabelBid.caption := FormatFloat('0.00',Price); 
  if TickType = ttAsk then LabelAsk.caption := FormatFloat('0.00',Price); 
  if TickType = ttLast then LabelLast.caption := FormatFloat('0.00',Price); 
end; 
 
procedure TFIABSocket.IABSocket1TickSize(Sender: TObject; DataId: Integer; 
  TickType: TIABTickType; Size: Integer); 
begin 
  if TickType = ttBidSize then Labelbidsize.caption := IntToStr(Size); 
  if TickType = ttAskSize then Labelasksize.caption := IntToStr(Size); 
  if TickType = ttLastSize then LabelSize.caption := IntToStr(Size); 
  if TickType = ttVolume then LabelVol.caption := IntToStr(Size); 
end; 
 
procedure TFIABSocket.Button7Click(Sender: TObject); 
begin 
  IABSocket1.GetOpenOrders; 
end; 
 
procedure TFIABSocket.IABSocket1OpenOrder(Sender: TObject; TempId: Integer; Order: TIABOrder); 
begin 
  MemoAcct.Lines.Insert(0,'OpenOrder ' + IntToStr(TempId) + ' ' + Order.Symbol + ' ' + IntToStr(Order.Quantity)); 
end; 
 
procedure TFIABSocket.IABSocket1AccountTime(Sender: TObject; TimeStamp: String); 
begin 
  MemoAcct.Lines.Insert(0,'TimeStamp ' + TimeStamp); 
end; 
 
procedure TFIABSocket.IABSocket1PortfolioUpdate(Sender: TObject; Index: Integer); 
begin 
  MemoAcct.Lines.Insert(0,IABSocket1.Portfolio[Index].Symbol + ' ' + IntToStr(IABSocket1.Portfolio[Index].Position)); 
end; 
 
procedure TFIABSocket.FormCreate(Sender: TObject); 
begin 
  ListBoxOrderType.Items.Add('MKT'); 
  ListBoxOrderType.Items.Add('LMT'); 
  ListBoxOrderType.Items.Add('STP'); 
  ListBoxOrderType.Items.Add('STPLMT'); 
  ListBoxOrderType.Items.Add('REL'); 
  ListBoxOrderType.Items.Add('VWAP'); 
  ListBoxOrderType.Items.Add('MOC'); 
  ListBoxOrderType.Items.Add('LMTCLS'); 
  ListBoxOrderType.Items.Add('TRAIL'); 
  ListBoxOrderType.ItemIndex := 0; 
  ComboSecType.ItemIndex := 2; 
  EditP.Text := '0' + DecimalSeparator + '00'; 
  EditExp.Text := GetIndexFutureExpiry; 
  MDataId := 500; 
end; 
 
procedure TFIABSocket.Button9Click(Sender: TObject); 
begin 
  if IABSocket1.Orders.Count > 0 then IABSocket1.CancelOrder(IABSocket1.Orders[IABSocket1.Orders.Count -1].TempId); 
end; 
 
procedure TFIABSocket.IABSocket1OrderStatus(Sender: TObject; Order: TIABOrder; Status: TIABOrderState); 
var s: string; 
begin 
  case Status of 
   osPendSubmit: s := 'pendsub'; 
   osPendCancel: s := 'pendcnl'; 
   osPreSubmit: s := 'presub'; 
   osSubmitted: s := 'submtd'; 
   osCancelled: s := 'cncld'; 
   osFilled: s := 'filld'; 
  end; 
  MemoOrderStat.Lines.Insert(0,'tId=' + IntToStr(Order.TempId) + ' pId=' + IntToStr(Order.permid) + ' f=' + IntToStr(Order.Filled) + ' r=' + IntToStr(Order.Remaining) + ' stat=' + s + ' p=' + FloatToStr(Order.FillPrice)); 
  MemoOrderStat.Lines.Objects[0] := TObject(Order.TempId); 
 
//    + ' ' + IntToStr(Order.LatestFillQty) + ' ' + IntToStr(Ord(Order.Changed)) + ' ' +  FloatToStr(Order.LatestFillPrice)); 
 
 
//  ** NOTE ** 
//  Use the properties of the Order parameter above, to determine the fill status of an order. 
//  You cannot rely on the status of an order to determine its fill. 
//  The TWS will fill orders under almost any status!  Particularly if its a partial fill. 
// 
//  Also new OnExecution in API 7 reports same as the Changed property and the OnFill event. 
//  Several ways to get the executions. 
//  Not certain if the sequence of Events is reliable?  (Onexecution first,  then Onstatus event) 
end; 
 
procedure TFIABSocket.IABSocket1ConnectionState(Sender: TObject; State: TIABConnection); 
begin 
  case State of 
    twsClosed: MemoError.Lines.Insert(0,'TWS connection closed'); 
    twsConnecting: MemoError.Lines.Insert(0,'Connecting to TWS'); 
    twsReady: MemoError.Lines.Insert(0,'TWS connection Ready'); 
    twsFailed: MemoError.Lines.Insert(0,'TWS connection Failed'); 
  end; 
end; 
 
function ShellExecAndWait32(Wait: Boolean;Directory, FileName, CmdParams:string; Visibility: Word; AppHwnd: HWND):Boolean; 
var Hinst: Longword; 
begin 
  Hinst := ShellExecute(AppHwnd,'open',PChar(FileName),PChar(CmdParams),PChar(Directory),Visibility); 
  Result := Hinst > 32; 
  if Result and Wait then WaitforSingleObject(Hinst,INFINITE); 
end; 
 
procedure TFIABSocket.Label4Click(Sender: TObject); 
begin 
  ShellExecAndWait32(false,'','http://www.v-planner.com/iabsocketapi/','',SW_SHOWNORMAL,Application.Handle); 
end; 
 
procedure TFIABSocket.Button6Click(Sender: TObject); 
begin 
  if EditA.Text <> 'Aux' then IABSocket1.DefOrder.AuxPrice := StrToFloat(EditA.Text); 
 
  IABSocket1.DefOrder.Quantity := StrToInt(EditV.Text); 
  IABSocket1.DefOrder.Price := StrToFloat(EditP.Text); 
  IABSocket1.DefOrder.Symbol := EditSym.Text; 
  IABSocket1.DefOrder.Exchange := EditExch.Text; 
  IABSocket1.DefOrder.Expiry := EditExp.Text; 
  IABSocket1.DefOrder.SecurityType := TIABSecurityType(ComboSecType.ItemIndex); 
 
  IABSocket1.GetInstrumentSpecs(IABSocket1.DefOrder); 
end; 
 
procedure TFIABSocket.IABSocket1InstrumentSpecDetails(Sender: TObject; Index: Integer); 
var s: string; ot: TIABOrderType; 
begin 
  with IABSocket1.InstrumentSpecs[Index] do 
    begin 
      s := MarketName + ' ' + TradingClass + ' ' + IntToStr(ContractId) + ' ' + Multiplier + ' ' + FloatToStr(MinimumTick); 
      for ot := Low(TIABOrderType) to High(TIABOrderType) do 
        if (ot in OrderTypes) then s := s + ' ' + OrderTypeTostr(ot); 
      s := s + ' ' + ValidExchanges; 
    end; 
  MemoAcct.Lines.Insert(0,s); 
end; 
 
procedure TFIABSocket.Button8Click(Sender: TObject); 
begin 
  FDepth.Show; 
end; 
 
procedure TFIABSocket.IABSocket1Execution(Sender: TObject; Order: TIABOrder); 
var LastExec: TIABExecution; s: string; 
begin 
  LastExec := Order.Executions[Order.ExecutionsCount -1]; 
  with LastExec do 
    s := 'e=' + ExecutionId + ' pId=' + IntToStr(PermId) + ' t=' + Time + ' act=' + AcctNumber + ' ' + Exchange + ' ' +  IntToStr(Ord(Side)) + ' ' + IntToStr(Volume) + ' ' + FloatToStr(Price); 
  MemoOrderStat.Lines.Insert(0,s); 
end; 
 
procedure TFIABSocket.IABSocket1MarketDepth(Sender: TObject; DataId, Index, Operation, Side, Size: Integer; Price: Double); 
begin 
  FDepth.AmendGrid(Index,Operation,Side,Size,Price,''); 
end; 
 
procedure TFIABSocket.IABSocket1MarketLevel2(Sender: TObject; DataId, Index, Operation, Side, Size: Integer; Price: Double; MMId: String); 
begin 
  FDepth.AmendGrid(Index,Operation,Side,Size,Price,MMId); 
end; 

end.