понедельник, 26 марта 2018 г.

Вывод в excel

import openpyxl
from openpyxl import Workbook
import os, errno


dat ={}
def put_excel(index, name, val):
    global dat
    dat[index] =  {'name':name,'val':val}

def put_name():
    global dat
    fg = []
    for key in dat.keys():
        fg.append(dat[key]['name'])
    ws.append(fg)

def put_val():
    global dat
    fg = []
    for key in dat.keys():
        fg.append(dat[key]['val'])
    ws.append(fg)


wb = Workbook()
ws = wb.active

# описываем заголовки таблицы:
# в такой последовательности будут выводится
put_excel(1,'open', 0)
put_excel(2,'high', 0)
put_excel(3,'low',  0)
put_excel(4,'close', 0)

#выводим заголовки в таблицу
put_name()

i=1
while i  <  5:
    put_excel(1,'open', 10+i)
    put_excel(2,'high', 20+i)
    put_excel(3,'low',  30+i)
    put_excel(4,'close', 40+i)
    i=i+1
    # выводим строку со значениями
    put_val()


wb.save(os.path.dirname(os.path.abspath(__file__)) + "/excel.xlsx")

пятница, 23 марта 2018 г.

ubuntu 16.04 python3-openpyxl

$ sudo apt update
$ sudo apt upgrade
$ sudo apt install python3-openpyxl

import openpyxl
import os
from openpyxl import Workbook

#try:
    #os.remove( "./exmo_excel.xlsx"))
#except OSError as e: # this would be "except OSError, e:" before Python 2.6
    #if e.errno != errno.ENOENT: # errno.ENOENT = no such file or directory
        #raise # re-raise exception if a different error occurred
#l = open("./tester.txt", 'a', encoding='utf-8')

# Создадим Excel файл
wb = Workbook()
ws = wb.active
# Вставим заголовки
ws.append(["Дата", "ID", "Тип сделки", "Кол-во", "Цена", "Сумма"])

# Сохраняем файл
wb.save(os.path.dirname(os.path.abspath(__file__)) + "/excel.xlsx")

среда, 21 марта 2018 г.

Cвечи plx

Особенности формирования неполной свечи,
Неполная свеча появляется когда в sql запрос попадает хотя бы одна сделка
а неполном периоде:
timestamp x =  1521933300

Расчет свечей из кэша :
data1 = [{'date': 1521929700, 'open': 8640.0, 'high': 8717.0, 'low': 8610.81133606, 'close': 8694.24124667}, {'date': 1521930600, 'open': 8694.24124712, 'high': 8719.44583815, 'low': 8650.76841592, 'close': 8667.85584522}, {'date': 1521931500, 'open': 8667.83364934, 'high': 8683.19046025, 'low': 8613.02673386, 'close': 8630.0}, {'date': 1521932400, 'open': 8630.0, 'high': 8653.33548722, 'low': 8610.81133606, 'close': 8653.33548722}]
cand2_st =  1521933300
cand2_end =  1521933300

data2= []

Удаляем последнюю свечу
data1 = [{'date': 1521929700, 'open': 8640.0, 'high': 8717.0, 'low': 8610.81133606, 'close': 8694.24124667}, {'date': 1521930600, 'open': 8694.24124712, 'high': 8719.44583815, 'low': 8650.76841592, 'close': 8667.85584522}, {'date': 1521931500, 'open': 8667.83364934, 'high': 8683.19046025, 'low': 8613.02673386, 'close': 8630.0}, {'date': 1521932400, 'open': 8630.0, 'high': 8653.33548722, 'low': 8610.81133606, 'close': 8653.33548722}]

Добавим последню свечу
Если data2 не пустой
Список в работу целиком :
data1 = [{'date': 1521929700, 'open': 8640.0, 'high': 8717.0, 'low': 8610.81133606, 'close': 8694.24124667}, {'date': 1521930600, 'open': 8694.24124712, 'high': 8719.44583815, 'low': 8650.76841592, 'close': 8667.85584522}, {'date': 1521931500, 'open': 8667.83364934, 'high': 8683.19046025, 'low': 8613.02673386, 'close': 8630.0}, {'date': 1521932400, 'open': 8630.0, 'high': 8653.33548722, 'low': 8610.81133606, 'close': 8653.33548722}]
—---------------------------------------------------------------------------------------------------------------------------------—
timestamp x =  1521933310
Расчет свечей из кэша :
data1 = [{'date': 1521930600, 'open': 8694.24124712, 'high': 8719.44583815, 'low': 8650.76841592, 'close': 8667.85584522}, {'date': 1521931500, 'open': 8667.83364934, 'high': 8683.19046025, 'low': 8613.02673386, 'close': 8630.0}, {'date': 1521932400, 'open': 8630.0, 'high': 8653.33548722, 'low': 8610.81133606, 'close': 8653.33548722}, {'date': 1521933300, 'open': 8653.13572438, 'high': 8653.13572438, 'low': 8653.13572438, 'close': 8653.13572438}]
cand2_st =  1521933300
cand2_end =  1521933310

data2= [{'date': 1521933300, 'open': 8653.13572438, 'high': 8653.13572438, 'low': 8653.13572438, 'close': 8653.13572438}]

Удаляем последнюю свечу
data1 = [{'date': 1521930600, 'open': 8694.24124712, 'high': 8719.44583815, 'low': 8650.76841592, 'close': 8667.85584522}, {'date': 1521931500, 'open': 8667.83364934, 'high': 8683.19046025, 'low': 8613.02673386, 'close': 8630.0}, {'date': 1521932400, 'open': 8630.0, 'high': 8653.33548722, 'low': 8610.81133606, 'close': 8653.33548722}, {'date': 1521933300, 'open': 8653.13572438, 'high': 8653.13572438, 'low': 8653.13572438, 'close': 8653.13572438}]

Добавим последню свечу
Если data2 не пустой
Список в работу целиком :
data1 = [{'date': 1521930600, 'open': 8694.24124712, 'high': 8719.44583815, 'low': 8650.76841592, 'close': 8667.85584522}, {'date': 1521931500, 'open': 8667.83364934, 'high': 8683.19046025, 'low': 8613.02673386, 'close': 8630.0}, {'date': 1521932400, 'open': 8630.0, 'high': 8653.33548722, 'low': 8610.81133606, 'close': 8653.33548722}, {'date': 1521933300, 'open': 8653.13572438, 'high': 8653.13572438, 'low': 8653.13572438, 'close': 8653.13572438}]


# candel_polo_5x.py
import time
import json
import requests
import urllib, http.client
import hmac, hashlib
import mysql.connector
import sys
import os, errno
import calendar
import numpy
import talib

from datetime import datetime

#Начало и конец свечей PERIOD1  # get_ticks (cand1_st, cand1_end, PERIOD1)
#MACD=26
MACD=2

PERIOD = 15 # минут
cand1_st = calendar.timegm((2018, 3, 24, 22, 0, 0, 0, 0, 0)) # время UTC
cand1_end = calendar.timegm((2018, 3, 25, 2, 0, 0, 0, 0, 0)) # время UTC

#1518628155 Начало базы 2018-02-14 20:09:15
#print('Начало базы', datetime.fromtimestamp(1518628155))
#Установим дату и время начала тестирования
#time_start = (2018, 1, 1, 0, 0, 0, 0, 0, 0) #Время UTC
time_start = (2018, 3, 24, 23, 0, 0, 0, 0, 0) #Время UTC

#timestampstart = time.mktime(time_start) #Локальное время
timestampstart = calendar.timegm(time_start) # время UTC
x=timestampstart
#x=1509494400
#x=1509494399
#x=1521932451
#x=1521932400
#x=1521932401
#x=1521933300
#x=1521933299
x=1521933300

print('Начало тестирования utc ', datetime.utcfromtimestamp(timestampstart))
#Установим дату и время завершения тестирования
#time_end = (2018, 3, 20, 0, 0, 0, 0, 0, 0) #Время UTC
time_end = (2018, 3, 25, 1, 0, 0, 0, 0, 0) #Время UTC
#time_end = (2018, 3, 13, 15, 0, 0, 0, 0, 0) #Время UTC
#time_end = (2018, 3, 20, 5, 0, 0, 0, 0, 0) #Время UTC
#timestampend = time.mktime(time_end) #Локальное время
timestampend = calendar.timegm(time_end) # время UTC
print('Заввершение тестирования utc ', datetime.utcfromtimestamp(timestampend))
y=timestampend

USE_LOG = True
DEBUG = False # True - выводить отладочную информацию, False - писать как можно меньше
numpy.seterr(all='ignore')


# Свой класс исключений
class ScriptError(Exception):
    pass
class ScriptQuitCondition(Exception):
    pass
    
def is_nan(x):
    return (x is numpy.nan or x != x)


