2018年6月29日 星期五

Windows Server 2012 Server Code on Hyper-V

Windows Server 2012 Server Code on Hyper-V

LAN
netsh interface ipv4 show config
Ethernet
netsh interface ipv4 set address Ethernet static 172.31.118.247 255.255.255.240 172.31.118.240
netsh interface ipv4 set dns Ethernet static 172.31.118.240

Enable Ping
netsh firewall set icmpsetting 8

Change to Private Network
Get-NetConnectionProfile
Set-NetConnectionProfile -Name “Unidentified network” -NetworkCategory Private

---

[check here to do better for PS and OnClient later]


PS 5.1
"Turn off password protected sharing" on remote server
\\172.31.118.241\share\Win8.1AndW2K12R2-KB3191564-x64.msu /quite
Get-Host shows 5.1
Enable-PSRemoting -Force
Restart-Service WinRM
winrm quickconfig

On Client
winrm quickconfig
winrm set winrm/config/client '@{TrustedHosts="172.31.118.247"}'
Set-Item wsman:\localhost\client\trustedhosts *
Test-WsMan 172.31.118.247
Enter-PSSession -ComputerName 172.31.118.247 -Credential Administrator



---


Set Filewall and Start MT4
netsh advfirewall firewall add rule name="MetaTrader 4 Server" protocol=TCP enable=yes DIR=In program="C:\MetaTrader4Server\mtsrv.exe" Action=Allow
Expand-Archive \\172.31.118.241\share\MetaTrader4Server.zip C:\
C:\MetaTrader4Server\mtsrv.exe /install
C:\MetaTrader4Server\mtsrv.exe /stop
Copy-Item \\172.31.118.241\share\StopOut.dll C:\MetaTrader4Server\plugins\ -force
C:\MetaTrader4Server\mtsrv.exe /start


2018年6月21日 星期四

C++ with NSQ and Visual Studio and vcpkg



vcpkg
https://www.jianshu.com/p/f06b8f77bc34
git clone https://github.com/Microsoft/vcpkg.git
powershell -exec bypass scripts\bootstrap.ps1
vcpkg.exe integrate install
vcpkg.exe search sqlite
vcpkg.exe install sqlite3 boost
vcpkg.exe list
vcpkg.exe install sqlite3:x64-windows

#include <sqlite3.h>
#include <iostream>
void main() {
std::cout << sqlite3_libversion() << "\n";
std::cin.get();
}

cmake (may not required)
Download cmake-3.8.0-win64-x64.msi with "Add CMake to the system PATH for all users"


getopt.h
https://github.com/skandhurkat/Getopt-for-Visual-Studio

https://github.com/Qihoo360/evpp/blob/master/docs/quick_start_windows_with_visualstudio.md

1. run bat file to generate vcpkg.exe

vcpkg install gflags:x64-windows glog:x64-windows openssl:x64-windows libevent:x64-windows thrift:x64-windows
vcpkg install evpp:x64-windows





Simplest


git clone https://github.com/Microsoft/vcpkg.git (so that C:\d\git\vcpkg\vcpkg.exe)
powershell -exec bypass scripts\bootstrap.ps1
vcpkg install evpp:x64-windows

2018年6月13日 星期三

QT 5.11


https://hk.saowen.com/

在visual studio 2017中配置Qt

QT creator編程C++第一步,説“Hello world!”

QLabel label("Hello, world");
label.setGeometry(200,200,200,200);
label.show();
Qt主窗口(Top Level Window)


QtGuiApplication1 w;           //創造一個主窗口物件
w.resize(300, 300);      //窗口尺寸為300*300
w.move(100, 100);        //窗口移動到距螢幕左上角100*100處
int windowXPos = w.x(); //窗口左上角x座標
int windowYPos = w.y(); //窗口左上角y座標
QRect windowGeometry = w.frameGeometry(); //返回的QRect可得窗口長、寬、位置等資訊。   
w.setWindowTitle(QObject::tr("Window Title")); //設定窗口標題
w.show();               //在螢幕上秀出窗口
元件概念(QWidget)

