def __feedDataTable(self):
     opt_data = TableHandler()
     opt_data.copyDataframe(self.dp.getOptionData().getDataFrame())
     stk_data = TableHandler()
     stk_data.copyDataframe(self.dp.getStockData().getDataFrame())
     ptf_data = TableHandler()
     ptf_data.copyDataframe(self.dp.getPortfolioData().getDataFrame())
     self.gui.onRepTableFeed(opt_data, stk_data, ptf_data)
     return
Exemplo n.º 2
0
 def onSaveBtClicked(self):
     rtn = QMessageBox.question(self, 'Confirm', 'Save position changes ?',
                                QMessageBox.Yes, QMessageBox.No)
     if rtn == QMessageBox.Yes:
         data = TableHandler()
         data.copy(self.model.data)
         invalid_rows = PosEditor.findInvalidRows(data)
         if invalid_rows:
             data.delRows(invalid_rows)
         if data.rows > 0:
             self.controler.onEditorClickBtSaveAll(data)
             self.close()
         else:
             cf = QMessageBox.warning(self, 'Error',
                                      'position record invalid !', QMessageBox.Yes)
     return
Exemplo n.º 3
0
 def findInvalidRows(t_data=TableHandler()):
     invalid_rows = list()
     for r in range(0, t_data.rows):
         for h in ['group', 'code', 'dir', 'lots', 'open_price', 'margin']:
             val = t_data.getByHeader(r, h)
             if val is None or val == '':
                 invalid_rows.append(r)
     return invalid_rows
 def __init__(self, gui):
     self.gui = gui
     #original position table
     self.ori_positions = None
     #etf quote
     self.etf = TableHandler()
     self.etf.reset(1, Engine.ETF_QUOTE_HEADERS, -1)
     #marketdata service
     self.md = MarketdataAdaptor()
     #database service
     self.dp = DADAPTOR.DataProxy()
     self.__reloadPositions()
     #flow control
     self.last_sync_time = DT.datetime.now()
     #gui communication
     self.msg = MessageQueue()
     self.msg_event = THD.Event()
     self.msg_thread = THD.Thread(target=self.__handleMessage)
     self.msg_thread.start()
     return
Exemplo n.º 5
0
 def onSaveAllBtClicked(self):
     rtn = QMessageBox.question(self, 'Confirm', 'Save position changes?',
                                QMessageBox.Yes, QMessageBox.No)
     if rtn == QMessageBox.Yes:
         data = TableHandler()
         data.copy(self.model.data)
         invalid_rows = PosEditor.findInvalidRows(data)
         if invalid_rows:
             data.delRows(invalid_rows)
         if data.rows > 0:
             self.controler.onEditorClickBtSaveAll(data)
         else:
             QMessageBox.warning(self, 'Error',
                                 'None valid records!', QMessageBox.Yes)
         #notify
         if invalid_rows:
             info_str = 'Invalid rows deleted:\n%s' % str([i+1 for i in invalid_rows])
             QMessageBox.warning(self, 'Warning', info_str, QMessageBox.Yes)
         else:
             self.close()
     return
 def __init__(self, gui):
     self.gui = gui
     #original position table
     self.ori_positions = None
     #etf quote
     self.etf = TableHandler()
     self.etf.reset(1, Engine.ETF_QUOTE_HEADERS, -1)
     #marketdata service
     self.md  = MarketdataAdaptor()
     #database service
     self.dp = DADAPTOR.DataProxy()
     self.__reloadPositions()
     #flow control
     self.last_sync_time = DT.datetime.now()
     #gui communication
     self.msg = MessageQueue()
     self.msg_event = THD.Event()
     self.msg_thread = THD.Thread(target=self.__handleMessage)
     self.msg_thread.start()
     return
Exemplo n.º 7
0
 def onSaveAllBtClicked(self):
     rtn = QMessageBox.question(self, 'Confirm', 'Save position changes?',
                                QMessageBox.Yes, QMessageBox.No)
     if rtn == QMessageBox.Yes:
         data = TableHandler()
         data.copy(self.model.data)
         invalid_rows = PosEditor.findInvalidRows(data)
         if invalid_rows:
             data.delRows(invalid_rows)
         if data.rows > 0:
             self.controler.onEditorClickBtSaveAll(data)
         else:
             QMessageBox.warning(self, 'Error', 'None valid records!',
                                 QMessageBox.Yes)
         #notify
         if invalid_rows:
             info_str = 'Invalid rows deleted:\n%s' % str(
                 [i + 1 for i in invalid_rows])
             QMessageBox.warning(self, 'Warning', info_str, QMessageBox.Yes)
         else:
             self.close()
     return
 def __feedPositionBaseData(self):
     tdata = TableHandler()
     tdata.copyDataframe(self.ori_positions)
     self.gui.onRepPositionBasedataFeed(tdata)
     return
 def __feedEtfQuote(self):
     snap_etf = TableHandler()
     snap_etf.copy(self.etf)
     self.gui.onRepEtfQuoteFeed(snap_etf)
     return