# Получаем данные, необходимые для построения индикаторов
#def get_ticks(pair):
def get_sql(st, end, PER):
    #global y
    #global x
    #_SQL = """select * from trade"""
    #x=int(time.time())
    #print('y = ',y)
    #print(datetime.fromtimestamp(y))
    pr = PER * 60
    #x= y - pr*50  #Для построения MACD требуется примерно 50 периодов свечей
    #_SQL = """select * from trade where date between 1519318790 and 1519318800; """
    _SQL = """SELECT
                    FLOOR(MIN(`date`)/%s)*%s AS date,
                    SUBSTRING_INDEX(MIN(CONCAT(`date`, '_', id, '_', rate)), '_', -1) AS `open`,
                    MAX(rate) AS high,
                    MIN(rate) AS low,
                    SUBSTRING_INDEX(MAX(CONCAT(`date`, '_', id, '_', rate)), '_', -1) AS `close`
              FROM trade
              WHERE date >= %s and date <= %s
              GROUP BY FLOOR(`date`/%s)
              ORDER BY date"""

    db = mysql.connector.connect(host="localhost", user="u", passwd="secret", db="polo")
    #db = mysql.connector.connect(host="10.8.1.1", user="u", passwd="secret", db="exmo")
    cur = db.cursor()
    try:
        cur.execute(_SQL,(pr,pr,st,end,pr))
        sdata=[]
        for item in cur.fetchall():
            sdata.append({'date':int(item[0]),'open':float(item[1]),'high':float(item[2]),'low':float(item[3]),'close':float(item[4])})
    except Exception as e:
        log(e)
    cur.close()
    db.close()
    #print(sdata)
    return sdata

# Выводит всякую информацию на экран, самое важное скидывает в Файл log.txt
def log(*args):
    if USE_LOG:
        l = open("./candel_polo.txt", 'a', encoding='utf-8')
        print(datetime.now(), *args, file=l)
        #print(datetime.fromtimestamp(y+3*60*60), *args, file=l) #Локальное время
        #print(datetime.utcfromtimestamp(y), *args, file=l)  #UTC

        l.close()
    print(datetime.now(),' ', *args)
    #print(datetime.fromtimestamp(y+3*60*60),' ', *args) #Локальное время
    #print(datetime.utcfromtimestamp(y),' ', *args) #UTC

def get_ticks (d, data, flg):
    global PERIOD
    global MACD
    # d текщее время на которое расчитывается свеча
    # data список предварительно рассчитанные свечи
    DEBUG = True
    if flg: #flg = True для ускорения используем кэш предрасчитанные свечи в списке data
        data1=[] #перегрузим  сюда свечи  до времени d с учетом запаса для расчета MACD
        for offset, elem in enumerate(data):
            #if True:
            if (data[offset]['date'] <=d) and (data[offset]['date'] >= (d - PERIOD*MACD*2*60)):
                data1.append(data[offset]) #не пропускаем последнюю свечу!
        cand2_st = data1[-1]['date'] # из последней свечи возьмем возьмем начала периода для расчета неполной свечи
        cand2_end = d # время UTC
        data2=get_sql(cand2_st, cand2_end, PERIOD) #расчет неполной свечи на момент d
        data1.pop() #удалим последнюю, полную закрытую свечу
        if len(data2)>0: # при расчете свечи на момент d может вернуться пустой список (если сделок не было)
            data1.append(data2[-1])
        if DEBUG: #отладка
            print()
            print('Расчет свечей из кэша :')
            print('data1 =', data1)
            print('cand2_st = ', cand2_st)
            print('cand2_end = ', cand2_end)
            print()
            print('data2=',data2)
            print()
            print("Удаляем последнюю свечу")
            print('data1 =', data1)
            print()
            print('Добавим последню свечу')
            print('Если data2 не пустой')
            print('Список в работу целиком :')
            print('data1 =', data1)
        return data1
    else: #flg = False свечи рассчитываются напрямую запросом sql
        cand2_st = d - PERIOD*MACD*2*60 # время UTC
        cand2_end = d # время UTC
        data2=get_sql(cand2_st, cand2_end, PERIOD)
        if DEBUG:# отладка
            print()
            print('Тоже напрямую через SQL :')
            print('cand2_st = ', cand2_st)
            print('cand2_end = ', cand2_end)
            print()
            print('data2 =', data2)
        return data2



log('свечи PERIOD = ',PERIOD, ' мин')
#log('начало запроса', datetime.utcfromtimestamp(x))
#log('окончание запроса', datetime.utcfromtimestamp(y))
#print('Начало запроса',datetime.now()) #UTC
data=get_sql(cand1_st, cand1_end, PERIOD)
#print(data)
#print('Конец запроса', datetime.now()) #UTC
#print(data)
print('текущее время x',datetime.utcfromtimestamp(x)) #UTC
print('timestamp x = ',x)

#while True:
data1=get_ticks(x, data, True)
#data1=get_ticks(x, data, False)
x=1521933310
data1=get_ticks(x, data, True)


#print(data1[-1])
#print(data1)
#x = x +3600

#x=x+1
#data2=get_sql(x-100, x, PERIOD)
#print(data2)

Заполнение базы plx

#sql_pol.1.4.py
#import numpy
#import talib
import requests
import json
import time
import calendar
import mysql.connector
import sys
from datetime import datetime
#from matplotlib.finance import candlestick2_ohlc
#i#mport matplotlib.animation as animation
#import matplotlib.pyplot as plt
#import matplotlib.ticker as ticker
from datetime import datetime
k=0
NO_DATA = False

def get_date(str_date):
    #https://pythonworld.ru/moduli/modul-time.html
    #print(str_date)
    t1=time.strptime(str_date,'%Y-%m-%d %H:%M:%S')
    #print(t1)
    t2 = calendar.timegm(t1)
    #print(t2)
    #print(datetime.utcfromtimestamp(t2))
    return t2


def get_polo():
    global NO_DATA
    global k
    global st_time
    global end_time
    pair = 'USDT_BTC'
    time.sleep(0.2)
    #chart_data={}
    #manual http://docs.python-requests.org/en/master/user/advanced/#request-and-response-objects
    while True:
        try:
            log('requests.get')
            #response  = requests.get('https://poloniex.com/public?command=returnTradeHistory&currencyPair=%s&start=%s&end=%s' % (pair,st_time,end_time), timeout = None)
            response  = requests.get('https://poloniex.com/public?command=returnTradeHistory&currencyPair=%s&start=%s&end=%s' % (pair,st_time,end_time), timeout = 5)
            log('response.status_code =', response.status_code)
            if response.status_code == 200:
                break
            else:
                log('response.status_code =', response.status_code)
        except Exception as e:
            log(e)
    chart_data = json.loads(response.text)
    k=-1
    if type(chart_data) is list:
        k = len(chart_data)
    #print('st_time = ', st_time)
    #print('end_time = ', end_time)
    #print('k = ',k)
    print(chart_data[-1])
    return chart_data


def update_trade(data):
    PAIR = 'BTC_USD'
    db = mysql.connector.connect(host="localhost", user="u", passwd="secret", db="polo")
    cur = db.cursor()
    #[{'globalTradeID': 355563163, 'tradeID': 20847088, 'date': '2018-03-20 17:31:49', 'type': 'buy', 'rate': '8775.87720002', 'amount': '0.00131316', 'total': '11.52413090'}]   
    #print(data)
    try:
        for item in reversed(data):
            _SQL = """insert ignore into trade
                      (gtrade_id, trade_id, date, type, rate, amount, total)
                      values
                      (%s,%s,%s,%s,%s,%s,%s)"""
            cur.execute(_SQL, (item['globalTradeID'], item['tradeID'], get_date(item['date']), item['type'], item['rate'], item['amount'],item['total']))
            db.commit()
    except Exception as e:
        log(e)
    cur.close()
    db.close()


def verify_trade():
    global st_time
    global end_time
    db = mysql.connector.connect(host="localhost", user="u", passwd="secret", db="polo")
    cur = db.cursor()
    try:
        _SQL = """select count(1) FROM trade
                  WHERE (date >=  %s and date <= %s)"""
        cur.execute(_SQL,(st_time, end_time))
        arr = cur.fetchall()
        #print(arr)
        #print('число записей ', arr[0][0])
        db.commit()
        return int(arr[0][0])
    except Exception as e:
        log(e)
    cur.close()
    db.close()

def update_verify():
    global st_time
    global end_time
    global k
    db = mysql.connector.connect(host="localhost", user="u", passwd="secret", db="polo")
    cur = db.cursor()
    try:
        _SQL = """insert ignore into  verify
                  (st_time, end_time, count)
                  values (%s,%s,%s)"""
        cur.execute(_SQL, (st_time, end_time, k))
        db.commit()
    except Exception as e:
        log(e)
    cur.close()
    db.close()

def get_end_time():
    db = mysql.connector.connect(host="localhost", user="u", passwd="secret", db="polo")
    cur = db.cursor()
    try:
        _SQL = """select end_time from  verify
                  order by end_time desc limit 1"""
        cur.execute(_SQL)
        arr = cur.fetchall()
        #print(arr)
        #print('число записей ', arr[0][0])
        db.commit()
        return int(arr[0][0])
    except Exception as e:
        log(e)
    cur.close()
    db.close()

def count_verify():
    db = mysql.connector.connect(host="localhost", user="u", passwd="secret", db="polo")
    cur = db.cursor()
    try:
        _SQL = """select count(1) FROM verify"""
        cur.execute(_SQL)
        arr = cur.fetchall()
        #print(arr)
        #print('число записей ', arr[0][0])
        db.commit()
        return int(arr[0][0])
    except Exception as e:
        log(e)
    cur.close()
    db.close()

def log(*args):
    #if USE_LOG:
    l = open("./sql_pol.txt", 'a', encoding='utf-8')
    print(datetime.now(), *args, file=l)
    #print(datetime.fromtimestamp(y), *args, file=l) #Локальное время
    #print(datetime.utcfromtimestamp(y), *args, file=l) #UTC
    l.close()
    print(datetime.now(),' ', *args)
    #print(datetime.fromtimestamp(y+3*60*60),' ', *args)
    #print(datetime.utcfromtimestamp(y),' ', *args)


   
