Category Archives: Code Snippet

Coding samples for various languages

TradeStation, Multicharts Example placing a Vwap order on an InteractiveBrokers account using IBPlugin

//-------------------------------------------------------------------------
// This signal demonstrates the use of IBPlugin to trade an IBKR account
// from within MultiCharts or TradeStation.
// The signal just connects to TWS/Gateway (watch port,IP)
// places a Vwap orders, waits 5 seconds and cancels this order
//-------------------------------------------------------------------------
// --- declare dll functions ---
external: "ibplugin.dll", int, "mtibTS_ON_CREATE", IEasyLanguageObject;

external: "ibplugin.dll", int, "mtibTS_ON_DESTROY", IEasyLanguageObject;


DefineDLLFunc: "ibplugin.DLL",int, "mtibINIT_SCRIPT_A",
                  LPSTR,{metatrader_identifier}
                  LPSTR,{expert_name}
                  int;{loglevel}


DefineDLLFunc: "ibplugin.DLL",int, "mtibDEINIT_SCRIPT";

DefineDLLFunc: "ibplugin.DLL",int, "mtibCONNECT_A",
                  int,{connid}
                  LPSTR,{ip}
                  int,{port}
                  int,{clientid}
                  int,{nbr_channels}
                  int;{timeout}
                  
DefineDLLFunc: "ibplugin.DLL",int, "mtibCONNECTION_STATUS",
                  int;{connid}
                  
                  
DefineDLLFunc: "ibplugin.DLL",int64, "mtibORDER_SEND_STR_A",
                  int,{connid}
                  int,{uidc}
                  int64,{uid}
                  LPSTR,{order_attrib_list}
                  int,{id_allocation}
                  int;{sync}

DefineDLLFunc: "ibplugin.DLL",int, "mtibORDER_DELETE",
                  int,{connid}
                  int64,{uid}
                  int;{sync}

DefineDLLFunc: "ibplugin.DLL",int, "mtibSLEEP",
                  int;{milliseconds}
                                    
Variables:
     conid_intel(270639),         {IBKR unique id for intel}
     port(7497),                 {API port of TWS or Gateway. Make sure API is on. Active X enabled, port same as here..}
     connection_id(1),             {ID of connection}
     order_attribute_str(""),    {list of attrib=value pairs as order attributes}
     algo_param_str(""),        {list of attrib=value pairs as algo param (Vwap is algo order)}
     uid_order(0),            {unique id of order}

     int_ret(0),                {int return value}
     Initialized(0);            {init flag flag}

{ DLL initialisation}

    {init the DLL }
