• 周四. 12月 1st, 2022

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

JavaScript version collector

[db:作者]

1月 6, 2022

lately ,FMZ Quantitative trading platform supports database interface , So use JavaScript Language can also easily implement a K Line market data collector .
There is a need , Act now ~

structure JavaScript Version market collector Before , Let’s get familiar with FMZ Database interface for DBExec.

DBExec function

Be familiar with the following operations first :

  • Create table
  • Write data to the table
  • Query the data in the table
function main() {
/* Create table 
 var strSql = [
 "CREATE TABLE RECORDS_MIN1(", 
 "TS INT PRIMARY KEY NOT NULL,",
 "HIGH REAL NOT NULL,", 
 "OPEN REAL NOT NULL,", 
 "LOW REAL NOT NULL,", 
 "CLOSE REAL NOT NULL,", 
 "VOLUME REAL NOT NULL)"
 ].join("")
 // DBExec The function returns :{"rowsAffected":1,"lastInsertId":18}
 */
/* Table write data 
 // INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
 // VALUES (1, 'Paul', 32, 'California', 20000.00 );
 var strSql = [
 "INSERT INTO RECORDS_MIN1 (TS, HIGH, OPEN, LOW, CLOSE, VOLUME)", 
 "VALUES (111111, 111.11, 111.12, 111.13, 111.14, 111.16);"
 ].join("")
 // DBExec The function returns :{"rowsAffected":1,"lastInsertId":1}
 */
/* Query the data in the table 
 // SELECT * FROM RECORDS_MIN1;
 var strSql = ["SELECT * FROM RECORDS_MIN1;"].join("")
 // DBExec The function returns :{"columns":["TS","HIGH","OPEN","LOW","CLOSE","VOLUME"],"values":[[111111,111.11,111.12,111.13,111.14,111.16]]}
 */
var ret = DBExec(strSql) // perform SQL sentence 
Log(ret)
}

Design collector

utilize FMZ Database interface for DBExec It can collect the information of the exchange K Line data .
For example, some strategies are based on very long K Line data calculation index , It’s not easy to collect data so that K The length of line data is enough to calculate the index , But when the policy program design is not perfect, the real disk stops abnormally 、 Temporary adjustment code 、 Temporarily adjust the policy parameters and other scenarios that need to restart the real disk . At this point, once the hard disk is restarted, the collected data will be gone ( Program variables ). So use the database interface , It is a very good solution to save the collected market data .

Our needs are also very simple :

  • The program polled to get the market
  • Judge BAR to update , That will be done BAR The data is written to the database table and saved .
  • Query the data of a table in a database
  • This example is to show the data , Added drawing ( Use the draw line library ), Through the policy interaction button , to update K Line chart .
  • Delete database tables
  • initialization , Recreate the database table , Write the latest data .

Simple data collector source code :