#Установим дату и время начала заполнения
# UTC
time_start = (2017, 1, 1, 0, 0, 0, 0, 0, 0)  #Время UTC
timestampstart = calendar.timegm(time_start) # время UTC
#Установим дату и время завершения заполнения
#UTC
if False: #True -заданное время  False текущее
    time_end = (2018, 3, 23, 20, 0, 0, 0, 0, 0) #Время UTC
    timestampend = calendar.timegm(time_end) # время UTC
else:
    timestampend  = time.time()
print('Время завершения выполнения', datetime.utcfromtimestamp(timestampend))


timeplus = 3600
st_time=timestampstart
log('count_verify()= ', count_verify())
if count_verify() > 0:
    log('get_end_time() = ', get_end_time())
    st_time=get_end_time() + 1
    log('Продолжаем работу c ', datetime.utcfromtimestamp(st_time))
log('Начало')
# Бесконечный цикл процесса - основная логика
#update_mysql(get_polo())
#if False:
if True:
    while True:
        #i=1
        #while i<5:
        try:
            if st_time > timestampend:
                log('Завершение заполнения базы', datetime.fromtimestamp(timestampend))
                sys.exit()
            #print('st_time = ', st_time)
            end_time=st_time+timeplus
            #print('end_time = ', end_time)
            i = 0
            while  i < 10 :
                try:
                    Flag = False
                    data=get_polo()
                    if type(data) is list:
                        Flag = True
                        if len(data) > 0:
                            update_trade(data)
                            count=verify_trade()
                            log('Верифицировано!') #Добавляем в sql запись
                            log('с ', datetime.utcfromtimestamp(st_time))
                            log('по ', datetime.utcfromtimestamp(end_time))
                            log('Количество записей ',k)
                            update_verify()
                            k=0
                            break
                        else:
                            log('Список нулевой длины  len(data) :',len(data))
                    else:
                        Flag = False
                        print('type(data) : ', type(data))
                    i = i + 1
                except Exception as e:
                    log(e)
                    time.sleep(1)
            if not Flag :
                log('Аварийное Завершение заполнения базы', datetime.fromtimestamp(st_time))
                log('Попытки получить данные из интернета неудачны')
                sys.exit()
            if k  > 0 :
                update_trade(data)
                count=verify_trade()
            else:
                count = 0
            if count == k :
                log('Верифицировано!') #Добавляем в sql запись
                log('с ', datetime.utcfromtimestamp(st_time))
                log('по ', datetime.utcfromtimestamp(end_time))
                #print('st_time = ', st_time)
                #print('end_time = ', end_time)
                log('Количество записей ',k)
                update_verify()
                k=0
            else:
                log('Аварийное Завершение заполнения базы', datetime.fromtimestamp(st_time))
                log('Не совпадение количества записе!')
                sys.exit()
            st_time=end_time+1 #Предполагаем что правая  граница  на polonix
            time.sleep(1)
            #i=i+1
        except Exception as e:
            log(e)

вторник, 20 марта 2018 г.

Настройка базы

https://poloniex.com/public?command=returnTradeHistory&currencyPair=USDT_BTC&start=1518628155&end=1518629000

$ sudo mysql -u root -p
(Можно задать пароль)

MariaDB [(none)]> create database polo;

Задать учетную запись u для базы polo с паролем secret

MariaDB [(none)]> grant all on polo.* to 'u' identified by 'secret';

MariaDB [(none)]> quit

$ mysql -u u -p polo

MariaDB [exmo]> create table trade (
id int auto_increment primary key,
ts timestamp default current_timestamp,
gtrade_id int not null,
trade_id int not null,
date int not null,
type varchar(4) not null,
rate decimal(30,8) not null,
amount decimal(30,8) not null,
total decimal(30,8) not null );

MariaDB [polo]> CREATE UNIQUE INDEX gtrade_id ON trade(gtrade_id);
MariaDB [polo]> CREATE UNIQUE INDEX trade_id ON trade(trade_id);
MariaDB [polo]> CREATE INDEX date ON trade(date);
MariaDB [polo]> CREATE INDEX rate ON trade(rate);
 
MariaDB [polo]> describe trade;
+-----------+---------------+------+-----+-------------------+----------------+
| Field     | Type          | Null | Key | Default           | Extra          |
+-----------+---------------+------+-----+-------------------+----------------+
| id        | int(11)       | NO   | PRI | NULL              | auto_increment |
| ts        | timestamp     | NO   |     | CURRENT_TIMESTAMP |                |
| gtrade_id | int(11)       | NO   | UNI | NULL              |                |
| trade_id  | int(11)       | NO   | UNI | NULL              |                |
| date      | int(11)       | NO   | MUL | NULL              |                |
| type      | varchar(4)    | NO   |     | NULL              |                |
| rate      | decimal(30,8) | NO   | MUL | NULL              |                |
| amount    | decimal(30,8) | NO   |     | NULL              |                |
| total     | decimal(30,8) | NO   |     | NULL              |                |
+-----------+---------------+------+-----+-------------------+----------------+

9 rows in set (0.00 sec)
 
  
$ mysql -u u -p polo



MariaDB [exmo]> create table verify ( 
id int auto_increment primary key,
ts timestamp default current_timestamp,
st_time int not null,
end_time int not null,
count int not null);
  
MariaDB [polo]> CREATE UNIQUE INDEX end_time ON verify(end_time);
 
MariaDB [polo]> describe verify;
+----------+-----------+------+-----+-------------------+----------------+
| Field    | Type      | Null | Key | Default           | Extra          |
+----------+-----------+------+-----+-------------------+----------------+
| id       | int(11)   | NO   | PRI | NULL              | auto_increment |
| ts       | timestamp | NO   |     | CURRENT_TIMESTAMP |                |
| st_time  | int(11)   | NO   |     | NULL              |                |
| end_time | int(11)   | NO   | UNI | NULL              |                |
| count    | int(11)   | NO   |     | NULL              |                |
+----------+-----------+------+-----+-------------------+----------------+
5 rows in set (0.00 sec)
 
  
MariaDB [polo]> delete from  verify; 
 
MariaDB [polo]> delete from  trade;
Query OK, 15 rows affected (0.00 sec)
 
python3 sql_pol.py
k =  13
[{'globalTradeID': 355582604, 'tradeID': 20851900, 'date': '2018-03-20 18:33:30',
 'type': 'buy', 'rate': '8805.27999977', 'amount': '0.01230000', 'total': '108.30494399'},
 {'globalTradeID': 355582602, 'tradeID': 20851899, 'date': '2018-03-20 18:33:29',
 'type': 'sell', 'rate': '8805.00000000', 'amount': '0.00017037', 'total': '1.50010785'},
 {'globalTradeID': 355582601, 'tradeID': 20851898, 'date': '2018-03-20 18:33:29',
 'type': 'sell', 'rate': '8805.00000000', 'amount': '0.00017037', 'total': '1.50010785'},
 {'globalTradeID': 355582599, 'tradeID': 20851897, 'date': '2018-03-20 18:33:29',
 'type': 'sell', 'rate': '8805.00000000', 'amount': '0.00017037', 'total': '1.50010785'},
 {'globalTradeID': 355582597, 'tradeID': 20851896, 'date': '2018-03-20 18:33:29',
 'type': 'sell', 'rate': '8805.00000000', 'amount': '0.00017037', 'total': '1.50010785'},
 {'globalTradeID': 355582593, 'tradeID': 20851895, 'date': '2018-03-20 18:33:28',
 'type': 'buy', 'rate': '8805.27999978', 'amount': '0.00085355', 'total': '7.51574674'},
 {'globalTradeID': 355582583, 'tradeID': 20851894, 'date': '2018-03-20 18:33:26',
 'type': 'sell', 'rate': '8805.00000000', 'amount': '0.00028395', 'total': '2.50017975'},
 {'globalTradeID': 355582581, 'tradeID': 20851893, 'date': '2018-03-20 18:33:26',
 'type': 'sell', 'rate': '8805.00000000', 'amount': '0.00028395', 'total': '2.50017975'},
 {'globalTradeID': 355582579, 'tradeID': 20851892, 'date': '2018-03-20 18:33:26',
 'type': 'sell', 'rate': '8805.00000000', 'amount': '0.00017037', 'total': '1.50010785'},
 {'globalTradeID': 355582578, 'tradeID': 20851891, 'date': '2018-03-20 18:33:26',
 'type': 'sell', 'rate': '8805.00000000', 'amount': '0.00028395', 'total': '2.50017975'},
 {'globalTradeID': 355582577, 'tradeID': 20851890, 'date': '2018-03-20 18:33:26',
 'type': 'sell', 'rate': '8805.00000000', 'amount': '0.00028395', 'total': '2.50017975'},
 {'globalTradeID': 355582576, 'tradeID': 20851889, 'date': '2018-03-20 18:33:26',
 'type': 'buy', 'rate': '8805.27999980', 'amount': '0.00400478', 'total': '35.26320923'},
 {'globalTradeID': 355582571, 'tradeID': 20851888, 'date': '2018-03-20 18:33:25',
 'type': 'buy', 'rate': '8805.27999980', 'amount': '0.00136569', 'total': '12.02528284'}]
 