if Initialized = 0  then begin

    //int_ret=mtibINIT_SCRIPT_A("multicharts","ibplugin_demo",3);
    Print("init=",int_ret);
    
    {connect to TWS / Gateway at standard port. make sure TWS or Gateway are setup to operate with API clients such as ibplugin  (http://www.youtube.com/watch?v=53tmypRq5wI)}
    mtibCONNECT_A(connection_id,"",port,1345,1,3000);
    
    // algo param pair sep char "|"    
    // algo param value assign char "~"
    // So an algo argument is defined by a string concatenation of id1~value1|id2~value2|id3~value3... and so on;how many attributes your algo requires


    // create the Vwap algo param string. The challenge: User need to figure out what parameters required for his algo order (https://interactivebrokers.github.io/tws-api/algos.html)
    algo_param_str="noTakeLiq~1"; // human say: noTakeLiq=1 (the ~ is used as assginment charactar within algo param definition)
    algo_param_str+="|speedUp~1";
    algo_param_str+="|allowPastEndTime~1";

    Print(    algo_param_str);    
    // order attrib pair sep char "#"
    // order attrib value assign char "="
    // So an order is defined by a string concatenation of id1=value1#id2=value2#id3=value3... and so on;how many attributes your order requires
    
    // create order attributes. The <algo_param_str> is such an attribute
    // the algo name (the 69 is the order attribute id.     
    order_attribute_str = "69=Vwap"; // algo name    
    // attribute separator and algo param id
    order_attribute_str += "#70=";
    order_attribute_str += algo_param_str;

    // action attribute    
    order_attribute_str += "#53=BUY";

    // type attribute    
    order_attribute_str += "#6=LMT";

    // exchange attribute    
    order_attribute_str += "#1007=SMART";

    // limit price attribute
    order_attribute_str += "#2=44.84";

    // outside RTH atribute (only false)
    order_attribute_str += "#14=0";

    // time in force attribute (only day accepted)
    order_attribute_str += "#5=DAY";

    // ordersize
    order_attribute_str += "#1=100";
    
    Print("connection status",mtibCONNECTION_STATUS(connection_id));
    
    Print(    order_attribute_str);
    { Finally place order }
    uid_order=mtibORDER_SEND_STR_A(connection_id,conid_intel, 0,     order_attribute_str,0,0);
    Print("uid=",    uid_order);

    // wait 5 seconds
    mtibSLEEP(5000);
    
    // cancel (delete) order async
    int_ret=mtibORDER_DELETE(connection_id,uid_order,0);
    Print("cancel ret=",    int_ret);
    
    Initialized=1;    
end;

#Events
    OnCreate =     mtibTS_ON_CREATE;
    OnDestroy = mtibTS_ON_DESTROY;
#end

Perl 5 x64 wrapper for TWSLink

Python 5 x64 wrapper for TWSLink along with Visual Studio wrapper solution and sample

  • 64 bit twslink2pl.dll and twslink2pl.pm included.
  • Visual Studion 2017 solution file included: This is to create your own twslink2 wrapper for other perl versions.
  • Includes also a small sample in the test folder of download.

 

When the TWSLink2 interfaces should change, which is unlikely, or a new Perl version is out which you want to use, you may want to have a new TWSLink2 wrapper,
so you can call TWSLink from within Perl. In order to build your own wrapper, you need some tools:

The Visual Studio project for this perl wrapper, assumes that swig is in c:\swig. Details about building the wrapper are in the readme.txt of download.

Note: With swig, Visual Studio and TWSLink2 wrapper cpp files (contained in download), you can build wrapper for ANY LANGUAGE contained in the swig world. Just watch the samples in the swig project, to get an idea and use the Perl wrapper Visual Studio project as draft.

View sample code

# --- including libs ---
# twslink module
use twslink2pl;
# module to modify console
#use Win32::Console;


# ----- Object creation -----
print "creating twslink wrapper:\n";
$tws = new twslink2pl::TWSLink2Wrap("",1);
#print "creating console:\n";
#$console = new Win32::Console;

#$tws->Load(true,"");
my $stime=gmtime();
print "start time=$stime\n";

print "Connecting . . . \n" ;
$status = $tws->CONNECT("127.0.0.1",7496,1,6000) ;
print "Connected=$status\n";
# register a stock; wait at the most 5 seconds until contract has been accpeted by tws


print "Register MSFT\n";
my $uidMSFT = $tws->REGISTER_CONTRACT("MSFT","STK","USD","NASDAQ","","","",0.0,"",0,0.0) ;
print "uid MSFT=$uidMSFT\n";

print "Place buy market 100 MSFT\n";
my $uidOrderMSFT = $tws->PLACE_ORDER($uidMSFT,0,"BUY","MKT",100,0.0,0.0,"GTC",1,0) ;
print "uid order MSFT=$uidOrderMSFT\n";
$tws->WAIT_FOR_FILLED($uidOrderMSFT,20000);

[ddownload id=”1869″ style=”link” text=”Download TWSLink Perl 5 x64 wrapper”]

MatLab script for TWSLink

A new short example for using TWSLink with the actual version of MatLab (MatLab 2017a) is available.

The old example may not compiled in current MatLab script editor as the header declaration for TWSLink exported function was not compatible. This has been changed. So the new example comes with modified headers and a minimal example how to load TWSLink, connect, register and place a trade.

Please use the example as follows:

  1. Make sure TWSLink is installed ([ddownload id=”281″ style=”link” text=”TWSLink setup”])
  2. Download MatLab example and unzip in a folder of your choice.
  3. Open MatLab (tested with MatLab 2017a).
  4. In the script editor open twslink.m file from MatLab example folder.
  5. Run the script. You might get asked to add this folder to path or to change folder for execution. Select “Change Folder“.

[ddownload id=”413″ style=”link” text=”Download MatLab example”]

 

% load twslink dll
loadlibrary('twslink2.dll','twslinkimp.h','alias','twslink');

% uid of contract
uid=0;
% uid of order
uid_order=0;

% register EUR.USD CASH 
uid = calllib('twslink', 'REGISTER_CONTRACT','EUR','CASH','USD','IDEALPRO','','','',0.0,'',0,0.0);

% connect to API (running TWS or gateway)
calllib('twslink', 'CONNECT','127.0.0.1',7496,1,10000);

% SEL 25.000 EUR.USD CASH
uid_order=calllib('twslink', 'PLACE_ORDER',uid,0,'SELL','MKT',25000,0.0,0.0,'GTC',1,0);

% unload twslink
unloadlibrary('twslink');

 

 

 

 

MQL Code Snippet for random number generation

This post is a suggestion how to generate an integer random number with the same randomness as the market itself. It is assumed, that market data series are more or less random. The function suggested below can be used in MetaTrader 4/5 Expert Advisors,Scripts or Indicators. The trick is simple: Just build the sum over a series of bars of the past, like:

s=sum(n,close-open)

 

, where n is the # of bars. Then divide the sum by minimal price movement to get a number which can be converted to an integer. Now scale this integer sum down buy the module of random number range.

s = s mod range

That’s it. This random number has the same distribution as the market itself (scaled to its range).

        

Function Code:

int random_int(MqlRates& rates[], double symbol_point,int range=2, bool use_tickcount=true)
{
     if(range > 0)
     {
        int len=ArraySize(rates);
        if(len > 0)
        {
           double bar_sum=0.0;
           for(int i=0;i < len;++i)
               bar_sum +=(rates[i].high - rates[i].low + MathAbs(rates[i].close - rates[i].open));
           // bar_sum has the same randomness as the market
           
           // make it integer convertable
           bar_sum /= symbol_point;
                      
           // add tickcount, to put random behaviour on backtest (where always the same rates selected)
           if(use_tickcount == true)
               bar_sum += GetTickCount();
               
           // scale random number to range
           int rnd=((int) bar_sum % range);
           
           //PrintFormat("rnd=%d bs=%.2f tc=%d dt=%s",rnd,bar_sum,GetTickCount(),TimeToStr(__rates_dyn[0].time));
           return rnd;
        }
     }
     return 0;
}

An application could be be to create random buy/sell orders for test purpose.

void test_random(void)
{
   int rnd=00;
   string sb_sequence;
   double point;
   MqlRates         rates_array[];
   
   // get point for symbol
   SymbolInfoDouble(_Symbol,SYMBOL_POINT,point);

   // make 100 random runs
   for(int i=0;i < 100;++i)
   {
      // get 10 bars in the past, with a moving offset 
      // (the order is not importent here)
      if(CopyRates(_Symbol ,PERIOD_CURRENT,i,10,rates_array) > 0)
      {
         // get a random number 0 or 1.
         // 0=OP_BUY,1=OP_SELL
         rnd=random_int(rates_array,point, 2,false);
         if(rnd == OP_BUY)
            sb_sequence += " buy";
         else
            sb_sequence += " sell";
            
      }
   }
   
   // print out sequence to Experts log
   Print(sb_sequence);
}