Documents de l'API de quantification par les inventeurs

Auteur:Le petit rêve, Créé: 2017-11-27 09:05:08, Mis à jour: 2023-07-12 16:47:31

Les données ont été reçues et le suivi n'a commencé que lorsque le mécanisme d'écoute EventLoop a été lancé, et les événements ont été oubliés. // Ces événements ne sont pas manqués à moins que la première ligne de code n'appelle EventLoop ((-1) et que le mécanisme d'écoute d'EventLoop ne soit initialement initialement installé.

// Log("GetDepth:", routine_getDepth.wait()) 如果这里提前调用wait函数取出GetDepth函数并发调用的结果,此次GetDepth函数收到请求结果的事件便不会在EventLoop函数返回
var ts1 = new Date().getTime()
var ret1 = EventLoop(0)

var ts2 = new Date().getTime()
var ret2 = EventLoop(0)

var ts3 = new Date().getTime()
var ret3 = EventLoop(0)

Log("第1个并发任务完成的为:", _D(ts1), ret1)
Log("第2个并发任务完成的为:", _D(ts2), ret2)
Log("第3个并发任务完成的为:", _D(ts3), ret3)

Log("GetTicker:", routine_getTicker.wait())
Log("GetDepth:", routine_getDepth.wait())
Log("GetTrades:", routine_getTrades.wait())

}


