Pages - Menu

標籤

AWS (1) bash (1) Boost (2) C (2) CMake (2) Concurrency_Programming (3) CPP (37) Database (2) DNS (1) Docker (4) Docker-Compose (1) ELK (1) emacs (4) gcp (1) gdrive (1) git (1) gitbash (2) gitlab (1) kvm (4) Linux (5) MT4 (4) MT5 (4) Multicast (2) MySQL (2) Nijatrader8 (1) OpenCV (1) Python (4) QT5 (1) R (1) rdp (3) screenshot (1) ssh (3) Tabnine (1) TCP (1) TensorFlow (1) Tools (12) Ubuntu_1904 (11) Ubuntu_20_04 (5) UDP (1) VS2010 (1) VS2015 (1) VS2019 (1) WebServer (1) Win10 (1) winmerge (1) WSL (1) xrdp (1)

搜尋此網誌

2020年4月30日星期四

DailyTimer for function callback for Linux

Aim

This class will callback the specific function once a day. This is a Linux version. Using Linux mutex and file system.

Source



#include <iostream>
#include <thread>

#include "DailyTimer.h"
#include "NLTimeUTC.h"
class FooClass
{
public:
    FooClass() {}
    ~FooClass() {}

    static void PrintProxy(void *p, int x)
    {
        FooClass *c = (FooClass*)p;
        c->Print(x);
    }
    void Print(int x)
    {
        std::cout << "Print from class " << x << std::endl;
    }
};
void Foo(int x)
{
    std::cout << "Print from otuside " << x << std::endl;
}
void NormalCase()
{
    NLTimeUTC curTime;
    DailyTimer timer(curTime, Foo, 10);
    timer.Start();
    int count = 0;
    while (count++ < 5)
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    timer.Stop();
}
void ClassCase()
{
    FooClass cc;
    NLTimeUTC curTime;
    DailyTimer timer(curTime, FooClass::PrintProxy, &cc, 10);
    timer.Start();
    int count = 0;
    while (count++ < 5)
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    timer.Stop();
}
int main(int argc , char *argv[])
{
    NormalCase();
    ClassCase();

    return 0;
}

MSecTimer for function callback for Linux

Aim

This timer class will count for a MSec duration and do the callback to a function with arguments.

Source

github

#include <iostream>
#include <thread>
#include <chrono>

#include "MSecTimer.h"

class FooClass
{
public:
    FooClass() {}
    ~FooClass() {}

    static void PrintProxy(void *p, int x)
    {
        FooClass *c = (FooClass*)p;
        c->Print(x);
    }
    void Print(int x)
    {
        std::cout << "Print from class " << x << std::endl;
    }
};
void Foo(int x)
{
    std::cout << "Print from otuside " << x << std::endl;
}
void NormalCase()
{
    MSecTimer timer(1000, Foo, 10);
    timer.Start();
    int count = 0;
    while (count++ < 5)
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    timer.Stop();
}
void ClassCase()
{
    FooClass cc;
    MSecTimer timer(1000, FooClass::PrintProxy, &cc, 10);
    timer.Start();
    int count = 0;
    while (count++ < 5)
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    timer.Stop();
}
int main(int argc, char *argv[])
{
    NormalCase();
    ClassCase();

    return 0;
}

Output


$ ./src/MSecTimer 
Print from otuside 10
Print from otuside 10
Print from otuside 10
Print from otuside 10
Print from class 10
Print from class 10
Print from class 10
Print from class 10

A class that handle time in a rough way for Linux

Aim

This class is a simple handler for time. You can do time adding, comparing. It works on Linux. It can get current time in debug mode and normal mode. In a trading strategy backtesting process, you may use the debug mode to get a current time.

Source



#include <iostream>
#include <thread>
#include <chrono>

#include "NLTimeUTC.h"