Exemplo n.º 10
0
 def __feedDataTable(self):
     opt_data = TableHandler()
     opt_data.copyDataframe(self.dp.getOptionData().getDataFrame())
     stk_data = TableHandler()
     stk_data.copyDataframe(self.dp.getStockData().getDataFrame())
     ptf_data = TableHandler()
     ptf_data.copyDataframe(self.dp.getPortfolioData().getDataFrame())
     self.gui.onRepTableFeed(opt_data, stk_data, ptf_data)
     return
Exemplo n.º 11
0
class Engine:
    etf_code = '510050.SH'
    ETF_QUOTE_HEADERS = ('last_price', 'open_price', 'high_price', 'low_price',
                         'update_time')

    STATISTICS_HEADERS = ('implied_vol', 'delta', 'gamma', 'vega', 'theta',
                          'intrnic', 'time_value')

    #-------------------------------------------------------------
    def __init__(self, gui):
        self.gui = gui
        #original position table
        self.ori_positions = None
        #etf quote
        self.etf = TableHandler()
        self.etf.reset(1, Engine.ETF_QUOTE_HEADERS, -1)
        #marketdata service
        self.md = MarketdataAdaptor()
        #database service
        self.dp = DADAPTOR.DataProxy()
        self.__reloadPositions()
        #flow control
        self.last_sync_time = DT.datetime.now()
        #gui communication
        self.msg = MessageQueue()
        self.msg_event = THD.Event()
        self.msg_thread = THD.Thread(target=self.__handleMessage)
        self.msg_thread.start()
        return

    def quit(self):
        self.__pushMsg(MessageTypes.QUIT)
        self.msg_thread.join()

    #-------------------------------------------------------------
    def qryUpdateData(self):
        self.__pushMsg(MessageTypes.UPDATE_QUOTE_DATA)

    def qryEtfQuoteFeed(self):
        self.__pushMsg(MessageTypes.GUI_QUERY_ETF_QUOTE_FEED)

    def qryTableDataFeed(self):
        self.__pushMsg(MessageTypes.GUI_QUERY_TABLE_FEED)

    def qryPositionBasedata(self):
        self.__pushMsg(MessageTypes.GUI_QUERY_POSITION_BASEDATA_FEED)

    def qryCalGreeksSensibilityByGroup(self, option_group_id, stock_group_id,
                                       x_axis_type):
        self.__pushMsg(MessageTypes.GUI_QUERY_CAL_SENSI,
                       (option_group_id, stock_group_id, PassedIndexType.GROUP,
                        x_axis_type))

    def qryCalGreeksSensibilityByPosition(self, option_rows, stock_rows,
                                          x_axis_type):
        self.__pushMsg(
            MessageTypes.GUI_QUERY_CAL_SENSI,
            (option_rows, stock_rows, PassedIndexType.ROW, x_axis_type))

    def qryExerciseCurveByGroup(self, option_group_id, stock_group_id):
        self.__pushMsg(
            MessageTypes.GUI_QUERY_EXERCISE_CURVE,
            (option_group_id, stock_group_id, PassedIndexType.GROUP))

    def qryExerciseCurveByPosition(self, option_rows, stock_rows):
        self.__pushMsg(MessageTypes.GUI_QUERY_EXERCISE_CURVE,
                       (option_rows, stock_rows, PassedIndexType.ROW))

    def qryReloadPositions(self, positions_data=None):
        self.__pushMsg(MessageTypes.GUI_QUERY_RELOAD_POSITIONS, positions_data)

    def qrySavePositionCsv(self):
        self.__pushMsg(MessageTypes.SAVE_POSITION_CSV)

    def __pushMsg(self, msg_type, content=None):
        self.msg.pushMsg(msg_type, content)
        self.msg_event.set()

    def __handleMessage(self):
        try:
            while True:
                msg = self.msg.getMsg()
                if msg is None:
                    self.msg_event.wait()
                    self.msg_event.clear()
                #update marketdata order by user
                elif msg.type is MessageTypes.UPDATE_QUOTE_DATA:
                    self.__updateData()
                #qry engine provide table data
                elif msg.type is MessageTypes.GUI_QUERY_TABLE_FEED:
                    self.__feedDataTable()
                #qry etf data
                elif msg.type is MessageTypes.GUI_QUERY_ETF_QUOTE_FEED:
                    self.__feedEtfQuote()
                #qry position base data for editor
                elif msg.type is MessageTypes.GUI_QUERY_POSITION_BASEDATA_FEED:
                    self.__feedPositionBaseData()
                #cal greeks sensibility
                elif msg.type is MessageTypes.GUI_QUERY_CAL_SENSI:
                    self.__calGreekSensibility(msg.content[0], msg.content[1],
                                               msg.content[2], msg.content[3])

                elif msg.type is MessageTypes.GUI_QUERY_EXERCISE_CURVE:
                    self.__calOptionExerciseProfitCurve(
                        msg.content[0], msg.content[1], msg.content[2])

                elif msg.type is MessageTypes.GUI_QUERY_RELOAD_POSITIONS:
                    self.__reloadPositions(msg.content)

                elif msg.type is MessageTypes.SAVE_POSITION_CSV:
                    self.__savePosition2Csv()

                elif msg.type is MessageTypes.QUIT:
                    break

        except Exception as err:
            self.gui.onEngineError(err)
        #thread terminate
        return

    #-----------------------------------------------------------
    #positions should be a instance of TableHandler
    def __reloadPositions(self, positions=None):
        if type(positions) is TableHandler:
            pos = positions.toDataFrame()
        else:
            pos, err = DADAPTOR.loadPositionCsv()
            if not err is None:
                raise Exception('load position csv failed ...')
        #save pos
        self.ori_positions = pos
        #separate data
        option_rows = list()
        stock_rows = list()
        for r in range(0, pos.shape[0]):
            code = pos['code'].iat[r]
            contract_type = self.md.getContractType(code)
            if contract_type in ['call', 'put']:
                option_rows.append(r)
            else:
                stock_rows.append(r)
        option_df = pos.iloc[option_rows, :]
        stock_df = pos.iloc[stock_rows, :]
        self.dp.initialize(option_df, stock_df)
        self.__updateData(True)
        return

    def __savePosition2Csv(self):
        DADAPTOR.savePositionCsv(self.ori_positions)
        return

    def __updateData(self, update_baseinfo=False):
        self.last_sync_time = DT.datetime.now()
        #stock
        self.__updateEtfData()
        stk = self.dp.getStockData()
        for r in range(0, stk.rows()):
            self.__updateStockRow(r)
        #option
        opt = self.dp.getOptionData()
        for r in range(0, opt.rows()):
            if update_baseinfo:
                self.__updateRowBaseInfos(r)
            self.__updateOptionRow(r)
        #update database
        self.dp.updateData()
        return

    #update etf price data
    def __updateEtfData(self):
        etf_last_price = self.md.getLastprice(Engine.etf_code)
        self.etf.setByHeader(0, 'last_price', etf_last_price)
        self.etf.setByHeader(0, 'update_time',
                             self.md.getLastUpdateTime(Engine.etf_code))
        if not self.etf.getByHeader(0, 'open_price') < 0:
            self.etf.setByHeader(
                0, 'high_price',
                max(etf_last_price, self.etf.getByHeader(0, 'high_price')))
            self.etf.setByHeader(
                0, 'low_price',
                min(etf_last_price, self.etf.getByHeader(0, 'low_price')))
        else:
            O = self.md.getDailyOpen(Engine.etf_code)
            H = self.md.getDailyHigh(Engine.etf_code)
            L = self.md.getDailyLow(Engine.etf_code)
            if O and H and L:
                self.etf.setByHeader(0, 'open_price', O)
                self.etf.setByHeader(0, 'high_price', H)
                self.etf.setByHeader(0, 'low_price', L)
        return

    def __updateStockRow(self, irow):
        pos = self.dp.getStockData()
        last_price = self.etf.getByHeader(0, 'last_price')
        float_profit = ANALYSER.getFloatProfit(
            pos.getByHeader(irow, 'dir'), pos.getByHeader(irow, 'lots'),
            pos.getByHeader(irow, 'open_price'), last_price,
            self.md.getStockMultiplier())
        pos.setByHeader(irow, 'last_price', last_price)
        pos.setByHeader(irow, 'float_profit', float_profit)
        return

    #update basic_infos like expiry, strike_price etc.
    def __updateRowBaseInfos(self, irow):
        pos = self.dp.getOptionData()
        code = pos.getByHeader(irow, 'code')
        pos.setByHeader(irow, 'type', self.md.getContractType(code))
        pos.setByHeader(irow, 'strike', self.md.getStrikePrice(code))
        pos.setByHeader(irow, 'expiry', self.md.getExerciseDate(code))
        pos.setByHeader(irow, 'left_days', self.md.getDaysBeforeExercise(code))
        return

    #update
    def __updateOptionRow(self, irow):
        pos = self.dp.getOptionData()
        code = pos.getByHeader(irow, 'code')
        last_price = self.md.getLastprice(code)
        pos.setByHeader(irow, 'last_price', last_price)
        ###################################
        S = self.etf.getByHeader(0, 'last_price')
        K = pos.getByHeader(irow, 'strike')
        T = pos.getByHeader(irow, 'left_days')
        opt_type = pos.getByHeader(irow, 'type')
        #greeks
        stat = None
        if opt_type.lower() == 'call':
            stat = ANALYSER.getStatistics(S, K, T, last_price, True)
        elif opt_type.lower() == 'put':
            stat = ANALYSER.getStatistics(S, K, T, last_price, False)
        if stat:
            for header in Engine.STATISTICS_HEADERS:
                pos.setByHeader(irow, header, stat[header])
        #trade state
        float_profit = ANALYSER.getFloatProfit(
            pos.getByHeader(irow, 'dir'), pos.getByHeader(irow, 'lots'),
            pos.getByHeader(irow, 'open_price'), last_price,
            self.md.getOptionMultiplier())
        pos.setByHeader(irow, 'float_profit', float_profit)
        return

    def __feedDataTable(self):
        opt_data = TableHandler()
        opt_data.copyDataframe(self.dp.getOptionData().getDataFrame())
        stk_data = TableHandler()
        stk_data.copyDataframe(self.dp.getStockData().getDataFrame())
        ptf_data = TableHandler()
        ptf_data.copyDataframe(self.dp.getPortfolioData().getDataFrame())
        self.gui.onRepTableFeed(opt_data, stk_data, ptf_data)
        return

    def __feedEtfQuote(self):
        snap_etf = TableHandler()
        snap_etf.copy(self.etf)
        self.gui.onRepEtfQuoteFeed(snap_etf)
        return

    def __feedPositionBaseData(self):
        tdata = TableHandler()
        tdata.copyDataframe(self.ori_positions)
        self.gui.onRepPositionBasedataFeed(tdata)
        return

    def __calGreekSensibility(self, option_idx, stock_idx, idx_type,
                              x_axis_type):
        opt = self.dp.getOptionData()
        stk = self.dp.getStockData()
        if idx_type is PassedIndexType.GROUP:
            opt_data = opt.getPositionDataByGroupId(option_idx)
            stk_data = stk.getPositionDataByGroupId(stock_idx)
        elif idx_type is PassedIndexType.ROW:
            opt_data = opt.getPositionDataByRowIdx(option_idx)
            stk_data = stk.getPositionDataByRowIdx(stock_idx)
        else:
            return

        if x_axis_type is XAxisType.PRICE:
            rtn = ANALYSER.getGreeksSensibilityByPrice(
                opt_data, stk_data, self.etf.getByHeader(0, 'last_price'))
        elif x_axis_type is XAxisType.VOLATILITY:
            rtn = ANALYSER.getGreeksSensibilityByVolatility(
                opt_data, stk_data, self.etf.getByHeader(0, 'last_price'))
        elif x_axis_type is XAxisType.TIME:
            rtn = ANALYSER.getGreeksSensibilityByTime(
                opt_data, stk_data, self.etf.getByHeader(0, 'last_price'))
        else:
            return

        self.gui.onRepCalGreeksSensibility(rtn, x_axis_type)
        return

    def __calOptionExerciseProfitCurve(self, option_idx, stock_idx, idx_type):
        opt = self.dp.getOptionData()
        stk = self.dp.getStockData()
        if idx_type is PassedIndexType.GROUP:
            opt_data = opt.getPositionDataByGroupId(option_idx)
            stk_data = stk.getPositionDataByGroupId(stock_idx)
        elif idx_type is PassedIndexType.ROW:
            opt_data = opt.getPositionDataByRowIdx(option_idx)
            stk_data = stk.getPositionDataByRowIdx(stock_idx)
        else:
            return

        rtn = ANALYSER.getExerciseProfitCurve(
            opt_data, stk_data, self.etf.getByHeader(0, 'last_price'))
        self.gui.onRepCalExerciseCurve(rtn)
        return
