Изобретатель количественно-химический учебный дневник (I) завершен

Автор:Маленькие мечты, Создано: 2016-05-23 23:10:46, Обновлено: 2019-08-01 10:31:25

Раньше редко писали журналы, сейчас чувствую, что нужно ежедневно записывать что-то, не могу ли я смотреть на солнце? Что писать? Записывайте учебу, работу! (на самом деле почти все)).

Вопрос первый:

  • 1, строка K диаграммы иногда пропускает один BAR, ищет BUG. Проблема найдена, проанализирована и не получена при тестировании с диском. На момент получения данных, два BAR уже прошли, поэтому последние данные изображены на графике, что приводит к прохождению одного или нескольких промежутков между ними.
  • 2, бегать некоторое время ((1 минуты циклов K-линии) без проблем, попробуйте снова ((30 минут циклов K-линии) проблема приходит, и неожиданно возникает:

TypeError: cannot read property length of null duk_hobject_props.c:2258 WToneAndWTtwo __FIL Эта ошибка была обнаружена.

Посмотрите ниже, что должно быть ошибкой в функции WToneAndWTtwo, которая читает имя значения null, которое называется свойством length, то есть переменной, например var name = null; затем я Для решения этой ошибки была написана функция: name.length.

function isNullAndLog(arr,strArrName){//空数组报错
     if(!arr){
         Log("arr is:",arr,"name:",strArrName);
         return true;
      }
      return false;
}

Подумайте, хм! Теперь все переменные, используемые для length, я вставляю в эту функцию, чтобы проверить, есть ли нулевые BUG, которые абсолютно не могут быть избегнуты. После 30 минут тестирования на К-линии, мы снова стерли:

TypeError: нельзя прочитать свойство length null duk_hobject_props.c:2258 WToneAndWTtwoФайлОшибка в сообщении.

Бэтти не может понять!!! терпение! выйти и поворачиваться вокруг и поменять мышление, или, может быть, проснуться! Когда я вернулся, я подумал, что это вызов базы показателей, параметры, которые были введены, были нулевыми, когда базы показателей были запущены, была ошибка.

function isNullAndLog(arr,strArrName){//空数组报错
    if(!arr){
        Log("arr is:",arr,"name:",strArrName);
        return true;
    }
    return false;
}

function main(){
   if(typeof(x) === undefined ){
       Log(typeof(x));
   }
    var aaa = null;
    Log(isNullAndLog(aaa));
    /*
    while(!aaa || aaa.length < 9){
        Log("while xunhuan");
        Sleep(5000 * 1000);
    } 
    */
    talib.EMA(aaa,5);
} 

Talib.EMA ((aaa,5); ключевая фраза aaa - null, которую я специально установил, чтобы посмотреть, как это работает. TypeError: Cannot read property length of null ~~OK. Вполне вероятно, что это проблема, продолжайте изменять код.

Вопрос 2:

И еще одна проблема, которая возникла, когда мы думали, что сейчас записываем код:

function DeleteNullEle(initArr){
    var dealArr = [];
    var initArrLen = initArr.length;
    for(var i = 0,j = 0 ; i < initArrLen ; i++,j++){
    //Log("initArr-",i,":",initArr[i]);//ceshi
    if(initArr[i] === null || isNaN(initArr[i]) ){
        j--;
        //Log("i:",i);//ceshi
        continue;
    }
        dealArr[j] = initArr[i];
    }
    //Log("dealArr:",dealArr);//ceshi
return dealArr;
}

Присоединяем эту функцию потому, что некоторые матрицы выглядят так [NaN, NaN, NaN, 22, 3, 56, 78, 4, 23], но когда изобретатель количественно проверяет, что при вводе с функцией Log это показывает null, это означает, что на самом деле это не так. Оставляя меня в замешательстве долгое время, я должен помнить, что если вы видите null, то это может быть NaN, поэтому вы не можете судить об этом.
Еще одна вещь, это это while ((!aaa gbla aaa.length < 10) {...}, если aaa === null, почему это не ошибка, потому что в этом случае выражение этого оператора В!aaa - это верно, поэтому последнее aaa.length может не быть выполнено. Некоторые из API используются.

Вопрос 3:

Кроме того, по просьбе одного из моих друзей, я изменил мониторинг разницы, на самом деле, я добавил диапазон диапазона, и WeChat продвинул, очень просто.

 if (diff != __lastDiff) {
//--------------------------------------------------------------------------------------------
        if(openWeixin){
            if( (diff <= price1 || diff >= price2 ) && off_on === true ){
                Log("差价:"+diff+"微信推送@");
                off_on = false;
                Sleep(1000);
            }else{
                off_on = true;
                Sleep(1000);
                }
        }
//---------------------------------------------------------------------------------------------
        // add添加数据到series, 参数格式为[series序号, 数据];
        __chart.add([0, [new Date().getTime(), diff]]);
        __lastDiff = diff;
    }

img

Код, вставленный между пустыми строками кода, очень прост и, возможно, еще не совершенен.

Вопрос 4 (не проблема, просто запись)

В эти дни в изучении стратегии написания фьючерсов, это более сложный пункт, чем на месте, (к счастью, есть большой фьючерсный торговый шаблон Z, иначе написание деталей сделки достаточно напиться >____

  • exchange.GetPosition() // используется для получения информации о хранении, обратите внимание, что эта функция возвращает массив с структурой позиции, которая содержит информацию о хранении.
  • exchange.SetMarginLevel ((MarginLevel) // Эта функция - это настройка рычага. Конкретные параметры MarginLevel выбор ((5 раз? 10 раз?) зависит от разновидности, биржи, конкретно, некоторые не могут измениться ((например, CTP товарные фьючерсы)
  • exchange.SetDirection ((Direction) // это очень важный API, который вызывается перед нижеприведенным, потому что только что были представлены 4 операции ((продать, открыть позиции...), эта функция устанавливает эти операции ((хотя есть немного дополнительного содержания), есть еще второй параметр CTP, который пока не изучен.
  • exchange.SetContractType ((ContractType) // Перед открытием, тиражированием, один из направлений сделки должен быть определен, а другой должен быть определен, так что с помощью этой функции устанавливается тип контракта. Параметры определяются на разных биржах. По сути, мы используем эти функции. Остальные функции остаются такими же, как и находки.
  • exchange.Buy() // купить
  • exchange.Sell ((() // продать Вот код моего эксперимента, где я выделил только одну часть (можно скопировать в main), чтобы проверить, на какой бирже тестируются товарные фьючерсы:img
 if (!manager) {//Z大写的商品期货模板类库,用来管理交易的对象(manager 初始时null)。不明白的可以去看源代码,QQ群共享有注释版。
        if (_C(exchange.GetPosition).length > 0) {
            throw "策略启动前不能有持仓.";
        }
        Log('交易平台:', exchange.GetName(), _C(exchange.GetAccount));  //输出当前交易所 信息
        var insDetail = _C(exchange.SetContractType, ContractTypeName);  // 用容错函数 _C ,容错调用 SetContractType函数  首先明确 设置交易的合约类型。
        Log("合约", insDetail.InstrumentName, "一手", insDetail.VolumeMultiple, "份, 最大下单量", insDetail.MaxLimitOrderVolume, "保证金率:", insDetail.LongMarginRatio.toFixed(4), insDetail.ShortMarginRatio.toFixed(4), "交割日期", insDetail.StartDelivDate);
        // 上面这个Log 显示出合约的一些信息,注意 在回测的时候,与实际运行的结果不一样,可以看图杠杆都是null,保证金率都是0,可以试试看。
        manager = $.NewPositionManager();  // 这个生成管理者 对象
    }
    exchange.SetMarginLevel(10); //不支持       在这里我试着设置了一下杠杆试试,发现  显示 错误:Not support     ,CTP商品期货 应该不能自己调整杠杆
    var positions = exchange.GetPosition();     在所有的操作前 ,我试着调用了一下 GetPosition 函数  获取一下持仓信息,显示的null
    Log(positions[0]);
    exchange.SetDirection("buy"); // 在所有的操作前需要设置  操作方向  ,这里设置 买开仓(做多)。
    var id = exchange.Buy(1911,1); // 执行买入操作  下了一个  限价单,  有兴趣的同学 可以试试 市价单。(嘿嘿!自己动手记得牢)
    positions = _C(exchange.GetPosition); //再获取下 持仓信息 看看
    Log(positions);  //有持仓信息了,  在上面 Buy的时候  有兴趣的同学 试试 用低价格 买入。  Buy(1000,1) 看看。

Вопрос 5: Сегодня мой друг написал фрагмент кода, в котором спрашивает, что с функцией Sleep (()) произошла большая ошибка, которая повлияла на политику высокой частоты.

function main(){
    for(var i = 0 ; i < 10 ; i++){
        var b1 = 0;
        var b2 = 0;
        var b3 = 15;
        while(b1 < 200){
            var t2s1 = (new Date()).getTime();
            b1++;
            Sleep(b3);
            var t2s6 = (new Date()).getTime();
            b2 += (t2s6 - t2s1);
        }
        Log("Sleep()",b3,"MS",b1,"平均次数",b2/b1);
    }
    throw 2;
}

Я провел ретротест и обнаружил, что функция Sleep в ретротесте будет работать в течение 1 секунды (отклонение времени до и после 1000), и тогда время ошибки в этом тестовом коде очень большое, но если использовать аналогичный диск, то ошибка в основном составляет менее 1 миллисекунды. Возможно, ошибка, вызванная алгоритмом работы системы ретротеста, принадлежит модели песочницы.

Вопрос 6: Сегодня утром мой друг сказал мне, что хост в полночь сломался, и прислал мне системный журнал.

- Это дневник.

runtime/cgo: pthread_create failed: Resource temporarily unavailable
SIGABRT: abort
PC=0x7f332c591cc9 m=2

goroutine 0 [idle]:

goroutine 1 [select, 207 minutes]:

С первой строки видно, что генерирование потока не удалось, ресурсы временно недоступны (недостаточно). Решение: 1, проверяет, работает ли бот с политическим кодом, используются ли ресурсы, которые не были выпущены, используется ли API с несколькими потоками; 2, Использование команды ulimit для проверки ограничений на системе хостера ((Linux) ). Этот блог можно посмотреть: (адрес блога)http://smilejay.com/2012/04/fork_resource/Я не знаю. 3, обратите внимание на использование системной памяти.

Использование ulimit -a:img

Параметры команды ulimit: -H устанавливает ограничения на жесткие ресурсы. -S устанавливает ограничения на программные ресурсы. -a показывает все текущие ограничения ресурсов. -c size: максимальное значение, которое можно установить для основного файла. -d size: максимальное значение, на которое можно установить фрагмент данных. -f size: максимальное значение, которое должно быть установлено для создания файла. -l size: максимальное значение, которое должно быть установлено для блокировки процесса в памяти. -m size: максимальное значение постоянной памяти, которое можно установить. -n size: устанавливает максимальное значение описателей файлов, которые могут быть открыты одновременно в ядре. -p size: максимальное значение, на которое устанавливается буферная зона трубопровода. Единица: кбайт -s size: максимальное значение, на которое можно установить стек. -t size: устанавливает максимальное количество времени использования процессора. -v size: максимальное значение, на которое можно настроить виртуальную память. -u <число программ> Максимальное количество программ, которые могут быть запущены пользователем

Друг, столкнувшийся с этой проблемой, обнаружил, что ошибочная функция фильтрации, возможно, является причиной проблемы, и нашел причину, которая привела к краху хостера (постоянное увеличение памяти); причина заключается в политике. SetErrorFilter (( 502: 503: tcp character unexpected networktimeout WSARecv Connect GetAddr no such reset httppreceived EOF reused ); Функция неправильно использована, она должна быть вызвана только один раз и не может быть написана в циклическую структуру.

Вопрос 7: Простое обобщение функций _C (((), _N (((), _G ((();

  • Функция _C(

Описание: Функция используется в основном для ошибочных API, таких как функция exchange.GetAccount (), которая называется _C ((exchange.GetAccount); обратите внимание, что название функции не включает в себя скобки, и если ошибочная функция требует добавления параметров, она записывается во втором параметре функции _C (), в том числе и в обратном порядке. Используйте примеры.

function main(){
    var account = null;
    var amount = 1;
    var price = 2000;
    account = exchange.GetAccount();
    Log("_C 函数使用前  account :",account);
    //exchange = null; 
    _C(exchange.Buy,price,amount);
    //exchange.Buy(price,1);
    account = exchange.GetAccount();
    Log("_C 函数使用后  account :",account);
}

Полагаю, что функция _C выглядит так:

 function ___C(functionName,p1){
    functionName("执行需要容错的函数,传入的测试参数为:",p1);
    Log("__C 容错函数启动,容错完毕");
}
function main(){
    pstr = "测试参数--hello";
    ___C(Log,pstr);
}

Результаты:img

  • Функция _N( Описание: Эта функция предназначена для обработки слишком большого количества последельных чисел с сохранением нескольких чисел. Примеры:
function main(){
    var pi = 3.1415926535897;
    Log("使用_N函数 前pi:",pi);
    var piOfDeal = _N(pi,2);
    Log("使用_N函数后 pi:",piOfDeal);
}

Результаты:img

  • Функция _G( Описание: Это глобальный словарь, который представлен в документации API и хранится. KV таблицы, постоянно сохраняемые локальные файлы, каждый бот имеет отдельную базу данных, которая существует после перезагрузки или выхода хоста K должен быть номером или строкой, независимо от размера, и V может быть любым, что можно выполнить в JSON. _G ((num, 1); // устанавливает глобальную переменную num, значение которой 1 _G ((num, ok); // Изменить глобальную переменную num, значение которой в строке ok _G ((num, null); // Удалить глобальную переменную num _G ((num); // возвращает значение глобальной переменной num _G(); // возвращает ID текущего робота _G ((null); // Удалить все глобальные переменные
function main(){
    Log("totalYLMoney 初始赋值 0");
    var totalYLMoney = 0;
    Log("totalYLMoney 已赋,  = ",totalYLMoney);
    if(typeof(_G("totalYLMoney_save")) !== "object"){
        totalYLMoney = _G("totalYLMoney_save"); 
        Log("读取 totalYLMoney 本地数据库 名称为totalYLMoney_save 的值 赋给 totalYLMoney ");
    }else{
        totalYLMoney = 100.12546328765458;
        _G("totalYLMoney_save",totalYLMoney.toString());
        Log("记录 totalYLMoney 保存到本地数据库");
    }
    Log("totalYLMoney",totalYLMoney);
    Log("typeof\(_G(\"totalYLMoney_save\"))",typeof(_G("totalYLMoney_save")));
}

Вышеперечисленный _G() код для тестирования функции требует тестирования на роботе, повторное тестирование не поддерживается. Метод тестирования, развернув программу на роботе, в первый раз запускает робот, и робот записывает 100.12546328765458; это значение в глобальном словарь под названием "totalYLMoney_save", снова запуская робот, вы обнаружите, что var totalYLMoney = 0, что после инициализации переменной totalYLMoney все еще читает из словаря значение, сохраненное при первом запуске стратегии.

Вопрос 8: Что вы думаете о стратегии прибыли и убытка:

Часто я вижу новых учеников в группе и спрашиваю о алгоритмах, которые помогают мне заработать деньги и терять деньги.

  • "Я не хочу, чтобы это было так.

Полезная прибыль равна: разделить (сегодняшнюю валюту - начальную валюту) на x нынешней цены + (сегодняшние деньги - начальные деньги)

Пример: Например, начальная цена монеты 10 долларов США, на счету начинается 5 долларов США, 100 долларов США. В течение определенного периода времени я купил 3 монеты по средней цене 15 долларов США. В конце этого периода цена монеты увеличилась до 20 долларов США. В данный момент мой счет составляет: 8 долларов США, 55 долларов США. Profit = (8 - 5) * 20 + (55 - 100) = 60 + (-45) = 15 Этот метод расчета Прибыль 15 юаней. (Примечание: в данный момент ваш доход является плавающим, потому что если в данный момент цена монеты сильно падает, возможно, вы не только не будете иметь прибыли, но и потеряете деньги, конечно, потеря также будет плавающей, потому что ваш доход в это время следует за ценой монеты, причина заключается в том, что вы делаете много плавных неудач, упадок пакета) Дополнительно, если в момент, когда цена монеты составляет 20 долларов США, на 20 долларов США продается 3 монеты, которые были куплены за 15 долларов США, в данный момент счет составляет: 5 монет, 115 долларов США; или алгоритм выше: Profit = (5 - 5) * 20 + (115 - 100) = 15, прибыль остается 15 юаней, разница в том, что если не учитывать первоначальную девальвацию, то прибыль не меняется с ценой.

  • Прибыль на счетах:

Учетная прибыль: (сейчас копейка x нынешняя цена + нынешние деньги) - (начальная копейка x начальная цена + начальные деньги)

Также используйте пример выше: например, начальная цена 10 долларов США, на счету начинается 5 долларов США, 100 долларов США. В течение определенного периода времени я покупаю 3 монета по средней цене 15 долларов США. В конце этого периода цена монеты увеличивается до 20 долларов США. Прибыль = (8 * 20 + 55) - (5 * 10 + 100) = 215 - 150 = 65 Этот метод вычисления прибыль 65 долларов. Прибыль = (5 * 20 + 115) - (5 * 10 + 100) = 215 - 150 = 65 в том же порядке.

Сравнение этих двух методов, прибыль 15, прибыль 65, на самом деле несложно увидеть. Первый метод игнорирует прибыль и убытки от повышения девальвации первоначального держателя. Второй алгоритм рассчитывает прибыль и убытки, включая прибыль от повышения девальвации первоначального держателя. Считается, что расчетная прибыль применяется для расчетов средств. Плавающая прибыль применяется к прибыли и убыткам, полученным в результате сделки в течение определенного периода времени. Это некоторые из опытов, если есть ошибки, пожалуйста, оставьте правильные отзывы, спасибо заранее ^-^

Вопрос 9: Один из членов группы увидел, что в таблице отображается строка состояния открытой политики, поэтому он перешел к следующему API и обнаружил, что, по-видимому, была добавлена новая функция, которая позволяет рисовать таблицы с помощью функции LogStatus.

Сначала посмотрите на API платформы:

LogStatus(Msg); //	此信息不保存到日志列表里, 只更新当前机器人的状态信息, 在日志上方显示, 可多次调用, 更新状态
LogStatus('这是一个普通的状态提示');
LogStatus('这是一个红色字体的状态提示 #ff0000');
LogStatus('这是一个多行的状态信息\n我是第二行');
var table = {type: 'table', title: '持仓信息', cols: ['列1', '列2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]};
LogStatus('`' + JSON.stringify(table)+'`'); // JSON序列化后两边加上`字符, 视为一个复杂消息格式(当前支持表格)
LogStatus('第一行消息\n`' + JSON.stringify(table)+'`\n第三行消息'); // 表格信息也可以在多行中出现
LogStatus('`' + JSON.stringify([table, table])+'`'); // 支持多个表格同时显示, 将以TAB显示到一组里

Проверка кода:

function main(){
    var value1 = 99;
    var value2 ="ceshi 01";
    var table1 = { type : "table", title : "ceshi1", cols : ["列1","列2","列3"] , rows : [ ["abc","def","ghi"] , ["1","2","3"] ] };
    var table2 = { type : "table", title : "ceshi2", cols : ["列1","列2","列3"] , rows : [ ["abc",value1,"ghi"] , [value2,"2","3"] ] };
    LogStatus("测试文本1\n`" + JSON.stringify([table1,table2]) + "`");
}

imgПервый рисунок показывает, что в разделительной таблице ceshi1 формат данных таблицы - var table1 и var table2 - объявленные переменные. Конечно, в таблице table1 все содержится в фиксированных строках. Следует отметить, что перед функцией JSON.stringify (([table1,table2]) необходимо добавить `; иначе таблица не будет показана. Конечно, мы должны использовать таблицы для динамического отображения некоторых данных, но не всегда они должны быть фиксированным текстовым контентом. В разделе table2 есть два теста, value1 и value2.imgНовые ученики могут копировать код, самостоятельно пробовать, изменять.

Вопрос 10: Пользователь хочет получить график доходности, возможно, в настоящее время описание API-документа, количественно измеренного изобретателем, является более простым, а использование графиков может быть более сложным.

Я использовал случайные аналоги динамических изменений доходности, чтобы показать кривую доходности на графике.

var ChartObj = {//画图
    tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A',enabled:true,valueDecimals:2,valueSuffix:'%'}, //提示框  就是鼠标在线上时 显示的一个 框框 里面有一些内容,这里是设置提示框的格式
    chart: { zoomType:'x',panning:true },//图表缩放  
    title: { text: '收益率 %'}, //标题
    rangeSelector: { //范围 区域 选择 
            buttons:  [{type: 'hour',count: 1, text: '1h'}, {type: 'hour',count: 3, text: '3h'}, {type: 'hour', count: 8, text: '8h'}, {type: 'all',text: 'All'}],
            selected: 0,
            inputEnabled: false
        },
    subtitle: {text: " 显示瞬时收益率 % "},//副标题
    xAxis:{type: 'datetime'}, //设置 X轴  的数值为时间类型
    yAxis: [{
            title: {text: '收益率 %'},//标题
            style: {color: '#4572A7'},//样式 
            //opposite: false  //生成右边Y轴
        }
    ],
    series: [//系列
        {name:'收益率',dataLables:{enabled:true,format:'{y} %'},type:'spline',yAxis:0,data:[]} //该图标只用到一条曲线  ,所以 只用设置一个数据序列
        ]                  
};
var chart = Chart(ChartObj);  //初始化

function main(){ //测试用的主函数
    chart.update(ChartObj); //更新
    chart.reset(); //清空图表
    var i = 0; //初始一个 i 值 , 后面循环用,   用来限制循环次数
    var randomNum = 0; //声明一个  随机数 初始化 0
    while(i < 5000){ //限制循环次数
        randomNum = Math.random() * 10;  // 生产随机数 0  -  9.9999
        //chart.add([0,[(new Date()),randomNum]]);
        chart.add(0,[(new Date()).getTime(),randomNum + 5]);  //把生成的随机数  按照时间(X 坐标)     把随机数 画在图表上(Y坐标)     
        Sleep(1000*60); // 程序 每次循环暂停60秒
        //chart.update(ChartObj);
        //chart.reset(500);
    }
    Log("over");
}
  • Вот одна проблема, которая озадачила меня полдня, и записываю её. Когда я пишу время, я пишу: new Date (().getTime (() Это миллисекундное число, если это new Date (()) то возникает небольшая проблема, например, время отображается, и масштабирование на оси X не используется. Также есть инструмент: {xDateFormat: %Y-%m-%d %H:%M:%S, %A, enabled:true,valueDecimals:2,valueSuffix:%}, этот настрой видится в просмотре материала. valueDecimals:2 ограничивает отображение значения оси Y, сохраняя 2-значные дроби, valueSuffix:%' в конце содержания в подсказке плюс этот символ %.

Больше

ЛиусингхуайУчитель Маленькой Мечты, пожалуйста, скажите мне, как я могу отменить все незавершенные заказы после заказа?

ЛуисЭто должно быть похвально!

Сильный дождьХорошая вещь... многое не сказано в документации API.

ОсеньШейх Мун всегда содержит хорошие вещи.

Короткая линия Ван Вон продает стратегию высокой ценыХорошая штука!

Маленькие мечтыБудьте любезны https://dn-filebox.qbox.me/bf52888dc68aba5326c403f2280994e81fbce2ee.png Ссылка на учебник: https://www.botvs.com/bbs-topic/475

Маленькие мечтыЭто очень удобно для обучения!