MariaDB [polo]> select * from trade;
MariaDB [polo]> select * from trade;
+----+---------------------+-----------+----------+------------+------+---------------+------------+--------------+
| id | ts                  | gtrade_id | trade_id | date       | type | rate          | amount     | total        |
+----+---------------------+-----------+----------+------------+------+---------------+------------+--------------+
| 52 | 2018-03-20 21:33:36 | 355582571 | 20851888 | 1521570805 | buy  | 8805.27999980 | 0.00136569 |  12.02528284 |
| 53 | 2018-03-20 21:33:36 | 355582576 | 20851889 | 1521570806 | buy  | 8805.27999980 | 0.00400478 |  35.26320923 |
| 54 | 2018-03-20 21:33:36 | 355582577 | 20851890 | 1521570806 | sell | 8805.00000000 | 0.00028395 |   2.50017975 |
| 55 | 2018-03-20 21:33:36 | 355582578 | 20851891 | 1521570806 | sell | 8805.00000000 | 0.00028395 |   2.50017975 |
| 56 | 2018-03-20 21:33:36 | 355582579 | 20851892 | 1521570806 | sell | 8805.00000000 | 0.00017037 |   1.50010785 |
| 57 | 2018-03-20 21:33:36 | 355582581 | 20851893 | 1521570806 | sell | 8805.00000000 | 0.00028395 |   2.50017975 |
| 58 | 2018-03-20 21:33:36 | 355582583 | 20851894 | 1521570806 | sell | 8805.00000000 | 0.00028395 |   2.50017975 |
| 59 | 2018-03-20 21:33:36 | 355582593 | 20851895 | 1521570808 | buy  | 8805.27999978 | 0.00085355 |   7.51574674 |
| 60 | 2018-03-20 21:33:36 | 355582597 | 20851896 | 1521570809 | sell | 8805.00000000 | 0.00017037 |   1.50010785 |
| 61 | 2018-03-20 21:33:36 | 355582599 | 20851897 | 1521570809 | sell | 8805.00000000 | 0.00017037 |   1.50010785 |
| 62 | 2018-03-20 21:33:36 | 355582601 | 20851898 | 1521570809 | sell | 8805.00000000 | 0.00017037 |   1.50010785 |
| 63 | 2018-03-20 21:33:36 | 355582602 | 20851899 | 1521570809 | sell | 8805.00000000 | 0.00017037 |   1.50010785 |
| 64 | 2018-03-20 21:33:36 | 355582604 | 20851900 | 1521570810 | buy  | 8805.27999977 | 0.01230000 | 108.30494399 |
+----+---------------------+-----------+----------+------------+------+---------------+------------+--------------+
15 rows in set (0.00 sec)
 
MariaDB [polo]> SELECT COUNT(1) FROM trade;
+----------+
| COUNT(1) |
+----------+
|     3846 |
+----------+
1 row in set (0.00 sec)
  
 
  
Чтобы экспортировать БД
$ mysqldump -u u -p polo > polo-dump.sql



Импортировать базу пароль: secret (пользователь u)
  
Чтобы импортировать БД
В первый раз нужно ее создать:

$ sudo mysql -u root -p
(Можно задать пароль)

MariaDB [(none)]> create database polo;

Задать учетную запись u для базы polo с паролем secret

MariaDB [(none)]> grant all on polo.* to 'u' identified by 'secret';

MariaDB [(none)]> quit

$ mysql -u u -p polo
 
 
$ mysql -u u -p polo < polo-dump.sql
Некоторые команды делать не нужно: 
 
MariaDB [polo]> select * from trade;
Empty set (0.01 sec)
 
 
MariaDB [polo]> delete from  trade;
Query OK, 13 rows affected (0.02 sec)
 
 
MariaDB [polo]> show tables;
+----------------+
| Tables_in_polo |
+----------------+
| trade          |
+----------------+
1 row in set (0.00 sec)

MariaDB [polo]> drop table trade;
Query OK, 0 rows affected (0.00 sec)


MariaDB [polo]> SHOW TABLES IN polo;
+----------------+
| Tables_in_polo |
+----------------+
| trade          |
+----------------+ 

настройка свечей

import time
import json
import requests
import urllib, http.client
import hmac, hashlib
import mysql.connector
import sys
import os, errno
import calendar
import numpy
import talib

from datetime import datetime

#1518628155 Начало базы 2018-02-14 20:09:15
#print('Начало базы', datetime.fromtimestamp(1518628155))
#Установим дату и время начала тестирования
time_start = (2018, 3, 14, 0, 0, 0, 0, 0, 0) #Время UTC
#timestampstart = time.mktime(time_start) #Локальное время
timestampstart = calendar.timegm(time_start) # время UTC
x=timestampstart
print('Начало тестирования utc ', datetime.utcfromtimestamp(timestampstart))
#Установим дату и время завершения тестирования
time_end = (2018, 3, 15, 0, 0, 0, 0, 0, 0) #Время UTC
#time_end = (2018, 3, 13, 15, 0, 0, 0, 0, 0) #Время UTC
#time_end = (2018, 3, 20, 5, 0, 0, 0, 0, 0) #Время UTC
#timestampend = time.mktime(time_end) #Локальное время
timestampend = calendar.timegm(time_end) # время UTC
print('Заввершение тестирования utc ', datetime.utcfromtimestamp(timestampend))
y=timestampend

PERIOD = 240 #Минут

USE_LOG = True
DEBUG = False # True - выводить отладочную информацию, False - писать как можно меньше
numpy.seterr(all='ignore')


# Свой класс исключений
class ScriptError(Exception):
    pass
class ScriptQuitCondition(Exception):
    pass
    
def is_nan(x):
    return (x is numpy.nan or x != x)


# Получаем данные, необходимые для построения индикаторов
#def get_ticks(pair):
def get_ticks(PER):
    global y
    global x
    #_SQL = """select * from trade"""
    #x=int(time.time())
    #print('y = ',y)
    #print(datetime.fromtimestamp(y))
    pr = PER * 60
    #x= y - pr*50  #Для построения MACD требуется примерно 50 периодов свечей
    #_SQL = """select * from trade where date between 1519318790 and 1519318800; """
    _SQL = """SELECT
                    FLOOR(MIN(`date`)/%s)*%s AS date,
                    SUBSTRING_INDEX(MIN(CONCAT(`date`, '_', id, '_', price)), '_', -1) AS `open`,
                    MAX(price) AS high,
                    MIN(price) AS low,
                    SUBSTRING_INDEX(MAX(CONCAT(`date`, '_', id, '_', price)), '_', -1) AS `close`
              FROM trade
              WHERE date >= %s and date <= %s
              GROUP BY FLOOR(`date`/%s)
              ORDER BY date"""
    #db = mysql.connector.connect(host="localhost", user="u", passwd="secret", db="exmo")
    db = mysql.connector.connect(host="10.8.1.1", user="u", passwd="secret", db="exmo")
    cur = db.cursor()
    cur.execute(_SQL,(pr,pr,x,y,pr))
    sdata=[]
    for item in cur.fetchall():
        sdata.append({'date':int(item[0]),'open':float(item[1]),'high':float(item[2]),'low':float(item[3]),'close':float(item[4])})
    cur.close()
    db.close()
    return sdata

# Выводит всякую информацию на экран, самое важное скидывает в Файл log.txt
def log(*args):
    if USE_LOG:
        l = open("./tester.txt", 'a', encoding='utf-8')
        print(datetime.now(), *args, file=l)
        #print(datetime.fromtimestamp(y+3*60*60), *args, file=l) #Локальное время
        #print(datetime.utcfromtimestamp(y), *args, file=l)  #UTC

        l.close()
    print(datetime.now(),' ', *args)
    #print(datetime.fromtimestamp(y+3*60*60),' ', *args) #Локальное время
    #print(datetime.utcfromtimestamp(y),' ', *args) #UTC

log('свечи PERIOD = ',PERIOD, ' мин')
log('начало запроса', datetime.utcfromtimestamp(x))
log('окончание запроса', datetime.utcfromtimestamp(y))
data=get_ticks(PERIOD)
date=numpy.asarray([int(item['date']) for item in data])
for offset, elem in enumerate(date):
    #print(datetime.fromtimestamp(date[offset]), data[offset]) #Локальное время
    print(datetime.utcfromtimestamp(date[offset]), data[offset]) #UTC

пятница, 16 марта 2018 г.

Pgadmin4 регламентные ежедневные операции

pgadmin4
1. Скачать pgadmin4 v2.1
2. Установить pgadmin4 v2.1
3. Первоначальная настройка






Регламентные ежедневные операции по обслуживанию

1. FULL VACUUM









.

среда, 14 марта 2018 г.

Тестовый стенд

CentOS 7.2.1511, PG 9.6.6-1.1С, Intel E5-2670 v2 @ 2.50GHz (10 VCPU), 32 Gb RAM
 
postgresql.conf
------------------------------------------------------------------------------------------------
DateStyle = 'ISO, DMY'
TimeZone = 'W-SU'

default_text_search_config = 'pg_catalog.russian'

lc_messages = 'C'
lc_monetary = 'ru_RU.UTF8'
lc_numeric = 'ru_RU.UTF8'
lc_time = 'ru_RU.UTF8'

listen_addresses = '0.0.0.0'

log_filename = 'postgresql-%Y-%m-%d.log'
log_rotation_size = '0'
log_timezone = 'W-SU'
log_truncate_on_rotation = 'on'
logging_collector = 'on'

shared_preload_libraries = 'online_analyze, plantuner, auto_explain'

online_analyze.enable = off
online_analyze.verbose = off
online_analyze.table_type = 'temporary'
online_analyze.scale_factor = 0.3
online_analyze.min_interval = 10000
online_analyze.threshold = 500
online_analyze.local_tracking = on

cpu_operator_cost = 0.0005

plantuner.fix_empty_table = on

autovacuum_naptime = '20' # s
#autovacuum_analyze_threshold = 20

bgwriter_delay = '10' # ms
bgwriter_lru_maxpages = '800'
bgwriter_lru_multiplier = '8'