Exemplo n.º 12
0
                                   QMessageBox.Yes, QMessageBox.No)
        if rtn == QMessageBox.Yes:
            self.controler.onEditorClickBtReloadPosition()
        return

    def onSaveCsvBtClicked(self):
        rtn = QMessageBox.question(self, 'Confirm',
                                   'Writing positions to position.csv?',
                                   QMessageBox.Yes, QMessageBox.No)
        if rtn == QMessageBox.Yes:
            self.controler.onSavePosition2Csv()
        return


#######################################################################
if __name__ == '__main__':
    import sys, random
    app = QApplication(sys.argv)

    pedit = PosEditor()

    th = TableHandler()
    th.reset(10, PosEditor.EDIT_TABLE_HEADERS)
    for r in range(0, 10):
        for h in PosEditor.EDIT_TABLE_HEADERS:
            th.setByHeader(r, h, random.randint(0, 10))

    pedit.wakeupEditor()

    sys.exit(app.exec_())
Exemplo n.º 13
0
 def __feedPositionBaseData(self):
     tdata = TableHandler()
     tdata.copyDataframe(self.ori_positions)
     self.gui.onRepPositionBasedataFeed(tdata)
     return
Exemplo n.º 14
0
 def __feedEtfQuote(self):
     snap_etf = TableHandler()
     snap_etf.copy(self.etf)
     self.gui.onRepEtfQuoteFeed(snap_etf)
     return