// usage: ./NLTimeUTC
void NormalUseCase()
{
    std::cout << __FUNCTION__ << "-----------------" << std::endl;
    {
        NLTimeUTC time;
        std::cout << time.ToString() << std::endl;
    }
    std::this_thread::sleep_for(std::chrono::seconds(1));
    {
        NLTimeUTC time;
        std::cout << time.ToString() << std::endl;
    }
}
void DebugUseCase_TickTick()
{
    {
        NLTimeUTC time;
        std::cout << time.ToString() << std::endl;
    }
    if (TSCLOCK_IS_DEBUG())
        TSCLOCK_ADD_SEC(1);
    else
        std::this_thread::sleep_for(std::chrono::seconds(1));
    {
        NLTimeUTC time;
        std::cout << time.ToString() << std::endl;
    }
}
void DebugUseCase()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-----------------" << std::endl;
    std::cout << "Is debug: " << TSCLOCK_IS_DEBUG() << std::endl;
    DebugUseCase_TickTick();

    TSCLOCK_SET_DEBUG(true);
    std::cout << "Is debug: " << TSCLOCK_IS_DEBUG() << std::endl;
    TSCLOCK_SET_CLOCK_DATE(2020, 3, 23, 3, 32, 40);
    DebugUseCase_TickTick();
}
int main(int argc, char *argv[])
{
    NormalUseCase();
    DebugUseCase();
    return 0;
}

Output

$ ./src/NLTimeUTC 
NormalUseCase-----------------
2020-05-01 03:43:15
2020-05-01 03:43:16

DebugUseCase-----------------
Is debug: 0
2020-05-01 03:43:16
2020-05-01 03:43:17
Is debug: 1
2020-03-23 03:32:40
2020-03-23 03:32:41

A Clock for trading strategy backtest for Linux

Aim

One may want to simulate a clock during a trading strategy backtest. With this class, one may select if this is a debug period, enable and disable to tune the clock. This class support multi-threading. This class on linux.

Source



#include <iostream>

#include "NLClock.h"

void StartStopDebug()
{
    std::cout << __FUNCTION__ << "-------------" << std::endl;
    std::cout << TSCLOCK_IS_DEBUG() << std::endl;
    TSCLOCK_SET_DEBUG(true);
    std::cout << TSCLOCK_IS_DEBUG() << std::endl;
    TSCLOCK_SET_DEBUG(false);
    std::cout << TSCLOCK_IS_DEBUG() << std::endl;
}
void SetClock()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------" << std::endl;
    TSCLOCK_SET_CLOCK_DATE(2020, 3, 20, 1, 20, 34);
    std::cout << TSCLOCK_GET_TIME_STRING() << std::endl;
}
void AddSecExample()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------" << std::endl;
    TSCLOCK_SET_CLOCK_DATE(2020, 3, 20, 1, 20, 34);
    std::cout << "Set clock: " << TSCLOCK_GET_TIME_STRING() << std::endl;
    TSCLOCK_ADD_SEC(1); // fail to add sec since currently is not be able to tune
    std::cout << "Fail example: " << TSCLOCK_GET_TIME_STRING() << std::endl;

    TSCLOCK_SET_ENABLE_TO_TUNE(true);
    TSCLOCK_ADD_SEC(1); // able to tune
    std::cout << "Success example: " << TSCLOCK_GET_TIME_STRING() << std::endl;
}
void AddSecExampleAdvance()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------" << std::endl;
    TSCLOCK_SET_CLOCK_DATE(2020, 3, 20, 1, 20, 34);
    std::cout << "Set clock: " << TSCLOCK_GET_TIME_STRING() << std::endl;
    // we may have different threads to share the same clock while backtesting a trading strategy
    // we may only tune the clock time when all the threads are ready
    // we firest set the clock untunable by counting the number
    // following is an example to show 3 threads ask the clock to wait
    TSCLOCK_SET_ENABLE_TO_TUNE(false);
    TSCLOCK_SET_ENABLE_TO_TUNE(false);
    TSCLOCK_SET_ENABLE_TO_TUNE(false);

    // we need 3 enable before we can tune the clock
    TSCLOCK_SET_ENABLE_TO_TUNE(true);
    TSCLOCK_ADD_SEC(1); // fail to add
    std::cout << "Fail example: " << TSCLOCK_GET_TIME_STRING() << std::endl;

    TSCLOCK_SET_ENABLE_TO_TUNE(true);
    TSCLOCK_SET_ENABLE_TO_TUNE(true);
    TSCLOCK_ADD_SEC(1); // able to add
    std::cout << "Success example: " << TSCLOCK_GET_TIME_STRING() << std::endl;
}
// usage: ./NLClock
int main(int argc, char *argv[])
{
    StartStopDebug();
    SetClock();
    AddSecExample();
    AddSecExampleAdvance();

    return 0;
}

Output

$ ./src/NLClock 
StartStopDebug-------------
0
1
0

SetClock-------------
2020-03-20 01:20:34

