Wednesday, November 5, 2008

Call C++ Open MP from C# code



static OMPCommon.TestCallback cb = new OMPCommon.TestCallback(Test);
static void Main(string[] args)
{
OMPCommon.Helper.UseOMP(cb);
Console.ReadLine();
}
static void Test(int i)
{
Console.WriteLine(i);
Thread.Sleep(5000);
}

// Set VS2008 C++ project Properties -->Configure --> C/C++ Language --> Support OpenMP
#include <omp.h>
#pragma once

using namespace System;

namespace OMPCommon {


public delegate void TestCallback(int i);
public ref class Helper
{
public:
static void UseOMP(TestCallback^ cb)
{
omp_set_num_threads(10);
#pragma omp parallel for
for (int i=0;i<20; i++)
{
cb(i);
}
}
};
}



Convert System.String to bstr



GMOBlotter::GMOBlotter(String^ TraderName, String^ TraderPassword, String^ XIPDBServer)
{
::bstr_t trader, pwd, server;
trader.Attach(static_cast(System::Runtime::InteropServices::Marshal::StringToBSTR(TraderName).ToPointer()));
pwd.Attach(static_cast(System::Runtime::InteropServices::Marshal::StringToBSTR(TraderPassword).ToPointer()));
server.Attach(static_cast(System::Runtime::InteropServices::Marshal::StringToBSTR(XIPDBServer).ToPointer()));
::MxEnumReturnCode ret;
ret=pMxgXOM->Login(trader, pwd, server, L"GMO_INTRADAY",::MxeEncryptionMethodNone);
};

Wednesday, October 15, 2008

VBS for NT services installation


Install/Uninstall by Name:

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colListOfServices = objWMIService.ExecQuery _
("SELECT * FROM Win32_Service WHERE Name = 'IA DB Logging'")
For Each objService in colListOfServices
objService.StopService()
objService.Delete()
Next

Install by source exe
DIM objShell
set objShell = wscript.createObject("wscript.shell")
iReturn = objShell.Run("C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\installUtil IACalcDaemon.exe")

Friday, October 10, 2008

C++ code for XIP Allocation


#import "C:\Program Files\Macgregor\XIP\Common\XIP\TypeLibs\MxXOM.tlb" no_namespace named_guids
#import "C:\Program Files\Macgregor\XIP\Common\XIP\TypeLibs\Xip.tlb" no_namespace named_guids exclude("_IMxXOMEvents","IMxComponentInfo","MxEnumMsgCode","MxEnumObjectType","MxEnumReturnCode","MxEnumBoolean","MxEnumXOMAction","MxEnumRefreshEventType")
#import "C:\Program Files\Macgregor\XIP\Common\XIP\TypeLibs\MxOrderGenerator.tlb" no_namespace named_guids exclude("_IMxXOMEvents","IMxComponentInfo","MxEnumMsgCode","MxEnumObjectType","MxEnumReturnCode","MxEnumBoolean","MxEnumXOMAction","MxEnumRefreshEventType","MxEnumEncryptionMethod","IMxComponentInfo_701")

IMxgXOMPtr pMxgXOM(__uuidof(MxgXOM));

GMOBlotter::GMOBlotter(String^ TraderName, String^ TraderPassword, String^ XIPDBServer)
{
::bstr_t trader, pwd, server;
trader.Attach(static_cast(System::Runtime::InteropServices::Marshal::StringToBSTR(TraderName).ToPointer()));
pwd.Attach(static_cast(System::Runtime::InteropServices::Marshal::StringToBSTR(TraderPassword).ToPointer()));
server.Attach(static_cast(System::Runtime::InteropServices::Marshal::StringToBSTR(XIPDBServer).ToPointer()));
::MxEnumReturnCode ret;
ret=pMxgXOM->Login(trader, pwd, server, L"GMO_INTRADAY",::MxeEncryptionMethodNone);
};

int GMOBlotter::Recalc(int TickNum)
{
::MxEnumReturnCode ret;
::HRESULT h;
IMxXOMAcctsAllocPtr pAcctsAlloc;
::CoInitialize(NULL);

try
{

IDispatchPtr pDis =pMxgXOM->GetCollection(L"TradeOrders");
IMxXOMOrdersPtr pOrd=NULL;
h=pDis->QueryInterface(::IID_IMxXOMOrders,(void **) &pOrd);
IMxXOMOrder3Ptr pTOrd;
VARIANT* v= new VARIANT();
h=pOrd->Item(TickNum,v);
v->pdispVal->QueryInterface(::IID_IMxXOMOrder2,(void**) &pTOrd);


h=pTOrd->GetAcctsAlloc()->QueryInterface(::IID_IMxXOMAcctsAlloc,(void**) &pAcctsAlloc);

ret=pAcctsAlloc->BeginProcessing();
// ret=pAcctsAlloc->Recalc();
pAcctsAlloc->raw_BeginProcessing(&ret);
h=pAcctsAlloc->raw_Recalc(&ret);
if (ret!=::MxeOK)
String^ error="Error";

}
catch (System::Runtime::InteropServices::COMException^ cex)
{
String^ err="";
return -1;
}
catch (...)
{
String^ err="";
return -1;
}
finally
{
pAcctsAlloc->raw_EndProcessing(::MxeProcessActionSave,&ret);
// ret=pAcctsAlloc->EndProcessing(::MxeProcessActionSave);
}
if (ret!=::MxeOK) return -1;
return 0;
};