Exemplo n.º 15
0
class Engine:
    etf_code = '510050.SH'
    ETF_QUOTE_HEADERS = ('last_price', 'open_price', 'high_price',
                         'low_price', 'update_time')

    STATISTICS_HEADERS = ('implied_vol', 'delta', 'gamma', 'vega',
                          'theta', 'intrnic', 'time_value')

    #-------------------------------------------------------------
    def __init__(self, gui):
        self.gui = gui
        #original position table
        self.ori_positions = None
        #etf quote
        self.etf = TableHandler()
        self.etf.reset(1, Engine.ETF_QUOTE_HEADERS, -1)
        #marketdata service
        self.md  = MarketdataAdaptor()
        #database service
        self.dp = DADAPTOR.DataProxy()
        self.__reloadPositions()
        #flow control
        self.last_sync_time = DT.datetime.now()
        #gui communication
        self.msg = MessageQueue()
        self.msg_event = THD.Event()
        self.msg_thread = THD.Thread(target=self.__handleMessage)
        self.msg_thread.start()
        return

    def quit(self):
        self.__pushMsg(MessageTypes.QUIT)
        self.msg_thread.join()

    #-------------------------------------------------------------
    def qryUpdateData(self):
        self.__pushMsg(MessageTypes.UPDATE_QUOTE_DATA)

    def qryEtfQuoteFeed(self):
        self.__pushMsg(MessageTypes.GUI_QUERY_ETF_QUOTE_FEED)

    def qryTableDataFeed(self):
        self.__pushMsg(MessageTypes.GUI_QUERY_TABLE_FEED)

    def qryPositionBasedata(self):
        self.__pushMsg(MessageTypes.GUI_QUERY_POSITION_BASEDATA_FEED)

    def qryCalGreeksSensibilityByGroup(self, option_group_id, stock_group_id, x_axis_type):
        self.__pushMsg(MessageTypes.GUI_QUERY_CAL_SENSI,
                       (option_group_id, stock_group_id,
                       PassedIndexType.GROUP, x_axis_type))

    def qryCalGreeksSensibilityByPosition(self, option_rows, stock_rows, x_axis_type):
        self.__pushMsg(MessageTypes.GUI_QUERY_CAL_SENSI,
                       (option_rows, stock_rows,
                        PassedIndexType.ROW, x_axis_type))

    def qryExerciseCurveByGroup(self, option_group_id, stock_group_id):
        self.__pushMsg(MessageTypes.GUI_QUERY_EXERCISE_CURVE,
                       (option_group_id, stock_group_id, PassedIndexType.GROUP))

    def qryExerciseCurveByPosition(self, option_rows, stock_rows):
        self.__pushMsg(MessageTypes.GUI_QUERY_EXERCISE_CURVE,
                       (option_rows, stock_rows, PassedIndexType.ROW))

    def qryReloadPositions(self, positions_data=None):
        self.__pushMsg(MessageTypes.GUI_QUERY_RELOAD_POSITIONS, positions_data)

    def qrySavePositionCsv(self):
        self.__pushMsg(MessageTypes.SAVE_POSITION_CSV)

    def __pushMsg(self, msg_type, content=None):
        self.msg.pushMsg(msg_type, content)
        self.msg_event.set()

    def __handleMessage(self):
        try:
            while True:
                msg = self.msg.getMsg()
                if msg is None:
                  self.msg_event.wait()
                  self.msg_event.clear()
                #update marketdata order by user
                elif msg.type is MessageTypes.UPDATE_QUOTE_DATA:
                    self.__updateData()
                #qry engine provide table data
                elif msg.type is MessageTypes.GUI_QUERY_TABLE_FEED:
                    self.__feedDataTable()
                #qry etf data
                elif msg.type is MessageTypes.GUI_QUERY_ETF_QUOTE_FEED:
                    self.__feedEtfQuote()
                #qry position base data for editor
                elif msg.type is MessageTypes.GUI_QUERY_POSITION_BASEDATA_FEED:
                    self.__feedPositionBaseData()
                #cal greeks sensibility
                elif msg.type is MessageTypes.GUI_QUERY_CAL_SENSI:
                    self.__calGreekSensibility(msg.content[0], msg.content[1],
                                               msg.content[2], msg.content[3])

                elif msg.type is MessageTypes.GUI_QUERY_EXERCISE_CURVE:
                    self.__calOptionExerciseProfitCurve(msg.content[0], msg.content[1],
                                                        msg.content[2])

                elif msg.type is MessageTypes.GUI_QUERY_RELOAD_POSITIONS:
                    self.__reloadPositions(msg.content)

                elif msg.type is MessageTypes.SAVE_POSITION_CSV:
                    self.__savePosition2Csv()

                elif msg.type is MessageTypes.QUIT:
                    break

        except Exception as err:
            self.gui.onEngineError(err)
        #thread terminate
        return

    #-----------------------------------------------------------
    #positions should be a instance of TableHandler
    def __reloadPositions(self, positions=None):
        if type(positions) is TableHandler:
            pos = positions.toDataFrame()
        else:
            pos, err = DADAPTOR.loadPositionCsv()
            if not err is None:
                raise Exception('load position csv failed ...')
        #save pos
        self.ori_positions = pos
        #separate data
        option_rows = list()
        stock_rows = list()
        for r in range(0, pos.shape[0]):
            code = pos['code'].iat[r]
            contract_type = self.md.getContractType(code)
            if contract_type in ['call', 'put']:
                option_rows.append(r)
            else:
                stock_rows.append(r)
        option_df = pos.iloc[option_rows, :]
        stock_df = pos.iloc[stock_rows, :]
        self.dp.initialize(option_df, stock_df)
        self.__updateData(True)
        return

    def __savePosition2Csv(self):
        DADAPTOR.savePositionCsv(self.ori_positions)
        return

    def __updateData(self, update_baseinfo=False):
        self.last_sync_time = DT.datetime.now()
        #stock
        self.__updateEtfData()
        stk = self.dp.getStockData()
        for r in range(0, stk.rows()):
            self.__updateStockRow(r)
        #option
        opt = self.dp.getOptionData()
        for r in range(0, opt.rows()):
            if update_baseinfo:
                self.__updateRowBaseInfos(r)
            self.__updateOptionRow(r)
        #update database
        self.dp.updateData()
        return

    #update etf price data
    def __updateEtfData(self):
        etf_last_price = self.md.getLastprice(Engine.etf_code)
        self.etf.setByHeader(0, 'last_price', etf_last_price)
        self.etf.setByHeader(0, 'update_time', self.md.getLastUpdateTime(Engine.etf_code))
        if not self.etf.getByHeader(0, 'open_price') < 0:
            self.etf.setByHeader(0, 'high_price', max(etf_last_price, self.etf.getByHeader(0, 'high_price')))
            self.etf.setByHeader(0, 'low_price', min(etf_last_price, self.etf.getByHeader(0, 'low_price')))
        else:
            O = self.md.getDailyOpen(Engine.etf_code)
            H = self.md.getDailyHigh(Engine.etf_code)
            L = self.md.getDailyLow(Engine.etf_code)
            if O and H and L:
                self.etf.setByHeader(0, 'open_price', O)
                self.etf.setByHeader(0, 'high_price', H)
                self.etf.setByHeader(0, 'low_price', L)
        return

    def __updateStockRow(self, irow):
        pos = self.dp.getStockData()
        last_price = self.etf.getByHeader(0, 'last_price')
        float_profit = ANALYSER.getFloatProfit(pos.getByHeader(irow, 'dir'),
                                               pos.getByHeader(irow, 'lots'),
                                               pos.getByHeader(irow, 'open_price'),
                                               last_price, self.md.getStockMultiplier())
        pos.setByHeader(irow, 'last_price', last_price)
        pos.setByHeader(irow, 'float_profit', float_profit)
        return

    #update basic_infos like expiry, strike_price etc.
    def __updateRowBaseInfos(self, irow):
        pos = self.dp.getOptionData()
        code = pos.getByHeader(irow, 'code')
        pos.setByHeader(irow, 'type', self.md.getContractType(code))
        pos.setByHeader(irow, 'strike', self.md.getStrikePrice(code))
        pos.setByHeader(irow, 'expiry', self.md.getExerciseDate(code))
        pos.setByHeader(irow, 'left_days', self.md.getDaysBeforeExercise(code))
        return

    #update
    def __updateOptionRow(self, irow):
        pos = self.dp.getOptionData()
        code = pos.getByHeader(irow, 'code')
        last_price = self.md.getLastprice(code)
        pos.setByHeader(irow, 'last_price', last_price)
        ###################################
        S = self.etf.getByHeader(0, 'last_price')
        K = pos.getByHeader(irow, 'strike')
        T = pos.getByHeader(irow, 'left_days')
        opt_type = pos.getByHeader(irow, 'type')
        #greeks
        stat = None
        if opt_type.lower() == 'call':
            stat = ANALYSER.getStatistics(S, K, T, last_price, True)
        elif opt_type.lower() == 'put':
            stat = ANALYSER.getStatistics(S, K, T, last_price, False)
        if stat:
            for header in Engine.STATISTICS_HEADERS:
                pos.setByHeader(irow, header, stat[header])
        #trade state
        float_profit = ANALYSER.getFloatProfit(pos.getByHeader(irow, 'dir'),
                                               pos.getByHeader(irow, 'lots'),
                                               pos.getByHeader(irow, 'open_price'),
                                               last_price, self.md.getOptionMultiplier())
        pos.setByHeader(irow, 'float_profit', float_profit)
        return

    def __feedDataTable(self):
        opt_data = TableHandler()
        opt_data.copyDataframe(self.dp.getOptionData().getDataFrame())
        stk_data = TableHandler()
        stk_data.copyDataframe(self.dp.getStockData().getDataFrame())
        ptf_data = TableHandler()
        ptf_data.copyDataframe(self.dp.getPortfolioData().getDataFrame())
        self.gui.onRepTableFeed(opt_data, stk_data, ptf_data)
        return

    def __feedEtfQuote(self):
        snap_etf = TableHandler()
        snap_etf.copy(self.etf)
        self.gui.onRepEtfQuoteFeed(snap_etf)
        return

    def __feedPositionBaseData(self):
        tdata = TableHandler()
        tdata.copyDataframe(self.ori_positions)
        self.gui.onRepPositionBasedataFeed(tdata)
        return

    def __calGreekSensibility(self, option_idx, stock_idx, idx_type, x_axis_type):
        opt = self.dp.getOptionData()
        stk = self.dp.getStockData()
        if idx_type is PassedIndexType.GROUP:
            opt_data = opt.getPositionDataByGroupId(option_idx)
            stk_data = stk.getPositionDataByGroupId(stock_idx)
        elif idx_type is PassedIndexType.ROW:
            opt_data = opt.getPositionDataByRowIdx(option_idx)
            stk_data = stk.getPositionDataByRowIdx(stock_idx)
        else:
            return

        if x_axis_type is XAxisType.PRICE:
            rtn = ANALYSER.getGreeksSensibilityByPrice(opt_data, stk_data,
                                                       self.etf.getByHeader(0, 'last_price'))
        elif x_axis_type is XAxisType.VOLATILITY:
            rtn = ANALYSER.getGreeksSensibilityByVolatility(opt_data, stk_data,
                                                            self.etf.getByHeader(0, 'last_price'))
        elif x_axis_type is XAxisType.TIME:
            rtn = ANALYSER.getGreeksSensibilityByTime(opt_data, stk_data,
                                                      self.etf.getByHeader(0, 'last_price'))
        else:
            return

        self.gui.onRepCalGreeksSensibility(rtn, x_axis_type)
        return

    def __calOptionExerciseProfitCurve(self, option_idx, stock_idx, idx_type):
        opt = self.dp.getOptionData()
        stk = self.dp.getStockData()
        if idx_type is PassedIndexType.GROUP:
            opt_data = opt.getPositionDataByGroupId(option_idx)
            stk_data = stk.getPositionDataByGroupId(stock_idx)
        elif idx_type is PassedIndexType.ROW:
            opt_data = opt.getPositionDataByRowIdx(option_idx)
            stk_data = stk.getPositionDataByRowIdx(stock_idx)
        else:
            return

        rtn = ANALYSER.getExerciseProfitCurve(opt_data, stk_data,
                                              self.etf.getByHeader(0, 'last_price'))
        self.gui.onRepCalExerciseCurve(rtn)
        return