```python
import time
def main():
    routine_getTicker = exchange.Go("GetTicker")
    routine_getDepth = exchange.Go("GetDepth")
    routine_getTrades = exchange.Go("GetTrades")
    
    ts1 = time.time()
    ret1 = EventLoop(0)
    
    ts2 = time.time()
    ret2 = EventLoop(0)
    
    ts3 = time.time()
    ret3 = EventLoop(0)
    
    Log("第1个并发任务完成的为:", _D(ts1), ret1)
    Log("第2个并发任务完成的为:", _D(ts2), ret2)
    Log("第3个并发任务完成的为:", _D(ts3), ret3)
    
    Log("GetTicker:", routine_getTicker.wait())
    Log("GetDepth:", routine_getDepth.wait())
    Log("GetTrades:", routine_getTrades.wait())
void main() {
    auto routine_getTicker = exchange.Go("GetTicker");
    auto routine_getDepth = exchange.Go("GetDepth");
    auto routine_getTrades = exchange.Go("GetTrades");
    
    auto ts1 = Unix() * 1000;
    auto ret1 = EventLoop(0);
    
    auto ts2 = Unix() * 1000;
    auto ret2 = EventLoop(0);
    
    auto ts3 = Unix() * 1000;
    auto ret3 = EventLoop(0);
    
    Log("第1个并发任务完成的为:", _D(ts1), ret1);
    Log("第2个并发任务完成的为:", _D(ts2), ret2);
    Log("第3个并发任务完成的为:", _D(ts3), ret3);
    
    Ticker ticker;
    Depth depth;
    Trades trades;
    routine_getTicker.wait(ticker);
    routine_getDepth.wait(depth);
    routine_getTrades.wait(trades);
    
    Log("GetTicker:", ticker);
    Log("GetDepth:", depth);
    Log("GetTrades:", trades);
}

Fonction intégrée

- Je ne sais pas.

_G(K, V)Cette fonction permet de sauvegarder une fonctionnalité de dictionnaire global, à la fois supportée par le retouche et le disque dur. Une fois le retouche terminé, les données sauvegardées sont effacées. La structure des données estKVLes tables sont des fichiers locaux qui sont conservés en permanence, une base de données distincte sur chaque disque, et qui existent après un redémarrage ou une sortie de l'administrateur.KIl faut écrire comme une chaîne, sans distinguer la taille et la taille.VIl peut être utilisé pour n'importe quoiJSONContenu sérialisé._G()La fonction n'a pas de paramètres à transmettre._G()La fonction renvoie le disque en cours.ID

function main(){
    // 设置一个全局变量num,值为1
    _G("num", 1)     
    // 更改一个全局变量num,值为字符串ok
    _G("num", "ok")    
    // 删除全局变量num
    _G("num", null)
    // 返回全局变量num的值
    Log(_G("num"))
    // 删除所有全局变量
    _G(null)
    // 返回实盘ID
    var robotId = _G()
}
def main():
    _G("num", 1)     
    _G("num", "ok")    
    _G("num", None)
    Log(_G("num"))
    _G(None)
    robotId = _G()
void main() {
    _G("num", 1);
    _G("num", "ok");
    _G("num", NULL);
    Log(_G("num"));
    _G(NULL);
    // 不支持 auto robotId = _G();
}

Attention: Utilisation_GLes données stockées en permanence fonctionnelle doivent être utilisées de manière raisonnable en fonction de la mémoire et de l'espace disque dur du matériel.Débordement de mémoireLe problème de l'écriture

_D ((Temps, Fmt)

_D(Timestamp, Fmt), renvoie la chaîne de temps correspondant à la barre de temps spécifiée.TimestampPour le type de valeur numérique, la valeur est en millisecondes.FmtPour le type de chaîne,FmtIl y a des gens qui pensent:yyyy-MM-dd hh:mm:ss, retourne la valeur: type de chaîne. Retourne la chaîne correspondant à la barre de temps spécifiée (millisecondes) sans passer aucun paramètre et renvoie l'heure actuelle; par exemple:_D()Ou alors_D(1478570053241)Le format par défaut est:yyyy-MM-dd hh:mm:ss

function main(){
    var time = _D()
    Log(time)
}
def main():
    strTime = _D()
    Log(strTime)
void main() {
    auto strTime = _D();
    Log(strTime);
}

Attention:PythonUtilisation stratégique_D()Les paramètres à noter sont les paramètres de temps au niveau des secondes.JavaScriptC++Dans la stratégie, le temps est calculé à l'échelle des millisecondes (une seconde équivaut à 1000 millisecondes). Utilisation en direct_D()Lorsqu'une fonction analyse un timestamp comme une chaîne de temps lisible, elle doit être attentive aux zones horaires et aux paramètres horaires du système d'exploitation dans lequel se trouve le programme administrateur._D()La fonction analyse une barre de temps comme une chaîne de temps lisible basée sur le temps du système hôte.

Par exemple, un chronomètre est1574993606000L'analyse par code:

function main() {
    Log(_D(1574993606000))
}
def main():
    # 北京时间的服务器上运行:2019-11-29 10:13:26 ,另一台其它地区的服务器上的托管者运行此代码结果则为:2019-11-29 02:13:26
    Log(_D(1574993606))
void main() {
    Log(_D(1574993606000));
}

_N ((Nombre, précision)

_N(Num, Precision), formater un nombre à virgule.NumPour le type de valeur,PrecisionPour l'ensemble. Retourne la valeur: type de valeur numérique.

Par exemple:_N(3.1415, 2)Il est supprimé3.1415La fonction renvoie la valeur de deux chiffres après le décimale.3.14

function main(){
    var i = 3.1415
    Log(i)
    var ii = _N(i, 2)
    Log(ii)
}
def main():
    i = 3.1415
    Log(i)
    ii = _N(i, 2)
    Log(ii)
void main() {
    auto i = 3.1415;
    Log(i);
    auto ii = _N(i, 2);
    Log(ii);
}

Si nous voulons changer tous les nombres N à gauche du décimale en 0, nous pouvons écrire ceci:

function main(){
    var i = 1300
    Log(i)
    var ii = _N(i, -3)
    // 查看日志得知为1000
    Log(ii)
}
def main():
    i = 1300
    Log(i)
    ii = _N(i, -3)
    Log(ii)
void main() {
    auto i = 1300;
    Log(i);
    auto ii = _N(i, -3);
    Log(ii);
}

Je suis désolé.

_C(function, args...)Cette fonction est une fonction de redémarrage, utilisée pour obtenir des transactions, obtenir des commandes non terminées, etc.

L'interface continue d'appeler la fonction spécifiée jusqu'à ce qu'elle renvoie le paramètre (().functionRetourne une valeur nulle oufalseIl y a aussi des cas où les utilisateurs peuvent demander à être appelés à nouveau._C(exchange.GetTicker)Le temps de répétition par défaut est de 3 secondes._CDelay(...)Les fonctions permettent de définir des intervalles de répétition, par exemple_CDelay(1000)Le changement_CL'intervalle de répétition de la fonction est de 1 seconde.

Pour les fonctions suivantes:

  • exchange.GetTicker()
  • exchange.GetDepth()
  • exchange.GetTrades()
  • exchange.GetRecords()
  • exchange.GetAccount()
  • exchange.GetOrders()
  • exchange.GetOrder()
  • exchange.GetPosition()

Je ne peux pas._C(...)Les fonctions sont appelées à accepter des erreurs._C(function, args...)Les fonctions ne sont pas limitées à celles énumérées ci-dessus.functionC'est une référence à une fonction, pas un appel à une fonction._C(exchange.GetTicker)Ce n'est pas_C(exchange.GetTicker())

function main(){
    var ticker = _C(exchange.GetTicker)
    // 调整_C()函数重试时间间隔为2秒
    _CDelay(2000)
    var depth = _C(exchange.GetDepth)
    Log(ticker)
    Log(depth)
}
def main():
    ticker = _C(exchange.GetTicker)
    _CDelay(2000)
    depth = _C(exchange.GetDepth)
    Log(ticker)
    Log(depth)
void main() {
    auto ticker = _C(exchange.GetTicker);
    _CDelay(2000);
    auto depth = _C(exchange.GetDepth);
    Log(ticker);
    Log(depth);
}

Utilisation pour les fonctions avec des paramètres_C(...)Je ne suis pas d'accord avec toi.

function main(){
    var records = _C(exchange.GetRecords, PERIOD_D1)
    Log(records)
}
def main():
    records = _C(exchange.GetRecords, PERIOD_D1)
    Log(records)
void main() {
    auto records = _C(exchange.GetRecords, PERIOD_D1);
    Log(records);
}

Il peut également être utilisé pour le traitement d'erreurs de fonctionnalités personnalisées:

var test = function(a, b){
    var time = new Date().getTime() / 1000
    if(time % b == 3){
        Log("符合条件!", "#FF0000")
        return true
    }
    Log("重试!", "#FF0000")
    return false
}

function main(){
    var ret = _C(test, 1, 5)
    Log(ret)
}
import time
def test(a, b):
    ts = time.time()
    if ts % b == 3:
        Log("符合条件!", "#FF0000")
        return True
    Log("重试!", "#FF0000")
    return False

def main():
    ret = _C(test, 1, 5)
    Log(ret)
// C++ 不支持这种方式对于自定义函数容错

_Cross ((Arr1, Arr2)

_Cross(Arr1, Arr2)Retournez l'ensembleArr1avecArr2Le nombre de cycles croisés de l'archive. Les nombres positifs représentent les cycles ascendants, les nombres négatifs les cycles descendants et 0 le prix actuel.

On peut simuler un ensemble de tests de données._Cross(Arr1, Arr2)Fonction:

// 快线指标
var arr1 = [1,2,3,4,5,6,8,8,9]
// 慢线指标
var arr2 = [2,3,4,5,6,7,7,7,7]
function main(){
    Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2))
    Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1))
}
arr1 = [1,2,3,4,5,6,8,8,9]     
arr2 = [2,3,4,5,6,7,7,7,7]
def main():
    Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2))
    Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1))
void main() {
    vector<double> arr1 = {1,2,3,4,5,6,8,8,9};
    vector<double> arr2 = {2,3,4,5,6,7,7,7,7};
    Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2));
    Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1));
}

img

Visualiser les données simulées pour les observer

img

Des instructions d'utilisation:Fonction intégrée_Cross analyse et instructions d'utilisation

JSONParse (en anglais)

JSONParse(strJson)Cette fonction est utilisée pour analyser les chaînes JSON. Une fonction permettant de analyser correctement les chaînes JSON contenant des valeurs numériques plus importantes est désignée par type de chaîne.

function main() {
    let s1 = '{"num": 8754613216564987646512354656874651651358}'
    Log("JSON.parse:", JSON.parse(s1))    // JSON.parse: {"num":8.754613216564988e+39}
    Log("JSONParse:", JSONParse(s1))      // JSONParse:  {"num":"8754613216564987646512354656874651651358"}
    
    let s2 = '{"num": 123}'
    Log("JSON.parse:", JSON.parse(s2))    // JSON.parse: {"num":123}
    Log("JSONParse:", JSONParse(s2))      // JSONParse:  {"num":123}
}
import json

def main():
    s1 = '{"num": 8754613216564987646512354656874651651358}'
    Log("json.loads:", json.loads(s1))    # json.loads: map[num:8.754613216564987e+39]
    Log("JSONParse:", JSONParse(s1))      # JSONParse:  map[num:8754613216564987646512354656874651651358]
    
    s2 = '{"num": 123}'
    Log("json.loads:", json.loads(s2))    # json.loads: map[num:123]
    Log("JSONParse:", JSONParse(s2))      # JSONParse:  map[num:123]
void main() {
    auto s1 = "{\"num\":8754613216564987646512354656874651651358}";
    Log("json::parse:", json::parse(s1));
    // Log("JSONParse:", JSONParse(s1));   // 不支持该函数
    
    auto s2 = "{\"num\":123}";
    Log("json::parse:", json::parse(s2));
    // Log("JSONParse:", JSONParse(s2));   // 不支持该函数
}

Couleurs personnalisées

Chaque chaîne de message peut être utilisée#ff0000Cette valeur RGB représente la perspective à afficher à la fin.#ff0000112233Les six derniers chiffres représentent la couleur du fond.

function main() {
    Log("红色", "#FF0000")
}
def main():
    Log("红色", "#FF0000")
void main() {
    Log("红色", "#FF0000");
}

Informations sur le journal

Les journaux sont enregistrés dans la base de données du disque virtuel au moment de son exécution.sqlite3Base de données, fichier de base de données sur disque physique dans le périphérique où se trouve le programme de l'administrateur, fichier de base de données dans le programme de l'administrateurrobotDans le répertoire des programmes exécutables. Par exemple:130350Les fichiers de base de données de disque dur sont../logs/storage/130350Dans ce répertoire..C'est à direrobotLe fichier de base de données est un fichier de base de données.130350.db3Je ne sais pas. Les journaux dans le système de retouche peuvent être consultés après la fin du retouche en cliquant sur le bouton en bas à droite de la page.Télécharger le journalLe bouton ] pour le téléchargement. Lorsqu'il est nécessaire de migrer le disque sur un autre serveur, l'administrateur peut déplacer le fichier de base de données du disque (extension nommée db3) vers le serveur de destination de la migration, en définissant le nom du fichier comme le disque correspondant sur la plate-forme. Ainsi, toutes les informations de journaux du disque précédent ne seront pas perdues lors de la migration vers le nouvel appareil.

Le journal de bord

Log(message), enregistrer un message dans la liste des journaux.messageIl peut être de n'importe quel type. Si on ajoute après la chaîne@Les messages sont ensuite envoyés dans la file d'attente de publication et sont ensuite envoyés à la boîte aux lettres, Telegram, WebHook, etc. configurées dans les paramètres de publication du compte de l'inventeur actuel.Centre de contrôlePage, en haut à droiteConfiguration du compteLe blogueur a écrit:Sélectionnez le boutonLes pages sont liées par les paramètres.)

Attention:

  • Les outils de débogage ne prennent pas en charge le boost.
  • Le système de retouche n'est pas compatible avec le boost.
function main() {
    Log("发明者量化你好 !@")
    Sleep(1000 * 5)
    // 字符串内加入#ff0000,打印日志显示为红色,并且推送消息
    Log("你好, #ff0000@")
}
def main():
    Log("发明者量化你好 !@")
    Sleep(1000 * 5)
    Log("你好, #ff0000@")
void main() {
    Log("发明者量化你好 !@");
    Sleep(1000 * 5);
    Log("你好, #ff0000@");
}

Le WebHookIl a été poussé:

UtilisationGolangLe service DEMO a été écrit:

package main
import (
    "fmt"
    "net/http"
)

func Handle (w http.ResponseWriter, r *http.Request) {
    defer func() {
        fmt.Println("req:", *r)
    }()
}

func main () {
    fmt.Println("listen http://localhost:9090")
    http.HandleFunc("/data", Handle)
    http.ListenAndServe(":9090", nil)
}

ParamètresWebHookhttp://XXX.XX.XXX.XX:9090/data?data=Hello_FMZ

Une fois que le service a été exécuté, une stratégie est exécutée, une stratégie est envoyée:

function main() {
    Log("msg", "@")
}
def main():
    Log("msg", "@")
void main() {
    Log("msg", "@");
}

Les messages sont envoyés par le système de service et imprimés:

listen http://localhost:9090
req: {GET /data?data=Hello_FMZ HTTP/1.1 1 1 map[User-Agent:[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/xx.x.xxxx.xxx Safari/537.36] Accept-Encoding:[gzip]] {} <nil> 0 [] false 1XX.XX.X.XX:9090 map[] map[] <nil> map[] XXX.XX.XXX.XX:4xxx2 /data?data=Hello_FMZ <nil> <nil> <nil> 0xc420056300}

L'impressionbase64Une image codée LogFonction d'impression prise en chargebase64L'image est codée pour être utilisée comme`Nous avons commencé avec:`La fin, par exemple:

function main() {
    Log("`data:image/png;base64,AAAA`")
}
def main():
    Log("`data:image/png;base64,AAAA`")
void main() {
    Log("`data:image/png;base64,AAAA`");
}

LogPrise en charge de l'impression directePythonJe ne sais pasmatplotlib.pyplotL'objet, tant qu'il contientsavefigLa méthode est simple.LogIl y a aussi des publications imprimées, comme:

import matplotlib.pyplot as plt 
def main(): 
    plt.plot([3,6,2,4,7,1]) 
    Log(plt)

Les journaux imprimés changent automatiquement de langue LogLes fonctions prennent en charge la commutation de langues.LogLes fonctions produisent du texte qui passe automatiquement à la langue correspondante selon la langue définie sur la page de la plateforme, par exemple:

function main() {
    Log("[trans]中文|abc[/trans]")
}
def main():
    Log("[trans]中文|abc[/trans]")
void main() {
    Log("[trans]中文|abc[/trans]");
}

Le montant de l'impôt sur les sociétés est calculé à partir du montant de l'impôt sur le capital.

LogProfit(Profit), enregistrer les gains et les pertes, imprimer les gains et les pertes et tracer une courbe d'acquisition basée sur les gains et les pertes; valeur du paramètre:RésultatsPour le type de valeur numérique.

La fonction peut être écrite en caractères.&En fin de compte, il suffit de dessiner des graphiques de revenus et non de publier des journaux de revenus, par exemple:LogProfit(10, '&')

LogProfitReset (en anglais seulement)

LogProfitReset(), vider tous les journaux d'acquisition, avec un paramètre de valeur entière, pour spécifier les entrées réservées.

function main() {
    // 在收益图表上打印30个点,然后重置,只保留最后10个点
    for(var i = 0; i < 30; i++) {
        LogProfit(i)
        Sleep(500)
    }
    LogProfitReset(10)
}
def main():
    for i in range(30):
        LogProfit(i)
        Sleep(500)
    LogProfitReset(10)
void main() {
    for(int i = 0; i < 30; i++) {
        LogProfit(i);
        Sleep(500);
    }
    LogProfitReset(10);
}

LogStatus (Msg)

LogStatus(Msg)Cette information n'est pas sauvegardée dans la liste des journaux, elle ne met à jour que l'information sur l'état du disque actuel. La barre d'état située au-dessus de la zone de journaux de la page du disque réel est affichée et permet d'appeler l'état de mise à jour plusieurs fois.MsgVous pouvez choisir n'importe quel type.

function main() {
    LogStatus('这是一个普通的状态提示')
    LogStatus('这是一个红色字体的状态提示#ff0000')
    LogStatus('这是一个多行的状态信息\n我是第二行')
}
def main():
    LogStatus('这是一个普通的状态提示')
    LogStatus('这是一个红色字体的状态提示#ff0000')
    LogStatus('这是一个多行的状态信息\n我是第二行')
void main() {
    LogStatus("这是一个普通的状态提示");
    LogStatus("这是一个红色字体的状态提示#ff0000");
    LogStatus("这是一个多行的状态信息\n我是第二行");
}

LogStatus(Msg)Prise en charge de l'impressionbase64L'image est codée pour être utilisée comme`Nous avons commencé avec:`La fin, par exemple:LogStatus("`data:image/png;base64,AAAA`")LogStatus(Msg)Prise en charge de la diffusion directePythonJe ne sais pasmatplotlib.pyplotL'objet, tant qu'il contientsavefigLes méthodes peuvent être transmises.LogStatus(Msg)Les fonctions, par exemple:

import matplotlib.pyplot as plt 
def main():
    plt.plot([3,6,2,4,7,1])
    LogStatus(plt) 

Exemple de sortie de données dans une barre d'état:

function main() {
    var table = {type: 'table', title: '持仓信息', cols: ['列1', '列2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]}
    // JSON序列化后两边加上`字符,视为一个复杂消息格式(当前支持表格)
    LogStatus('`' + JSON.stringify(table) + '`')                    
    // 表格信息也可以在多行中出现
    LogStatus('第一行消息\n`' + JSON.stringify(table) + '`\n第三行消息')
    // 支持多个表格同时显示,将以TAB显示到一组里
    LogStatus('`' + JSON.stringify([table, table]) + '`')
    
    // 也可以构造一个按钮在表格中,策略用GetCommand接收cmd属性的内容                                
    var table = { 
        type: 'table', 
        title: '持仓操作', 
        cols: ['列1', '列2', 'Action'], 
        rows: [ 
            ['abc', 'def', {'type':'button', 'cmd': 'coverAll', 'name': '平仓'}]
        ]
    }
    LogStatus('`' + JSON.stringify(table) + '`') 
    // 或者构造一单独的按钮
    LogStatus('`' + JSON.stringify({'type':'button', 'cmd': 'coverAll', 'name': '平仓'}) + '`') 
    // 可以自定义按钮风格(bootstrap的按钮属性)
    LogStatus('`' + JSON.stringify({'type':'button', 'class': 'btn btn-xs btn-danger', 'cmd': 'coverAll', 'name': '平仓'}) + '`')
}
import json
def main():
    table = {"type": "table", "title": "持仓信息", "cols": ["列1", "列2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]}
    LogStatus('`' + json.dumps(table) + '`')
    LogStatus('第一行消息\n`' + json.dumps(table) + '`\n第三行消息')
    LogStatus('`' + json.dumps([table, table]) + '`')

    table = {
        "type" : "table", 
        "title" : "持仓操作", 
        "cols" : ["列1", "列2", "Action"], 
        "rows" : [
            ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "平仓"}]
        ] 
    }
    LogStatus('`' + json.dumps(table) + '`')
    LogStatus('`' + json.dumps({"type": "button", "cmd": "coverAll", "name": "平仓"}) + '`')
    LogStatus('`' + json.dumps({"type": "button", "class": "btn btn-xs btn-danger", "cmd": "coverAll", "name": "平仓"}) + '`')