MainWindow, Dialog, Label, Buttons inherits from QWidget inherits from QObject.
Top Level Widget includes MainWindow that must has no parents.
Non-window widget includes labels, buttons that must has a parent.
Typically top level widget put in stack in main() but sub widget put in heap using new with chained parents.

int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QLabel *label1 = new QLabel();
label1->setText("Label 1");
label1->show();
QLabel label2;
label2.setText("Label 2");
label2.show();
int ret = a.exec();
delete label1;    //label1需自行釋放記憶體
return ret;
}

QWidget (Typical)

int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QWidget w;
w.show();
return a.exec();
}

QPushButton

class MyWidget : public QWidget
{
 Q_OBJECT
public:
 MyWidget(QWidget *parent = 0) {
  setWindowTitle(tr("My Title"));
  btn1 = new QPushButton(tr("Start"), this); //第二個參數指定父元件,如果沒有就要用布局管理員,否則無法顯現該元件
  btn1->setGeometry(30, 30, 80, 30);         //設定位置大小
  btn1->setText(tr("Change"));               //設定內容文字
  btn1->setFont(QFont("Times", 12));       //設定字型
  btn2 = new QPushButton(this);
  btn2->setGeometry(30, 80, 60, 60);
  btn2->setIcon(QIcon("icon.jpg"));       //設定按鈕圖案
  btn2->setIconSize(QSize(50, 50));       //設定圖案大小
 }
private:
 QPushButton *btn1;
 QPushButton *btn2;
};

#include "MyWidget.h"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MyWidget w;
w.show();
return a.exec();
}
QLabel

MyWidget(QWidget *parent = 0) {
 setWindowTitle(tr("Two Labels"));
 label1 = new QLabel(this);
 label1->setText(tr("Text Label"));
 label1->setGeometry(20, 20, 60, 20);        //設定位置大小
 label1->setAlignment(Qt::AlignCenter);   //label文字置中

 QPixmap p("icon.png");                   //載入圖檔
 label2 = new QLabel(this);
 label2->setGeometry(25, 60, 60, 60);
 label2->setPixmap(p.scaled(60, 60, Qt::KeepAspectRatio));  //將圖案縮小為(60,60)
}
QFrame

MyWidget(QWidget *parent = 0) {
 setWindowTitle(tr("QFrame Title"));
 myFrame = new QFrame(this);
 myFrame->setGeometry(10, 10, 150, 40);
 myFrame->setLineWidth(2);
 myFrame->setFrameStyle(QFrame::Box | QFrame::Sunken);
}
QRadioButton

setWindowTitle(tr("Radio Titles"));
myGroupBox = new QGroupBox(tr("Set of buttons"), this);
myGroupBox->setGeometry(30, 30, 100, 100);
check1 = new QRadioButton(tr("B1"), this);
check1->setChecked(true);                //設定check1為打勾狀態
check2 = new QRadioButton(tr("B2"), this);
check3 = new QRadioButton(tr("B3"), this);
myLayout = new QVBoxLayout;
myLayout->addWidget(check1);
myLayout->addWidget(check2);
myLayout->addWidget(check3);
myGroupBox->setLayout(myLayout);
And more widght...


信號槽範例

Button clicked() broadcasts a signal and a "private slot:" function can handle data.

connect(myBtn, SIGNAL(clicked()), this, SLOT(showMessageBox()));
connect(myEdit, SIGNAL(textChanged()), this, SLOT(showMessageBox()));
The object button broadcasts a signal clicked() and this object handle it by the slot function.


































class MyWidget : public QWidget
{
 Q_OBJECT
public:
 MyWidget(QWidget *parent = 0) :
  QWidget(parent)
 {
  m_value = 0;
  myLcd = new QLCDNumber(this);
  myLcd->setGeometry(80, 30, 150, 50);
  mySlider = new QSlider(Qt::Horizontal, this);
  mySlider->setRange(0, 100);
  mySlider->setValue(30);
  mySlider->setGeometry(80, 110, 150, 50);
  connect(mySlider, SIGNAL(valueChanged(int)), this, SLOT(setValue(int)));
  connect(this, SIGNAL(valueChanged(int)), myLcd, SLOT(display(int)));
  setValue(30);
 }
private:
 int m_value;
 QLCDNumber *myLcd;
 QSlider *mySlider;
public slots:
 void setValue(int value) {
  if (value != m_value) {
   m_value = value;
   emit valueChanged(m_value);
  }
 }
signals:
 void valueChanged(int);
};
自建的signal和slot函式回傳值皆為void,且參數基本上要相同(本例為int)
若signal的參數多於slot的參數,則額外的參數會被slot忽略