AddSecExample-------------
Set clock: 2020-03-20 01:20:34
Fail example: 2020-03-20 01:20:34
Success example: 2020-03-20 01:20:35

AddSecExampleAdvance-------------
Set clock: 2020-03-20 01:20:34
Fail example: 2020-03-20 01:20:34
Success example: 2020-03-20 01:20:35

Linux conditional variable

Aim

This is a wrapper of linux conditional variable. You can wait with a given time or just wait forever.

Source



#include <iostream>
#include <thread>
#include <chrono>

#include "LinuxCond.h"

LinuxCond cond;
void firstWorker()
{
    int count = 0;
    while (count++ < 5)
    {
        std::cout << "firstWorker say Hello" << std::endl;
        cond.Wait();
    }
}
void secondWorker()
{
    int count = 0;
    while (count++ < 5)
    {
        std::cout << "secondWorker say Hello" << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));
        cond.Signal();
    }
}
int main(int argc, char *argv[])
{
    std::thread worker1(firstWorker); worker1.detach();
    std::thread worker2(secondWorker); worker2.detach();

    int count = 0;
    while (count++ < 5)
    {
        std::this_thread::sleep_for(std::chrono::seconds(2));
    }

    return 0;
}

Output

$ ./src/LinuxCond 
firstWorker say Hello
secondWorker say Hello
secondWorker say Hello
firstWorker say Hello
secondWorker say Hello
firstWorker say Hello
secondWorker say Hello
firstWorker say Hello
secondWorker say Hello
firstWorker say Hello

Critical section for Linux

Aim

This is an example to create a critical section which is recursively callable. This is OS dependency supporting C++98.

Source

#include <iostream>
#include "CriticalSection.h"

CriticalSection section;

void FooLoop(int thisCount)
{
    CriticalLock lock(section);
    if (thisCount < 10)
    {
        std::cout << "count: " << thisCount++ << std::endl;
        FooLoop(thisCount);
    }
    else
        return;
}

int main(int argc, char *argv[])
{
    FooLoop(0);

    return 0;
}

Output

$ ./src/CriticalSection 
count: 0
count: 1
count: 2
count: 3
count: 4
count: 5
count: 6
count: 7
count: 8
count: 9

Mutex for Linux

Aim

We would like to have a mutex class on linux platform which can replace std::mutex. This mutex is not recursive but supporting in C++98.

Source



#include <iostream>

#include "DefaultMutex.h"

// usage: ./DefaultMutexLinux
int main(int argc, char *argv[])
{
    {
        DefaultMutex defaultMutex;
        DefaultLock lock(defaultMutex);
        // Here is thread safe
    }
    return 0;
}

Logger for Linux

Aim

This Logger class has the same function as this. In this example I want to reduce the dependence on std library and add more Linux OS dependence and also we can keep using older C++. This class can C++11.

Source

Input parser

Aim

This is a simple example to show an argument input parser. You can set default value, required or not, short name and full name.

Source


#include <iostream>
#include "InputParser.h"

// Usage: ./InputParser --input abc.txt
// Usage: ./InputParser
int main(int argc, char *argv[])
{
    InputParser parser;
    parser.AddOption("i", "input", true); // required value example
    parser.AddOption("n", "number", false, "20"); // default value example
    parser.AddOption("o", "output"); // optional value example
    if (!parser.DoParse(argc, argv, true))
    {
        std::cout << "ERR not enough arguments" << std::endl;
        return 1;
    }

    std::cout << "input: " << parser["i"] << std::endl;
    std::cout << "number: " << std::stoi(parser["n"]) << std::endl;
    std::cout << "output: " << parser["o"] << std::endl;
    return 0;
}

Output

$ ./src/InputParser --input abc.txt
input: abc.txt
number: 20
output: 

$ ./src/InputParser
ERR: Option is needed --input
ERR: Usage: YourApp [-o|--output] <output>
 [-i|--input] <input>
 [-n|--number] <number>
ERR not enough arguments

Logger

Aim

In cpp project, we may need a way to handle log message. This class is an example to show how to do that. This logger is aimed running on Linux and Windows. This is a singleton class.

Source

#include <iostream>
#include "Logger.h"

// usage: ./Logger
class Foo
{
public:
    Foo() { LOGMSG_CLASS_NAME("Foo"); }
    ~Foo() {}