void main() {
    json table = R"({"type": "table", "title": "持仓信息", "cols": ["列1", "列2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]})"_json;
    LogStatus("`" + table.dump() + "`");
    LogStatus("第一行消息\n`" + table.dump() + "`\n第三行消息");
    json arr = R"([])"_json;
    arr.push_back(table);
    arr.push_back(table);
    LogStatus("`" + arr.dump() + "`");

    table = R"({
        "type" : "table", 
        "title" : "持仓操作", 
        "cols" : ["列1", "列2", "Action"], 
        "rows" : [
            ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "平仓"}]
        ] 
    })"_json;
    LogStatus("`" + table.dump() + "`");
    LogStatus("`" + R"({"type": "button", "cmd": "coverAll", "name": "平仓"})"_json.dump() + "`");
    LogStatus("`" + R"({"type": "button", "class": "btn btn-xs btn-danger", "cmd": "coverAll", "name": "平仓"})"_json.dump() + "`");
}

Définition de la fonctionnalité: Définition de la fonctionnalité

img

function main() {
    var table = {
        type: "table",
        title: "状态栏按钮的禁用、描述功能测试",
        cols: ["列1", "列2", "列3"], 
        rows: []
    }
    var button1 = {"type": "button", "name": "按钮1", "cmd": "button1", "description": "这是第一个按钮"}
    var button2 = {"type": "button", "name": "按钮2", "cmd": "button2", "description": "这是第二个按钮,设置为禁用", "disabled": true}
    var button3 = {"type": "button", "name": "按钮3", "cmd": "button3", "description": "这是第三个按钮,设置为启用", "disabled": false}
    table.rows.push([button1, button2, button3])
    LogStatus("`" + JSON.stringify(table) + "`")
}
import json
def main():
    table = {
        "type": "table",
        "title": "状态栏按钮的禁用、描述功能测试",
        "cols": ["列1", "列2", "列3"], 
        "rows": []
    }
    button1 = {"type": "button", "name": "按钮1", "cmd": "button1", "description": "这是第一个按钮"}
    button2 = {"type": "button", "name": "按钮2", "cmd": "button2", "description": "这是第二个按钮,设置为禁用", "disabled": True}
    button3 = {"type": "button", "name": "按钮3", "cmd": "button3", "description": "这是第三个按钮,设置为启用", "disabled": False}
    table["rows"].append([button1, button2, button3])
    LogStatus("`" + json.dumps(table) + "`")