# storage specific
effective_io_concurrency = '2'
random_page_cost = '2'

checkpoint_completion_target = 0.9
#checkpoint_segments = '128'
max_connections = '1000'

synchronous_commit = 'off'
commit_delay = '1000'

# 1C specific
escape_string_warning = 'off'
standard_conforming_strings = 'off'
max_locks_per_transaction = '256'
work_mem = 65536

# pgbadger
log_directory = '/var/log/pgsql'
log_filename = 'postgresql.log'
log_min_duration_statement = 0s
log_autovacuum_min_duration = 0
log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '
log_checkpoints = on
log_connections = on
log_disconnections = on
log_lock_waits = on
log_temp_files = 0

# backup
max_wal_senders = 4
wal_level = hot_standby
wal_keep_segments = 1024
------------------------------------------------------------------------------------------------
postgresql.auto.conf
------------------------------------------------------------------------------------------------
# Do not edit this file manually!
# It will be overwritten by ALTER SYSTEM command.
effective_cache_size = '12288MB'
work_mem = '32MB'
shared_buffers = '12288MB'
maintenance_work_mem = '512MB'
temp_buffers = '32MB'
temp_tablespaces = 'user_temp'
max_files_per_process = '24576'
autovacuum_max_workers = '8'
autovacuum_analyze_scale_factor = '0.01'
autovacuum_vacuum_scale_factor = '0.02'
random_page_cost = '1.5'
log_statement = 'none'
------------------------------------------------------------------------------------------------

Установка 1С 8.3.10 СУБД PostgreSQL версия 9.6.7.1-1C ubuntu 16.04.4 

Обновление статьи ниже:

Установка 1С 8.3.12.1529 СУБД PostgreSQL версия 9.6.7.1-1C ubuntu 16.04.4  

 

В данной статье опишем установку сервера и клиента 1С 8.3.10.2650 с СУБД PostgreSQL версия 9.6.5-4.1С на ubuntu 16.04.3 на virtualbox.
Нам потребуется (все 64 бит):
1. ubuntu 16.04.4
2. 1С берем на сайте 8.3.10.2699 при наличии договора ИТС
3. PostgreSQL версия 9.6.7.1-1C дистрибутивдополнительные модули  при наличии договора ИТС 
4.  Фонты берем etersoft по кнопке получить (после бесплатной регистрации wine.local для ubuntu 16.04 64 бит)
5. Драйверы hasp берем etersoft

1. Устанавливаем ubuntu 16.04.3 desktop без swap файла, т.е. размечаем вручную весь диск ext4 root.
Настройки виртуальной машины - RAM (минимум 4GB)
Сеть - сетевой мост.

Проще всего пробросить в виртуальную машину лицензии 1С:Предприятия 8 посредством локального hasp.


Настройки ubuntu пользователь (привязка в скриптах) user пароль 12345, имя компьютера любое, позже мы его сменим скриптом, как и ip адрес.

После установки, Ctrl +Alt + T (окно терминала)
$ sudo apt update -y
$ sudo apt upgrade -y
$ sudo apt install mc ssh samba -y

Возможно sudo apt upgrade -y не пройдет из за блокировки, тогда sudo reboot и повторите с начала.

$ lsusb
Bus 001 Device 002: ID 80ee:0021 VirtualBox USB Tablet
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

Пробросить hasp средствами VirtualBox

$ lsusb
Bus 001 Device 004: ID 0529:0001 Aladdin Knowledge Systems HASP copy protection dongle
Bus 001 Device 003: ID 0529:0001 Aladdin Knowledge Systems HASP copy protection dongle
Bus 001 Device 002: ID 80ee:0021 VirtualBox USB Tablet
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub


2. Настройка сети скриптом.
Узнаем ip и имя адаптера
$ ip a
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:53:b6:81 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.169/24 brd 192.168.0.255 scope global enp0s3

Откроем firefox (в ubuntu), откроем эту страничку  и скопируем в буфер скрипт настройки сети:

$ nano network.sh

Скопируем из буфера следующий скрипт, в котором Вам нужно исправить ip, адрес шлюза и имя адаптера в соответствии со своей сетью:


#!/bin/bash
# настройка ip и hostname
#----------------------------------------------------------------------
_hostname="kamin"
# real computer
#_iface="enp0s31f6"
# kvm iface
#_iface="ens3"
# virtualbox iface
_iface="enp0s3"
#_iface="enp1s0"
_address="192.168.0.169"
_gateway="192.168.0.1"
_netmask="255.255.255.0"
_nameserver="8.8.8.8"
#----------------------------------------------------------------------
#add a swap file to an Ubuntu 16.04
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
sudo cp /etc/fstab /etc/fstab.bak
sudo echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# отключим сетевой менеджер
#sudo systemctl stop NetworkManager.service
#sudo systemctl disable NetworkManager.service
# настроим статический ip
sudo cat > /tmp/interfaces <<EOF
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
#auto $_iface
#iface $_iface inet dhcp
iface $_iface inet static
address $_address
netmask $_netmask
gateway $_gateway
dns-nameservers $_nameserver
auto $_iface
EOF
sudo cp /tmp/interfaces /etc/network
#sudo rm /etc/resolv.conf
#sudo /bin/su -c "echo 'nameserver $_nameserver' > /etc/resolv.conf"
# изменим hostname и ip
sudo cat > /tmp/hosts <<EOF
127.0.0.1       localhost
$_address       $_hostname
EOF
sudo cp /tmp/hosts /etc
# изменим hostname
sudo hostname $_hostname
sudo /bin/su -c "echo $_hostname > /etc/hostname"
# отключим ip6
sudo /bin/su -c "echo 'net.ipv6.conf.all.disable_ipv6 = 1' >> /etc/sysctl.conf"
sudo /bin/su -c "echo 'net.ipv6.conf.default.disable_ipv6 = 1' >> /etc/sysctl.conf"
sudo /bin/su -c "echo 'net.ipv6.conf.lo.disable_ipv6 = 1' >> /etc/sysctl.conf"
#sudo /bin/su -c "echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf"
sudo /bin/su -c "echo 'vm.swappiness=0' >> /etc/sysctl.conf"
#sudo /bin/su -c "echo 'vm.vfs_cache_pressure = 50' >> /etc/sysctl.conf"
sudo sysctl -p
# перезагрузим сеть
sudo systemctl restart networking.service
#sudo systemctl start networking.service
#sudo systemctl enable networking.service
# Настройка sudo journalctl -b sudo journalctl -b -1 sudo journalctl --list-boots
sudo sed -i 's/#Storage=auto/Storage=persistent/' /etc/systemd/journald.conf
# Отключение уведомлений службы Apport (/var/crash)
sudo sed -i 's/enabled=1/enabled=0/' /etc/default/apport
# Настройка ftp пользователь: test пароль: test
sudo apt install pure-ftpd -y
sudo groupadd ftpgroup
sudo usermod -aG ftpgroup user
sudo ln -s /etc/pure-ftpd/conf/PureDB /etc/pure-ftpd/auth/50pure
sudo mkdir /home/user/test
sudo chown -R user:ftpgroup /home/user/test
#sudo pure-pw useradd test -u user -d /home/user/test
# Заведем пользователя ftp test с паролем test
sudo echo -e "test\ntest\n" | sudo pure-pw useradd test -u user -d /home/user/test
sudo pure-pw mkdb
sudo service pure-ftpd restart
# ubuntu
# Отключим службу ondemand
# (для разгона cpu)
# cat /proc/cpuinfo | grep MHz
# systemctl status ondemand
sudo systemctl stop ondemand
sudo systemctl disable ondemand
# shutdown -r now

Сохраним файл network.sh

Сделаем исполняем
$ chmod +x network.sh

Выполним:

$ ./network.sh

Перезагрузимся

$ sudo reboot

3. Установка СУБД PostgreSQL версия 9.6.5-4.1С и 1c скриптом:

После перезагрузки по сети можно подключиться любым ftp клиентом к ftp серверу на нашей виртуальной машине (по ip или или имени ud1604) пользователь test пароль test и загрузить файлы установки:

Файлы необходимые для установки (предварительно нужно скачать по указанным в начале статьи ссылкам):

postgresql_9.6.5_4.1C_amd64_addon_deb.tar.bz2
postgresql_9.6.5_4.1C_amd64_deb.tar.bz2
server.deb64.tar.gz
client.deb64.tar.gz
fonts-ttf-ms_1.0-eter4ubuntu_all.deb
haspd_7.60-eter1debian_amd64.deb
haspd-modules_7.60-eter1debian_amd64.deb

Исправим bug
Several regex warnings when installing latest postgres update

sudo nano /usr/sbin/pam_getenv
строка 78 заменить
$val =~ s/(?<!\\)\${([^}]+)}/$ENV{$1}||""/eg;
на
$val =~ s/(?<!\\)\$\{([^}]+)\}/$ENV{$1}||""/eg;

Откроем firefox (в ubuntu), откроем эту страничку  и скопируем в буфер скрипт установки СУБД PostgreSQL версия 9.6.5-4.1С и 1c:

$ nano install_post967_1.sh

Скопируем из буфера следующий скрипт:

#!/bin/sh
sudo apt-get install libicu55 postgresql-common -y
sudo cp /usr/share/hunspell/ru_RU.aff  /usr/share/hunspell/ru_RU.aff.copy
sudo sed -e '1s/^\xef\xbb\xbf//' /usr/share/hunspell/ru_RU.aff
mkdir -p /tmp/post
cp /home/user/test/postgresql_9.6.7_1.1C_amd64_deb.tar.bz2 /tmp/post/
cp /home/user/test/postgresql_9.6.7_1.1C_amd64_addon_deb.tar.bz2 /tmp/post/
cd /tmp/post
tar -xvf postgresql_9.6.7_1.1C_amd64_deb.tar.bz2
cd postgresql-9.6.7-1.1C_amd64_deb
sudo dpkg -i *.deb
cd /tmp/post/
tar -xvf postgresql_9.6.7_1.1C_amd64_addon_deb.tar.bz2
cd postgresql-9.6.7-1.1C_amd64_addon_deb
sudo dpkg -i *.deb
sudo -u postgres psql -U postgres -c "alter user postgres with password 'pass';"
sudo cp /etc/postgresql/9.6/main/postgresql.conf /etc/postgresql/9.6/main/postgresql.conf.bak
# установка 1с
mkdir -p /tmp/1ctmp
cd /tmp/1ctmp
sudo apt install imagemagick
sudo apt install -y unixodbc libgsf-1-114 libglib2.0
#ubuntu
#sudo apt install ttf-mscorefonts-installer -y
#debian
#wget  http://ftp.ru.debian.org/debian/pool/contrib/m/msttcorefonts/ttf-mscorefonts-installer_3.6_all.deb
sudo  apt install -y xfonts-utils cabextract
#sudo dpkg -i ttf-mscorefonts-installer_3.6_all.deb
# фонты от Etersoft
#ubuntu
cp /home/user/test/fonts-ttf-ms_1.0-eter4ubuntu_all.deb /tmp/1ctmp
sudo dpkg -i fonts-ttf-ms_1.0-eter4ubuntu_all.deb
sudo apt -f -y install
#debian
#cp /home/user/Загрузки/fonts-ttf-ms_1.0-eter4debian_all.deb /tmp/1ctmp
#sudo dpkg -i fonts-ttf-ms_1.0-eter4debian_all.deb
cp /home/user/test/deb64.tar.gz /tmp/1ctmp
cp /home/user/test/client.deb64.tar.gz /tmp/1ctmp
tar xvzf deb64.tar.gz
tar xvzf client.deb64.tar.gz
sudo dpkg -i 1c*.deb
sudo apt -f -y install
sudo chown -R usr1cv8:grp1cv8 /opt/1C
sudo echo -e "pass\npass\n" | sudo passwd usr1cv8
sudo service srv1cv83 start
#sudo service srv1cv83 status
sudo  apt install -y libc6-i386
mkdir /tmp/hasp
cd /tmp/hasp
#cp /home/user/test/haspd_7.60-eter1debian_amd64.deb /tmp/hasp
#cp /home/user/test/haspd-modules_7.60-eter1debian_amd64.deb /tmp/hasp
cp /home/user/test/haspd_7.60-eter1ubuntu_amd64.deb /tmp/hasp
cp /home/user/test/haspd-modules_7.60-eter1ubuntu_amd64.deb /tmp/hasp
#wget http://download.etersoft.ru/pub/Etersoft/HASP/last/x86_64/Debian/8/haspd_7.60-eter1debian_amd64.deb
#wget http://download.etersoft.ru/pub/Etersoft/HASP/last/x86_64/Ubuntu/16.04/haspd_7.40-eter10ubuntu_amd64.deb
#wget http://download.etersoft.ru/pub/Etersoft/HASP/last/x86_64/Debian/8/haspd-modules_7.60-eter1debian_amd64.deb
#wget http://download.etersoft.ru/pub/Etersoft/HASP/last/x86_64/Ubuntu/16.04/haspd-modules_7.40-eter10ubuntu_amd64.deb
sudo dpkg -i *.deb
sudo apt-get install -f -y
sudo service haspd start
#sudo service haspd status
#sudo shutdown -r now

Сохраним файл install_post967_1.sh

Сделаем исполняем
$ chmod +x  install_post967_1.sh

Выполним:

$ ./install_post967_1.sh
Не встал скриптом imagemagick?
$ sudo apt-get install imagemagick

$ sudo reboot

$ sudo systemctl status postgresql.service
● postgresql.service - PostgreSQL RDBMS
   Loaded: loaded (/lib/systemd/system/postgresql.service; enabled; vendor preset: enabled)
   Active: active (exited) since Ср 2018-03-14 16:45:43 MSK; 7min ago
  Process: 1430 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
 Main PID: 1430 (code=exited, status=0/SUCCESS)
    Tasks: 0
   Memory: 0B
      CPU: 0
   CGroup: /system.slice/postgresql.service

мар 14 16:45:43 kamin systemd[1]: Starting PostgreSQL RDBMS...
мар 14 16:45:43 kamin systemd[1]: Started PostgreSQL RDBMS.
user@kamin:~$

$ sudo ss -tunpl | grep 5432
tcp    LISTEN     0      128       *:5432                  *:*                   users:(("postgres",pid=1269,fd=6))
  
$ sudo systemctl start postgresql.service
$ sudo systemctl restart postgresql.service
$ sudo systemctl stop postgresql.service

$ sudo systemctl status srv1cv83.service
● srv1cv83.service - LSB: Starts and stops the 1C:Enterprise daemons
   Loaded: loaded (/etc/init.d/srv1cv83; bad; vendor preset: enabled)
   Active: active (exited) since Ср 2018-03-14 16:45:46 MSK; 11min ago
     Docs: man:systemd-sysv-generator(8)
  Process: 1215 ExecStart=/etc/init.d/srv1cv83 start (code=exited, status=0/SUCCESS)
    Tasks: 0
   Memory: 0B
      CPU: 0

мар 14 16:45:41 kamin systemd[1]: Starting LSB: Starts and stops the 1C:Enterprise daemons...
мар 14 16:45:41 kamin su[1267]: Successful su for usr1cv8 by root
мар 14 16:45:41 kamin su[1267]: + ??? root:usr1cv8
мар 14 16:45:41 kamin su[1267]: pam_unix(su:session): session opened for user usr1cv8 by (uid=0)
мар 14 16:45:46 kamin srv1cv83[1215]: Starting 1C:Enterprise 8.3 server: OK
мар 14 16:45:46 kamin systemd[1]: Started LSB: Starts and stops the 1C:Enterprise daemons.




$ sudo ss -tlnp | grep :15
LISTEN     0      128          *:1560                     *:*                   users:(("rphost",pid=1402,fd=23))
LISTEN     0      128          *:1540                     *:*                   users:(("rphost",pid=1402,fd=15),("ragent",pid=1305,fd=15))
LISTEN     0      128          *:1541                     *:*                   users:(("rmngr",pid=1325,fd=12))
LISTEN     0      128         :::1560                    :::*                   users:(("rphost",pid=1402,fd=22))
LISTEN     0      128         :::1540                    :::*                   users:(("rphost",pid=1402,fd=14),("ragent",pid=1305,fd=14))
LISTEN     0      128         :::1541                    :::*                   users:(("rmngr",pid=1325,fd=11))      

$ sudo poweroff
$ sudo poweroff

Здесь полезно сделать "консервы".
До подключения базы 1с легко менять ip адрес и название сервера.
Сделаем выгрузку post967.ova

Перезагрузимся, если не делали выгрузку или просто загрузим виртуалку.


Можно подключать базу 1С postgres пароль pass




sudo nano  /etc/postgresql/9.6/main/postgresql.conf

Заменить:

#------------------------------------------------------------------------------
data_directory = '/var/lib/postgresql/9.6/main'        # use data in another directory
hba_file = '/etc/postgresql/9.6/main/pg_hba.conf'    # host-based authentication file
ident_file = '/etc/postgresql/9.6/main/pg_ident.conf'    # ident configuration file
external_pid_file = '/var/run/postgresql/9.6-main.pid'            # write an extra PID file
listen_addresses = '*'        # what IP address(es) to listen on;
port = 5432                # (change requires restart)
max_connections = 1000            # (change requires restart)
unix_socket_directories = '/var/run/postgresql'    # comma-separated list of directories
ssl = false                # (change requires restart)
ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem'        # (change requires restart)
ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'        # (change requires restart)
#------------------------------------------------------------------------------
# RESOURCE USAGE (except WAL)
#------------------------------------------------------------------------------
#shared_buffers = 128MB            # min 128kB
shared_buffers = 12288MB
#temp_buffers = 8MB                     # min 800kB
temp_buffers = 32MB
#work_mem = 4MB                         # min 64kB
work_mem = 32MB
#maintenance_work_mem = 64MB            # min 1MB
maintenance_work_mem = 512MB
dynamic_shared_memory_type = posix    # the default is the first option
#max_files_per_process = 1000           # min 25
max_files_per_process = 24576
#shared_preload_libraries = 'online_analyze, plantuner'    # (change requires restart)
shared_preload_libraries = 'online_analyze, plantuner, auto_explain'
# - Background Writer -

#bgwriter_delay = 200ms                 # 10-10000ms between rounds
bgwriter_delay = 10ms
#bgwriter_delay = 20ms
#bgwriter_lru_maxpages = 100            # 0-1000 max buffers written/round
bgwriter_lru_maxpages = 800
#bgwriter_lru_multiplier = 2.0          # 0-10.0 multiplier on buffers scanned/round
bgwriter_lru_multiplier = 8.0

# - Asynchronous Behavior -

