Пример #1
0
def get_intra_day_df(num_weeks_back, symbol, time_frame):
    if symbol in Oanda.OandaSymbols:
        return Oanda.get_intraDay_DOHLCV_pandas(num_weeks_back, symbol)
    else:
        if time_frame == '1d':
            return CandleHelper.get_daily_DOHLCV_pandas(symbol, num_weeks_back)

        return CandleHelper.get_intraDay_DOHLCV_pandas(symbol, num_weeks_back)
Пример #2
0
def calc_oz_pandas(df, average_tf='W'):
    print('test')
    print(average_tf)
    new_df = Oanda.resample_DOHLCV_pandas(df, average_tf)
    new_df['DHi'] = new_df['High'] - new_df['Open']
    new_df['DLo'] = new_df['Low'] - new_df['Open']
    new_df['MLo'] = new_df['Open'] + new_df['DLo'].rolling(window=10).mean().shift(1)
    new_df['MHi'] = new_df['Open'] + new_df['DHi'].rolling(window=10).mean().shift(1)
    return new_df
Пример #3
0
def monitor(set_obj, nav_path):
    print('Monitor started...')
    broker1 = forexcom('dummy', set_obj)
    broker2 = Oanda('dummy', set_obj)
    timer = 60 * 5
    time_cum = 0

    init_nav = broker1.get_nav() + broker2.get_nav()
    prev_nav = init_nav
    while True:
        try:
            current_nav = broker1.get_nav() + broker2.get_nav()
            #print ('current NAV: '+str(current_nav)) #for debugging
            time_cum += timer

            weekday = datetime.datetime.today().weekday()
            now = datetime.datetime.now()

            if current_nav - init_nav > -set_obj.get_max_loss():
                if time_cum >= 3600:  #check every hour
                    init_nav = current_nav
                    time_cum = 0

                    if int(now.hour) == 15:  #if 3 pm
                        nav_file = open(nav_path, 'a')
                        writer = csv.writer(nav_file)
                        writer.writerow(
                            [str(now.strftime("%Y%m%d_%H%M%S")), current_nav])

                prev_nav = current_nav
                time.sleep(timer)
            else:
                if current_nav - prev_nav < -set_obj.get_max_loss():
                    send_hotmail('Loss exceeds max limit',
                                 {'msg': 'All threads stopped'}, set_obj)
                    os._exit(
                        0)  #if loss>max loss limit exit the entire program
                else:  # withdraw
                    init_nav = current_nav

        except:
            time.sleep(5)
            monitor(set_obj, nav_path)
Пример #4
0
    def __init__(self, ccy, trd_enabled, set_obj):
        self.broker1 = forexcom(o2f(ccy), set_obj)
        self.broker2 = Oanda(ccy, set_obj)
        self.trd_enabled = trd_enabled
        self.set_obj = set_obj

        self.ccy = ccy  #in XXX_YYY format
        self.locker = threading.Lock()
        self.run = True

        self.bd = get_boundary(self.ccy)
        self.last_quote1 = {'ask': -999999, 'bid': -999999}
        self.last_quote2 = {'ask': -1, 'bid': -1}
        self.time_stamp1 = datetime.datetime(2017, 1, 1, 0, 0, 0, 0)
        self.time_stamp2 = datetime.datetime(2017, 1, 1, 0, 0, 0, 0)
        self.trd_buffer_time = datetime.datetime(2017, 1, 1, 0, 0, 0, 0)
        self.safe_buffer_time = datetime.datetime(2017, 1, 1, 0, 0, 0, 0)
        self.stream_queue = queue.Queue()

        #configuration
        self.max_amount = set_obj.get_max_amount()
        self.amount = set_obj.get_single_amount()  #min amount
        self.latency_limit = set_obj.get_latency_limit()
        self.neg_tol = MAX_NEG_TRD
        self.safe_buffer = SAFE_BUFFER  #seconds
        self.trd_buffer = TRD_BUFFER  #seconds
        self.trd_hour = TRD_HOUR

        self.num_neg_spread = 0
        self.spread_open_act = 0
        self.trd_amount = 0
        self.trd_time = 1
        self.current_amount = 0
        self.profit = 0

        self.check_position(
        )  #initialize is_open flag/open type, get current amount
        self.connect_db()  #<-- True=dev testing