void main() {
    json table = R"({
        "type": "table",
        "title": "状态栏按钮的禁用、描述功能测试",
        "cols": ["列1", "列2", "列3"], 
        "rows": []
    })"_json;
    json button1 = R"({"type": "button", "name": "按钮1", "cmd": "button1", "description": "这是第一个按钮"})"_json;
    json button2 = R"({"type": "button", "name": "按钮2", "cmd": "button2", "description": "这是第二个按钮,设置为禁用", "disabled": true})"_json;
    json button3 = R"({"type": "button", "name": "按钮3", "cmd": "button3", "description": "这是第三个按钮,设置为启用", "disabled": false})"_json;
    json arr = R"([])"_json;
    arr.push_back(button1);
    arr.push_back(button2);
    arr.push_back(button3);
    table["rows"].push_back(arr);
    LogStatus("`" + table.dump() + "`");
}

Les paramètres de style des boutons d'état:

img

function main() {
    var table = {
        type: "table",
        title: "状态栏按钮样式",
        cols: ["默认", "原始", "成功", "信息", "警告", "危险"], 
        rows: [
            [
                {"type":"button", "class": "btn btn-xs btn-default", "name": "默认"},
                {"type":"button", "class": "btn btn-xs btn-primary", "name": "原始"},
                {"type":"button", "class": "btn btn-xs btn-success", "name": "成功"},
                {"type":"button", "class": "btn btn-xs btn-info", "name": "信息"},
                {"type":"button", "class": "btn btn-xs btn-warning", "name": "告警"},
                {"type":"button", "class": "btn btn-xs btn-danger", "name": "危险"}
            ]
        ]
    }
    LogStatus("`" + JSON.stringify(table) + "`")
}
import json
def main():
    table = {
        "type": "table",
        "title": "状态栏按钮样式",
        "cols": ["默认", "原始", "成功", "信息", "警告", "危险"], 
        "rows": [
            [
                {"type":"button", "class": "btn btn-xs btn-default", "name": "默认"},
                {"type":"button", "class": "btn btn-xs btn-primary", "name": "原始"},
                {"type":"button", "class": "btn btn-xs btn-success", "name": "成功"},
                {"type":"button", "class": "btn btn-xs btn-info", "name": "信息"},
                {"type":"button", "class": "btn btn-xs btn-warning", "name": "告警"},
                {"type":"button", "class": "btn btn-xs btn-danger", "name": "危险"}
            ]
        ]
    }
    LogStatus("`" + json.dumps(table) + "`")
void main() {
    json table = R"({
        "type": "table",
        "title": "状态栏按钮样式",
        "cols": ["默认", "原始", "成功", "信息", "警告", "危险"], 
        "rows": [
            [
                {"type":"button", "class": "btn btn-xs btn-default", "name": "默认"},
                {"type":"button", "class": "btn btn-xs btn-primary", "name": "原始"},
                {"type":"button", "class": "btn btn-xs btn-success", "name": "成功"},
                {"type":"button", "class": "btn btn-xs btn-info", "name": "信息"},
                {"type":"button", "class": "btn btn-xs btn-warning", "name": "告警"},
                {"type":"button", "class": "btn btn-xs btn-danger", "name": "危险"}
            ]
        ]
    })"_json;
    LogStatus("`" + table.dump() + "`");
}

La combinaisonGetCommand()Les fonctions, les fonctionnalités d'interaction avec les boutons d'état:

function test1() {
    Log("调用自定义函数")
}

function main() {
    while (true) {
        var table = {
            type: 'table',
            title: '操作',
            cols: ['列1', '列2', 'Action'],
            rows: [
                ['a', '1', {
                    'type': 'button',                       
                    'cmd': "CoverAll",                      
                    'name': '平仓'                           
                }],
                ['b', '1', {
                    'type': 'button',
                    'cmd': 10,                              
                    'name': '发送数值'
                }],
                ['c', '1', {
                    'type': 'button',
                    'cmd': _D(),                          
                    'name': '调用函数'
                }],
                ['d', '1', {
                    'type': 'button',
                    'cmd': 'test1',       
                    'name': '调用自定义函数'
                }]
            ]
        }
        LogStatus(_D(), "\n", '`' + JSON.stringify(table) + '`')

        var str_cmd = GetCommand()
        if (str_cmd) {
            Log("接收到的交互数据 str_cmd:", "类型:", typeof(str_cmd), "值:", str_cmd)
            if(str_cmd == "test1") {
                test1()
            }
        }

        Sleep(500)
    }
}
import json
def test1():
    Log("调用自定义函数")

def main():
    while True:
        table = {
            "type": "table", 
            "title": "操作", 
            "cols": ["列1", "列2", "Action"],
            "rows": [
                ["a", "1", {
                    "type": "button", 
                    "cmd": "CoverAll",
                    "name": "平仓"
                }],
                ["b", "1", {
                    "type": "button",
                    "cmd": 10,
                    "name": "发送数值" 
                }], 
                ["c", "1", {
                    "type": "button",
                    "cmd": _D(),
                    "name": "调用函数" 
                }],
                ["d", "1", {
                    "type": "button",
                    "cmd": "test1",
                    "name": "调用自定义函数" 
                }]
            ]
        }

        LogStatus(_D(), "\n", "`" + json.dumps(table) + "`")
        str_cmd = GetCommand()
        if str_cmd:
            Log("接收到的交互数据 str_cmd", "类型:", type(str_cmd), "值:", str_cmd)
            if str_cmd == "test1":
                test1()
        Sleep(500)
void test1() {
    Log("调用自定义函数");
}

void main() {
    while(true) {
        json table = R"({
            "type": "table", 
            "title": "操作", 
            "cols": ["列1", "列2", "Action"],
            "rows": [
                ["a", "1", {
                    "type": "button", 
                    "cmd": "CoverAll",
                    "name": "平仓"
                }],
                ["b", "1", {
                    "type": "button",
                    "cmd": 10,
                    "name": "发送数值" 
                }], 
                ["c", "1", {
                    "type": "button",
                    "cmd": "",
                    "name": "调用函数" 
                }],
                ["d", "1", {
                    "type": "button",
                    "cmd": "test1",
                    "name": "调用自定义函数" 
                }]
            ]
        })"_json;
        table["rows"][2][2]["cmd"] = _D();
        LogStatus(_D(), "\n", "`" + table.dump() + "`");
        auto str_cmd = GetCommand();
        if(str_cmd != "") {
            Log("接收到的交互数据 str_cmd", "类型:", typeid(str_cmd).name(), "值:", str_cmd);
            if(str_cmd == "test1") {
                test1();
            }
        }
        Sleep(500);
    }
}

L'entrée de données est également prise en charge lors de l'interaction avec les boutons de la barre d'état de la construction.GetCommand()Une fonction de capture. Augmentation de la structure des données des boutons de contrôle dans la barre d'étatinputPar exemple, pour{"type": "button", "cmd": "open", "name": "开仓"}Augmentation"input": {"name": "开仓数量", "type": "number", "defValue": 1}Une fenêtre pop-up avec le contrôle de la zone d'entrée (données dont la valeur par défaut est de 1 dans la zone d'entrée, c'est-à-dire des données dont la valeur defValue est définie) peut être saisie et envoyée avec la commande de la touche. Par exemple, lorsque vous exécutez le code de test suivant, une fenêtre pop-up avec la zone d'entrée apparaît après avoir cliqué sur le bouton "Open" et entre dans la zone d'entrée.111Il a ensuite cliqué sur "Confirmé".GetCommandLa fonction capture les messages suivants:open:111

function main() {
    var tbl = {
        type: "table",
        title: "操作",
        cols: ["列1", "列2"],
        rows: [
            ["开仓操作", {"type": "button", "cmd": "open", "name": "开仓", "input": {"name": "开仓数量", "type": "number", "defValue": 1}}],
            ["平仓操作", {"type": "button", "cmd": "coverAll", "name": "全部平仓"}]
        ] 
    }

    LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
    while (true) {
        var cmd = GetCommand()
        if (cmd) {
            Log("cmd:", cmd)
        }
        Sleep(1000)
    }
}
import json

def main():
    tbl = {
        "type": "table", 
        "title": "操作", 
        "cols": ["列1", "列2"],
        "rows": [
            ["开仓操作", {"type": "button", "cmd": "open", "name": "开仓", "input": {"name": "开仓数量", "type": "number", "defValue": 1}}],
            ["平仓操作", {"type": "button", "cmd": "coverAll", "name": "全部平仓"}]
        ]
    }

    LogStatus(_D(), "\n", "`" + json.dumps(tbl) + "`")
    while True:
        cmd = GetCommand()
        if cmd:
            Log("cmd:", cmd)
        Sleep(1000)
void main() {
    json tbl = R"({
        "type": "table", 
        "title": "操作", 
        "cols": ["列1", "列2"],
        "rows": [
            ["开仓操作", {"type": "button", "cmd": "open", "name": "开仓", "input": {"name": "开仓数量", "type": "number", "defValue": 1}}],
            ["平仓操作", {"type": "button", "cmd": "coverAll", "name": "全部平仓"}]
        ]
    })"_json;

    LogStatus(_D(), "\n", "`" + tbl.dump() + "`");
    while(true) {
        auto cmd = GetCommand();
        if(cmd != "") {
            Log("cmd:", cmd);
        }
        Sleep(1000);
    }
}