#effective_io_concurrency = 1           # 1-1000; 0 disables prefetching
effective_io_concurrency =  2
#------------------------------------------------------------------------------
# WRITE AHEAD LOG
#------------------------------------------------------------------------------
#wal_level = minimal                    # minimal, replica, or logical
wal_level = hot_standby
fsync = on                             # flush data to disk for crash safety
#synchronous_commit = on                # synchronization level;
synchronous_commit = off
#commit_delay = 0                       # range 0-100000, in microseconds
commit_delay = 1000
#checkpoint_completion_target = 0.5     # checkpoint target duration, 0.0 - 1.0
checkpoint_completion_target = 0.9

#------------------------------------------------------------------------------
# REPLICATION
#------------------------------------------------------------------------------
#max_wal_senders = 0            # max number of walsender processes
max_wal_senders = 4
#wal_keep_segments = 0          # in logfile segments, 16MB each; 0 disables
wal_keep_segments = 1024
#------------------------------------------------------------------------------
# QUERY TUNING
#------------------------------------------------------------------------------
# - Planner Cost Constants -
#random_page_cost = 4.0                 # same scale as above
random_page_cost =  2.0
#random_page_cost = 1.5
#cpu_operator_cost = 0.0025             # same scale as above
cpu_operator_cost = 0.0005
#effective_cache_size = 4GB
effective_cache_size = 12288MB

from_collapse_limit = 20
join_collapse_limit = 20        # 1 disables collapsing of explicit
                    # JOIN clauses
#------------------------------------------------------------------------------
# ERROR REPORTING AND LOGGING
#------------------------------------------------------------------------------

log_destination = 'stderr'        # Valid values are combinations of
logging_collector = on        # Enable capturing of stderr and csvlog
log_directory = 'pg_log'        # directory where log files are written,
#log_filename = 'postgresql-%a.log'    # log file name pattern,
log_filename = 'postgresql-%Y-%m-%d.log'
log_truncate_on_rotation = on        # If on, an existing log file with the
log_rotation_age = 1d            # Automatic rotation of logfiles will
log_rotation_size = 0        # Automatic rotation of logfiles will
#log_min_duration_statement = -1        # -1 is disabled, 0 logs all statements
log_min_duration_statement = 0

# - What to Log -
#log_checkpoints = off
log_checkpoints = on
#log_connections = off
log_connections = on
#log_disconnections = off
log_disconnections = on
#log_line_prefix = '%t [%p-%l] %q%u@%d '                        # special values:
log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '
#log_lock_waits = off                   # log lock waits >= deadlock_timeout
log_lock_waits = on
log_statement = 'none'                  # none, ddl, mod, all
#log_temp_files = -1                    # log temporary files equal or larger
log_temp_files = 0
log_timezone = 'W-SU'
#------------------------------------------------------------------------------
# RUNTIME STATISTICS
#------------------------------------------------------------------------------
stats_temp_directory = '/var/run/postgresql/9.6-main.pg_stat_tmp'

#------------------------------------------------------------------------------
# AUTOVACUUM PARAMETERS
#------------------------------------------------------------------------------

autovacuum = on            # Enable autovacuum subprocess?  'on'
#log_autovacuum_min_duration = -1       # -1 disables, 0 logs all actions and
log_autovacuum_min_duration = 0
#autovacuum_max_workers = 3             # max number of autovacuum subprocesses
autovacuum_max_workers =  4
#autovacuum_naptime = 1min              # time between autovacuum runs
autovacuum_naptime = 20s
#autovacuum_vacuum_scale_factor = 0.2   # fraction of table size before vacuum
autovacuum_vacuum_scale_factor = 0.02
#autovacuum_analyze_scale_factor = 0.1  # fraction of table size before analyze
autovacuum_analyze_scale_factor = 0.01
#------------------------------------------------------------------------------
# CLIENT CONNECTION DEFAULTS
#------------------------------------------------------------------------------

datestyle = 'iso, dmy'
timezone = 'W-SU'
lc_messages = 'ru_RU.UTF-8'            # locale for system error message
lc_monetary = 'ru_RU.UTF-8'            # locale for monetary formatting
lc_numeric = 'ru_RU.UTF-8'            # locale for number formatting
lc_time = 'ru_RU.UTF-8'                # locale for time formatting
default_text_search_config = 'pg_catalog.russian'
#------------------------------------------------------------------------------
# LOCK MANAGEMENT
#------------------------------------------------------------------------------
#max_locks_per_transaction = 150        # min 10
max_locks_per_transaction =  256
#------------------------------------------------------------------------------
# VERSION/PLATFORM COMPATIBILITY
#------------------------------------------------------------------------------
# - Previous PostgreSQL Versions -
#escape_string_warning = on
escape_string_warning = off
#standard_conforming_strings = on
standard_conforming_strings = off
#------------------------------------------------------------------------------
# ERROR HANDLING
#------------------------------------------------------------------------------

#------------------------------------------------------------------------------
# CONFIG FILE INCLUDES
#------------------------------------------------------------------------------

#------------------------------------------------------------------------------
# CUSTOMIZED OPTIONS
#------------------------------------------------------------------------------

#online_analyze.threshold = 50
online_analyze.threshold = 500
#online_analyze.scale_factor = 0.1
online_analyze.scale_factor = 0.3
online_analyze.enable = off
online_analyze.verbose = off
online_analyze.local_tracking = on
online_analyze.min_interval = 10000
online_analyze.table_type = 'temporary'
plantuner.fix_empty_table = on
#------------------------------------------------------------------------------

Сохранить.

$ sudo systemctl restart postgresql.service
$ sudo systemctl restart srv1cv83.service 
.
$ nano changeip.sh

Скопируем из буфера следующий скрипт, в котором Вам нужно исправить ip и адрес шлюза в соответствии со своей сетью:

#!/bin/bash
# настройка ip и hostname
#----------------------------------------------------------------------
_hostname="kamin"
# real computer
#_iface="enp0s31f6"
# kvm iface
#_iface="ens3"
# virtualbox iface
#_iface="enp0s3"
_iface="enp1s0"
_address="192.168.1.95"
_gateway="192.168.1.1"
_netmask="255.255.255.0"
_nameserver="8.8.8.8"
#----------------------------------------------------------------------
# настроим статический ip
sudo cat > /tmp/interfaces <<EOF
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
#auto $_iface
#iface $_iface inet dhcp
iface $_iface inet static
address $_address
netmask $_netmask
gateway $_gateway
dns-nameservers $_nameserver
auto $_iface
EOF
sudo cp /tmp/interfaces /etc/network#sudo rm /etc/resolv.conf
#sudo /bin/su -c "echo 'nameserver $_nameserver' > /etc/resolv.conf"
# изменим hostname и ip
sudo cat > /tmp/hosts <<EOF
127.0.0.1       localhost
$_address       $_hostname
EOF
sudo cp /tmp/hosts /etc
# изменим hostname
sudo hostname $_hostname
sudo /bin/su -c "echo $_hostname > /etc/hostname"
# перезагрузим сеть
sudo systemctl restart networking.service

Сохраним файл changeip.sh

Сделаем исполняем
$ chmod +x changeip.sh

Выполним:

$ ./changeip.sh

понедельник, 5 марта 2018 г.

Тестирование

import time
import json
import requests
import urllib, http.client
import hmac, hashlib
import mysql.connector
import sys

# Если нет нужных пакетов - читаем тут: https://bablofil.ru/python-indicators/
import numpy
import talib

from datetime import datetime

#Установим дату и время начала тестирования
time_start = (2018, 2, 28, 0, 0, 0, 0, 0, 0)
timestampstart = time.mktime(time_start)
#print(timestampstart)
print('Начало тестирования', datetime.fromtimestamp(timestampstart))
#Установим дату и время завершения тестирования
time_end = (2018, 3, 4, 0, 0, 0, 0, 0, 0)
timestampend = time.mktime(time_end)
#print(timestampend)
print('Завершение тестирования',datetime.fromtimestamp(timestampend))

#y=int(time.time()) - 3600*24*2
y=int(timestampstart)

#print(datetime.fromtimestamp(y))
PERIOD = 5 # Период в минутах для построения свечей краткосрочного MACD
BEAR_PERC = 100  # % что считаем поворотом при медведе (подробности - https://bablofil.ru/macd-python-stock-bot/
BULL_PERC = 0  # % что считаем поворотом при быке (поймать максимум 99)
BUY=True
PROFIT = 1

# ключи API, которые предоставила exmo
#API_KEY = 'K-            кей'
# обратите внимание, что добавлена 'b' перед строкой
#API_SECRET = b'S-секрет'

# Список пар, на которые торгуем
MARKETS = [
    'BTC_USD'
]

CAN_SPEND = 20 # Сколько USD готовы вложить в бай
MARKUP = 0.001 # 0.001 = 0.1% - Какой навар со сделки хотим получать

STOCK_FEE = 0.002 # Какую комиссию берет биржа
#PERIOD = 4 # Период в минутах для построения свечей
ORDER_LIFE_TIME = 0.5 # Через сколько минут отменять неисполненный ордер на покупку 0.5 = 30 сек.

USE_MACD = True # True - оценивать тренд по MACD, False - покупать и продавать невзирая ни на что



API_URL = 'api.exmo.me'
API_VERSION = 'v1'

#USE_LOG = False
USE_LOG = True

DEBUG = False # True - выводить отладочную информацию, False - писать как можно меньше

numpy.seterr(all='ignore')

curr_pair = None

# Свой класс исключений
class ScriptError(Exception):
    pass
class ScriptQuitCondition(Exception):
    pass
    
