추세선 전략추가
This commit is contained in:
@@ -48,6 +48,8 @@ import {
|
||||
import IndicatorPaletteTab from './strategyEditor/IndicatorPaletteTab';
|
||||
import TemplatePaletteTab, { type TemplatePaletteRow } from './strategyEditor/TemplatePaletteTab';
|
||||
import SidewaysFilterPaletteTab from './strategyEditor/SidewaysFilterPaletteTab';
|
||||
import TrendLinePaletteTab from './strategyEditor/TrendLinePaletteTab';
|
||||
import { buildTrendLineConditionNode } from '../utils/trendLinePalette';
|
||||
import { buildSidewaysFilterNode, loadSidewaysPaletteItems } from '../utils/sidewaysFilterPaletteStorage';
|
||||
import {
|
||||
BAND_PALETTE_CHIP_ITEMS,
|
||||
@@ -319,7 +321,7 @@ export default function StrategyEditorPage({
|
||||
const [sellCondition, setSellCondition] = useState<LogicNode | null>(null);
|
||||
const [signalTab, setSignalTab] = useState<SignalTab>('buy');
|
||||
const [rightTab, setRightTab] = useState<'indicators' | 'templates'>('indicators');
|
||||
const [indicatorSubTab, setIndicatorSubTab] = useState<'auxiliary' | 'composite' | 'range'>('auxiliary');
|
||||
const [indicatorSubTab, setIndicatorSubTab] = useState<'auxiliary' | 'composite' | 'range' | 'trendline'>('auxiliary');
|
||||
const [auxiliaryPalette, setAuxiliaryPalette] = useState<PaletteItem[]>(() => loadPaletteItems('auxiliary'));
|
||||
const [compositePalette, setCompositePalette] = useState<PaletteItem[]>(() => loadPaletteItems('composite'));
|
||||
const [sidewaysPalette, setSidewaysPalette] = useState(() => loadSidewaysPaletteItems());
|
||||
@@ -1436,6 +1438,15 @@ export default function StrategyEditorPage({
|
||||
scheduleStrategyPersist();
|
||||
}, [DEF, currentRoot, setCurrentRoot, scheduleStrategyPersist, sidewaysPalette]);
|
||||
|
||||
const applyTrendLine = useCallback((item: { indicatorType: string; leftField?: string }, lookback: number) => {
|
||||
const newNode = buildTrendLineConditionNode(item, buySellTab(signalTab), DEF, lookback);
|
||||
handleEditorStateChange(prev => {
|
||||
const root = prev.root;
|
||||
if (!root) return updateBranchRoot(prev, START_NODE_ID, newNode);
|
||||
return updateBranchRoot(prev, START_NODE_ID, mergeAtRoot(root, newNode, false));
|
||||
});
|
||||
}, [signalTab, DEF, handleEditorStateChange]);
|
||||
|
||||
const templateRows = useMemo(
|
||||
() => buildStrategyTemplatePaletteRows({
|
||||
def: DEF,
|
||||
@@ -2487,6 +2498,16 @@ export default function StrategyEditorPage({
|
||||
>
|
||||
횡보필터
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={`se-palette-subtab se-palette-subtab--trendline${indicatorSubTab === 'trendline' ? ' se-palette-subtab--on' : ''}`}
|
||||
onClick={() => {
|
||||
setIndicatorSubTab('trendline');
|
||||
setSelectedPaletteKey(null);
|
||||
}}
|
||||
>
|
||||
추세
|
||||
</button>
|
||||
</div>
|
||||
{indicatorSubTab === 'auxiliary' ? (
|
||||
<IndicatorPaletteTab
|
||||
@@ -2524,7 +2545,7 @@ export default function StrategyEditorPage({
|
||||
applyPaletteItem(item);
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
) : indicatorSubTab === 'range' ? (
|
||||
<SidewaysFilterPaletteTab
|
||||
def={DEF}
|
||||
items={sidewaysPalette}
|
||||
@@ -2541,6 +2562,21 @@ export default function StrategyEditorPage({
|
||||
applySidewaysFilter(item.id);
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<TrendLinePaletteTab
|
||||
signalType={buySellTab(signalTab)}
|
||||
searchQuery={paletteSearch}
|
||||
selectedItemId={
|
||||
selectedPaletteKey?.startsWith('trendline:')
|
||||
? selectedPaletteKey.slice('trendline:'.length)
|
||||
: null
|
||||
}
|
||||
onSelectItem={id => setSelectedPaletteKey(id ? paletteKey('trendline', id) : null)}
|
||||
onAddToCanvas={(item, lookback) => {
|
||||
selectPalette('trendline', item.id);
|
||||
applyTrendLine(item, lookback);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user