QTableWidget

















Ending

2018年6月12日 星期二

MT4 Bookmark Login

https://blog.csdn.net/MT4Develop/article/details/78464175

https://www.2cto.com/kf/201711/696119.html

https://blog.csdn.net/MT4Develop/article/details/51925398



基于MT4平台实现二元交易的思路

市面上有很多基于MT4做的二元交易。 
这里只简单说下我做的思路。 
主要要处理两个方面的事,一个是在客户端对二元信息的 展示,另一个是在服务端处理二元信息的交互以及对下单逻辑的处理。
1.客户端 
客户端可以自己做一个程序,做个登录界面, 
这里写图片描述 
然后去 服务端验证用户名以及密码,验证成功后,加载MT4本身的客户端程序,使其自动登录,并附加(SetWindowsHookEx)一个自己写的dll文件到该进程上。 
附加dll是 为了拦截一些MT4界面上的消息,当点击二元商品时,弹出一个自己的窗口界面(如下图)并关闭MT4本身的下单界面,在这个界面中进行二元的操作与信息展示 
这里写图片描述
对于二元的下单以及信息获取,这里可以自己维护通讯,直接与服务端通讯,不需要与 MT4客户端发生任何关系。
2.服务端 
服务端主要要处理 这么几个事,首先是客户端的一些数据请求的回应,例如验证用户帐号,获取二元的持仓,二元的下单等。 
这里可以利用MT4插件的扩展事件 
int APIENTRY MtSrvTelnet(const ULONG ip, char *buf, const int maxlen) 
来做,MT4会将收到的数据转发到插件的这个事件中,事件处理后,会将数据返回给客户端。
由于二元业务是根据时间对单据进行结算,所以需要在插件中启动一个 线程,时刻检查单据的情况,在插件的启动事件
int APIENTRY   MtSrvStartup(CServerInterface *server)  
  • 1
启动一个线程即可,在线程里对持仓单据持续检查,发现时间到了的就进行平仓操作,并计算相关的盈亏更新到单据中。 
另外要注意启动的线程要在插件停止事件中关闭
void APIENTRY  MtSrvCleanup(void)
  • 1
,否则可能会造成MT4服务端启时崩溃。


___



如何使用MT4平台实现二元交易

市面上有很多基于MT4做的二元交易。
这里只简单说下我做的思路。
主要要处理两个方面的事,一个是在客户端对二元信息的 展示,另一个是在服务端处理二元信息的交互以及对下单逻辑的处理。
1.客户端
客户端可以自己做一个程序,做个登录界面,
这里写图片描述
然后去 服务端验证用户名以及密码,验证成功后,加载MT4本身的客户端程序,使其自动登录,并附加(SetWindowsHookEx)一个自己写的dll文件到该进程上。
附加dll是 为了拦截一些MT4界面上的消息,当点击二元商品时,弹出一个自己的窗口界面(如下图)并关闭MT4本身的下单界面,在这个界面中进行二元的操作与信息展示
这里写图片描述
对于二元的下单以及信息获取,这里可以自己维护通讯,直接与服务端通讯,不需要与 MT4客户端发生任何关系。
2.服务端
服务端主要要处理 这么几个事,首先是客户端的一些数据请求的回应,例如验证用户帐号,获取二元的持仓,二元的下单等。
这里可以利用MT4插件的扩展事件
int APIENTRY MtSrvTelnet(const ULONG ip, char *buf, const int maxlen)
来做,MT4会将收到的数据转发到插件的这个事件中,事件处理后,会将数据返回给客户端。
由于二元业务是根据时间对单据进行结算,所以需要在插件中启动一个 线程,时刻检查单据的情况,在插件的启动事件
?
1
<code>int APIENTRY   MtSrvStartup(CServerInterface *server)  </code>
启动一个线程即可,在线程里对持仓单据持续检查,发现时间到了的就进行平仓操作,并计算相关的盈亏更新到单据中。
另外要注意启动的线程要在插件停止事件中关闭
?
1
<code>void APIENTRY  MtSrvCleanup(void)</code>
,否则可能会造成MT4服务端启时崩溃。