# все обращения к API проходят через эту функцию
def call_api(api_method, http_method="POST", **kwargs):
    
    payload = {'nonce': int(round(time.time()*1000))}

    if kwargs:
        payload.update(kwargs)
    payload =  urllib.parse.urlencode(payload)

    H = hmac.new(key=API_SECRET, digestmod=hashlib.sha512)
    H.update(payload.encode('utf-8'))
    sign = H.hexdigest()
    
    headers = {"Content-type": "application/x-www-form-urlencoded",
           "Key":API_KEY,
           "Sign":sign}
    conn = http.client.HTTPSConnection(API_URL, timeout=90)
    conn.request(http_method, "/"+API_VERSION + "/" + api_method, payload, headers)
    response = conn.getresponse().read()
    
    conn.close()

    try:
        obj = json.loads(response.decode('utf-8'))

        if 'error' in obj and obj['error']:
            raise ScriptError(obj['error'])
        return obj
    except json.decoder.JSONDecodeError:
        raise ScriptError('Ошибка анализа возвращаемых данных, получена строка', response)

# Получаем с биржи данные, необходимые для построения индикаторов
#def get_ticks(pair):
def get_ticks(pair, PER):
    global y
    #print('PER =', PER)
    #resource = requests.get('https://api.exmo.me/v1/trades/?pair=%s&limit=10000' % pair)
    #data = json.loads(resource.text)
    #_SQL = """select * from trade"""
    #x=int(time.time())
    print(datetime.fromtimestamp(y))
    pr = PER * 60
    x= y - pr*100
    #_SQL = """select * from trade where date between 1519318790 and 1519318800; """
    _SQL = """SELECT
                    FLOOR(MIN(`date`)/%s)*%s AS date,
                    SUBSTRING_INDEX(MIN(CONCAT(`date`, '_', id, '_', price)), '_', -1) AS `open`,
                    MAX(price) AS high,
                    MIN(price) AS low,
                    SUBSTRING_INDEX(MAX(CONCAT(`date`, '_', id, '_', price)), '_', -1) AS `close`
              FROM trade
              WHERE date >= %s and date <= %s
              GROUP BY FLOOR(`date`/%s)
              ORDER BY date"""
    db = mysql.connector.connect(host="localhost", user="u", passwd="secret", db="exmo")
    cur = db.cursor()
    cur.execute(_SQL,(pr,pr,x,y,pr))
    chart_data = {} # сформируем словарь с ценой закрытия по PERIOD минут
    #s=int(float(data[pair][1]['date'])/(PERIOD*60))*(PERIOD*60) #Время последней свечи, которая все время  меняется
    for item in cur.fetchall():
        d = item[0] # Округляем время сделки до PERIOD минут
        if not d in chart_data:
            chart_data[d] = {'open':0, 'close':0, 'high':0, 'low':0}
        chart_data[d]['close'] = float(item[4])
        chart_data[d]['open'] = float(item[1])
        chart_data[d]['high'] = float(item[2])
        chart_data[d]['low'] = float(item[3])
    cur.close()
    db.close()
    return chart_data
# С помощью MACD делаем вывод о целесообразности торговли в данный момент (https://bablofil.ru/macd-python-stock-bot/)

def get_macd_advice(chart_data):  
    quotes = {}
    quotes['open']=numpy.asarray([chart_data[item]['open'] for item in sorted(chart_data)])
    quotes['close']=numpy.asarray([chart_data[item]['close'] for item in sorted(chart_data)])
    quotes['high']=numpy.asarray([chart_data[item]['high'] for item in sorted(chart_data)])
    quotes['low']=numpy.asarray([chart_data[item]['low'] for item in sorted(chart_data)])
    #print(quotes['close'][-1])

    macd, macdsignal, macdhist = talib.MACD(quotes['close'], fastperiod=12, slowperiod=26, signalperiod=9)
    slowk, slowd = talib.STOCH(quotes['high'], quotes['low'], quotes['close'], fastk_period=21, slowk_period=1, slowk_matype=0, slowd_period=3, slowd_matype=0)
    #macd, macdsignal, macdhist = talib.MACD(numpy.asarray([chart_data[item] for item in sorted(chart_data)]), fastperiod=12, slowperiod=26, signalperiod=9)
    #real  = talib.RSI(numpy.asarray([chart_data[item] for item in sorted(chart_data)]), timeperiod=14)
    real = talib.AROONOSC(quotes['high'], quotes['low'], timeperiod=14)
    idx = numpy.argwhere(numpy.diff(numpy.sign(macd - macdsignal)) != 0).reshape(-1) + 0
    inters = []
    for offset, elem in enumerate(macd):
        if offset in idx:
            inters.append(elem)
        else:
            inters.append(numpy.nan)
    trand = 'BULL' if macd[-1] > macdsignal[-1] else 'BEAR'
    max_v = 0
    growing = False
    for offset, elem in enumerate(macdhist):
        growing = False      
        curr_v = macd[offset] - macdsignal[offset]
        if abs(curr_v) > abs(max_v):
            max_v = curr_v
        perc = curr_v/max_v        
        if      (macd[offset] > macdsignal[offset]): # восходящий тренд
            v = 1
            growing = True
            mc = macd[offset]
        else:
            v = 0
        if offset in idx and not numpy.isnan(elem):
            # тренд изменился
            max_v = curr_v = 0 # обнуляем пик спреда между линиями
        #hist_data.append(v*1000)
    #hist_data2 = []
    for offset, elem in enumerate(slowk):
        a=20
        p_a=float(slowk[offset-1])
        p_b=float(slowd[offset-1])
        p_c=float(slowd[offset])
        p_d=float(slowk[offset])
        try:
            if (p_a<a and p_b<a and p_c<a and p_d<a) and (p_a==p_b and p_a==p_d):
                av_point=a/2
            elif (p_a>100-a and p_b>100-a and p_c>100-a and p_d>100-a) and (p_a==p_b and p_a==p_d):
                av_point=100-a/2
            else:
                av_point=((p_c-p_b)*(p_a-p_b)/((p_c-p_b)+(p_a-p_d)))+p_b
        except:
            print('деление на 0?')
        v=0
        if (slowk[offset-1] < slowd[offset-1] and slowk[offset] >= slowd[offset] and av_point<a):
            v = -1 # Покупать!
        if (slowk[offset-1] > slowd[offset-1] and slowk[offset] <= slowd[offset] and av_point>80):
            #activity_time = True
            v= 1 # Продовать!
        #hist_data2.append(v)
    #return ({'curr':(macd[-1] -  macdsignal[-1]),'macd':mc,  'trand':trand, 'growing':growing,'stoch':v, 'close':quotes['close'][-1],'rsi':real[-1]})
    return ({'trand':trand, 'growing':growing,'stoch':v, 'close':quotes['close'][-1]})
# Выводит всякую информацию на экран, самое важное скидывает в Файл log.txt
def log(*args):
    
    if USE_LOG:
        l = open("./tester.txt", 'a', encoding='utf-8')
        #print(datetime.now(), *args, file=l)
        print(datetime.fromtimestamp(y), *args, file=l)
        l.close()
    #print(datetime.now(),' ', *args)
    print(datetime.fromtimestamp(y),' ', *args)

# Ф-ция для создания ордера на покупку
def create_buy(pair):
    #global USE_LOG
    #USE_LOG = True
    log(pair, "Создаем ордер на покупку")
    #USE_LOG = False  
    
# Ф-ция для создания ордера на продажу
def create_sell(pair):
    #global USE_LOG
    #USE_LOG = True
    log(pair, "Создаем ордер на продажу")
# Ф-ция для определения падения  цены покупки
def good_price(pair): # Возвращает True при  цене продажи > 1.005 цены покупки
    drop = True
    return(drop)
# Бесконечный цикл процесса - основная логика
while True:
    try:
        for pair in MARKETS: # Проходим по каждой паре из списка в начале\           
            try:
                macd_advice = get_macd_advice(chart_data=get_ticks(pair,PERIOD))
                print("Ситуация на рынке:", macd_advice)
                if BUY:
                    #if macd_advice['growing'] and macd_advice['stoch']==-1:
                    if macd_advice['growing']:
                        BUY = False
                        log(pair, "Ситуация на рынке:", macd_advice)
                        PRICE = macd_advice['close']
                        log(pair, "цена покупки:", PRICE)
                        PRICE1 = PRICE *1.005
                        #log(pair, "Продажа не дешевле:", PRICE1)
                        log(pair, "Покупаем")
                        log(pair, "-------------------------------------------")
                else:
                #if False:
                    #if macd_advice['growing'] and macd_advice['stoch']==1:
                    if not macd_advice['growing']:
                        if macd_advice['close'] >= PRICE1:
                            log(pair, "Ситуация на рынке:", macd_advice)
                            #log(pair, "Продажа не дешевле:", PRICE1)
                            PRICE2 = macd_advice['close']     
                            log(pair, "Цена продажи:", PRICE2)
                            BUY =  True
                            PROF = PRICE2/PRICE - 0.004
                            log(pair, "Профит от продажи:", PROF)
                            PROFIT = PROFIT*PROF
                            log(pair, "Профит от начала:", PROFIT)
                            log(pair, "Продаем")
                            log(pair, "-------------------------------------------")
                        #else:
                            #log(pair, "цена покупки:", PRICE)
                            #log(pair, "Ситуация на рынке:", macd_advice)
                            #log(pair, "не продаем дешевле!")
            except ScriptError as e:
                    print(e)
            except ScriptQuitCondition as e:
                print(e)
            except Exception as e:
                print("!!!!",e)
        #time.sleep(1)
        y=y+10 # Прибавляем 10 с.
        if y > timestampend:
            log(pair, "Завершение тестирования!")
            sys.exit()
    except Exception as e:
        print(e)