La fusionLogStatus(Msg)Les cellules dans les tableaux dessinés par les fonctions:

  • Fusion horizontale

    function main() {
        var table = { 
            type: 'table', 
            title: '持仓操作', 
            cols: ['列1', '列2', 'Action'], 
            rows: [ 
                ['abc', 'def', {'type':'button', 'cmd': 'coverAll', 'name': '平仓'}]
            ]
        } 
        var ticker = exchange.GetTicker()
        // 添加一行数据,第一个和第二个单元格合并,并且输出ticker变量在合并后的单元格内
        table.rows.push([{body : JSON.stringify(ticker), colspan : 2}, "abc"])    
        LogStatus('`' + JSON.stringify(table) + '`')
    }
    
    import json
    def main():
        table = {
            "type" : "table",
            "title" : "持仓操作",
            "cols" : ["列1", "列2", "Action"],
            "rows" : [
                ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "平仓"}]
            ]
        }
        ticker = exchange.GetTicker()
        table["rows"].append([{"body": json.dumps(ticker), "colspan": 2}, "abc"])
        LogStatus("`" + json.dumps(table) + "`")
    
    void main() {
        json table = R"({
            "type" : "table",
            "title" : "持仓操作",
            "cols" : ["列1", "列2", "Action"],
            "rows" : [
                ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "平仓"}]
            ]
        })"_json;
    
        auto ticker = exchange.GetTicker();
        json jsonTicker = R"({"Buy": 0, "Sell": 0, "High": 0, "Low": 0, "Volume": 0, "Last": 0, "Time": 0})"_json;
        jsonTicker["Buy"] = ticker.Buy;
        jsonTicker["Sell"] = ticker.Sell;
        jsonTicker["Last"] = ticker.Last;
        jsonTicker["Volume"] = ticker.Volume;
        jsonTicker["Time"] = ticker.Time;
        jsonTicker["High"] = ticker.High;
        jsonTicker["Low"] = ticker.Low;
    
        json arr = R"([{"body": {}, "colspan": 2}, "abc"])"_json;
        arr[0]["body"] = jsonTicker;
        table["rows"].push_back(arr);
        LogStatus("`" + table.dump() + "`");
    }
    

  • Fusion verticale

    function main() {
        var table = { 
            type: 'table', 
            title: '表格演示', 
            cols: ['列A', '列B', '列C'], 
            rows: [ 
                ['A1', 'B1', {'type':'button', 'cmd': 'coverAll', 'name': 'C1'}]
            ]
        } 
    
        var ticker = exchange.GetTicker()
        var name = exchange.GetName()
    
        table.rows.push([{body : "A2 + B2:" + JSON.stringify(ticker), colspan : 2}, "C2"])
        table.rows.push([{body : "A3 + A4 + A5:" + name, rowspan : 3}, "B3", "C3"])
        // A3被上一行第一个单元格合并
        table.rows.push(["B4", "C4"])
        // A2被上一行第一个单元格合并
        table.rows.push(["B5", "C5"])                                            
        table.rows.push(["A6", "B6", "C6"])
        LogStatus('`' + JSON.stringify(table) + '`')
    }
    
    import json
    def main():
        table = {
            "type" : "table", 
            "title" : "表格演示", 
            "cols" : ["列A", "列B", "列C"], 
            "rows" : [
                ["A1", "B1", {"type": "button", "cmd": "coverAll", "name": "C1"}]
            ]
        }
        
        ticker = exchange.GetTicker()
        name = exchange.GetName()
        
        table["rows"].append([{"body": "A2 + B2:" + json.dumps(ticker), "colspan": 2}, "C2"])
        table["rows"].append([{"body": "A3 + A4 + A5:" + name, "rowspan": 3}, "B3", "C3"])
        table["rows"].append(["B4", "C4"])
        table["rows"].append(["B5", "C5"])
        table["rows"].append(["A6", "B6", "C6"])
        LogStatus("`" + json.dumps(table) + "`")
    
    void main() {
        json table = R"({
            "type" : "table", 
            "title" : "表格演示", 
            "cols" : ["列A", "列B", "列C"], 
            "rows" : [
                ["A1", "B1", {"type": "button", "cmd": "coverAll", "name": "C1"}]
            ]
        })"_json;
        // 为了测试,代码简短易读,这里使用构造的数据
        json jsonTicker = R"({"High": 0, "Low": 0, "Buy": 0, "Sell": 0, "Last": 0, "Time": 0, "Volume": 0})"_json;
        auto name = exchange.GetName();
        json arr1 = R"([{"body": "", "colspan": 2}, "C2"])"_json;
        arr1[0]["body"] = "A2 + B2:" + jsonTicker.dump();
        json arr2 = R"([{"body": "", "rowspan": 3}, "B3", "C3"])"_json;
        arr2[0]["body"] = "A3 + A4 + A5:" + name;
        table["rows"].push_back(arr1);
        table["rows"].push_back(arr2);
        table["rows"].push_back(R"(["B4", "C4"])"_json);
        table["rows"].push_back(R"(["B5", "C5"])"_json);
        table["rows"].push_back(R"(["A6", "B6", "C6"])"_json);
        LogStatus("`" + table.dump() + "`");
    }
    

Le tableau de bord de la barre d'état montre:

function main() {
    var table1 = {type: 'table', title: 'table1', cols: ['列1', '列2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]}
    var table2 = {type: 'table', title: 'table2', cols: ['列1', '列2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]}
    LogStatus('`' + JSON.stringify([table1, table2]) + '`')
}
import json
def main():
    table1 = {"type": "table", "title": "table1", "cols": ["列1", "列2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]}
    table2 = {"type": "table", "title": "table2", "cols": ["列1", "列2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]}
    LogStatus("`" + json.dumps([table1, table2]) + "`")
void main() {
    json table1 = R"({"type": "table", "title": "table1", "cols": ["列1", "列2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]})"_json;
    json table2 = R"({"type": "table", "title": "table2", "cols": ["列1", "列2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]})"_json;
    json arr = R"([])"_json;
    arr.push_back(table1);
    arr.push_back(table2);
    LogStatus("`" + arr.dump() + "`");
}

img

En plus d'afficher des feuilles séparées, vous pouvez afficher plusieurs feuilles disposées de haut en bas.

function main(){
    var tab1 = {
        type : "table",
        title : "表格1",
        cols : ["1", "2"],
        rows : []
    }
    var tab2 = {
        type : "table",
        title : "表格2",
        cols : ["1", "2", "3"],
        rows : []
    }
    var tab3 = {
        type : "table",
        title : "表格3",
        cols : ["A", "B", "C"],
        rows : []
    }

    tab1.rows.push(["jack", "lucy"])
    tab2.rows.push(["A", "B", "C"])
    tab3.rows.push(["A", "B", "C"])

    LogStatus('`' + JSON.stringify(tab1) + '`\n' + 
        '`' + JSON.stringify(tab2) + '`\n' +
        '`' + JSON.stringify(tab3) + '`')
  
    Log("exit")
}
import json
def main():
    tab1 = {
        "type": "table", 
        "title": "表格1", 
        "cols": ["1", "2"], 
        "rows": []
    }
    tab2 = {
        "type": "table", 
        "title": "表格2", 
        "cols": ["1", "2", "3"], 
        "rows": []
    }
    tab3 = {
        "type": "table", 
        "title": "表格3", 
        "cols": ["A", "B", "C"], 
        "rows": []
    }

    tab1["rows"].append(["jack", "lucy"])
    tab2["rows"].append(["A", "B", "C"])
    tab3["rows"].append(["A", "B", "C"])
    LogStatus("`" + json.dumps(tab1) + "`\n" + 
        "`" + json.dumps(tab2) + "`\n" + 
        "`" + json.dumps(tab3) + "`")
void main() {
    json tab1 = R"({
        "type": "table", 
        "title": "表格1", 
        "cols": ["1", "2"], 
        "rows": []
    })"_json;
    json tab2 = R"({
        "type": "table", 
        "title": "表格2", 
        "cols": ["1", "2", "3"], 
        "rows": []
    })"_json;
    json tab3 = R"({
        "type": "table", 
        "title": "表格3", 
        "cols": ["A", "B", "C"], 
        "rows": []
    })"_json;
    tab1["rows"].push_back(R"(["jack", "lucy"])"_json);
    tab2["rows"].push_back(R"(["A", "B", "C"])"_json);
    tab3["rows"].push_back(R"(["A", "B", "C"])"_json);
    LogStatus("`" + tab1.dump() + "`\n" + 
        "`" + tab2.dump() + "`\n" +
        "`" + tab3.dump() + "`");
}