___

MT4服务端插件案例

需求描述

客户本来有一个交易系统,要求mt4与该系统交互,做到与该系统数据同步。 
以下是客户的需求原文。
MT4只作为一个桌面版的交易工具,和WebTrader共用一个账号体系,MT4的所有功能最终都通过Web API连接券商系统的后台实现。MT4终端需要实现以下功能: 
●登录 
用户可以在MT4终端登录券商系统,登录后可以进行查询、下单、平仓等操作,MT4终端需要正确保存用户的登录状态,超时后需要重新登录。 
●查询账号保证金 
用户可以在MT4终端查询自己交易账号的保证金情况 
●查询持仓 
用户可以在MT4终端查询到自己交易账号的持仓情况 
●查询挂单 
用户可以在MT4终端查询到自己交易账号委托的LIMIT和STOP类型订单 
●查询交易记录 
用户可以在MT4终端查询到自己交易账号的历史交易记录 
●下单 
用户可以在MT4终端下单,订单抛给通过券商系统执行,成交后通过查询持仓和保证金更新用户的账号信息 
●撤单 
用户可以在MT4终端撤销自己委托的LIMIT和STOP类型的订单 
●平仓 
用户可以在MT4终端对交易账号中持仓的订单进行平仓,平仓成功后通过查询持仓和保证金更新用户的账号信息 
●设置止损 
用户可以在MT4终端对持仓中的订单设置或修改止损价位 
●设置止盈 
用户可以在MT4终端对持仓中的订单设置或修改止盈价位

实现细节

本文中将原有系统WebTrade简称为web接口.

1)登录

MT4的登录事件
int  APIENTRY        MtSrvUserLogin(const UserInfo *info)
  • 1
由于此事件需要在mt4验证过用户名密码后才能触发,所以用户帐号和密码必须已经存在于MT4中。 
MT4帮助对此事件的说明,如下
int APIENTRY MtSrvUserLogin(const UserInfo *info) 
Purpose- 
filter connections by clients. 
The hook is called after the client has successfully authorized by the server. This hook can be used to filter the client’s access to the server on basis of the own internal data. 
Parameters: 
info - client info 
Return values: 
TRUE - default value - allow login for this client 
FALSE - block the client’s login, return “account disabled” (RET_ACCOUNT_DISABLED), and close the connection
进入此事件后,插件根据UserInfo中的用户名与密码,去调用web接口进行用户名与密码验证,根据验证的结果返回此事件的结果值,从而决定MT4客户端是否能登录成功。如果web接口验证通过,则同时将用户的相关信息(余额,单据历史,单据)都全部同步到MT4中来, 需要用到以下几个MT4服务端接口。
int         __stdcall ClientsChangeBalance(const int login,const ConGroup *grp,const double value,LPCSTR comment);
int         __stdcall OrdersAdd(const TradeRecord *start,UserInfo* user,const ConSymbol *symb);
int         __stdcall OrdersUpdate(TradeRecord *order,UserInfo* user,const int mode);
  • 1
  • 2
  • 3

2)动态刷新数据

在服务的启动事件中开一个线程
int APIENTRY MtSrvStartup(CServerInterface *server)  
{
    //---- check version
    if(server==NULL)                        return(FALSE);
    if(server->Version()!=ServerApiVersion) return(FALSE);
    //---- save server interface link
    ExtServer=server;

    if (hThread == 0)
    {
        UINT     id;
        runing = true;
        hThread = _beginthreadex(NULL, 256000, DoCheckData, NULL, 0, &id);
    }

    return(TRUE);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
在线程中定时向web接口请求当前在线的MT4用户的相关数据(余额,持仓单据等),然后与MT4内的数据进行比较,将有差异的地方进行修正。

3)下单相关处理