Пример #5
0
def fill_up_to_now(symbol, last_df):
    my_df = last_df.reset_index()
    day_diff = getToday().day - my_df['Date'][0].day
    if day_diff > 4:
        new_df = OZ.generate_overlays_oz_pandas('1h', symbol,
                                                numWeeksBack=200).dropna()
    else:
        new_df = Oanda.get_intraday_pandas_dback(
            symbol, Oanda.H1,
            max(day_diff,
                1))  # get_intraday_pandas_dback(Symbol, 3600, max(DayDiff,1) )
        new_df['Symbol'] = symbol
        new_df['qOpen'] = my_df['qOpen'][0]
        new_df['qLo'] = my_df['qLo'][0]
        new_df['qHi'] = my_df['qHi'][0]
        new_df['mOpen'] = my_df['mOpen'][0]
        new_df['mLo'] = my_df['mLo'][0]
        new_df['mHi'] = my_df['mHi'][0]
        new_df['wOpen'] = my_df['wOpen'][0]
        new_df['wLo'] = my_df['wLo'][0]
        new_df['wHi'] = my_df['wHi'][0]
    return new_df
Пример #6
0
class hft:
    def __init__(self, ccy, trd_enabled, set_obj):
        self.broker1 = forexcom(o2f(ccy), set_obj)
        self.broker2 = Oanda(ccy, set_obj)
        self.trd_enabled = trd_enabled
        self.set_obj = set_obj

        self.ccy = ccy  #in XXX_YYY format
        self.locker = threading.Lock()
        self.run = True

        self.bd = get_boundary(self.ccy)
        self.last_quote1 = {'ask': -999999, 'bid': -999999}
        self.last_quote2 = {'ask': -1, 'bid': -1}
        self.time_stamp1 = datetime.datetime(2017, 1, 1, 0, 0, 0, 0)
        self.time_stamp2 = datetime.datetime(2017, 1, 1, 0, 0, 0, 0)
        self.trd_buffer_time = datetime.datetime(2017, 1, 1, 0, 0, 0, 0)
        self.safe_buffer_time = datetime.datetime(2017, 1, 1, 0, 0, 0, 0)
        self.stream_queue = queue.Queue()

        #configuration
        self.max_amount = set_obj.get_max_amount()
        self.amount = set_obj.get_single_amount()  #min amount
        self.latency_limit = set_obj.get_latency_limit()
        self.neg_tol = MAX_NEG_TRD
        self.safe_buffer = SAFE_BUFFER  #seconds
        self.trd_buffer = TRD_BUFFER  #seconds
        self.trd_hour = TRD_HOUR

        self.num_neg_spread = 0
        self.spread_open_act = 0
        self.trd_amount = 0
        self.trd_time = 1
        self.current_amount = 0
        self.profit = 0

        self.check_position(
        )  #initialize is_open flag/open type, get current amount
        self.connect_db()  #<-- True=dev testing

    def connect_db(self, local=False):

        if local == True:
            self.conn_db = connect(host='localhost',
                                   user='******',
                                   passwd='FN891124mysql',
                                   db='tradingdb')

        else:

            self.conn_db = connect(
                host='mysqlaws.cwdlc79zzkjv.us-east-2.rds.amazonaws.com',
                user='******',
                passwd='FN891124mysqlaws',
                db='tradingdb')

    def insert_trd_rec(self, trd_rec):

        try:
            cur = self.conn_db.cursor()

            values = ''
            key_list = [
                'datetime', 'ccy', 'amount', 'buysell', 'sprd_open',
                'ib_quote', 'oanda_quote', 'fill_price', 'profit'
            ]
            for key in key_list:
                value_tmp = str(
                    trd_rec[key])  #.replace(',','/').replace(':','/')
                #print (str(key)+' : '+value_tmp)
                values += value_tmp + ','
            values = values[0:-1]

            sql = "INSERT INTO fxarb VALUES (" + values + ");"

            #print (sql)
            cur.execute(str(sql))
            cur.close()
            self.conn_db.commit()
        except Exception as error:
            if ('ConnectionAbortedError' in str(error)) == True:
                print(str(error))
                print('error encounted, reconnecting...')
                self.connect_db()
                self.insert_trd_rec(trd_rec)

    def print_stream(self):

        while True:
            print(self.stream_queue.get())
            self.stream_queue.task_done()

    def quotesHandler(self, ls_data):
        self.last_quote1['bid'] = float(ls_data['values']['Bid'])
        self.last_quote1['ask'] = float(ls_data['values']['Offer'])
        self.time_stamp1 = datetime.datetime.now()

        if (self.time_stamp1 - self.trd_buffer_time).total_seconds() > self.trd_buffer and \
                (self.time_stamp1 - self.safe_buffer_time).total_seconds() > self.safe_buffer:
            self.locker.acquire()
            self.execute()
            self.locker.release()
        self.stream_queue.put('Forexcom (' + self.ccy + ')' + ' ' +
                              self.time_stamp1.strftime("%Y-%m-%d %H:%M:%S") +
                              ' ' + str(self.last_quote1))

    def trading(self, broker):

        try:

            if broker == 'Forexcom':

                self.ls_client = LightstreamerClient(
                    self.broker1.username, self.broker1.session_id,
                    "https://push.cityindex.com", "STREAMINGALL")

                try:
                    self.ls_client.connect()
                except Exception as e:
                    print("Unable to connect to Lightstreamer Server", e)

                subscription = LightstreamerSubscription(
                    adapter="PRICES",
                    mode="MERGE",
                    items=["PRICE." + str(self.broker1.market_id)],
                    fields=["Bid", "Offer"])
                subscription.addlistener(self.quotesHandler)

                self.ls_client.subscribe(subscription)

                while True:
                    if self.run == False:
                        self.ls_client.disconnect()
                        return None

            elif broker == 'Oanda':

                params = {
                    "instruments": self.broker2.ccy,
                }

                req = pricing.PricingStream(accountID=self.broker2.account_id,
                                            params=params)
                resp_stream = self.broker2.client.request(req)
                for ticks in resp_stream:
                    if self.run == True:

                        if ticks['type'] != 'HEARTBEAT':

                            self.last_quote2['bid'] = float(
                                ticks['bids'][0]['price'])
                            self.last_quote2['ask'] = float(
                                ticks['asks'][0]['price'])
                            self.time_stamp2 = datetime.datetime.now()
                            if self.time_stamp2.hour == TRD_RESET_HOUR:  #reset daily trade limit
                                self.trd_time = 0

                            if (self.time_stamp2-self.trd_buffer_time).total_seconds()>self.trd_buffer and \
                                    (self.time_stamp2-self.safe_buffer_time).total_seconds()>self.safe_buffer: #only call execute when resume==True
                                self.locker.acquire()
                                self.execute()
                                self.locker.release()

                            self.stream_queue.put(broker + '(' + self.ccy +
                                                  ')' + ' ' +
                                                  self.time_stamp2.strftime(
                                                      "%Y-%m-%d %H:%M:%S") +
                                                  ' ' + str(self.last_quote2))
                    else:
                        return None

            else:

                print('unknwon broker...')
                return None

        except Exception as error:

            try:
                self.locker.release()
            except Exception as lckErr:
                None

            exc_type, exc_obj, exc_tb = sys.exc_info()
            fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
            print(exc_type, fname, exc_tb.tb_lineno)
            if broker == 'Forexcom':
                self.ls_client.disconnect()  #disconnect first
                self.broker1.connect()
            elif broker == 'Oanda':
                self.broker2.connect()

            print(
                str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")) +
                ' ' + broker + ' trading failed: ' + str(error))
            print('restarting ' + broker + ' ...')
            time.sleep(30)
            self.trading(broker)

    '''
    def start(self):
        
        try:
            print (self.ccy+' started...')
            threads=[]
            threads.append(threading.Thread(target=self.trading,args=['Forexcom']))
            threads.append(threading.Thread(target=self.trading,args=['Oanda']))
            threads.append(threading.Thread(target=self.print_stream,args=[]))

            for thread in threads:
                thread.start()

        except Exception as error:
            print (self.ccy, 'error encounter in trading, restarting...')
            time.sleep(5)
            self.start()
    
    '''

    def start(self):

        print(self.ccy + ' started...')
        printThread = threading.Thread(target=self.print_stream, args=[])
        printThread.start()

        while True:

            self.run = True

            threads = []
            threads.append(
                threading.Thread(target=self.trading, args=['Forexcom']))
            threads.append(
                threading.Thread(target=self.trading, args=['Oanda']))

            for thread in threads:
                thread.start()

            time.sleep(RESTART_TIME)

            self.run = False

            for thread in threads:
                thread.join()

            print(datetime.datetime.now(),
                  self.ccy + ' scheduled restarting...')

    def close_position(self):
        self.broker1.close_position()
        self.broker2.close_position()

    def check_position(self):

        broker1_pos_info = self.broker1.get_position()
        broker2_pos_info = self.broker2.get_position()

        #check current open position:
        if broker1_pos_info['units'] == broker2_pos_info[
                'units']:  #if amount are the same in two accounts

            if broker1_pos_info['side'] == 'buy':
                self.current_amount = broker1_pos_info['units']
            else:
                self.current_amount = -broker1_pos_info['units']

        else:  #if amount are not the same in two account close all
            if broker2_pos_info['units'] == 0:
                self.broker1.close_position()
            elif broker1_pos_info['units'] == 0:
                self.broker2.close_position()
            else:
                self.close_position()

            send_hotmail('Unbalanced position (' + self.ccy + '):',
                         {'msg': ' Position closed out'}, self.set_obj)

    def get_trd_amount(self, sprd, dir):
        '''
        avl_amount=0

        if dir=='1': #buy more forex.com
            avl_amount=self.max_amount-self.current_amount
        elif dir=='2': #buy more Oanda
            avl_amount=self.current_amount+self.max_amount
        '''

        self.trd_amount = self.amount

    def execute(self):
        try:
            #ask=buy, bid=sell
            last_quote1_snap = copy.deepcopy(self.last_quote1)
            last_quote2_snap = copy.deepcopy(self.last_quote2)

            trading_time = datetime.datetime.now()
            dt1 = trading_time - self.time_stamp1
            dt2 = trading_time - self.time_stamp2

            if self.trd_time<=MAX_TRD_TIME \
                    and (trading_time.hour in self.trd_hour) \
                    and (last_quote2_snap['bid']-last_quote1_snap['ask'])>=self.bd[0] \
                    and abs(last_quote2_snap['bid']-last_quote1_snap['ask'])<self.bd[1] \
                    and max(dt1.total_seconds(), dt2.total_seconds())<self.latency_limit \
                    and self.current_amount<self.max_amount:

                self.get_trd_amount(last_quote2_snap['bid'] -
                                    last_quote1_snap['ask'],
                                    '1')  #calculate trade amount

                if self.trd_amount != 0:  #if it is zero, then no need to trade

                    if self.trd_enabled == True:
                        fill_price = self.buy1sell2()
                    else:
                        fill_price = {
                            '1': last_quote1_snap['ask'],
                            '2': last_quote2_snap['bid']
                        }

                    if fill_price != -1:

                        if self.ccy[-3:] == 'USD':
                            self.spread_open_act = fill_price[
                                '2'] - fill_price['1']
                        else:
                            self.spread_open_act = (
                                fill_price['2'] - fill_price['1']) / (
                                    (fill_price['1'] + fill_price['2']) / 2)

                        self.current_amount += self.trd_amount  #relative to broker1
                        self.profit = self.spread_open_act * self.trd_amount - self.trd_amount * 0.000095
                        self.trd_time += 1

                        time_now = datetime.datetime.now().strftime(
                            "%Y-%m-%d %H:%M:%S")

                        trd_rec = {
                            'datetime':
                            '\'' + time_now + '\'',
                            'ccy':
                            '\'' + self.ccy + '\'',
                            'amount':
                            self.trd_amount,
                            'buysell':
                            '\'' + 'buy Forex.com/sell Oanda' + '\'',
                            'sprd_open':
                            self.spread_open_act,
                            'forex_quote':
                            '\'' + str(last_quote1_snap).replace('\'', '') +
                            '\'',
                            'oanda_quote':
                            '\'' + str(last_quote2_snap).replace('\'', '') +
                            '\'',
                            'fill_price':
                            '\'' + str(fill_price).replace('\'', '') + '\'',
                            'profit':
                            self.profit
                        }
                        self.insert_trd_rec(trd_rec)
                        send_hotmail('Position opened (' + self.ccy + ')',
                                     trd_rec, self.set_obj)

                        if self.spread_open_act < 0:
                            self.num_neg_spread += 1
                            if self.num_neg_spread >= self.neg_tol:
                                self.safe_buffer_time = datetime.datetime.now()
                        else:
                            self.trd_buffer_time = datetime.datetime.now()
                            self.num_neg_spread = 0


            elif  self.trd_time<=MAX_TRD_TIME \
                    and (trading_time.hour in self.trd_hour) \
                    and (last_quote1_snap['bid']-last_quote2_snap['ask'])>=self.bd[0] \
                    and abs(last_quote1_snap['bid']-last_quote2_snap['ask'])<self.bd[1] \
                    and max(dt1.total_seconds(), dt2.total_seconds())<self.latency_limit \
                    and self.current_amount>-self.max_amount:

                self.get_trd_amount(last_quote1_snap['bid'] -
                                    last_quote2_snap['ask'],
                                    '2')  #calculate trade amount

                if self.trd_amount != 0:  #if it is zero, then no need to trade

                    if self.trd_enabled == True:
                        fill_price = self.sell1buy2()
                    else:
                        fill_price = {
                            '1': last_quote1_snap['bid'],
                            '2': last_quote2_snap['ask']
                        }

                    if fill_price != -1:

                        if self.ccy[-3:] == 'USD':
                            self.spread_open_act = fill_price[
                                '1'] - fill_price['2']
                        else:
                            self.spread_open_act = (
                                fill_price['1'] - fill_price['2']) / (
                                    (fill_price['1'] + fill_price['2']) / 2)
                        self.current_amount -= self.trd_amount
                        self.profit = self.spread_open_act * self.trd_amount - self.trd_amount * 0.000095
                        self.trd_time += 1

                        time_now = datetime.datetime.now().strftime(
                            "%Y-%m-%d %H:%M:%S")
                        trd_rec = {
                            'datetime':
                            '\'' + time_now + '\'',
                            'ccy':
                            '\'' + self.ccy + '\'',
                            'amount':
                            -self.trd_amount,
                            'buysell':
                            '\'' + 'sell Forex.com/buy Oanda' + '\'',
                            'sprd_open':
                            self.spread_open_act,
                            'forex_quote':
                            '\'' + str(last_quote1_snap).replace('\'', '') +
                            '\'',
                            'oanda_quote':
                            '\'' + str(last_quote2_snap).replace('\'', '') +
                            '\'',
                            'fill_price':
                            '\'' + str(fill_price).replace('\'', '') + '\'',
                            'profit':
                            self.profit
                        }
                        self.insert_trd_rec(trd_rec)
                        send_hotmail('Position opened (' + self.ccy + ')',
                                     trd_rec, self.set_obj)

                        if self.spread_open_act < 0:
                            self.num_neg_spread += 1
                            if self.num_neg_spread >= self.neg_tol:

                                self.safe_buffer_time = datetime.datetime.now()
                        else:
                            self.trd_buffer_time = datetime.datetime.now()
                            self.num_neg_spread = 0

        except Exception as error:
            print(self.ccy, 'error encountered, error: ' + str(error))

    def buy1sell2(self):

        threads_trd = []
        threads_trd.append(
            threading.Thread(target=self.broker1.make_mkt_order,
                             args=[self.trd_amount, 'buy', self.last_quote1]))
        threads_trd.append(
            threading.Thread(target=self.broker2.make_mkt_order,
                             args=[self.trd_amount, 'sell']))

        for thread in threads_trd:
            thread.start()

        return {'1': self.last_quote1['ask'], '2': self.last_quote2['sell']}

    def sell1buy2(self):

        threads_trd = []
        threads_trd.append(
            threading.Thread(target=self.broker1.make_mkt_order,
                             args=[self.trd_amount, 'sell', self.last_quote1]))
        threads_trd.append(
            threading.Thread(target=self.broker2.make_mkt_order,
                             args=[self.trd_amount, 'buy']))

        for thread in threads_trd:
            thread.start()

        return {'1': self.last_quote1['bid'], '2': self.last_quote2['ask']}

    '''
    def buy1sell2(self):
        fill_price_sell = self.broker2.make_fok_order(self.trd_amount, 'sell', self.last_quote2['bid'])
        if fill_price_sell>0:
            fill_price_buy = self.broker1.make_mkt_order(self.trd_amount, 'buy', self.last_quote1)
            if fill_price_buy>0:
                return {'1' : fill_price_buy, '2': fill_price_sell}
            else:
                self.close_position()
                send_hotmail('Execution error ('+self.ccy+'):', {'msg':'Oanda not executed'}, self.set_obj)
                return -1
        else:
            return -1

    def sell1buy2(self):
        fill_price_buy = self.broker2.make_fok_order(self.trd_amount, 'buy', self.last_quote2['ask'])
        if fill_price_buy>0:
            fill_price_sell = self.broker1.make_mkt_order(self.trd_amount, 'sell', self.last_quote1)
            if fill_price_sell>0:
                return {'1' : fill_price_sell, '2': fill_price_buy}
            else:
                self.close_position()
                send_hotmail('Execution error ('+self.ccy+'):', {'msg':'Oanda not executed'}, self.set_obj)
                return -1
        else:
            return -1

    '''
    '''
Пример #7
0
def get_weekly_df(num_weeks_back, symbol):
    if symbol in Oanda.OandaSymbols:
        weekly_df = Oanda.get_weekly_dohlcv_pandas(num_weeks_back, symbol)
    else:
        weekly_df = CandleHelper.get_weekly_dohlcv_pandas(num_weeks_back, symbol)
    return weekly_df
Пример #8
0
 def test_get_availableSymbols(self):
     Symbols = Oanda.get_availableSymbols()
     self.assertGreater(len(Symbols), 10)