L'effet de course:

Attention: Lorsque la stratégie est exécutée sur le disque, la barre d'état est mise en mode veille si l'historique est consulté sur la page du disque. Prise en charge de l'exportation en mode modebase64Des images codées, également prises en charge dans les tableaux affichés dans la barre d'étatbase64Les images post-encodées. Les images post-encodées ne sont plus affichées avec le code de l'exemple car les données de chaîne sont généralement longues.

Activation du journal

EnableLog(IsEnable), enregistrement des journaux d'ouverture et de fermeture des informations de commande.isEnableLe type est Boolean.IsEnablePourfalseLes données de la base de données sont stockées sur des disques durs et ne sont pas imprimées sur le disque.

Tableau de référence

Chart(...)Le graphique est un graphique qui est un graphique.

Chart({...})Le paramètre est:JSONSérieuxLes stocks élevésJe ne sais pasHighcharts.StockChartParamètres.__isStockPropriétés, si elles sont spécifiées__isStock:falseLe graphique est affiché comme un graphique ordinaire.

Attention: S'il est réglé__isStockL'attribut estfalseLes graphiques utilisés sont:Tableaux de bordLe blogueur a écrit:

Highcharts图表

S'il est réglé__isStockL'attribut esttrueLes graphiques utilisés sont:Les stocks élevés(par défaut)__isStockPourtrueIl y a aussi une photo de l'établissement.

Highstocks图表

Retournez à l'appeladd(n, data)nPourseriesL'index (par exemple 0),dataPour écrire des données dans le graphique) à l'index spécifiéseriesAjouter des données, appelerreset()Les données graphiques sont vides.resetIl est possible d'utiliser un paramètre numérique pour spécifier le nombre de lignes réservées.

Vous pouvez appeleradd(n, data, i)iC'est pour cela que les donnéesseriesL'index de la page de destination est un index de la page de destination.seriesIl y a des données dans le texte.

On peut utiliser des nombres négatifs, -1 pour le dernier, -2 pour le deuxième décimale. Par exemple, en traçant une ligne, modifier les données sur le dernier point de la ligne:

chart.add(0, [1574993606000, 13.5], -1)Le changementseries[0].dataLes données du premier point de la fraction de la première fraction du premier point de la fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la première fraction de la deuxième fraction de la première fraction de la première fraction de la seconde fraction de la seconde fraction de la seconde fraction.

Prise en charge de l'affichage de plusieurs graphiques, la configuration consiste simplement à entrer des paramètres d'arrayés tels que:var chart = Chart([{...}, {...}, {...}])Par exemple, le graphique 1 a deuxseriesLe graphique 2 a uneseriesIl y a une figure sur le graphique 3.seriesAlors?addLorsque les IDs de séquence 0 et 1 sont spécifiés pour représenter les données des deux séquences du graphique 1 mis à jour,addLorsque l'ID de séquence est défini comme 2 indique le premier de la figure 2.seriesLa séquence 3 est la première séquence de la figure 3.seriesIl y a aussi des gens qui sont morts.

HighStockshttp://api.highcharts.com/highstock

Les multiples graphiques montrent quelques paramètres d'attributs:Exemples

Par exemple, les objets de configuration de graphique:

var cfgA = {
    extension: {
        // 不参于分组,单独显示,默认为分组 'group'
        layout: 'single', 
        // 指定高度,可以设置为字符串,"300px",设置数值300会自动替换为"300px"
        height: 300,      
        // 指定宽度占的单元值,总值为12
        col: 8            
    },
    title: {
        text: '盘口图表'
    },
    xAxis: {
        type: 'datetime'
    },
    series: [{
        name: '买一',
        data: []
    }, {
        name: '卖一',
        data: []
    }]
}

var cfgB = {
    title: {
        text: '差价图'
    },
    xAxis: {
        type: 'datetime'
    },
    series: [{
        name: '差价',
        type: 'column',
        data: []
    }]
}

var cfgC = {
    __isStock: false,
    title: {
        text: '饼图'
    },
    series: [{
        type: 'pie',
        name: 'one',
        // 指定初始数据后不需要用add函数更新,直接更改图表配置就可以更新序列
        data: [                    
            ["A", 25],
            ["B", 25],
            ["C", 25],
            ["D", 25]
        ]                
    }]
}

var cfgD = {
    extension: {
        layout: 'single',
        // 指定宽度占的单元值,总值为12
        col: 8,                    
        height: '300px'
    },
    title: {
        text: '盘口图表'
    },
    xAxis: {
        type: 'datetime'
    },
    series: [{
        name: '买一',
        data: []
    }, {
        name: '卖一',
        data: []
    }]
}

var cfgE = {
    __isStock: false,
    extension: {
        layout: 'single',
        col: 4,
        height: '300px'
    },
    title: {
        text: '饼图2'
    },
    series: [{
        type: 'pie',
        name: 'one',
        data: [
            ["A", 25],
            ["B", 25],
            ["C", 25],
            ["D", 25]
        ]
    }]
}
cfgA = {
    "extension" : {
        "layout" : "single", 
        "height" : 300,
        "col" : 8
    }, 
    "title" : {
        "text" : "盘口图表"
    },
    "xAxis" : {
        "type" : "datetime" 
    }, 
    "series" : [{
        "name" : "买一",
        "data" : []
    }, {
        "name" : "卖一", 
        "data" : []
    }]
}    

cfgB = {
    "title" : {
        "text" : "差价图"
    }, 
    "xAxis" : {
        "type" : "datetime"
    }, 
    "series" : [{
        "name" : "差价", 
        "type" : "column", 
        "data" : []
    }]
}    

cfgC = {
    "__isStock" : False,
    "title" : {
        "text" : "饼图"
    }, 
    "series" : [{
        "type" : "pie", 
        "name" : "one", 
        "data" : [
            ["A", 25],
            ["B", 25],
            ["C", 25],
            ["D", 25]
        ]
    }]
}    

cfgD = {
    "extension" : {
        "layout" : "single",
        "col" : 8,
        "height" : "300px"
    }, 
    "title" : {
        "text" : "盘口图表"
    }, 
    "series" : [{
        "name" : "买一", 
        "data" : []
    }, {
        "name" : "卖一",
        "data" : []
    }]
}    

cfgE = {
    "__isStock" : False, 
    "extension" : {
        "layout" : "single", 
        "col" : 4,
        "height" : "300px"
    }, 
    "title" : {
        "text" : "饼图2"
    },
    "series" : [{
        "type" : "pie",
        "name" : "one", 
        "data" : [
            ["A", 25], 
            ["B", 25], 
            ["C", 25], 
            ["D", 25]
        ]
    }]
}
json cfgA = R"({
    "extension" : {
        "layout" : "single", 
        "height" : 300,
        "col" : 8
    }, 
    "title" : {
        "text" : "盘口图表"
    },
    "xAxis" : {
        "type" : "datetime" 
    }, 
    "series" : [{
        "name" : "买一",
        "data" : []
    }, {
        "name" : "卖一", 
        "data" : []
    }]
})"_json;    

json cfgB = R"({
    "title" : {
        "text" : "差价图"
    }, 
    "xAxis" : {
        "type" : "datetime"
    }, 
    "series" : [{
        "name" : "差价", 
        "type" : "column", 
        "data" : []
    }]
})"_json;    

json cfgC = R"({
    "__isStock" : false,
    "title" : {
        "text" : "饼图"
    }, 
    "series" : [{
        "type" : "pie", 
        "name" : "one", 
        "data" : [
            ["A", 25],
            ["B", 25],
            ["C", 25],
            ["D", 25]
        ]
    }]
})"_json;    

json cfgD = R"({
    "extension" : {
        "layout" : "single",
        "col" : 8,
        "height" : "300px"
    }, 
    "title" : {
        "text" : "盘口图表"
    }, 
    "series" : [{
        "name" : "买一", 
        "data" : []
    }, {
        "name" : "卖一",
        "data" : []
    }]
})"_json;    