Thursday, September 11, 2008

TFS Branching and Merging draft Guideline


Branch and Merge is a core concept in TFS to facilate Source Control and release
management. There are various approach to these topics. But here are brain-dump
while encountering practical issues using TFS ( Team Fundation server).

(1) Agile Development Directory Structure representing Team, products, solutions,
major branch

Trading System
CRD
XIP
GMO.XIP
Branches
2008
2009
Trunk


(2) Each branch represent a weekly release version. and Trunk should not be released.
This will allows us to support different usage of XIP solution for different
business cases and still support common core.
If CMMI are used, then the structure could be based on version number not related to Dates

(3) For non-release related feature (eg. new helper function or bug fixes), a
feature branches should be used for the changes. In other words, Trunk can only be
changed through merge back from branches.

(4) Branching should be off Tip Revision (Latest Version), rather than a label since TFS needs
to duplicated files on branching and we have to use duplicated directory structure, which in
itself already acts like Label.

Wednesday, August 13, 2008

Use reflection to dump properies

 For debugging purposes, we can use the following reflection based code:

public static string DumpOrderBean(OrderBean ob)
{

PropertyInfo[] pi = typeof(OrderBean).GetProperties();
StringBuilder sb= new StringBuilder();
foreach (PropertyInfo p in pi)
{
if (p.Name.IndexOf("Bean")<0)
sb.Append(p.Name +" :"+ p.GetValue(ob, null)+"\r\n");
}
StreamWriter w= new StreamWriter(@"c:\JGBRollTestOB.txt");
w.Write(sb.ToString()); w.Flush();

OrderAllocationBean oa = ob.allocationBeans[0];
PropertyInfo[] pi2 = typeof(OrderAllocationBean).GetProperties();
StringBuilder sb2 = new StringBuilder();
foreach (PropertyInfo p2 in pi2)
{
if (p2.Name.IndexOf("Bean") < 0)
sb2.Append(p2.Name + ":" + p2.GetValue(oa, null) + "\r\n");
}
StreamWriter w2 = new StreamWriter(@"c:\JGBRollTestOAB.txt");
w2.Write(sb2.ToString()); w2.Flush();
return sb.ToString();
}


Friday, August 1, 2008

Constrain SQL like pattern for Commission Rate lookup


SQL Like allow pattern match but normally return multiple rows. If you have one
commision rate for a pattern, carefully specified pattern will allow look up to
return just one value without the ambiguity as shown here:
FSMI% vs. FSMIU%

In general, we need to consider the following:

(1) Clearly define Bloomberg symbol as 2 charaters key and Add GMO prefix to
generate external security id pattern. (GMO_EXT_SEC_ID_PATN_DEF).
In particular, Commission Rate table GMO_BROKER_COMM need to have Foreign key
constraints from GMO_EXT_SEC_ID_PATN_DEF to avoid invalid security.

(2) GMO_BROKER_COMM need to have a trigger constraint to make sure the following
will not return more than one row:
select * from GMO_BROKER_COMM2 where
(EXT_SEC_ID_PATN like @EXT_SEC_ID_PATN or
@EXT_SEC_ID_PATN like EXT_SEC_ID_PATN)

in particular, if we need to have both FSMI% and FSMIU%, we will need to span out
even with duplcation rates:
FSMIH% 2.95
FSMIG% 2.95
FSMIZ% 2.95

FSMIU% 4.95

This will eliminate ambiguity.

(3) We need [BB_SYMBOL] [char](2) NOT NULL to keep space for Bloomberg symbol
and that will avoid some ambiguity like FBC % vs. FBCC%

(4) FBC % vs. FBC%
FB C -- SET50 FUTURES maps to FBC %
F BC -- CORN FUTURE maps to FBC%
we currenlty do not have commission rate for FBC %. But we need to be
careful when enter rates in the future

(5) The following is the SQL used in Mid-Tier:
select * from GMO_BROKER_COMM where @ext_sec_id like EXT_SEC_ID_PATN