    void PrintLog()
    {
        LOGMSG_MSG("Multi thread function--------------\n");
        LOGMSG_DBG("Log inside class\n");
        LOGMSG_WRN("Log inside class\n");
        LOGMSG_MSG("Log inside class\n");
        LOGMSG_ERR("Log inside class\n");
        LOGMSG_MSG("\n");

        LOGMSG_MSG_S() << "Single thread function-----------------\n";
        LOGMSG_MSG_S() << "Log inside class\n";
        LOGMSG_DBG_S() << "Log inside class\n";
        LOGMSG_WRN_S() << "Log inside class\n";
        LOGMSG_ERR_S() << "Log inside class\n";
    }
};
int main (int argc, char *argv[])
{
    Logger::LoggerConfig config;
    config.logLevel = Logger::LogLevel::DEBUG;
    config.logPath = "./tempLog";
    config.fileSize = 0;
    config.fileSizeLimit = 4 * 1024 * 1024; // 4 MByte
    config.isToConsole = true;
    config.isToFile = true;

    LOGMSG_INIT(config);
    LOGMSG_MSG_C("Multi thread function--------------\n");
    LOGMSG_DBG_C("Log outside class\n");
    LOGMSG_WRN_C("Log outside class\n");
    LOGMSG_MSG_C("Log outside class\n");
    LOGMSG_ERR_C("Log outside class\n");
    LOGMSG_MSG_C("\n");

    LOGMSG_MSG_S_C() << "Single thread function-----------------\n";
    LOGMSG_MSG_S_C() << "Log outside class\n";
    LOGMSG_DBG_S_C() << "Log outside class\n";
    LOGMSG_WRN_S_C() << "Log outside class\n";
    LOGMSG_ERR_S_C() << "Log outside class\n";

    Foo xx;
    xx.PrintLog();
    return 0;
}

Output

This logger can output to console and files. Following is the example of the output. The file size and the location can be controlled by a config class.
20200430_152749_293 [MSG]                      main:    38, 13163,Multi thread function--------------
20200430_152749_293 [DBG]                      main:    39, 13163,Log outside class
20200430_152749_293 [WRN]                      main:    40, 13163,Log outside class
20200430_152749_293 [MSG]                      main:    41, 13163,Log outside class
20200430_152749_293 [ERR]                      main:    42, 13163,Log outside class
20200430_152749_293 [MSG]                      main:    43, 13163,
20200430_152749_293 [MSG]                      main:    45, 13163,Single thread function-----------------
20200430_152749_293 [MSG]                      main:    46, 13163,Log outside class
20200430_152749_293 [DBG]                      main:    47, 13163,Log outside class
20200430_152749_293 [WRN]                      main:    48, 13163,Log outside class
20200430_152749_293 [ERR]                      main:    49, 13163,Log outside class
20200430_152749_293 [MSG]                       Foo::                 PrintLog:    13, 13163,Multi thread function--------------
20200430_152749_293 [DBG]                       Foo::                 PrintLog:    14, 13163,Log inside class
20200430_152749_293 [WRN]                       Foo::                 PrintLog:    15, 13163,Log inside class
20200430_152749_293 [MSG]                       Foo::                 PrintLog:    16, 13163,Log inside class
20200430_152749_293 [ERR]                       Foo::                 PrintLog:    17, 13163,Log inside class
20200430_152749_293 [MSG]                       Foo::                 PrintLog:    18, 13163,
20200430_152749_293 [MSG]                       Foo::                 PrintLog:    20, 13163,Single thread function-----------------
20200430_152749_293 [MSG]                       Foo::                 PrintLog:    21, 13163,Log inside class
20200430_152749_293 [DBG]                       Foo::                 PrintLog:    22, 13163,Log inside class
20200430_152749_293 [WRN]                       Foo::                 PrintLog:    23, 13163,Log inside class
20200430_152749_293 [ERR]                       Foo::                 PrintLog:    24, 13163,Log inside class

CMakeLists.txt

if (UNIX)
else ()
  list(REMOVE_ITEM ${folderName}_inc ${CMAKE_CURRENT_SOURCE_DIR}/DefaultMutex.h)
  list(REMOVE_ITEM ${folderName}_inc ${CMAKE_CURRENT_SOURCE_DIR}/NLFileSys.h)
  list(REMOVE_ITEM ${folderName}_src ${CMAKE_CURRENT_SOURCE_DIR}/DefaultMutex.cpp)
  list(REMOVE_ITEM ${folderName}_src ${CMAKE_CURRENT_SOURCE_DIR}/NLFileSys.cpp)