交易事件
int APIENTRY MtSrvTradeTransaction(TradeTransInfo *trans,const UserInfo *user,int *request_id)
{
    if (trans->type == TT_ORDER_IE_OPEN 
        || trans->type == TT_ORDER_IE_CLOSE
        || trans->type == TT_ORDER_PENDING_OPEN
        || trans->type == TT_ORDER_DELETE
        || trans->type == TT_ORDER_MODIFY
        )
    {
        return TradeTransaction(trans, user);
    }

    return(RET_ERROR);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
如果是下单请求,则先调用web接口下单,根据web的下单结果(成功/失败), 决定此事件的返回值,影响MT4下单的结果。

2018年6月6日 星期三

Linux Apache MySQL PHP on CentOS 7.4 (LAMP)


CentOS
cat /etc/*release
CentOS Linux release 7.5.1804 (Core)

EPEL
sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY*
sudo yum -y install epel-release

nano
sudo yum -y install nano

MariaDB
sudo yum -y install mariadb-server mariadb
sudo systemctl start mariadb.service
sudo systemctl enable mariadb.service
mysql_secure_installation
[Enter] the default empty password
[Y] to set root pasword
[Enter Password]
[Confirm Password]
[Y] to remove anonymous users
[Y] to disallow root login remotely
[Y] to remove test database
[Y] to reload privilege tables to apply changes now

Apache
sudo yum -y install httpd
sudo systemctl start httpd.service
sudo systemctl enable httpd.service
sudo firewall-cmd --permanent --zone=public --add-service=http
sudo firewall-cmd --permanent --zone=public --add-service=https
sudo firewall-cmd --reload

Test
http://172.31.118.243/

Remi for PHP 7
sudo rpm -Uvh http://rpms.remirepo.net/enterprise/remi-release-7.rpm
sudo yum install -y yum-utils
sudo yum update -y
sudo yum repolist all | grep PHP
sudo yum-config-manager --enable remi-php72
sudo yum repolist all | grep PHP
sudo yum install -y php php-opcache
sudo systemctl restart httpd.service

PHP File
ls /var/www/html/
sudo nano /var/www/html/info.php
<?php
phpinfo();
http://172.31.118.243/info.php

Support MySQL in PHP
sudo yum search php | grep mysql
php72-php-mysqlnd
sudo yum search php | grep pdo
php72-php-pdo
sudo yum install -y php72-php-mysqlnd php72-php-pdo
sudo yum -y install php-mysqlnd php-pdo
sudo yum -y install php-gd php-ldap php-odbc php-pear php-xml php-xmlrpc php-mbstring php-soap curl curl-devel
sudo systemctl restart httpd.service
http://172.31.118.243/info.php

phpMyAdmin
sudo yum install -y phpMyAdmin
sudo nano /etc/httpd/conf.d/phpMyAdmin.conf
[locate <Directory /usr/share/phpMyAdmin/><IfModule mod_authz_core.c>]
[remove <requireAny /> tag, add "Require all granted"]
sudo nano /etc/phpMyAdmin/config.inc.php
[change auth_type from cookie to http]
sudo systemctl restart httpd.service
http://172.31.118.243/phpmyadmin/

Server Side Code

cat b.php
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$time = date('r');
echo "data: The server time is: {$time}\n\nretry: 333\n\n";
flush();
?>

cat a.html
<!DOCTYPE html>
<html>
<body>
<h1>Getting server updates</h1>
<div id="result"></div>
<script>
if(typeof(EventSource) !== "undefined") {
    var source = new EventSource("b.php");
    source.onmessage = function(event) {
        document.getElementById("result").innerHTML += event.data + "<br>";
    };
} else {
    document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events...";
}
</script>
</body>
</html>

 http://172.31.118.243/a.html



2023 Promox on Morefine N6000 16GB 512GB

2023 Promox on Morefine N6000 16GB 512GB Software Etcher 100MB (not but can be rufus-4.3.exe 1.4MB) Proxmox VE 7.4 ISO Installer (1st ISO re...