json cfgE = R"({
    "__isStock" : false, 
    "extension" : {
        "layout" : "single", 
        "col" : 4,
        "height" : "300px"
    }, 
    "title" : {
        "text" : "饼图2"
    },
    "series" : [{
        "type" : "pie",
        "name" : "one", 
        "data" : [
            ["A", 25], 
            ["B", 25], 
            ["C", 25], 
            ["D", 25]
        ]
    }]
})"_json;
  • cfgA.extension.layoutAttributs

    Si cette propriété est définie comme "single", les graphiques ne seront pas superposés (ils ne seront pas affichés sous forme de balises de page) et seront affichés séparément (affichage plat).

  • cfgA.extension.heightAttributs

    Cette propriété est utilisée pour définir la hauteur du graphique, une valeur pouvant être de type numérique ou définie comme "300px".

  • cfgA.extension.colAttributs

    Cette propriété est utilisée pour définir la largeur du graphique, la largeur de la page est divisée en 12 unités, la largeur du graphique en 8 unités.

    La stratégie de l'exemple complet:

    Dans l'exemple ci-dessus, les objets de configuration graphique affichent l'effet:

  • Les données sur les objets de configuration du graphique peuvent être mises à jour en modifiant directement la configuration du graphique, puis en mettant à jour le graphique:

    Il y a aussi des cas où les gens ne sont pas d'accord.JavaScriptPartie de code de l'exempleLe modèle complet):

    cfgC.series[0].data[0][1] = Math.random() * 100
    cfgE.series[0].data[0][1] = Math.random() * 100
    // update实际上等于重置了图表的配置
    chart.update([cfgA, cfgB, cfgC, cfgD, cfgE])
    

    DéclarationaddUne méthode pour mettre à jour les données, par exemple en ajoutant un élément à un diagramme de gâteaux.JavaScriptPartie de code de l'exempleLe modèle complet):

    // 为饼图增加一个数据点,add只能更新通过add方式添加的数据点,内置的数据点无法后期更新
    chart.add(3, {
        name: "ZZ",
        y: Math.random() * 100
    })
    
  • Utilisation parallèleChartExemple de fonction

    Voici un exemple simple de dessin:

    // 这个chart在JavaScript语言中是对象,在使用Chart函数之前我们需要声明一个配置图表的对象变量chart
    var chart = {                                           
        // 该字段标记图表是否为一般图表,有兴趣的可以改成false运行看看
        __isStock: true,                                    
        // 缩放工具
        tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A'},    
        // 标题
        title : { text : '差价分析图'},                       
        // 选择范围
        rangeSelector: {                                    
            buttons:  [{type: 'hour',count: 1, text: '1h'}, {typ

Plus de

Je ne sais pas.Il y a un problème: est-ce que la fonction C doit être répétée ou seulement une fois?

Je vous en prie._C ((function, args...) est-ce le 3s par défaut? Est-ce que je peux modifier le paramètre par défaut en plaçant _CDelay ((1000) directement avant _C ((function, args...)?

Le repas?Cluster: si vous créez 1000 robots en même temps, et sans stress, vous pouvez créer plusieurs hôtes pour diviser les tâches. Y a-t-il des exemples de code pour créer des clusters? Comment créer plusieurs hôtes pour diviser les tâches

- Je suis désolée.Log ((talib.help (('MACD')); peut être utilisé uniquement sous js, il n'y a pas d'attribut talib.help sous python...

Cjz140La différence entre la fonction C (Args) et la fonction Sleep est que je pense que c'est la même chose.

3263243yComment effacer le filtre d'erreur après le filtre d'erreur?

Je ne sais pas.Si vous souhaitez utiliser une bibliothèque tierce, quelle est la solution?

Je ne sais pas.Qu'est-ce que la classe mère doit remplir si vous voulez hériter de la nouvelle classe définie par l'objet de l'échange?

ethanwuY a-t-il des outils de débogage locaux?

PénélopeJe ne sais pas si c'est le cas, mais j'aimerais savoir ce que c'est.

PénélopePourquoi la fonction sell est grise, est-ce que la fonction de représentation n'est plus disponible?

PénélopePourquoi la fonction sell est grise, est-ce que la fonction de représentation n'est plus disponible?

PénélopeJS n'est pas un langage, haha, mais je veux savoir si je peux supporter ES6.

PénélopeJS n'est pas un langage, haha, mais je veux savoir si je peux supporter ES6.

Don.Comment écrire la ligne médiane du volume?

la tortueSi vous achetez sur exchange.Buy.1000 au prix du marché, qu'est-ce qui vous revient si vous échouez?

Le fils de NingCette nouvelle police est superbe.

l'hippopotameLe réseau de test de Bitmex (testnet.bitmex.com) dispose également d'une interface API, mais actuellement, les échanges ne peuvent sélectionner que la station principale de Bitmex, dont l'adresse de documentation API est https://testnet.bitmex.com/app/apiOverview. Comment soutenir?

C'est pas vrai.Var ret1 = exchanges[0].IO (("api", "future_estimated_price", "symbol=btc_usd"); Log (('ok futures estimé prix de livraison', ret1); https://dn-filebox.qbox.me/d1ed268c1e75753c5d289447d279aa9d81e41b5f.png Pourquoi appeler les interfaces de fonctionnalités d'autres échanges et écrire une erreur?

allenefrostlineVous voulez savoir quelle est la différence entre realTicker et Ticker? Récemment, la stratégie de réécriture de l'appareil est apparue en même temps, mais il ne semble pas y avoir de mention dans la première API.

les visionsBonjour, en tant que développeur python, que pensez-vous que votre documentation API écrive? Certaines interfaces de champs fonctionnent bizarrement, pouvez-vous écrire un document comme githubpage et readdocs?

allenefrostlineGetAccount: [EAPI: Rate limit exceeded] Vous voulez savoir comment cela fonctionne?

Zjx2314Ne pas prendre en charge StochRSI, peut-on l'ajouter dès que possible?

YhfggLes scripts sont-ils sur leur propre serveur Ali Cloud ou sur le cluster botvs?

YhfggQuelle version de python utilisez-vous?

très bien.L'interprétation de GetFee devrait être de renvoyer une structure de Fee, en moins d'un composant.

Je suis désolée.Est-il possible d'appeler talib avec les méthodes de js?

YhfggRechercher une documentation python

Je suis désolé.Le fond de code de l'éditeur stratégique peut-il être noir?

Don.Comment configurer les résumés dans les messages WeChat des robots?

Numéro: fouEst-il possible d'ajouter un champ de prix égal à la structure des commandes?

Le petit.GetOrders: Retrouve tous les ordres en suspens, renvoie une structure d'arithmétique d'ordres, dans le commerce chinois de Bitcoin ETH, ne renvoie que les 10 articles les plus récents.

YhfggLes fonctions mathématiques nécessaires à la théorie de la probabilité statistique, où les utiliser?

Je vous en prie.Que signifie la valeur de retour de la fonction $.Cross ((x, y)?

Ma grand-mère l'appelaitLe LogReset efface tous les journaux et peut utiliser un paramètre numérique pour spécifier les entrées réservées. Comment faire pour supprimer les derniers logs?

- Je ne sais pas.La fonction CORRE dans talib ne semble pas avoir été transférée ou a-t-elle été oubliée?

La montagne pauvre de LiangyangIl semble qu'il n'y ait pas de fonctionnalité de référence d'indicateur!

Petite ou grandeComment le temps de lecture de la ligne k est-il traduit par le temps actuel oh, je ne comprends pas, trop long, résolu, merci

Petite ou grandeJe n'arrive pas à écrire les nombres dans les entrées avec records.remove (records[0])

le serpentLa ligne K horaire est la ligne habituelle, mais comment appeler ATR pour la ligne K journalier?

le serpentLa ligne K horaire est la ligne habituelle, mais comment appeler ATR pour la ligne K journalier?

57278863Apprenez comment les futures traditionnelles obtiennent des prix et des commandes, désolé, les racines sont minces

le cerveauL'exemple de la négociation traditionnelle de contrats à terme!

Petite ou grandeZero, peux-tu écrire un exemple de négociation traditionnelle de contrats à terme?

Petite ou grandeComment imprimer l'état de stockage de plusieurs objets blancs en même temps, comment imprimer mon [object object], comment obtenir l'état de stockage de plusieurs objets et des objets blancs, ainsi que GetTicker (), comment obtenir la semaine, la semaine suivante et le trimestre de la semaine.

C'est pas vrai.Est-ce que les échanges à terme peuvent obtenir des marchés avec GetTicker (??), et retourner des marchés de ce type de contrat (?? la semaine, la semaine suivante...)?

Ils vendentQuel est l'indicateur StochRSI que vous pouvez ajouter?

le momoxPour annuler une commande en fonction du numéro de commande, retournez true ou false, et demandez true= la cellule a été annulée avec succès, non?

le momoxCette méthode permet de stocker des variables globales qui peuvent être utilisées pour partager des données entre différentes stratégies.

- Je ne sais pas.Une vague de popularité

NulVous pouvez réinitialiser les journaux de revenus avec LogProfitReset.

- Je vous en prieEst-il possible de copier directement l'EA?

Je suis un homme.J'ai trouvé cette plateforme géniale, superbe, beaucoup de communication en groupe.

Petite ou grandeQuelle est cette langue, y a-t-il des ressources pour l'apprendre?

Jeux vidéoUne erreur de données pendant une semaine et je ne peux pas connecter le robot.

Je vous en prie.L'indicateur TA est-il seulement un calcul du prix de clôture?

- Je suis désolé.Salut, tout le monde.

Le petit rêveLa fonction _C essaie sans réfléchir jusqu'à ce que le résultat soit obtenu avec succès.

Le petit rêveLa bibliothèque talib de python doit être installée. https://www.botvs.com/bbs-topic/669 peut être consulté dans ce post.

Le petit rêveSleep est le nombre de millisecondes pendant lesquelles le programme ne fait rien et attend que le paramètre soit défini, _C est la fonction qui appelle à nouveau le paramètre une fois transmis.

Le petit rêveSans héritage, JS est directement enveloppé dans l'objet {name: "nouveau objet", old_exchange : exchange[0],...... }

Le petit rêveL'éditeur local, le plugin de synchronisation à distance, qui est essentiellement un éditeur local, le débogage à distance.

Le petit rêveVous pouvez venir sur le QQ, ^^, c'est facile à discuter~

Le petit rêveDans la documentation de l'API, grise signifie que cette fonction n'a pas trop d'explication étendue, elle est affichée en gris, la représentation en bleu a plus d'explications, c'est tout.

Le petit rêveL'ES6 n'est pas supporté pour le moment ^^

Le petit rêveJe peux aller au groupe QQ, vous pouvez me décrire le problème, je vais y répondre ^^

Le petit rêveLe message de retour est un message d'erreur, et la commande ne sera pas effectuée (en fait, c'est acheter, pas assez d'argent!).

la tortuePar exemple, OKCoin, si la quantité achetée est supérieure à celle détenue, que revient-il?

Le petit rêveJe suis en train d'essayer de trouver un numéro de commande sur lequel je peux retourner un numéro de commande sur OK Futures.

NulLes transactions sont déjà prises en charge lors de l'exécution, vous devez télécharger le dernier hôte. Prise en charge de la documentation API détaillée Bter/Poloniex. Description de la fonction de transaction dans la barre ci-dessous (en supprimant le cache du navigateur et en le rafraîchissant si vous ne le voyez pas)

Le petit rêveJe suis QQ, je vais vous aider à trouver votre problème.

Familles occupéesSi vous avez besoin d'une liste blanche, j'ai configuré l'adresse IP de l'hôte.

Le petit rêveC'est un lien sous-jacent qui n'a pas été créé. Le serveur n'a pas répondu.

Familles occupéesCe qui est embarrassant, c'est que les stratégies que j'ai pu exécuter ont échoué à l'époque des bitcoins et que GetAccount n'a pas pu accéder à GetAccount: Post http://api.btc38.com/v1/getMyBalance.php: read tcp 192.168.0.227:58596->211.149.148.144:80: wsarecv: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. 2017-05-23 21:08:24 L'ère des bitcoins Une erreur GetAccount: timeout 2017-05-23 21:08:02 L'ère des bitcoins Une erreur GetAccount: timeout 2017-05-23 21:07:40 L'ère des Bitcoins Une erreur s'est produite sur GetAccount: timeout 2017-05-23 21:07:20 Relancer le jeu Est-ce que c'est une question de liste blanche d'IP?

Le petit rêveLes serveurs de l'échange ne répondent pas et le protocole TCP n'a pas été mis en place.

Familles occupéesUne tentative de connexion a échoué parce que la partie connectée n'a pas correctement répondu après une période de temps.

Le petit rêveBonjour! Il s'agit de la fonction exchange.IO ((api, ApiName, Args) qui n'est pas prise en charge, voir https://www.botvs.com/bbs-topic/812

Familles occupéesUne tentative de connexion a échoué parce que la partie connectée n'a pas répondu correctement après une période de temps,

Familles occupéesL'ère des bitcoins ne le soutient-elle pas?

Le petit rêvePour les personnes qui ont besoin d'aide, veuillez cliquer sur le lien suivant: https://dn-filebox.qbox.me/a709b30c6cc0a3565234b9e0c99b073f7ba8b454.png Il est normal que ce soit le cas.

Le fils de NingPar exemple, je voulais faire une transaction en poloniex, mais il n'y a que quelques monnaies prises en charge par BOTvs, et exchange.IO ne semble pas prendre en charge le réseau P.

Le petit rêveVous pouvez appeler exchange.IO.

Le fils de NingQu'en est-il des API qui nécessitent une vérification de compte?

Le petit rêveSi l'API ne nécessite pas de vérification de compte, elle peut être utilisée avec httpQuery (voir la documentation BotVS pour plus de détails).

Le petit rêveLes paramètres de l'API HttpQuery peuvent être transmis: https://www.okcoin.com/api/v1/future_estimated_price.do?symbol=btc_usd, c'est tout. Pour les API d'échange qui ne nécessitent pas de vérification de compte, utilisez directement la fonction HttpQuery de la plate-forme. Le blogueur a également publié un article intitulé:

les visionsMerci beaucoup, j'espère que vous aurez une excellente documentation de l'API.

Le petit rêveSi vous voulez savoir où l'API de realTicker a été vue?

Le petit rêveIl est également possible de télécharger des fichiers sur le serveur de téléchargement. La documentation de l'API est en JavaScript. Les articles décrits dans la version python sont placés en haut de la page de la communauté de discussion sur le plugin.

NulBonjour, merci pour l'idée, la documentation de l'API est en cours de refonte.

Le petit rêveBonjour ~ il est indiqué que la fréquence d'accès est dépassée. Pour les personnes qui ont besoin d'aide, veuillez cliquer sur le lien suivant: https://dn-filebox.qbox.me/a09498920d04cac62624b7438a058d2098d8fb00.png La fonction Sleep (1000) est-elle utilisée dans la stratégie? Cette fonction 1000 permet à un programme de suspendre une seconde par tour, qui peut être réglée par lui-même, dans le but de contrôler la fréquence d'accès aux API du programme, car certaines plateformes de change ont fixé une limite d'accès maximale, une certaine durée au-delà d'une certaine fréquence d'accès sera refusée, bloquant l'adresse IP.

Le petit rêveIl est également possible de télécharger des fichiers sur les réseaux sociaux. J'ai écrit personnellement que les indicateurs de STOCHRSI qui ont été comparés à OK sont d'accord, c'est que la vitesse est un peu lente et doit être optimisée pour le moment.

NulVous pouvez choisir d'effectuer des réponses sur le serveur fourni par botvs ou sur le serveur de votre hôte, version 2.7.5.

Le petit rêveIl y a aussi des photos de l'événement.

Le petit rêveMaintenant, vous pouvez configurer votre propre style de fond.

Le petit rêveLa documentation python est en cours d'écriture.

Le petit rêveIl y a aussi une bibliothèque de supports talib.

Je ne sais pas. https://www.botvs.com/bbs-topic/276

Le petit rêveIl semble y avoir un exemple dans Strategy Square, https://www.botvs.com/strategy/15098

NulL'attribut AvgPrice d'Order peut être consulté par les échanges qui le supportent, les échanges qui ne le supportent pas seront toujours 0

YhfggComment les sources tierces sont-elles citées?

NulMathJS ne peut pas répondre à cette demande, il ne peut que rechercher des stratégies de copie et d'importation de bibliothèques tierces. Pour accélérer la compilation, le système n'a que quelques bibliothèques intégrées.

Le petit rêveIl y a un problème dans le groupe où vous pouvez m'envoyer un message - je suis en ligne.

Je vous en prie.Merci beaucoup.

Le petit rêveVous pouvez consulter les annotations de la bibliothèque de crypto-monnaie et analyser les annotations de la fonction $.Cross.

NulVous ne pouvez pas supprimer les derniers articles, vous ne pouvez que conserver les derniers articles, supprimer tous les anciens.

le cerveauPour obtenir chaque position en position[i], position est une matrice

Le fils de NingLes données de l'échange.GetRecords (Période_D1);

le cerveauMon futur traditionnel est toujours de répliquer GetAccount: not login, "pas de mot de passe, pas de connexion".

NulPar défaut, c'est la semaine. Pour obtenir le type de contrat spécifié, vous devez d'abord configurer le type de contrat.

NulComme vous pouvez le voir, cette valeur est la valeur de retour de l'action d'annulation de l'ordre retourné par l'échange, mais l'annulation réelle n'est pas annulée, cela dépend de la façon dont elle est traitée à l'intérieur de l'échange.

le momox3q

NulNon, c'est une séparation.

Je vous en prie.Bien sûr que non, c'est exclusif à MT4.

NulLes ressources JavaScript sont partout sur le web.

Ils vendentVotre problème a-t-il été résolu?

NulLa plupart du temps, les données transmises peuvent être directement des enregistrements ou une matrice de prix pur.