#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Created on Mon Jul 06 20:00:30 2016

@author: Jiansen
"""
import requests
import threading
import copy
import logging
import os
#import urllib3
import json
from scipy import stats
#from decimal import Decimal, getcontext, ROUND_HALF_DOWN

#from event00 import TickEvent,TickEvent2
#import time
import oandapy
import httplib
import pandas as pd
import math
import numpy as np
import pywt
import time
from settings import STREAM_DOMAIN, API_DOMAIN, ACCESS_TOKEN, ACCOUNT_ID
from param_EUR_USD import MA_dict, threshold_dict,sltp_dict
import Queue

#for writing data
import datetime
from bson.objectid import ObjectId
import pymongo as pm
from pymongo import MongoClient
import statsmodels.tsa.stattools as ts
#requests.adapters.DEFAULT_RETRIES = 5
from warningOps import warning
from seriesADF import getADF
corpid=  'wxf8ba6658b456540b'
secret='f78XFqKjNnNJF8Mpkb3BVh4BMpa-vbChBWMHu653KjFL0-mqT67lDQlt5YaEeD6w'
warn = warning(corpid,secret)
client = MongoClient('localhost',27017)
collection = client.test_database.tick_test 


def getDoc(data):
    lis=data['tick']
    ask=lis['ask']
    bid=lis['bid']
    instrument=lis['instrument']
    time0=datetime.datetime.strptime(lis['time'], '%Y-%m-%dT%H:%M:%S.%fZ')
    date = time0.strftime("%Y-%m-%d")
    hms  = time0.strftime("%H:%M:%S")
    ms   =  time0.microsecond
    sec  =  3600*time0.hour+60*time0.minute+ time0.second
    sec_ms = sec*1000+ms
    post = {u'ask':ask, u'bid': bid,u'instrument': instrument, u'date':date, 
            u'hms':hms,u'ms':ms,u'sec':sec,u'sec_ms':sec_ms}
    return post

def denoise(X,wave0):
    wavelet=wave0
    if len(X)>=8:
        level0= 1
        if np.floor(np.log(len(X)))>7:
           level0= np.floor(np.log(len(X))/2.0) 
        thres = 2*np.sqrt(2*np.log(len(X))/len(X))*np.std(X)
        thres = 0.0
        WaveletCoeffs = pywt.wavedec(X, wavelet, level=level0)
        NewWaveletCoeffs = map (lambda x: pywt.threshold(x, thres, mode='hard'),WaveletCoeffs)
        newWave2 = pywt.waverec( NewWaveletCoeffs, wavelet)
        return newWave2
    else:
        logging.warning( "the series is too short")
        return X


#compute the liquidity index
def ohlcv_lis(lis):
    def get_ohlcv(candle, i):
        return map(candle[i].get,["openMid","highMid","lowMid","closeMid","volume"])    
    ohlcv1 = np.array([get_ohlcv(lis,0)])
    for i in range(1,len(lis)-1,1): # drop the last row
        ohlcv1 = np.concatenate((ohlcv1, np.array([get_ohlcv(lis,i)])),axis=0)
    return ohlcv1

def liq15min(lis):
    def vol_F(q1, q2, q3, q4):
        return (math.sqrt(math.log(q2/q3) - 2.0*(2.0*math.log(2.0) - 1.0)*math.log(q4/q1)))    
    liq = 0.0
    sigma = pd.Series()
    for i in range(0,len(lis),1):
        s1 = vol_F(lis[i,0],lis[i,1],lis[i,2],lis[i,3])
        sigma = np.append(sigma,s1)
    liq = math.sqrt(np.sum(lis[:,4])/100)/np.mean(sigma)
    liq = round(liq)
    return liq
    


#-------------------------#
class Event(object):
    pass
        
class TickEvent2(Event):
    def __init__(self, instrument, time, bid, ask):
        self.type = 'TICK'
        self.instrument = instrument
        self.time = time
        self.bid = bid
        self.ask = ask
        
class LiqEvent(Event):
    def __init__(self, instrument, time, liq):
        self.type = 'LIQ'
        self.instrument = instrument
        self.time = time
        self.liq = liq

class OrderEvent(Event):
    def __init__(self, instrument, units, order_type, side, stopLoss, takeProfit,stra):
        self.type = 'ORDER'
        self.instrument = instrument
        self.units = units
        self.order_type = order_type
        self.side = side
        self.stopLoss = stopLoss,
        self.takeProfit = takeProfit
        self.stra = stra
                
class CloseEvent(Event):
    def __init__(self, instrument,num):
        self.type = 'CLOSE'
        self.instrument = instrument
        self.num = num
#--------------------------Liq------------------------------------------#
class LiqForex(object):
    def __init__(
        self, domain, access_token,
        account_id, instruments,ct, gran, dd, events_queue
    ):
        self.domain = domain
        self.access_token = access_token
        self.account_id = account_id
        self.instruments = instruments
        self.ct = ct
        self.gran=gran
        self.dd= dd
        self.events_queue = events_queue
        
    def getLiq(self):
        try:
            requests.packages.urllib3.disable_warnings()
            s = requests.Session()
            #s.keep_alive = False
            url = "https://" + self.domain + "/v1/candles"
            headers = {'Authorization' : 'Bearer ' + self.access_token}
            params = {'instrument':self.instruments, 'accountId' : self.account_id,
                      'count':self.ct,'candleFormat':'midpoint','granularity':self.gran}
            req = requests.Request('GET', url, headers=headers, params=params)     
            pre = req.prepare()
            logging.info( pre)
            resp = s.send(pre, stream=False, verify=False)
            try:            
                msg=json.loads(resp.text)
            except Exception as e:
                logging.warning( "Caught exception when converting message into json\n" + str(e))
                return   
            if msg.has_key("candles"):    
                time=msg.get("candles")[-1]["time"]
                lis = ohlcv_lis(msg.get("candles"))
                liqS = pd.Series()
                for i in range(0, len(lis)- (self.dd+1) ,1):
                    s2 = liq15min(lis[i:i+self.dd])
                    liqS = np.append(liqS,s2)
                liq=liqS[-1] 
                logging.info( "liq=".format(liq))
                tev = LiqEvent(self.instruments,time,liq)
                self.events_queue.put(tev,False)
        except Exception as e:
            s.close()
            content0 = "Caught exception when connecting to history\n" + str(e)
            logging.warning(content0)
            #warn.tradingWarning(content0) 
    def activeLiq(self,period):
        while True:
            self.getLiq()    
            time.sleep(period)
#--------------------------------------------------------------------#
class StreamingForexPrices(object):
    def __init__(
        self, domain, access_token,
        account_id, instruments,ct, gran, dd, events_queue
    ):
        self.domain = domain
        self.access_token = access_token
        self.account_id = account_id
        self.instruments = instruments
        self.ct = ct
        self.gran=gran
        self.dd= dd
        self.events_queue = events_queue

    def connect_to_stream(self):
        try:
            requests.packages.urllib3.disable_warnings()
            s = requests.Session()  # socket
            url = "https://" + self.domain + "/v1/prices"
            headers = {'Authorization' : 'Bearer ' + self.access_token}
            params = {'instruments' : self.instruments, 'accountId' : self.account_id}
            time.sleep(0.8) # sleep some seconds
            req = requests.Request('GET', url, headers=headers, params=params)
            pre = req.prepare()
            resp = s.send(pre, stream=True, verify=False)
            return resp
        except Exception as e:
            #global s
            s.close()
            content0 = "Caught exception when connecting to stream\n" + str(e)
            logging.warning(content0)
            #warn.tradingWarning(content0)

    def stream_to_queue_old(self,collection):
        response = self.connect_to_stream()
        if response.status_code != 200:
            return
        for line in response.iter_lines(1):
            if line:
                try:
                    msg = json.loads(line)
                except Exception as e:
                    content0 = "Caught exception when converting message into json\n" + str(e)
                    logging.warning(content0)
                    return
                if msg.has_key("instrument") or msg.has_key("tick"):
                    logging.info(msg)
                    instrument = msg["tick"]["instrument"]
                    time = msg["tick"]["time"]
                    bid = msg["tick"]["bid"]
                    ask = msg["tick"]["ask"]
                    tev = TickEvent2(instrument, time, bid, ask)
                    self.events_queue.put(tev,False)
                    post= getDoc(msg)
                    collection.insert_one(post)
        
#--------------
#------
 # new strategy           
class LiqMAStrategy(object):
    """
    """
    def __init__(
        self, access_token, account_id, pairs, units, events, stopLoss1, takeProfit1,stopLoss2, takeProfit2,
        short_window1, long_window1,short_window2, long_window2, idxU, lam, thres1, thres2,thres3, thres4, adf_thres
    ):
        self.access_token = access_token
        self.account_id = account_id

        self.pairs = pairs
        self.units = units
        self.stopLoss1 = stopLoss1
        self.takeProfit1 = takeProfit1
        self.stopLoss2 = stopLoss2
        self.takeProfit2 = takeProfit2
        self.pairs_dict = self.create_pairs_dict()
        self.events = events
        self.short_window1 = short_window1
        self.long_window1 = long_window1
        self.short_window2 = short_window2
        self.long_window2 = long_window2
        self.idxU = idxU
        self.lam = lam
        self.priceLis1 = pd.Series()    #for trends
        self.priceLis2 = pd.Series()    #for reversion
        self.thres1 = thres1
        self.thres2 = thres2
        self.thres3 = thres3
        self.thres4 = thres4
        self.adf_thres = adf_thres


    def create_pairs_dict(self):
        attr_dict = {
            "ticks": 0,
            "tick0": 0,
            "priceLS":0.0,
            "invested": False,
            "short_sma": None,
            "long_sma": None,
            "longShort": None,
            "short_slope":None,
            "long_slope":None,  # False denotes sell, while True denotes buy
            "check": False,
            "orlis":[0,0,0,0],
            "stra": 0,
            "fixed": False
        }
        #pairs_dict = {}
        pairs_dict = copy.deepcopy(attr_dict)
        return pairs_dict

    def check_order(self,check):
        if check== True:
            oanda0 = oandapy.API(environment="practice", access_token=self.access_token)
            responseTrades = oanda0.get_trades(self.account_id,instrument=self.pairs)
            if responseTrades.get("trades")==[]:
                pd = self.pairs_dict
                pd["orlis"].pop(0)
                logging.info(" orlis: "+str(pd["orlis"])) 
                pd["orlis"].append(0)
                logging.info(" orlis: "+str(pd["orlis"])) 
                if pd["orlis"][0:4]==[1,1,0,0]:   
                    logging.warning( "Stop Loss Order Executed!")
                    #warn.tradingWarning(" Stop Loss Order Executed!")
                    pd["invested"]= False
                    pd["fixed"] = False  #position closed, the stra type is free
                    pd["check"] = False
                else:
                    pass
            else:
                pd = self.pairs_dict
                #pd["orlis"][0] = copy.copy(pd["orlis"][1])
                pd["orlis"].pop(0)
                pd["orlis"].append(1)
                logging.info("not empty- orlis: "+str(pd["orlis"])) 
                pd["invested"]= True
                pd["fixed"] = True  #position closed, the stra type is free
                pd["check"] = True              
        else:
            pass

    def getSlope(self,aa):
        '''
        return the slope ratio of a time series
        ---args---
        aa: a (np.ndarray) object as a time series
        '''
        return stats.linregress(np.arange(0,len(aa),1),aa)[0]

    def get_new_price_lis(self,price_lis,pairs_dict,window):
        '''
        change the attributes in pairs_dict and return it
        Arguments:
            pairs_dict {[type]} -- [description]
             {[type]} -- [description]
        '''
        newPriceLis =  denoise(price_lis,'db4')
        pairs_dict["short_sma"] = np.mean(newPriceLis[-window:])
        pairs_dict["long_sma"] =  np.mean(newPriceLis) 
        return newPriceLis 

    def compute_slope(self,price_lis,window_length,k):
        '''[summary]
        compute the slope ratio for a short time series
        Arguments:
            price_lis {np.ndarray} -- the filtered time series to compute the slope ratio
            for both SMA and LMA
            default: newPriceLis
            window_length {[type]} -- a parameter for the SMA
            k: an parameter for performing average, default->0.5
            default: self.short_window2
        Returns:
            [float] -- [the slope ratio]
        '''
        amp = lambda lis: (lis-lis[0])*10000.0
        pShort =   amp(price_lis[-window_length:])
        pLong =  amp(price_lis)
        #compute the slope ratio
        aveSlope = k*self.getSlope(pShort)+ (1-k)*self.getSlope(pLong)   
        return aveSlope

    def set_invested_check_fixed(self,pair_dict,invested_bool,check_bool,fixed_bool):
        pair_dict["invested"] = invested_bool
        pair_dict["check"] = check_bool
        pair_dict["fixed"] = fixed_bool
        time.sleep(0.0)                  

    def calculate_signals(self, event):
        #if True:        
        global liqIndex
        global newPriceLis
        if event.type == 'TICK':
            price = (event.bid+event.ask)/2.000
            self.priceLis1 = np.append(self.priceLis1,price)
            self.priceLis2 = np.append(self.priceLis2,price)
            if len(self.priceLis1)>max([self.long_window1,self.long_window2]):
                self.priceLis1=self.priceLis1[-self.long_window1:]
                self.priceLis2=self.priceLis2[-self.long_window2:]
            else:
                pass
            #liqIndex= event.liq
            logging.info("liqIndex= "+str(liqIndex)+"\n")
            logging.info("price= "+str(price))
            pd = self.pairs_dict
            logging.info("check"+str(pd["check"]))
            self.check_order(pd["check"])   #check whether the SLTP order is triggered..
            # Only start the strategy when we have created an accurate short window
            logging.info("INVESTED= "+str(pd["invested"]))
            if not pd["invested"]:
                #global price0
                if pd["ticks"]>max([self.long_window1, self.long_window2])+1 and liqIndex > self.idxU:
                    if not pd["fixed"]:
                        critAdf = getADF(collection).priceADF(200,1)
                        if critAdf > self.adf_thres:
                            pd["stra"] = "reversion"
                            newPriceLis = self.get_new_price_lis(self.priceLis2, pd, self.short_window2)
                            aveSlope = self.compute_slope(newPriceLis,self.short_window2, 0.5)
                            logging.info( "REVERSION+aveSlope="+str(aveSlope))
                        else:
                            pd["stra"] = "trends"
                            newPriceLis = self.get_new_price_lis(self.priceLis1, pd, self.short_window1)
                            aveSlope = self.compute_slope(newPriceLis,self.short_window1, 0.5)
                            logging.info("TRENDS+aveSlope="+str(aveSlope))
                    else:
                        raise ValueError("pd[fixed] should be False!")

                    price0, price1 = event.bid, event.ask
                    if pd["stra"] =="trends":
                        if pd["short_sma"] > pd["long_sma"] and aveSlope> self.thres1:
                            side = "buy"
                            logging.info("price02={0}".format(price0))
                            self.set_invested_check_fixed(pd,True,True,True)
                            sl_b, tp_b= round(price0 - self.stopLoss1,5),round(price1 + self.takeProfit1,5)
                            order = OrderEvent(self.pairs, self.units, "market", side, sl_b, tp_b,"Trends")
                            self.events.put(order)
                            pd["longShort"] = True
                            pd["tick0"]= pd["ticks"]
                            pd["priceLS"]= price0
                        elif pd["short_sma"] < pd["long_sma"] and aveSlope< -self.thres1:
                            side = "sell"
                            logging.info("price01={0}".format(price1))
                            self.set_invested_check_fixed(pd,True,True,True)
                            sl_s,tp_s = round(price1 + self.stopLoss1,5),round(price0 - self.takeProfit1,5)
                            order = OrderEvent(self.pairs, self.units, "market", side, sl_s, tp_s,"Trends")
                            self.events.put(order)
                            pd["longShort"] = False
                            pd["tick0"]= pd["ticks"]
                            pd["priceLS"]= price1
                        else:
                            pd["fixed"] = False

                    elif pd["stra"] =="reversion":
                        if pd["short_sma"] > pd["long_sma"] and aveSlope> self.thres3:
                            side = "sell"
                            logging.info("price02={0}".format(price1))
                            self.set_invested_check_fixed(pd,True,True,True)
                            sl_s,tp_s = round(price1+self.stopLoss2,5),round(price0-self.takeProfit2,5)
                            order = OrderEvent(self.pairs, self.units, "market", side, sl_s, tp_s,"reversion")
                            self.events.put(order)
                            pd["longShort"] = False
                            pd["tick0"]= pd["ticks"]
                            pd["priceLS"]= price0
                        elif pd["short_sma"] < pd["long_sma"] and aveSlope< -self.thres3:
                            side = "buy"
                            logging.info("price01={0}".format(price0))
                            self.set_invested_check_fixed(pd,True,True,True)
                            sl_b, tp_b = round(price0-self.stopLoss2,5),round(price1+self.takeProfit2,5)
                            order = OrderEvent(self.pairs, self.units, "market", side, sl_b, tp_b,"reversion")
                            self.events.put(order)
                            pd["longShort"] = True
                            pd["tick0"]= pd["ticks"]
                            pd["priceLS"]= price1
                        else:
                            pd["fixed"] = False
                    else:
                        pass
                else:
                    pass
            elif pd["invested"]:
                sign= 1 if pd["longShort"] == True else -1

                if pd["stra"] =="trends":
                    logging.info("Trends position!")                   
                    newPriceLis = self.get_new_price_lis(self.priceLis1, pd, self.short_window1)
                    basePrice=pd["priceLS"]+sign*self.lam*np.std(self.priceLis1)*np.sqrt(pd["ticks"]-pd["tick0"])
                    logging.info( "basePrice="+str(basePrice))
                    logging.info( "short_sma"+str(pd["short_sma"]))
                    logging.info( "long_sma"+str(pd["long_sma"]))
                    aveSlope = self.compute_slope(newPriceLis,self.short_window1, 0.5)
                    logging.info( "aveSlope="+str(aveSlope))
                    if  not pd["longShort"]  and aveSlope > -self.thres2:
                        #side = "sell"
                        self.set_invested_check_fixed(pd,False,False,False)
                        #warn.tradingWarning(" check->False Executed!")
                        close_order = CloseEvent(self.pairs,0)
                        self.events.put(close_order)
                    elif pd["longShort"] and aveSlope < self.thres2:
                        #side = "buy"
                        self.set_invested_check_fixed(pd,False,False,False)
                        #warn.tradingWarning(" check->False Executed!")
                        close_order = CloseEvent(self.pairs,0)
                        self.events.put(close_order)
                    else: #not closing positions, just keep the pd["fixed"] as True.
                        pd["fixed"] = True  #should we add pd["invested"]

                elif pd["stra"] =="reversion":
                    logging.info( "Reversion position!")                   
                    newPriceLis = self.get_new_price_lis(self.priceLis2, pd, self.short_window2)
                    basePrice=pd["priceLS"]+sign*self.lam*np.std(self.priceLis2)*np.sqrt(pd["ticks"]-pd["tick0"])
                    logging.info( "basePrice="+str(basePrice))
                    logging.info( "short_sma"+str(pd["short_sma"]))
                    logging.info( "long_sma"+str(pd["long_sma"]))
                    aveSlope = self.compute_slope(newPriceLis,self.short_window2, 0.5)
                    logging.info( "aveSlope="+str(aveSlope))
                    if pd["short_sma"] < pd["long_sma"]-0.00006  and not pd["longShort"]:
                        #side = "sell"
                        self.set_invested_check_fixed(pd,False,False,False)
                        #warn.tradingWarning(" check->False Executed!")
                        close_order = CloseEvent(self.pairs,0)
                        self.events.put(close_order)
                    elif pd["short_sma"] > pd["long_sma"]+0.00006 and pd["longShort"]:
                        #side = "buy"
                        self.set_invested_check_fixed(pd,False,False,False)
                        #warn.tradingWarning(" check->False Executed!")
                        close_order = CloseEvent(self.pairs,0)
                        self.events.put(close_order)
                    else:
                        pd["fixed"] = True  #should we add pd["invested"]
                else:
                    pass

            pd["ticks"] += 1
            logging.info("current Tick "+str(pd["ticks"])+"\n"+str(time.ctime()))

#--------------------------------------------------------------------#
class Execution(object):
    def __init__(self, domain, access_token, account_id):
        self.domain = domain
        self.access_token = access_token
        self.account_id = account_id
        self.conn = self.obtain_connection()

    def obtain_connection(self):
        return httplib.HTTPSConnection(self.domain)

    def execute_order(self, event):
        oanda0 = oandapy.API(environment="practice", access_token=self.access_token)
        try:
            responseX = oanda0.create_order(self.account_id,
            instrument=event.instrument,
            units= event.units,
            side= event.side,
            type= event.order_type,
            stopLoss =   event.stopLoss,
            takeProfit = event.takeProfit
            )           
        except Exception as e:
            content0 = "Caught OnadaError when sending the orders\n" + str(e)
            logging.warning(content0)
            return             
        logging.info( "Execute Order ! \n {0}".format(responseX))
        content0 = str(event.stra)+"Execute Order ! "+" "+str(event.side)+" "+ str(event.units)+" units of "+str(event.instrument)
        #warn.tradingWarning(content0)
        logging.info(content0)
        
    def close_order(self, event):
        oanda0 = oandapy.API(environment="practice", access_token=self.access_token)
        response1= oanda0.get_trades(self.account_id,instrument=event.instrument)
        order_lis= response1["trades"]
        if order_lis !=[]:
            for order in order_lis:  #close all trades
                responseX = oanda0.close_trade(self.account_id,trade_id= order['id'])
                logging.info( "Close Order ! \n {0}".format(responseX))
                content0  = "Close Order !" + "profit: "+str(responseX['profit'])+" CLOSE "+str(responseX['instrument'])
                content0  = content0 + " "+str(responseX['side'])+" at "+ str(responseX['price'])
                #warn.tradingWarning(content0)
        else:
            logging.warning("No trade to be closed! :{0}".format(time.ctime()))

#--------------------------------------------------------------------#
def trade(events, strategy,execution,heartbeat):
    """
    """
    global liqIndex
    while True: 
        try:
            event = events.get(False)
        except Queue.Empty:
            pass
        else:
            if event is not None:
                if event.type =='LIQ':
                    liqIndex= event.liq
                    #print "current index ="+str(liqIndex)
                elif event.type == 'TICK':
                    strategy.calculate_signals(event)
                    logging.info( "Tick!")
                elif event.type == 'ORDER':
                    logging.info( "Executing order!")
                    execution.execute_order(event)
                elif event.type == "CLOSE":
                    logging.info( "Close trading!")
                    execution.close_order(event)
        time.sleep(heartbeat)
#--------------------------------------------------------------------#        
if __name__ == "__main__":
    pairs = "EUR_USD"
    logPath = '/home/zheng/data/trading/EUR_USD/'
    logName = 'eur_usd.log'
    logging.basicConfig(filename= os.path.join(logPath,logName),
                    format='%(levelname)s:%(message)s',level=logging.DEBUG)    
    global liqIndex
    liqIndex=0
    ct = 20
    gran ='M15'
    time_dict = {
    "S5": 5,
    "S10": 10,
    "S15": 15,
    "S30": 30,
    "M1": 60,
    "M2": 120 }
    dd = 11
    lam= 0.1     #0.5 basePrice tuning
    units = 100    #100
    #----------Parameters----------------
    short_window1= MA_dict['short_window1']  
    long_window1 = MA_dict['long_window1']
    short_window2= MA_dict['short_window2']
    long_window2 = MA_dict['long_window2']

    idxu = threshold_dict['idxu']    
    thres1= threshold_dict['thres1'] 
    thres2= threshold_dict['thres2'] 
    thres3 = threshold_dict['thres3'] 
    thres4= threshold_dict['thres4'] 
    adf_thres =  threshold_dict['adf_thres']

    sl1 = sltp_dict['sl1']   #10
    tp1 = sltp_dict['tp1']   #10
    sl2 = sltp_dict['sl2']   #10
    tp2 = sltp_dict['tp2']   #10
    #--------------------------------------
    #pairs = "EUR_USD"
    #pip = 10000.0
    heartbeat= 0.2 
    period= 600    
    print 'initial'
    print('MA:\n sw1 {0} lw1 {1} sw2 {2} lw2 {3}'.format(short_window1, long_window1, short_window2, long_window2))
    print('parameters:\n thres1 {0} thres2 {1} thres3 {2} thres4 {3}'.format(thres1,thres2,thres3,thres4))
    print('sltp_parameters:\n {0} {1} {2} {3}'.format(sl1,tp1,sl2,tp2))    
    events = Queue.Queue()
    # initial the threads
    prices = StreamingForexPrices(STREAM_DOMAIN, ACCESS_TOKEN, ACCOUNT_ID, pairs, ct, gran, dd, events)
    liquidity = LiqForex(API_DOMAIN, ACCESS_TOKEN, ACCOUNT_ID, pairs, ct, gran, dd, events)
    execution = Execution(API_DOMAIN, ACCESS_TOKEN, ACCOUNT_ID)
    #strategy = MovingAverageCrossStrategy(pairs, units, events, sl, tp, short_window,long_window)
    strategy = LiqMAStrategy(ACCESS_TOKEN, ACCOUNT_ID, pairs, units, events, sl1, tp1, sl2, tp2, short_window1,long_window1,
        short_window2,long_window2,idxu,lam,thres1,thres2,thres3,thres4,adf_thres)
    # construct the thread
    price_thread = threading.Thread(target=prices.stream_to_queue_old, args=[collection])
    liq_thread = threading.Thread(target= liquidity.activeLiq, args=[period])
    trade_thread = threading.Thread(target=trade, args=(events, strategy,execution,heartbeat))
    print "Full?:",events.full()
    trade_thread.start() 
    price_thread.start()
    liq_thread.start()