Автор: Николай Камынин
Тот факт, что программа на QPILE для торгового терминала QUIK должна быть представлена в текстовом виде, создает определенные проблемы для защиты авторских прав при ее распространении.
Для того, чтобы обеспечить некоторую защиту исходного текста программы применяют кодирование переменных таким образом, чтобы понять логику работы программы по ее тексту было затруднительно.
Программа, осуществляющая такое кодирование называется ОБФУСКАТОР.
Предлагаю Вашему вниманию результат работы ОБФУСКАТОРА.
Фрагмент исходного текста программы:
‘ *****************************************************
FUNC detect_position()
table = «ORDERS»
max_index = GET_NUMBER_OF(table)
if(co_index > max_index + 1)
co_index = 1
end if
for orders_i from co_index to max_index
if( GET_VALUE(GET_ITEM(table,orders_i),»SECCODE») == SECCODE _
AND GET_VALUE(GET_ITEM(table,orders_i),»STATUS») == «FILLED» _
AND GET_VALUE(GET_ITEM(table,orders_i),»CLASSCODE») == CLASSCODE _
AND GET_VALUE(GET_ITEM(table,orders_i),»ACCOUNT») == ACCOUNT _
AND 0+GET_VALUE(GET_ITEM(table,orders_i),»NUMBER») > last_order_id )
save_needed = 1
last_order_id = 0+GET_VALUE(GET_ITEM(table,orders_i),»NUMBER»)
order_q = 0+GET_VALUE(GET_ITEM(table,orders_i),»QUANTITY»)
order_op = GET_VALUE(GET_ITEM(table,orders_i),»OPERATION»)
‘ ———————————————————————-
trade_q = 0
trade_p = 0
for trades_i from 1 to GET_NUMBER_OF(«TRADES»)
if(0+GET_VALUE(GET_ITEM(«TRADES»,trades_i),»ORDER_NUMBER») == last_order_id)
qq = 0+GET_VALUE(GET_ITEM(«TRADES»,trades_i),»QUANTITY»)
pp = 0+GET_VALUE(GET_ITEM(«TRADES»,trades_i),»PRICE»)
trade_q = trade_q + qq
trade_p = trade_p + (qq*pp)
end if
end for
if(trade_q > 0)
trade_p = trade_p / trade_q
end if
‘ ———————————————————————-
if(order_q != trade_q)
write_log(«Рассинхронизация заявок и сделок: » & last_order_id & «, » & order_q & «/» & trade_q)
last_order_id=last_order_id-1
RETURN
end if
‘ ———————————————————————-
log_action=»»
if( position == «n» )
set_position(order_op,trade_q,trade_p)
log_action=»Открытие позиции » & position & pquantity
else
if( (position == «L» AND order_op == «BUY») OR (position == «S» AND order_op == «SELL») )
log_action=»Наращивание позиции » & position & pquantity
pprice = pprice * pquantity + trade_p * trade_q
pquantity = pquantity + trade_q
pprice = pprice / pquantity
else
if(trade_q == pquantity)
log_action=»Закрытие позиции » & position & pquantity
position = «n»
pquantity = 0
else
if(trade_q < pquantity)
log_action=»Уменьшение позиции » & position & pquantity
pquantity = pquantity — order_q
else
log_action=»Переворот позиции » & position & pquantity
set_position(order_op,trade_q-pquantity,trade_p)
end if
end if
end if
end if
write_log(log_action & «: » & last_order_id & «, » & order_op & » » & order_q & «*» & FLOOR(trade_p*10)/10)
if(STOP_ORDER_MGR == 1)
check_stop_order()
end if
co_index = orders_i
‘ ———————————————————————-
end if
end for
END FUNC
‘ ***************************************************
‘ * MAIN PROGRAMM *
‘ ***************************************************
DELETE_ALL_ITEMS()
DELETE_ALL_LABELS(GRAPH_TAG)
‘ ***************************************************
get_qdata()
‘ проверим, все ли нужные данные считались из терминала
data_error=0
if(ltime == 0)
data_error = data_error + 1
end if
if(qcap == -1)
data_error = data_error + 2
end if
if(data_error > 0)
output=set_value(output,»A»,»Ожидание»)
add_item(outp_i,output)
output=set_value(output,»A»,»данных… [» & data_error & «]»)
add_item(outp_i,output)
RETURN
end if
if(qcap == 0)
output=set_value(output,»A»,»Ошибка»)
add_item(outp_i,output)
output=set_value(output,»A»,»определения»)
add_item(outp_i,output)
output=set_value(output,»A»,»рабочего»)
add_item(outp_i,output)
output=set_value(output,»A»,»капитала.»)
add_item(outp_i,output)
RETURN
end if
‘ ****************************************************
if(initialized == 0)
if(get_file_len(DATAFILE) == -1)
save_needed = 1
write_log(«Создание файла данных » & DATAFILE)
end if
initialized = 1
init_level_settings()
co_index = GET_NUMBER_OF(«ORDERS») + 1
write_log(«Инициализация: » & SECCODE & «.» & CLASSCODE & » » & co_index)
end if
‘ ***************************************************
if(save_needed == 0)
load_data()
else
save_data()
end if
‘ ***************************************************
detect_position()
get_bar(ldate,ltime)
‘ ***************************************************
if(position == «n»)
if(CALC1_SIZE>0)
exec_calc(CALC1_SIZE,PLOT_CALC1)
end if
if(CALC2_SIZE>0)
exec_calc(CALC2_SIZE,PLOT_CALC2)
end if
if(CALC_SATO>0)
exec_sato()
end if
else
position_calc()
end if
‘ ***************************************************
END_PROGRAM
Данный фрагмент после ОБФУСКАТОРА:
FUNC _17615()
_11352=»ORDERS»
_10735=GET_NUMBER_OF(_11352)
IF(_13740 > _10735+1)
_13740=1
END IF
FOR _15713 FROM _13740 TO _10735
IF(GET_VALUE(GET_ITEM(_11352,_15713),»_14815″)==_14815 AND GET_VALUE(GET_ITEM(_11352,_15713),»STATUS»)==»FILLED»AND GET_VALUE(GET_ITEM(_11352,_15713),»_19441″)==_19441 AND GET_VALUE(GET_ITEM(_11352,_15713),»_12233″)==_12233 AND 0+GET_VALUE(GET_ITEM(_11352,_15713),»NUMBER»)> _11644)
_12176=1
_11644=0+GET_VALUE(GET_ITEM(_11352,_15713),»NUMBER»)
_15951=0+GET_VALUE(GET_ITEM(_11352,_15713),»_18947″)
_15433=GET_VALUE(GET_ITEM(_11352,_15713),»OPERATION»)
_10311=0
_19544=0
FOR _16652 FROM 1 TO GET_NUMBER_OF(«TRADES»)
IF(0+GET_VALUE(GET_ITEM(«TRADES»,_16652),»ORDER_NUMBER»)==_11644)
_19097=0+GET_VALUE(GET_ITEM(«TRADES»,_16652),»_18947″)
_16416=0+GET_VALUE(GET_ITEM(«TRADES»,_16652),»PRICE»)
_10311=_10311+_19097
_19544=_19544+(_19097*_16416)
END IF
END FOR
IF(_10311 > 0)
_19544=_19544/_10311
END IF
IF(_15951 !=_10311)
_12896(«РАССИНХРОНИЗАЦИЯ ЗАЯВОК И СДЕЛОК:»&_11644&»,»&_15951&»/»&_10311)
_11644=_11644-1
RETURN
END IF
_11294=»»
IF(_13275==»N»)
_15519(_15433,_10311,_19544)
_11294=»ОТКРЫТИЕ ПОЗИЦИИ»&_13275&_18661
ELSE
IF((_13275==»L»AND _15433==»BUY»)OR(_13275==»S»AND _15433==»SELL»))
_11294=»НАРАЩИВАНИЕ ПОЗИЦИИ»&_13275&_18661
_13346=_13346*_18661+_19544*_10311
_18661=_18661+_10311
_13346=_13346/_18661
ELSE
IF(_10311==_18661)
_11294=»ЗАКРЫТИЕ ПОЗИЦИИ»&_13275&_18661
_13275=»N»
_18661=0
ELSE
IF(_10311 < _18661)
_11294=»УМЕНЬШЕНИЕ ПОЗИЦИИ»&_13275&_18661
_18661=_18661-_15951
ELSE
_11294=»ПЕРЕВОРОТ ПОЗИЦИИ»&_13275&_18661
_15519(_15433,_10311-_18661,_19544)
END IF
END IF
END IF
END IF
_12896(_11294&»:»&_11644&»,»&_15433&» «&_15951&»*»&FLOOR(_19544*10)/10)
IF(_10340==1)
_18034()
END IF
_13740=_15713
END IF
END FOR
END FUNC
DELETE_ALL_ITEMS()
DELETE_ALL_LABELS(_16060)
_10208()
_16373=0
IF(_15520==0)
_16373=_16373+1
END IF
IF(_19072==-1)
_16373=_16373+2
END IF
IF(_16373 > 0)
_14560=SET_VALUE(_14560,»A»,»ОЖИДАНИЕ»)
ADD_ITEM(_17645,_14560)
_14560=SET_VALUE(_14560,»A»,»ДАННЫХ… [«&_16373&»]»)
ADD_ITEM(_17645,_14560)
RETURN
END IF
IF(_19072==0)
_14560=SET_VALUE(_14560,»A»,»ОШИБКА»)
ADD_ITEM(_17645,_14560)
_14560=SET_VALUE(_14560,»A»,»ОПРЕДЕЛЕНИЯ»)
ADD_ITEM(_17645,_14560)
_14560=SET_VALUE(_14560,»A»,»РАБОЧЕГО»)
ADD_ITEM(_17645,_14560)
_14560=SET_VALUE(_14560,»A»,»КАПИТАЛА.»)
ADD_ITEM(_17645,_14560)
RETURN
END IF
IF(_10180==0)
IF(GET_FILE_LEN(_10529)==-1)
_12176=1
_12896(«СОЗДАНИЕ ФАЙЛА ДАННЫХ»&_10529)
END IF
_10180=1
_14006()
_13740=GET_NUMBER_OF(«ORDERS»)+1
_12896(«ИНИЦИАЛИЗАЦИЯ:»&_14815&».»&_19441&» «&_13740)
END IF
IF(_12176==0)
_17674()
ELSE
_17331()
END IF
_17615()
_10206(_19835,_15520)
IF(_13275==»N»)
IF(_10864>0)
_14614(_10864,_10146)
END IF
IF(_15337>0)
_14614(_15337,_13504)
END IF
IF(_17235>0)
_15263()
END IF
ELSE
_12332()
END IF
END_PROGRAM
Кроме того, данная программа выполняет сборку портфеля
на основе основной программы и библиотек функций, оптимизирует текст программы,
включая в него из библиотек лишь используемые функции,
убирает комментарии и выявляет обращение к функциям,
описание которых отсутствует в библиотеках.
Программа распространяется на коммерческой основе.