var collecter = {}
collecter.init = function(tableName) {
this.preBarTS = 0
this.tableName = tableName
this.tableAvaliable = false
// testing tableName surface 
if (typeof(tableName) == "undefined" || typeof(tableName) != "string") {
Log(tableName)
throw "tableName error!"
}
// SELECT * FROM RECORDS_MIN1 LIMIT 1
var strSql = "SELECT * FROM " + tableName + " LIMIT 1"
var ret = DBExec(strSql)
if (!ret) {
// Table does not exist , Create table 
Log(" Try to read the table ", this.tableName, " The data of , Read failed , Start creating table ", this.tableName)
var strSql = [
"CREATE TABLE " + tableName + "(",
"TS INT PRIMARY KEY NOT NULL,",
"HIGH REAL NOT NULL,",
"OPEN REAL NOT NULL,",
"LOW REAL NOT NULL,",
"CLOSE REAL NOT NULL,",
"VOLUME REAL NOT NULL)"
].join("")
ret = DBExec(strSql)
if (!ret) {
throw " establish " + tableName + " Table failed !"
}
Log(" establish ", tableName, " surface ", ret)
}
Log(this.tableName, ret)
this.tableAvaliable = true
}
collecter.run = function(records) {
if (!this.tableAvaliable) {
return
}
var len = records.length
var lastBar = records[len - 1]
var beginBar = records[0]
var ret = null
if (this.preBarTS == 0) {
// initial 
/*
 DELETE FROM table_name WHERE [condition];
 */
var strSql = "DELETE FROM " + this.tableName + " WHERE TS >= " + beginBar.Time + ";"
ret = DBExec(strSql)
Log(" Delete the duplicate part of the current record ", ret)
// write in 
ret = DBExec("BEGIN")
Log("BEGIN:", ret)
for (var i = 0 ; i < len - 1 ; i++) {
var strSql = [
"INSERT INTO " + this.tableName + " (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) ",
`VALUES (${records[i].Time}, ${records[i].High}, ${records[i].Open}, ${records[i].Low}, ${records[i].Close}, ${records[i].Volume});`
].join("")
DBExec(strSql)
}
ret = DBExec("COMMIT")
Log("COMMIT:", ret)
this.preBarTS = lastBar.Time
} else if(this.preBarTS != lastBar.Time) {
// to update 
var strSql = [
"INSERT INTO " + this.tableName + " (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) ",
`VALUES (${records[len-2].Time}, ${records[len-2].High}, ${records[len-2].Open}, ${records[len-2].Low}, ${records[len-2].Close}, ${records[len-2].Volume});`
].join("")
ret = DBExec(strSql)
Log("INSERT:", ret)
this.preBarTS = lastBar.Time
}
}
collecter.getRecords = function() {
// Read database 
var strSql = "SELECT * FROM " + this.tableName + ";"
var ret = DBExec(strSql)
// Log("SELECT * FROM .. :", ret)
// SELECT * FROM .. : {"columns":["TS","HIGH","OPEN","LOW","CLOSE","VOLUME"],"values":[[1616110200000,58085.9,57716.2,57664.3,57757.6,24.216], ...]}
var arr = ret.values
var r = []
for (var i = 0 ; i < arr.length ; i++) {
r.push({
Time : arr[i][0],
High : arr[i][1],
Open : arr[i][2],
Low : arr[i][3],
Close : arr[i][4],
Volume : arr[i][5]
})
}
return r
}
collecter.deleteTable = function() {
// DROP TABLE database_name.table_name;
var strSql = "DROP TABLE " + this.tableName
var ret = DBExec(strSql)
if (!ret) {
Log(" Delete table ", this.tableName, " Failure :", ret)
} else {
Log(" Delete table ", this.tableName, " DROP TABLE:", ret)
this.tableAvaliable = false
}
}
function main() {
collecter.init(tableName)
while(true) {
var r = _C(exchange.GetRecords)
// records tbl
var rTbl = {
type : "table",
title : " data ",
cols : ["strTime", "Time", "High", "Open", "Low", "Close", "Volume"],
rows : []
}
var arrR = []
if (collecter.tableAvaliable) {
arrR = collecter.getRecords()
}
for (var i = arrR.length - 1; (i > arrR.length - 1 - 9) && (i >= 0); i--) {
var bar = arrR[i]
rTbl.rows.push([_D(bar.Time), bar.Time, bar.High, bar.Open, bar.Low, bar.Close, bar.Volume])
}
LogStatus(_D(), " Acquired K Line data length :", arrR.length, ", collecter.tableAvaliable:", collecter.tableAvaliable, "\n",
"`" + JSON.stringify(rTbl) + "`")
collecter.run(r)
// Interactive testing 
var cmd = GetCommand()
if(cmd) {
// Processing interaction 
Log(" Interactive commands :", cmd)
var arr = cmd.split(":")
// Read from database K Line data , Refresh the chart 
if(arr[0] == "refreshRecords") {
if (collecter.tableAvaliable) {
var records = collecter.getRecords()
$.PlotRecords(records, collecter.tableName) // Use the draw line library to draw 
} else {
Log(" The corresponding database table does not exist collecter.tableAvaliable:", collecter.tableAvaliable)
}
} else if (arr[0] == "deleteBDTable") { // Delete database tables 
collecter.deleteTable()
} else if (arr[0] == "initCollecter") { // Initialize the collector 
Log(" Initialize the collector ")
collecter.init(tableName)
}
}
Sleep(5000)
}
}

test

Comparative data

Policy address :https://www.fmz.com/strategy/267223

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注