Exemplo n.º 16
0
class MatrixModel(QAbstractTableModel):
    def __init__(self, parent=None):
        super(MatrixModel, self).__init__(parent)
        self.data = TableHandler()
        #signal&slot
        return

    def clearAll(self):
        self.data.clear()
        self.emit(SIGNAL('modelReset()'))

    def clearContent(self):
        self.data.clearContent()
        self.emit(SIGNAL('modelReset()'))

    def setSize(self, rows, col_headers):
        self.data.reset(rows, col_headers)
        self.emit(SIGNAL('modelReset()'))
        return

    def setTableContent(self, table_handler_inst):
        self.data.copyContent(table_handler_inst)
        self.emit(SIGNAL('modelReset()'))
        return

    def appendRows(self, n=1):
        self.data.addRows(n)
        self.emit(SIGNAL('rowsInserted(const QModelIndex &, int, int)'),
                  QModelIndex(), self.data.rows, self.data.rows + n - 1)

    def deleteRows(self, row_list):
        self.data.delRows(row_list)
        self.emit(SIGNAL('modelReset()'))

    def getValue(self, row, column):
        return self.data.get(row, column)

    def getValueByHeader(self, row, header):
        return self.data.getByHeader(row, header)

    #qt inherit & override
    #-----------------------------------------------------------
    def rowCount(self, QModelIndex_parent=None, *args, **kwargs):
        return self.data.rows

    def columnCount(self, QModelIndex_parent=None, *args, **kwargs):
        return self.data.columns

    def headerData(self, p_int, Qt_Orientation, int_role=None):
        if int_role == Qt.DisplayRole:
            if Qt_Orientation == Qt.Horizontal:
                return self.data.getHoriHeader(p_int)
            elif Qt_Orientation == Qt.Vertical:
                return str(p_int + 1)
        return None

    def data(self, QModelIndex, int_role=None):
        if QModelIndex.isValid():
            if int_role == Qt.DisplayRole:
                return self.data.get(QModelIndex.row(), QModelIndex.column())
        return None

    def setData(self, QModelIndex, p_object, int_role=None):
        if int_role == Qt.EditRole:
            self.data.set(QModelIndex.row(), QModelIndex.column(), p_object)
        return True

    def flags(self, QModelIndex):
        return Qt.ItemIsEditable | super(MatrixModel, self).flags(QModelIndex)
Exemplo n.º 17
0
 def __init__(self, parent=None):
     super(MatrixModel, self).__init__(parent)
     self.data = TableHandler()
     #signal&slot
     return
Exemplo n.º 18
0
                self.controler.onEditorClickBtSaveAll(data)
                self.close()
            else:
                cf = QMessageBox.warning(self, 'Error',
                                         'position record invalid !', QMessageBox.Yes)
        return

    def onReloadBtClicked(self):
        rtn = QMessageBox.question(self, 'Confirm', 'Reload from position.csv ?',
                                   QMessageBox.Yes, QMessageBox.No)
        if rtn == QMessageBox.Yes:
            self.controler.onEditorClickBtReloadPosition()
        return

#######################################################################
if __name__ == '__main__':
    import sys, random
    app = QApplication(sys.argv)

    pedit = PosEditor()

    th = TableHandler()
    th.reset(10, PosEditor.EDIT_TABLE_HEADERS)
    for r in range(0, 10):
        for h in PosEditor.EDIT_TABLE_HEADERS:
            th.setByHeader(r, h, random.randint(0,10))

    pedit.wakeupEditor()

    sys.exit(app.exec_())