endif ()
We remove some files during building binary if we are not using linux.

# Handle extra Flags
if (Use_Linux_Lock)
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUse_Linux_Lock")
  message(STATUS "Use linux lock")
elseif (Use_Windows_Lock)
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUse_Windows_Lock")
  message(STATUS "Use window lock")
else ()
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUse_Std_Lock")
  message(STATUS "Use std lock")
endif ()
We can select which mutex lock to use while using cmake.

Example:

cmake -G Ninja ../Logger/ -DCMAKE_BUILD_TYPE=Debug -DUse_Linux_Lock=True

Logger.h

#ifdef Use_Linux_Lock
#include "DefaultMutex.h"
#elif Use_Windows_Lock
#elif Use_Std_Lock
#include <mutex>
#endif
Here shows how to select library files in cpp.

2020年4月29日星期三

Count Timer

Aim

This is an example showing how to use CountTimer.

Build and Run


mkdir build
cd build
cmake -G Ninja ../CountTimer -DCMAKE_BUILD_TYPE=Debug
ninja
./src/CountTimer

Source

#include <iostream>
#include <thread>

#include "CountTimer.h"

// usage: ./CountTimer
void SimpleStartStop()
{
    std::cout << "Simple Start Stop:" << std::endl;
    using namespace std::chrono_literals;
    CountTimer timer;
    timer.Start();
    std::this_thread::sleep_for(200ms);
    timer.Stop();
    std::cout << "Second: " << timer.GetSecond()
              << " MSecond: " << timer.GetMSecond()
              << " NSecond: " << timer.GetNSecond() << std::endl;
}
void MovingStartStop()
{
    std::cout << "Moving Start Stop:" << std::endl;
    using namespace std::chrono_literals;
    CountTimer timer;
    timer.Start();
    for (int i = 0; i < 3; i++)
    {
        std::this_thread::sleep_for(500ms);
        timer.MovingStop();
        std::cout << "Second: " << timer.GetSecond()
                  << " MSecond: " << timer.GetMSecond()
                  << " NSecond: " << timer.GetNSecond() << std::endl;
    }
}
void TimeToString()
{
    std::cout << "Time To String:" << std::endl;
    using namespace std::chrono_literals;
    CountTimer timer;
    timer.Start();
    std::cout << "StartTimeGmt: " << timer.ToStringStartTime() << " StartTimeLocal: " << timer.ToStringStartTime(false) << std::endl;
    std::this_thread::sleep_for(1s);
    timer.Stop();
    std::cout << "StopTimeGmt: " << timer.ToStringStopTime() << " StopTimeLocal: " << timer.ToStringStopTime(false) << std::endl;
}
int main(int argc, char *argv[])
{
    SimpleStartStop();
    MovingStartStop();
    TimeToString();

    return 0;
}

Output

Simple Start Stop:
Second: 0 MSecond: 200 NSecond: 200091
Moving Start Stop:
Second: 1 MSecond: 500 NSecond: 500089
Second: 1 MSecond: 1000 NSecond: 1000210
Second: 2 MSecond: 1500 NSecond: 1500337
Time To String:
StartTimeGmt: 2020-04-30 02:28:25 StartTimeLocal: 2020-04-30 10:28:25
StopTimeGmt: 2020-04-30 02:28:26 StopTimeLocal: 2020-04-30 10:28:26

2020年4月24日星期五

Integrate DLL and MT4/5 VS2015

Aim

This is an example followed VS 2010 example. Here we will use VS 2015 to repeat the same example.

How to select the version of visual studio



vc140 is equal to vs2015, so we may use vs2015 for python 3.8 integration. MT4 need 32 bit version, MT5 may can use 64 bit version.

Steps

  • Create new project


  • In stdafx.h add

#define _DLLAPI extern "C" __declspec(dllexport)

2020年4月21日星期二

Backtest MHI in Ninjatrader

Background

  • Ninjatrader version 8.0.21.1 64-bit
  • MHI, tick data bought from Tick Data Suit, symbol: HK40

Import data



Backtest Instrument

Select Merge back adjusted, and do a backtest in Strategy Analyzer. The absolute value of the chart is wrong, but the relatively value is correct, for example the bar length is right.

 


After the first round, select Merge non back adjusted, and do the backtest again. This time the value of the chart is correct.

Reference

Here is a problem related to the chart data not correct. Link.
This problem is due to future rollover problem, we should select the correct scheme while backtesting. Merge Policy